xref: /original-bsd/bin/date/date.c (revision 93001edb)
1e8f3668aSmckusick /*
2e4fa375eSbostic  * Copyright (c) 1985, 1987, 1988, 1993
3e4fa375eSbostic  *	The Regents of the University of California.  All rights reserved.
4c2c8d999Sbostic  *
561d627fdSbostic  * %sccs.include.redist.c%
6e8f3668aSmckusick  */
7e8f3668aSmckusick 
8ad4dcd8fSsam #ifndef lint
9e4fa375eSbostic static char copyright[] =
10e4fa375eSbostic "@(#) Copyright (c) 1985, 1987, 1988, 1993\n\
11e4fa375eSbostic 	The Regents of the University of California.  All rights reserved.\n";
12c2c8d999Sbostic #endif /* not lint */
13e8f3668aSmckusick 
14e8f3668aSmckusick #ifndef lint
15*93001edbSbostic static char sccsid[] = "@(#)date.c	8.2 (Berkeley) 04/28/95";
16c2c8d999Sbostic #endif /* not lint */
17ad4dcd8fSsam 
1836fa1a6bSkarels #include <sys/param.h>
1929f671e3Swnj #include <sys/time.h>
2095e6f391Sbostic 
2195e6f391Sbostic #include <ctype.h>
2295e6f391Sbostic #include <err.h>
2395e6f391Sbostic #include <fcntl.h>
24fe3493caSbostic #include <stdio.h>
2574c46193Sbostic #include <stdlib.h>
261afa398dSbostic #include <string.h>
2795e6f391Sbostic #include <syslog.h>
2895e6f391Sbostic #include <unistd.h>
2995e6f391Sbostic 
3095e6f391Sbostic #include "extern.h"
318df64c17Sgusella 
3274c46193Sbostic time_t tval;
3374c46193Sbostic int retval, nflag;
3463fd2155Sbill 
3595e6f391Sbostic static void setthetime __P((char *));
3695e6f391Sbostic static void badformat __P((void));
3795e6f391Sbostic static void usage __P((void));
3895e6f391Sbostic 
3995e6f391Sbostic int logwtmp __P((char *, char *, char *));
4095e6f391Sbostic 
4195e6f391Sbostic int
main(argc,argv)4263fd2155Sbill main(argc, argv)
43ad4dcd8fSsam 	int argc;
44fe3493caSbostic 	char **argv;
4563fd2155Sbill {
46fe3493caSbostic 	extern int optind;
47fe3493caSbostic 	extern char *optarg;
48fe3493caSbostic 	struct timezone tz;
490850ca54Sbostic 	int ch, rflag;
5074c46193Sbostic 	char *format, buf[1024];
5163fd2155Sbill 
5233de07beSbostic 	tz.tz_dsttime = tz.tz_minuteswest = 0;
530850ca54Sbostic 	rflag = 0;
54*93001edbSbostic 	while ((ch = getopt(argc, argv, "d:nr:ut:")) != -1)
55fe3493caSbostic 		switch((char)ch) {
56c2c8d999Sbostic 		case 'd':		/* daylight savings time */
57fe3493caSbostic 			tz.tz_dsttime = atoi(optarg) ? 1 : 0;
58fe3493caSbostic 			break;
59c2c8d999Sbostic 		case 'n':		/* don't set network */
60fe3493caSbostic 			nflag = 1;
611a1d0a1fSkarels 			break;
620850ca54Sbostic 		case 'r':		/* user specified seconds */
630850ca54Sbostic 			rflag = 1;
64b4781d87Sbostic 			tval = atol(optarg);
65b4781d87Sbostic 			break;
6674c46193Sbostic 		case 'u':		/* do everything in GMT */
676c8be42fSbostic 			(void)setenv("TZ", "GMT0", 1);
681a1d0a1fSkarels 			break;
69c2c8d999Sbostic 		case 't':		/* minutes west of GMT */
7074c46193Sbostic 					/* error check; don't allow "PST" */
7133de07beSbostic 			if (isdigit(*optarg)) {
7233de07beSbostic 				tz.tz_minuteswest = atoi(optarg);
7333de07beSbostic 				break;
7433de07beSbostic 			}
7533de07beSbostic 			/* FALLTHROUGH */
761a1d0a1fSkarels 		default:
7733de07beSbostic 			usage();
781a1d0a1fSkarels 		}
79fe3493caSbostic 	argc -= optind;
80fe3493caSbostic 	argv += optind;
81fe3493caSbostic 
8274c46193Sbostic 	/*
8374c46193Sbostic 	 * If -d or -t, set the timezone or daylight savings time; this
8474c46193Sbostic 	 * doesn't belong here, there kernel should not know about either.
8574c46193Sbostic 	 */
86fe3493caSbostic 	if ((tz.tz_minuteswest || tz.tz_dsttime) &&
8795e6f391Sbostic 	    settimeofday(NULL, &tz))
8895e6f391Sbostic 		err(1, "settimeofday");
89fe3493caSbostic 
9095e6f391Sbostic 	if (!rflag && time(&tval) == -1)
9195e6f391Sbostic 		err(1, "time");
92fe3493caSbostic 
93*93001edbSbostic 	format = "%a %b %e %H:%M:%S %Z %Y";
94fe3493caSbostic 
9574c46193Sbostic 	/* allow the operands in any order */
9674c46193Sbostic 	if (*argv && **argv == '+') {
9774c46193Sbostic 		format = *argv + 1;
9874c46193Sbostic 		++argv;
99fe3493caSbostic 	}
100fe3493caSbostic 
10174c46193Sbostic 	if (*argv) {
10274c46193Sbostic 		setthetime(*argv);
10374c46193Sbostic 		++argv;
104fe3493caSbostic 	}
10574c46193Sbostic 
10674c46193Sbostic 	if (*argv && **argv == '+')
10774c46193Sbostic 		format = *argv + 1;
10874c46193Sbostic 
10974c46193Sbostic 	(void)strftime(buf, sizeof(buf), format, localtime(&tval));
110*93001edbSbostic 	(void)printf("%s\n", buf);
11174c46193Sbostic 	exit(retval);
11274c46193Sbostic }
11374c46193Sbostic 
11474c46193Sbostic #define	ATOI2(ar)	((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
11595e6f391Sbostic void
setthetime(p)11674c46193Sbostic setthetime(p)
11774c46193Sbostic 	register char *p;
11874c46193Sbostic {
11974c46193Sbostic 	register struct tm *lt;
12074c46193Sbostic 	struct timeval tv;
1217391f40dSbostic 	char *dot, *t;
12274c46193Sbostic 
1237391f40dSbostic 	for (t = p, dot = NULL; *t; ++t) {
1247391f40dSbostic 		if (isdigit(*t))
1257391f40dSbostic 			continue;
1267391f40dSbostic 		if (*t == '.' && dot == NULL) {
1277391f40dSbostic 			dot = t;
1287391f40dSbostic 			continue;
1297391f40dSbostic 		}
13074c46193Sbostic 		badformat();
1317391f40dSbostic 	}
13274c46193Sbostic 
13374c46193Sbostic 	lt = localtime(&tval);
13474c46193Sbostic 
1357391f40dSbostic 	if (dot != NULL) {			/* .ss */
1367391f40dSbostic 		*dot++ = '\0';
1377391f40dSbostic 		if (strlen(dot) != 2)
138d24fe13cSralph 			badformat();
1397391f40dSbostic 		lt->tm_sec = ATOI2(dot);
14074c46193Sbostic 		if (lt->tm_sec > 61)
14174c46193Sbostic 			badformat();
14274c46193Sbostic 	} else
14374c46193Sbostic 		lt->tm_sec = 0;
14474c46193Sbostic 
14574c46193Sbostic 	switch (strlen(p)) {
14674c46193Sbostic 	case 10:				/* yy */
14774c46193Sbostic 		lt->tm_year = ATOI2(p);
14874c46193Sbostic 		if (lt->tm_year < 69)		/* hack for 2000 ;-} */
14974c46193Sbostic 			lt->tm_year += 100;
15074c46193Sbostic 		/* FALLTHROUGH */
15174c46193Sbostic 	case 8:					/* mm */
15274c46193Sbostic 		lt->tm_mon = ATOI2(p);
15374c46193Sbostic 		if (lt->tm_mon > 12)
15474c46193Sbostic 			badformat();
155c289d8baSbostic 		--lt->tm_mon;			/* time struct is 0 - 11 */
15674c46193Sbostic 		/* FALLTHROUGH */
15774c46193Sbostic 	case 6:					/* dd */
15874c46193Sbostic 		lt->tm_mday = ATOI2(p);
15974c46193Sbostic 		if (lt->tm_mday > 31)
16074c46193Sbostic 			badformat();
16174c46193Sbostic 		/* FALLTHROUGH */
16274c46193Sbostic 	case 4:					/* hh */
16374c46193Sbostic 		lt->tm_hour = ATOI2(p);
16474c46193Sbostic 		if (lt->tm_hour > 23)
16574c46193Sbostic 			badformat();
16674c46193Sbostic 		/* FALLTHROUGH */
16774c46193Sbostic 	case 2:					/* mm */
16874c46193Sbostic 		lt->tm_min = ATOI2(p);
16974c46193Sbostic 		if (lt->tm_min > 59)
17074c46193Sbostic 			badformat();
17174c46193Sbostic 		break;
17274c46193Sbostic 	default:
17374c46193Sbostic 		badformat();
17474c46193Sbostic 	}
17574c46193Sbostic 
17674c46193Sbostic 	/* convert broken-down time to GMT clock time */
17774c46193Sbostic 	if ((tval = mktime(lt)) == -1)
17874c46193Sbostic 		badformat();
17974c46193Sbostic 
18074c46193Sbostic 	/* set the time */
18174c46193Sbostic 	if (nflag || netsettime(tval)) {
182c2c8d999Sbostic 		logwtmp("|", "date", "");
18374c46193Sbostic 		tv.tv_sec = tval;
18474c46193Sbostic 		tv.tv_usec = 0;
1850f558095Sbostic 		if (settimeofday(&tv, NULL)) {
186993df27fSbostic 			perror("date: settimeofday");
187993df27fSbostic 			exit(1);
188fe3493caSbostic 		}
189c2c8d999Sbostic 		logwtmp("{", "date", "");
1908df64c17Sgusella 	}
1910f558095Sbostic 
1920f558095Sbostic 	if ((p = getlogin()) == NULL)
1930f558095Sbostic 		p = "???";
1940f558095Sbostic 	syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
19563fd2155Sbill }
19663fd2155Sbill 
19795e6f391Sbostic static void
badformat()19874c46193Sbostic badformat()
19963fd2155Sbill {
20095e6f391Sbostic 	warnx("illegal time format");
20174c46193Sbostic 	usage();
2021d873399Skarels }
20333de07beSbostic 
20495e6f391Sbostic static void
usage()20533de07beSbostic usage()
20633de07beSbostic {
20774c46193Sbostic 	(void)fprintf(stderr,
208b4781d87Sbostic 	    "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]\n");
209b4781d87Sbostic 	(void)fprintf(stderr, "            [yy[mm[dd[hh]]]]mm[.ss]]\n");
21074c46193Sbostic 	exit(1);
21133de07beSbostic }
212