1 /* 2 * Copyright (c) 1985, 1987, 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)date.c 5.2 (Berkeley) 02/25/91"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 #include <sys/time.h> 20 #include <sys/file.h> 21 #include <syslog.h> 22 #include <unistd.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <ctype.h> 27 28 time_t tval; 29 int retval, nflag; 30 31 main(argc, argv) 32 int argc; 33 char **argv; 34 { 35 extern int optind; 36 extern char *optarg; 37 struct timezone tz; 38 int ch; 39 char *format, buf[1024]; 40 41 tz.tz_dsttime = tz.tz_minuteswest = 0; 42 while ((ch = getopt(argc, argv, "d:nut:")) != EOF) 43 switch((char)ch) { 44 case 'd': /* daylight savings time */ 45 tz.tz_dsttime = atoi(optarg) ? 1 : 0; 46 break; 47 case 'n': /* don't set network */ 48 nflag = 1; 49 break; 50 case 'u': /* do everything in GMT */ 51 (void)setenv("TZ", "GMT", 1); 52 break; 53 case 't': /* minutes west of GMT */ 54 /* error check; don't allow "PST" */ 55 if (isdigit(*optarg)) { 56 tz.tz_minuteswest = atoi(optarg); 57 break; 58 } 59 /* FALLTHROUGH */ 60 default: 61 usage(); 62 } 63 argc -= optind; 64 argv += optind; 65 66 /* 67 * If -d or -t, set the timezone or daylight savings time; this 68 * doesn't belong here, there kernel should not know about either. 69 */ 70 if ((tz.tz_minuteswest || tz.tz_dsttime) && 71 settimeofday((struct timeval *)NULL, &tz)) { 72 perror("date: settimeofday"); 73 exit(1); 74 } 75 76 if (time(&tval) == (time_t)-1) { 77 perror("date: time"); 78 exit(1); 79 } 80 81 format = "%a %b %e %H:%M:%S %Z %Y\n"; 82 83 /* allow the operands in any order */ 84 if (*argv && **argv == '+') { 85 format = *argv + 1; 86 ++argv; 87 } 88 89 if (*argv) { 90 setthetime(*argv); 91 ++argv; 92 } 93 94 if (*argv && **argv == '+') 95 format = *argv + 1; 96 97 (void)strftime(buf, sizeof(buf), format, localtime(&tval)); 98 (void)printf("%s", buf); 99 exit(retval); 100 } 101 102 #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; 103 setthetime(p) 104 register char *p; 105 { 106 register struct tm *lt; 107 struct timeval tv; 108 int dot; 109 char *t; 110 111 for (t = p, dot = 0; *t; ++t) 112 if (!isdigit(*t) && (*t != '.' || dot++)) 113 badformat(); 114 115 lt = localtime(&tval); 116 117 if (t = index(p, '.')) { /* .ss */ 118 *t++ = '\0'; 119 if (lt->tm_sec > 61) 120 badformat(); 121 } else 122 lt->tm_sec = 0; 123 124 for (t = p; *t; ++t) 125 if (!isdigit(*t)) 126 badformat(); 127 128 switch (strlen(p)) { 129 case 10: /* yy */ 130 lt->tm_year = ATOI2(p); 131 if (lt->tm_year < 69) /* hack for 2000 ;-} */ 132 lt->tm_year += 100; 133 /* FALLTHROUGH */ 134 case 8: /* mm */ 135 lt->tm_mon = ATOI2(p); 136 if (lt->tm_mon > 12) 137 badformat(); 138 --lt->tm_mon; /* time struct is 0 - 11 */ 139 /* FALLTHROUGH */ 140 case 6: /* dd */ 141 lt->tm_mday = ATOI2(p); 142 if (lt->tm_mday > 31) 143 badformat(); 144 /* FALLTHROUGH */ 145 case 4: /* hh */ 146 lt->tm_hour = ATOI2(p); 147 if (lt->tm_hour > 23) 148 badformat(); 149 /* FALLTHROUGH */ 150 case 2: /* mm */ 151 lt->tm_min = ATOI2(p); 152 if (lt->tm_min > 59) 153 badformat(); 154 break; 155 default: 156 badformat(); 157 } 158 159 /* convert broken-down time to GMT clock time */ 160 if ((tval = mktime(lt)) == -1) 161 badformat(); 162 163 if (!(p = getlogin())) /* single-user or no tty */ 164 p = "root"; 165 syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); 166 167 /* set the time */ 168 if (nflag || netsettime(tval)) { 169 logwtmp("|", "date", ""); 170 tv.tv_sec = tval; 171 tv.tv_usec = 0; 172 if (settimeofday(&tv, (struct timezone *)NULL)) { 173 perror("date: settimeofday"); 174 exit(1); 175 } 176 logwtmp("{", "date", ""); 177 } 178 } 179 180 badformat() 181 { 182 (void)fprintf(stderr, "date: illegal time format.\n"); 183 usage(); 184 } 185 186 usage() 187 { 188 (void)fprintf(stderr, 189 "usage: date [-nu] [-d dst] [-t west] [+format] [yy[mm[dd[hh]]]]mm[.ss]]\n"); 190 exit(1); 191 } 192