Commit | Line | Data |
---|---|---|
e1d473bc | 1 | #ifndef lint |
5acde4b0 | 2 | static char *sccsid = "@(#)date.c 4.3 (Berkeley) %G%"; |
e1d473bc SL |
3 | #endif |
4 | ||
0698cf89 | 5 | /* |
5acde4b0 | 6 | * Date - print and set date |
0698cf89 | 7 | */ |
5acde4b0 CL |
8 | |
9 | #include <stdio.h> | |
0698cf89 | 10 | #include <time.h> |
0698cf89 | 11 | #include <utmp.h> |
5acde4b0 | 12 | #define WTMP "/usr/adm/wtmp" |
e1d473bc SL |
13 | |
14 | struct timeval tv; | |
15 | struct timezone tz; | |
0698cf89 BJ |
16 | char *ap, *ep, *sp; |
17 | int uflag; | |
18 | ||
19 | char *timezone(); | |
20 | static int dmsize[12] = | |
e1d473bc | 21 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
5acde4b0 | 22 | static char *usage = "usage: date [-u] [yymmddhhmm[.ss]]\n"; |
0698cf89 BJ |
23 | |
24 | struct utmp wtmp[2] = { {"|", "", 0}, {"{", "", 0}}; | |
25 | ||
26 | char *ctime(); | |
27 | char *asctime(); | |
28 | struct tm *localtime(); | |
29 | struct tm *gmtime(); | |
30 | ||
31 | main(argc, argv) | |
e1d473bc SL |
32 | int argc; |
33 | char *argv[]; | |
0698cf89 BJ |
34 | { |
35 | register char *tzn; | |
0698cf89 | 36 | int wf, rc; |
0698cf89 | 37 | |
0698cf89 | 38 | rc = 0; |
e1d473bc | 39 | gettimeofday(&tv, &tz); |
5acde4b0 | 40 | if (argc > 1 && strcmp(argv[1], "-u") == 0) { |
0698cf89 BJ |
41 | argc--; |
42 | argv++; | |
43 | uflag++; | |
44 | } | |
e1d473bc | 45 | if (argc > 1) { |
0698cf89 BJ |
46 | ap = argv[1]; |
47 | if (gtime()) { | |
5acde4b0 | 48 | printf(usage); |
0698cf89 BJ |
49 | exit(1); |
50 | } | |
51 | /* convert to GMT assuming local time */ | |
5acde4b0 | 52 | if (uflag == 0) { |
e1d473bc | 53 | tv.tv_sec += (long)tz.tz_minuteswest*60; |
0698cf89 | 54 | /* now fix up local daylight time */ |
e1d473bc SL |
55 | if (localtime(&tv.tv_sec)->tm_isdst) |
56 | tv.tv_sec -= 60*60; | |
0698cf89 | 57 | } |
e1d473bc SL |
58 | tv.tv_sec = tv.tv_sec; |
59 | wtmp[0].ut_time = tv.tv_sec; | |
60 | if (settimeofday(&tv, (struct timezone *)0) < 0) { | |
0698cf89 | 61 | rc++; |
5acde4b0 CL |
62 | perror("Failed to set date"); |
63 | } else if ((wf = open(WTMP, 1)) >= 0) { | |
0698cf89 BJ |
64 | time(&wtmp[1].ut_time); |
65 | lseek(wf, 0L, 2); | |
66 | write(wf, (char *)wtmp, sizeof(wtmp)); | |
67 | close(wf); | |
68 | } | |
69 | } | |
5acde4b0 | 70 | if (rc == 0) |
e1d473bc SL |
71 | time(&tv.tv_sec); |
72 | if (uflag) { | |
73 | ap = asctime(gmtime(&tv.tv_sec)); | |
0698cf89 BJ |
74 | tzn = "GMT"; |
75 | } else { | |
76 | struct tm *tp; | |
e1d473bc | 77 | tp = localtime(&tv.tv_sec); |
0698cf89 | 78 | ap = asctime(tp); |
e1d473bc | 79 | tzn = timezone(tz.tz_minuteswest, tp->tm_isdst); |
0698cf89 BJ |
80 | } |
81 | printf("%.20s", ap); | |
82 | if (tzn) | |
83 | printf("%s", tzn); | |
84 | printf("%s", ap+19); | |
85 | exit(rc); | |
86 | } | |
87 | ||
88 | gtime() | |
89 | { | |
90 | register int i, year, month; | |
91 | int day, hour, mins, secs; | |
92 | struct tm *L; | |
93 | char x; | |
94 | ||
5acde4b0 | 95 | ep = ap; |
0698cf89 | 96 | while(*ep) ep++; |
5acde4b0 CL |
97 | sp = ap; |
98 | while(sp < ep) { | |
0698cf89 BJ |
99 | x = *sp; |
100 | *sp++ = *--ep; | |
101 | *ep = x; | |
102 | } | |
5acde4b0 | 103 | sp = ap; |
e1d473bc | 104 | gettimeofday(&tv, 0); |
5acde4b0 | 105 | L = localtime(&tv.tv_sec); |
0698cf89 | 106 | secs = gp(-1); |
5acde4b0 CL |
107 | if (*sp != '.') { |
108 | mins = secs; | |
109 | secs = 0; | |
110 | } else { | |
111 | sp++; | |
0698cf89 BJ |
112 | mins = gp(-1); |
113 | } | |
114 | hour = gp(-1); | |
115 | day = gp(L->tm_mday); | |
116 | month = gp(L->tm_mon+1); | |
117 | year = gp(L->tm_year); | |
e1d473bc SL |
118 | if (*sp) |
119 | return (1); | |
5acde4b0 CL |
120 | if (month < 1 || month > 12 || |
121 | day < 1 || day > 31 || | |
122 | mins < 0 || mins > 59 || | |
123 | secs < 0 || secs > 59) | |
e1d473bc | 124 | return (1); |
5acde4b0 CL |
125 | if (hour == 24) { |
126 | hour = 0; | |
127 | day++; | |
0698cf89 | 128 | } |
5acde4b0 | 129 | if (hour < 0 || hour > 23) |
e1d473bc SL |
130 | return (1); |
131 | tv.tv_sec = 0; | |
0698cf89 | 132 | year += 1900; |
5acde4b0 | 133 | for (i = 1970; i < year; i++) |
e1d473bc | 134 | tv.tv_sec += dysize(i); |
0698cf89 | 135 | /* Leap year */ |
5acde4b0 | 136 | if (dysize(year) == 366 && month >= 3) |
e1d473bc SL |
137 | tv.tv_sec++; |
138 | while (--month) | |
139 | tv.tv_sec += dmsize[month-1]; | |
140 | tv.tv_sec += day-1; | |
141 | tv.tv_sec = 24*tv.tv_sec + hour; | |
142 | tv.tv_sec = 60*tv.tv_sec + mins; | |
143 | tv.tv_sec = 60*tv.tv_sec + secs; | |
144 | return (0); | |
0698cf89 BJ |
145 | } |
146 | ||
147 | gp(dfault) | |
148 | { | |
149 | register int c, d; | |
150 | ||
5acde4b0 | 151 | if (*sp == 0) |
e1d473bc | 152 | return (dfault); |
5acde4b0 CL |
153 | c = (*sp++) - '0'; |
154 | d = (*sp ? (*sp++) - '0' : 0); | |
155 | if (c < 0 || c > 9 || d < 0 || d > 9) | |
e1d473bc SL |
156 | return (-1); |
157 | return (c+10*d); | |
0698cf89 | 158 | } |