xref: /original-bsd/bin/date/date.c (revision b4781d87)
1e8f3668aSmckusick /*
2c2c8d999Sbostic  * Copyright (c) 1985, 1987, 1988 The Regents of the University of California.
3c2c8d999Sbostic  * All rights reserved.
4c2c8d999Sbostic  *
561d627fdSbostic  * %sccs.include.redist.c%
6e8f3668aSmckusick  */
7e8f3668aSmckusick 
8ad4dcd8fSsam #ifndef lint
9e8f3668aSmckusick char copyright[] =
10c2c8d999Sbostic "@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\
11e8f3668aSmckusick  All rights reserved.\n";
12c2c8d999Sbostic #endif /* not lint */
13e8f3668aSmckusick 
14e8f3668aSmckusick #ifndef lint
15*b4781d87Sbostic static char sccsid[] = "@(#)date.c	5.3 (Berkeley) 03/09/91";
16c2c8d999Sbostic #endif /* not lint */
17ad4dcd8fSsam 
1836fa1a6bSkarels #include <sys/param.h>
1929f671e3Swnj #include <sys/time.h>
208df64c17Sgusella #include <sys/file.h>
218df64c17Sgusella #include <syslog.h>
221afa398dSbostic #include <unistd.h>
23fe3493caSbostic #include <stdio.h>
2474c46193Sbostic #include <stdlib.h>
251afa398dSbostic #include <string.h>
261afa398dSbostic #include <ctype.h>
278df64c17Sgusella 
2874c46193Sbostic time_t tval;
2974c46193Sbostic int retval, nflag;
3063fd2155Sbill 
3163fd2155Sbill main(argc, argv)
32ad4dcd8fSsam 	int argc;
33fe3493caSbostic 	char **argv;
3463fd2155Sbill {
35fe3493caSbostic 	extern int optind;
36fe3493caSbostic 	extern char *optarg;
37fe3493caSbostic 	struct timezone tz;
3874c46193Sbostic 	int ch;
3974c46193Sbostic 	char *format, buf[1024];
4063fd2155Sbill 
4133de07beSbostic 	tz.tz_dsttime = tz.tz_minuteswest = 0;
42*b4781d87Sbostic 	while ((ch = getopt(argc, argv, "d:nr:ut:")) != EOF)
43fe3493caSbostic 		switch((char)ch) {
44c2c8d999Sbostic 		case 'd':		/* daylight savings time */
45fe3493caSbostic 			tz.tz_dsttime = atoi(optarg) ? 1 : 0;
46fe3493caSbostic 			break;
47c2c8d999Sbostic 		case 'n':		/* don't set network */
48fe3493caSbostic 			nflag = 1;
491a1d0a1fSkarels 			break;
50*b4781d87Sbostic 		case 'r':
51*b4781d87Sbostic 			tval = atol(optarg);
52*b4781d87Sbostic 			break;
5374c46193Sbostic 		case 'u':		/* do everything in GMT */
5474c46193Sbostic 			(void)setenv("TZ", "GMT", 1);
551a1d0a1fSkarels 			break;
56c2c8d999Sbostic 		case 't':		/* minutes west of GMT */
5774c46193Sbostic 					/* error check; don't allow "PST" */
5833de07beSbostic 			if (isdigit(*optarg)) {
5933de07beSbostic 				tz.tz_minuteswest = atoi(optarg);
6033de07beSbostic 				break;
6133de07beSbostic 			}
6233de07beSbostic 			/* FALLTHROUGH */
631a1d0a1fSkarels 		default:
6433de07beSbostic 			usage();
651a1d0a1fSkarels 		}
66fe3493caSbostic 	argc -= optind;
67fe3493caSbostic 	argv += optind;
68fe3493caSbostic 
6974c46193Sbostic 	/*
7074c46193Sbostic 	 * If -d or -t, set the timezone or daylight savings time; this
7174c46193Sbostic 	 * doesn't belong here, there kernel should not know about either.
7274c46193Sbostic 	 */
73fe3493caSbostic 	if ((tz.tz_minuteswest || tz.tz_dsttime) &&
74fe3493caSbostic 	    settimeofday((struct timeval *)NULL, &tz)) {
75993df27fSbostic 		perror("date: settimeofday");
76993df27fSbostic 		exit(1);
7736fa1a6bSkarels 	}
78fe3493caSbostic 
79*b4781d87Sbostic 	if (!tval && time(&tval) == (time_t)-1) {
8074c46193Sbostic 		perror("date: time");
81fe3493caSbostic 		exit(1);
82fe3493caSbostic 	}
83fe3493caSbostic 
8474c46193Sbostic 	format = "%a %b %e %H:%M:%S %Z %Y\n";
85fe3493caSbostic 
8674c46193Sbostic 	/* allow the operands in any order */
8774c46193Sbostic 	if (*argv && **argv == '+') {
8874c46193Sbostic 		format = *argv + 1;
8974c46193Sbostic 		++argv;
90fe3493caSbostic 	}
91fe3493caSbostic 
9274c46193Sbostic 	if (*argv) {
9374c46193Sbostic 		setthetime(*argv);
9474c46193Sbostic 		++argv;
95fe3493caSbostic 	}
9674c46193Sbostic 
9774c46193Sbostic 	if (*argv && **argv == '+')
9874c46193Sbostic 		format = *argv + 1;
9974c46193Sbostic 
10074c46193Sbostic 	(void)strftime(buf, sizeof(buf), format, localtime(&tval));
10174c46193Sbostic 	(void)printf("%s", buf);
10274c46193Sbostic 	exit(retval);
10374c46193Sbostic }
10474c46193Sbostic 
10574c46193Sbostic #define	ATOI2(ar)	((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
10674c46193Sbostic setthetime(p)
10774c46193Sbostic 	register char *p;
10874c46193Sbostic {
10974c46193Sbostic 	register struct tm *lt;
11074c46193Sbostic 	struct timeval tv;
11174c46193Sbostic 	int dot;
11274c46193Sbostic 	char *t;
11374c46193Sbostic 
11474c46193Sbostic 	for (t = p, dot = 0; *t; ++t)
11574c46193Sbostic 		if (!isdigit(*t) && (*t != '.' || dot++))
11674c46193Sbostic 			badformat();
11774c46193Sbostic 
11874c46193Sbostic 	lt = localtime(&tval);
11974c46193Sbostic 
12074c46193Sbostic 	if (t = index(p, '.')) {		/* .ss */
12174c46193Sbostic 		*t++ = '\0';
12274c46193Sbostic 		if (lt->tm_sec > 61)
12374c46193Sbostic 			badformat();
12474c46193Sbostic 	} else
12574c46193Sbostic 		lt->tm_sec = 0;
12674c46193Sbostic 
12774c46193Sbostic 	for (t = p; *t; ++t)
12874c46193Sbostic 		if (!isdigit(*t))
12974c46193Sbostic 			badformat();
13074c46193Sbostic 
13174c46193Sbostic 	switch (strlen(p)) {
13274c46193Sbostic 	case 10:				/* yy */
13374c46193Sbostic 		lt->tm_year = ATOI2(p);
13474c46193Sbostic 		if (lt->tm_year < 69)		/* hack for 2000 ;-} */
13574c46193Sbostic 			lt->tm_year += 100;
13674c46193Sbostic 		/* FALLTHROUGH */
13774c46193Sbostic 	case 8:					/* mm */
13874c46193Sbostic 		lt->tm_mon = ATOI2(p);
13974c46193Sbostic 		if (lt->tm_mon > 12)
14074c46193Sbostic 			badformat();
141c289d8baSbostic 		--lt->tm_mon;			/* time struct is 0 - 11 */
14274c46193Sbostic 		/* FALLTHROUGH */
14374c46193Sbostic 	case 6:					/* dd */
14474c46193Sbostic 		lt->tm_mday = ATOI2(p);
14574c46193Sbostic 		if (lt->tm_mday > 31)
14674c46193Sbostic 			badformat();
14774c46193Sbostic 		/* FALLTHROUGH */
14874c46193Sbostic 	case 4:					/* hh */
14974c46193Sbostic 		lt->tm_hour = ATOI2(p);
15074c46193Sbostic 		if (lt->tm_hour > 23)
15174c46193Sbostic 			badformat();
15274c46193Sbostic 		/* FALLTHROUGH */
15374c46193Sbostic 	case 2:					/* mm */
15474c46193Sbostic 		lt->tm_min = ATOI2(p);
15574c46193Sbostic 		if (lt->tm_min > 59)
15674c46193Sbostic 			badformat();
15774c46193Sbostic 		break;
15874c46193Sbostic 	default:
15974c46193Sbostic 		badformat();
16074c46193Sbostic 	}
16174c46193Sbostic 
16274c46193Sbostic 	/* convert broken-down time to GMT clock time */
16374c46193Sbostic 	if ((tval = mktime(lt)) == -1)
16474c46193Sbostic 		badformat();
16574c46193Sbostic 
16674c46193Sbostic 	if (!(p = getlogin()))			/* single-user or no tty */
16774c46193Sbostic 		p = "root";
16874c46193Sbostic 	syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
16974c46193Sbostic 
17074c46193Sbostic 	/* set the time */
17174c46193Sbostic 	if (nflag || netsettime(tval)) {
172c2c8d999Sbostic 		logwtmp("|", "date", "");
17374c46193Sbostic 		tv.tv_sec = tval;
17474c46193Sbostic 		tv.tv_usec = 0;
175c2c8d999Sbostic 		if (settimeofday(&tv, (struct timezone *)NULL)) {
176993df27fSbostic 			perror("date: settimeofday");
177993df27fSbostic 			exit(1);
178fe3493caSbostic 		}
179c2c8d999Sbostic 		logwtmp("{", "date", "");
1808df64c17Sgusella 	}
18163fd2155Sbill }
18263fd2155Sbill 
18374c46193Sbostic badformat()
18463fd2155Sbill {
18574c46193Sbostic 	(void)fprintf(stderr, "date: illegal time format.\n");
18674c46193Sbostic 	usage();
1871d873399Skarels }
18833de07beSbostic 
18933de07beSbostic usage()
19033de07beSbostic {
19174c46193Sbostic 	(void)fprintf(stderr,
192*b4781d87Sbostic 	    "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]\n");
193*b4781d87Sbostic 	(void)fprintf(stderr, "            [yy[mm[dd[hh]]]]mm[.ss]]\n");
19474c46193Sbostic 	exit(1);
19533de07beSbostic }
196