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