Annotation of coherent/d/bin/date.c, revision 1.1.1.1

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(&ltime));
                     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(&ltime);
                    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(&ltime);
                    148:                if (!sflag && tmp->tm_isdst)
                    149:                        ltime -= HOUR;
                    150:        }
                    151:        status = stime(&ltime);
                    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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.