Windows global stuff:
[krb5.git] / src / lib / des425 / unix_time.c
1 /*
2  * unix_time.c
3  * 
4  * Glue code for pasting Kerberos into the Unix environment.
5  *
6  * Originally written by John Gilmore, Cygnus Support, May '94.
7  * Public Domain.
8  *
9  * Required for use by the Cygnus krb.a.
10  */
11
12
13 #include "k5-int.h"
14
15 #ifndef _MSDOS
16 #include <sys/time.h>
17
18 krb5_ui_4
19 unix_time_gmt_unixsec (usecptr)
20      krb5_ui_4  *usecptr;
21 {
22         struct timeval  now;
23
24         (void) gettimeofday (&now, (struct timezone *)0);
25         if (usecptr)
26                 *usecptr = now.tv_usec;
27         return now.tv_sec;
28 }
29
30 #else /* _MSDOS */
31
32 /*
33  * Originally written by John Gilmore, Cygnus Support, May '94.
34  * Public Domain.
35  */
36
37 #include <time.h>
38 #include <sys/timeb.h>
39 #include <dos.h>
40 #include <string.h>
41
42 /*
43  * Due to the fact that DOS time can be unreliable we have reverted
44  * to using the AT hardware clock and converting it to Unix time.
45  */
46 static long win_time_get_epoch(void);
47
48 krb5_ui_4
49 unix_time_gmt_unixsec (usecptr)
50      krb5_ui_4  *usecptr;
51 {
52     struct tm tm;
53     union _REGS inregs;                         /* For calling BIOS */
54     union _REGS outregs;
55     struct _timeb now;
56     time_t time;
57     long convert;                               /* MSC 7.00 bug work around */
58     krb5_ui_4 retval;                           /* What we return */
59
60     _ftime(&now);                               /* Daylight savings time */
61
62     /* Get time from AT hardware clock INT 0x1A, AH=2 */
63     memset(&inregs, 0, sizeof(inregs));
64     inregs.h.ah = 2;
65     _int86(0x1a, &inregs, &outregs);
66
67     /* 0x13 = decimal 13, hence the decoding below */
68     tm.tm_sec = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F);
69     tm.tm_min = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
70     tm.tm_hour = 10 * ((outregs.h.ch & 0xF0) >> 4) + (outregs.h.ch & 0x0F);
71
72     /* Get date from AT hardware clock INT 0x1A, AH=4 */
73     memset(&inregs, 0, sizeof(inregs));
74     inregs.h.ah = 4;
75     _int86(0x1a, &inregs, &outregs);
76
77     tm.tm_mday = 10 * ((outregs.h.dl & 0xF0) >> 4) + (outregs.h.dl & 0x0F);
78     tm.tm_mon = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F) - 1;
79     tm.tm_year = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
80     tm.tm_year += 100 * ((10 * (outregs.h.ch & 0xF0) >> 4)
81                     + (outregs.h.ch & 0x0F) - 19);
82
83     tm.tm_wday = 0;
84     tm.tm_yday = 0;
85     tm.tm_isdst = now.dstflag;
86
87     time = mktime(&tm);
88
89     convert = win_time_get_epoch();
90     retval = time + convert;
91
92         if (usecptr)
93                 *usecptr = retval;
94
95     return retval;
96 }
97 /*
98  * This routine figures out the current time epoch and returns the
99  * conversion factor.  It exists because 
100  * Microloss screwed the pooch on the time() and _ftime() calls in
101  * its release 7.0 libraries.  They changed the epoch to Dec 31, 1899!
102  * Idiots...   We try to cope.
103  */
104
105 static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70};
106 static long epoch = 0;
107 static int epoch_set = 0;
108
109 static long
110 win_time_get_epoch()
111 {
112
113     if (!epoch_set) {
114         epoch = 0 - mktime (&jan_1_70); /* Seconds til 1970 localtime */
115         epoch += _timezone;             /* Seconds til 1970 GMT */
116         epoch_set = 1;
117     }
118     return epoch;
119 }
120
121 #endif