xref: /openbmc/linux/fs/isofs/util.c (revision 976fa9a3)
1 /*
2  *  linux/fs/isofs/util.c
3  */
4 
5 #include <linux/time.h>
6 #include "isofs.h"
7 
8 /*
9  * We have to convert from a MM/DD/YY format to the Unix ctime format.
10  * We have to take into account leap years and all of that good stuff.
11  * Unfortunately, the kernel does not have the information on hand to
12  * take into account daylight savings time, but it shouldn't matter.
13  * The time stored should be localtime (with or without DST in effect),
14  * and the timezone offset should hold the offset required to get back
15  * to GMT.  Thus  we should always be correct.
16  */
17 
18 int iso_date(char * p, int flag)
19 {
20 	int year, month, day, hour, minute, second, tz;
21 	int crtime;
22 
23 	year = p[0];
24 	month = p[1];
25 	day = p[2];
26 	hour = p[3];
27 	minute = p[4];
28 	second = p[5];
29 	if (flag == 0) tz = p[6]; /* High sierra has no time zone */
30 	else tz = 0;
31 
32 	if (year < 0) {
33 		crtime = 0;
34 	} else {
35 		crtime = mktime64(year+1900, month, day, hour, minute, second);
36 
37 		/* sign extend */
38 		if (tz & 0x80)
39 			tz |= (-1 << 8);
40 
41 		/*
42 		 * The timezone offset is unreliable on some disks,
43 		 * so we make a sanity check.  In no case is it ever
44 		 * more than 13 hours from GMT, which is 52*15min.
45 		 * The time is always stored in localtime with the
46 		 * timezone offset being what get added to GMT to
47 		 * get to localtime.  Thus we need to subtract the offset
48 		 * to get to true GMT, which is what we store the time
49 		 * as internally.  On the local system, the user may set
50 		 * their timezone any way they wish, of course, so GMT
51 		 * gets converted back to localtime on the receiving
52 		 * system.
53 		 *
54 		 * NOTE: mkisofs in versions prior to mkisofs-1.10 had
55 		 * the sign wrong on the timezone offset.  This has now
56 		 * been corrected there too, but if you are getting screwy
57 		 * results this may be the explanation.  If enough people
58 		 * complain, a user configuration option could be added
59 		 * to add the timezone offset in with the wrong sign
60 		 * for 'compatibility' with older discs, but I cannot see how
61 		 * it will matter that much.
62 		 *
63 		 * Thanks to kuhlmav@elec.canterbury.ac.nz (Volker Kuhlmann)
64 		 * for pointing out the sign error.
65 		 */
66 		if (-52 <= tz && tz <= 52)
67 			crtime -= tz * 15 * 60;
68 	}
69 	return crtime;
70 }
71