|
|
1.1 ! root 1: /* ! 2: * date.c ! 3: * Print and set the date. ! 4: */ ! 5: ! 6: #include <stdio.h> ! 7: #include <ctype.h> ! 8: #include <sys/types.h> ! 9: #include <time.h> ! 10: #include <sys/timeb.h> ! 11: ! 12: #if COHERENT ! 13: #include <utmp.h> ! 14: #include <sys/stat.h> ! 15: #endif ! 16: ! 17: void error(); ! 18: void usage(); ! 19: ! 20: #define TFCFLAG 0 /* Truly French GMT is UTC */ ! 21: int gmtflag; /* Do things in Greenwich Mean Time */ ! 22: int sflag; /* Suppress DST conversion when setting */ ! 23: struct tm *gtime(); ! 24: struct timeb tb; ! 25: time_t timep[2]; ! 26: #define MIN (60L) ! 27: #define HOUR (60L*60L) ! 28: #define DAY (60L*60L*24L) ! 29: #define APR 3 ! 30: #define OCT 9 ! 31: ! 32: #if COHERENT ! 33: struct utmp utmps[2]; ! 34: char utmpf[] = "/usr/adm/wtmp"; ! 35: struct stat sbuf; ! 36: char btimf[] = "/etc/boottime"; ! 37: #endif ! 38: ! 39: /* ! 40: * Table of days per month. ! 41: * This will be adjusted for leap years. ! 42: */ ! 43: char dpm[] = { ! 44: 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ! 45: }; ! 46: ! 47: main(argc, argv) ! 48: char *argv[]; ! 49: { ! 50: register char *s; ! 51: register struct tm *tmp; ! 52: long ltime; ! 53: char *tzone; ! 54: ! 55: if (argc>1 && *argv[1]=='-') { ! 56: if (argv[1][1]=='u' && argv[1][2]=='\0') ! 57: gmtflag = 1; ! 58: else if (argv[1][1]=='s' && argv[1][2]=='\0') ! 59: sflag = 1; ! 60: else ! 61: usage(); ! 62: argc--; ! 63: argv++; ! 64: } ! 65: if (argc > 2) ! 66: usage(); ! 67: if (argc > 1) ! 68: sdate(argv[1]); ! 69: ftime(&tb); ! 70: ltime = tb.time; ! 71: s = asctime(tmp = gtime(<ime)); ! 72: s[24] = '\0'; ! 73: if (!gmtflag) ! 74: tzone = tzname[tmp->tm_isdst]; ! 75: else ! 76: tzone = TFCFLAG ? "UTC" : "GMT"; ! 77: printf("%s %s\n", s, tzone); ! 78: exit(0); ! 79: } ! 80: ! 81: /* ! 82: * Set the date/time based on ! 83: * string 's'. ! 84: */ ! 85: sdate(s) ! 86: char *s; ! 87: { ! 88: register char *sp; ! 89: register int year; ! 90: register int month; ! 91: int status; ! 92: #if COHERENT ! 93: int ufd; ! 94: #endif ! 95: long ltime; ! 96: struct tm *tmp; ! 97: ! 98: ftime(&tb); ! 99: ltime = tb.time; ! 100: #if COHERENT ! 101: utmps[0].ut_time = ltime; ! 102: #endif ! 103: tmp = gtime(<ime); ! 104: for (sp = s; *sp != '\0'; sp++) ! 105: ; ! 106: if ((sp -= 2) < s) ! 107: usage(); ! 108: if (sp>s && sp[-1]=='.') { ! 109: tmp->tm_sec = convert(sp, 60, s); ! 110: sp--; ! 111: } else { ! 112: sp += 2; ! 113: tmp->tm_sec = 0; ! 114: } ! 115: tmp->tm_min = convert(sp-=2, 60, s); ! 116: tmp->tm_hour = convert(sp-=2, 24, s); ! 117: if ((sp-=2) >= s) { ! 118: tmp->tm_mday = convert(sp, 31+1, s); ! 119: if ((sp-=2) >= s) { ! 120: tmp->tm_mon = convert(sp, 12+1, s) - 1; ! 121: if ((sp-=2) >= s) ! 122: tmp->tm_year = convert(sp, 100, s); ! 123: } ! 124: } ! 125: if (tmp->tm_mday > dpm[tmp->tm_mon]) ! 126: usage(); ! 127: /* ! 128: * Convert using the year, month, day, hour, minute, ! 129: * and second values in the 'tm' structure. ! 130: * When all is completed, take care of timezone. ! 131: */ ! 132: ltime = tmp->tm_sec + MIN*tmp->tm_min + HOUR*tmp->tm_hour; ! 133: ltime += (tmp->tm_mday-1) * DAY; ! 134: year = 1900 + tmp->tm_year; ! 135: /* ! 136: * Adjust length of February in leap years. ! 137: */ ! 138: if (!isleap(year)) ! 139: dpm[1] = 28; ! 140: month = tmp->tm_mon; ! 141: while (--month >= 0) ! 142: ltime += dpm[month] * DAY; ! 143: while (--year >= 1970) ! 144: ltime += (long)DAY * (isleap(year) ? 366 : 365); ! 145: if (!gmtflag) { ! 146: ltime += timezone; ! 147: tmp = localtime(<ime); ! 148: if (!sflag && tmp->tm_isdst) ! 149: ltime -= HOUR; ! 150: } ! 151: status = stime(<ime); ! 152: if (status < 0) { ! 153: #if COHERENT ! 154: error("no permission"); ! 155: #else ! 156: error("bad date"); ! 157: #endif ! 158: return; ! 159: } ! 160: ! 161: #if COHERENT ! 162: /* Correct the modtime of /etc/boottime */ ! 163: stat(btimf, &sbuf); ! 164: timep[0] = ltime - utmps[0].ut_time + sbuf.st_mtime; ! 165: timep[1] = timep[0]; ! 166: utime(btimf, timep); ! 167: ! 168: /* Note the change of time in /usr/adm/wtmp */ ! 169: utmps[1].ut_time = ltime; ! 170: utmps[0].ut_line[0] = '|'; ! 171: utmps[1].ut_line[0] = '}'; ! 172: if ((ufd = open(utmpf, 1)) >= 0) { ! 173: lseek(ufd, 0L, 2); ! 174: write(ufd, utmps, sizeof (utmps)); ! 175: close(ufd); ! 176: } ! 177: #endif ! 178: } ! 179: ! 180: /* ! 181: * Return 1 on leap years. ! 182: */ ! 183: isleap(yr) ! 184: register yr; ! 185: { ! 186: if (yr%4000 == 0) ! 187: return (0); ! 188: if (yr%400==0 || (yr%100!=0 && yr%4==0)) ! 189: return (1); ! 190: return (0); ! 191: } ! 192: ! 193: /* ! 194: * Convert a piece of the time. ! 195: * The pointer cp should never fall before ! 196: * beg and the two digits parsed should be ! 197: * less than max. ! 198: */ ! 199: convert(cp, max, beg) ! 200: register char *cp; ! 201: char *beg; ! 202: { ! 203: register val; ! 204: ! 205: if (cp<beg || !isdigit(cp[0]) || !isdigit(cp[1])) ! 206: usage(); ! 207: val = (cp[0]-'0')*10 + cp[1]-'0'; ! 208: if (val >= max) ! 209: usage(); ! 210: return (val); ! 211: } ! 212: ! 213: /* ! 214: * Return either local time or Greenwich ! 215: * Mean 'tm' in a 'tm' structure. ! 216: */ ! 217: struct tm * ! 218: gtime(tp) ! 219: register time_t *tp; ! 220: { ! 221: return (gmtflag ? gmtime(tp) : localtime(tp)); ! 222: } ! 223: ! 224: void ! 225: usage() ! 226: { ! 227: fprintf(stderr, "Usage: date [-u] [yymmddhhmm[.ss]]\n"); ! 228: exit(1); ! 229: } ! 230: ! 231: void ! 232: error(x) ! 233: { ! 234: fprintf(stderr, "date: %r\n", &x); ! 235: exit(1); ! 236: } ! 237: ! 238: /* end of date.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.