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