Annotation of coherent/b/etc/ATclock.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * ATclock.c
                      3:  * 5/16/90
                      4:  * ATclock - read or set the IBM AT real-time clock
                      5:  * Usage:  /etc/ATclock [YY[MM[DD[HH[MM[.SS]]]]]]
                      6:  * cc -s -i -O -o ATclock ATclock.c ATclockas.s
                      7:  *
                      8:  */
                      9: 
                     10: #include <stdio.h>
                     11: #include <fcntl.h>
                     12: 
                     13: #define        USAGE   "Usage: /etc/ATclock [YY[MM[DD[HH[MM[.SS]]]]]]\n"
                     14: 
                     15: /* Offsets within clock memory. */
                     16: #define        DIAG    14              /* Diagnostic port: bit(7) -> powerloss */
                     17:                                /*                  bit(2) -> bad time  */
                     18: #define        BADCLK  0x84
                     19: #define        STAT    10              /* Status port:     bit(7) -> updating  */
                     20: #define        UPDATE  0x80
                     21: #define        YEAR    9
                     22: #define        MON     8
                     23: #define        DAY     7
                     24: #define        HOUR    4
                     25: #define        MIN     2
                     26: #define        SEC     0
                     27: 
                     28: #define        DEV_CMOS        "/dev/cmos"
                     29: #define        DEV_CLOCK       "/dev/clock"
                     30: 
                     31: #define CLKLEN 10
                     32: 
                     33: /* Forward. */
                     34: int    bcd();
                     35: void   clock();
                     36: void   clockcheck();
                     37: void   fatal();
                     38: void   sanity();
                     39: void   set();
                     40: void   usage();
                     41: 
                     42: int    zget();
                     43: void   zput();
                     44: 
                     45: /* Globals. */
                     46: unsigned char clkbuf[CLKLEN];  /* Clock image buffer (ten BCD digits). */
                     47: 
                     48: int    fd_cmos;
                     49: int    fd_clock;
                     50: 
                     51: /*
                     52:  * zget()
                     53:  *
                     54:  * read a byte from a specified offset in CMOS
                     55:  *
                     56:  */
                     57: int
                     58: zget(offset)
                     59: int offset;
                     60: {
                     61:        int ret;
                     62: 
                     63:        lseek(fd_cmos, (long)offset, 0);
                     64:        if(read(fd_cmos, &ret, 1) != 1) {
                     65:                fprintf(stderr, "Can't read CMOS byte %d\n", offset);
                     66:                exit (1);
                     67:        }
                     68:        return ret & 0xff;
                     69: }
                     70: 
                     71: main(argc, argv) int argc; char *argv[];
                     72: {
                     73:        if((fd_cmos = open(DEV_CMOS, O_RDONLY)) == -1) {
                     74:                fprintf(stderr, "ATclock: can't read %s.\n",
                     75:                  DEV_CMOS);
                     76:                exit(1);
                     77:        }
                     78: 
                     79:        if((fd_clock = open(DEV_CLOCK, O_RDONLY)) == -1) {
                     80:                fprintf(stderr, "ATclock: can't read %s.\n",
                     81:                  DEV_CLOCK);
                     82:                exit(1);
                     83:        }
                     84: 
                     85:        if (argc > 2)
                     86:                usage();
                     87: 
                     88:        if (zget(DIAG) & BADCLK)
                     89:                fatal("bad clock");             /* check for valid clock */
                     90: 
                     91:        if (read(fd_clock, clkbuf, CLKLEN) != CLKLEN) {
                     92:                fprintf(stderr, "Can't read %d bytes from %s.\n",
                     93:                  CLKLEN, DEV_CLOCK);
                     94:                exit(1);
                     95:        }
                     96: 
                     97:        if (argc == 2) {
                     98:                close(fd_clock);
                     99:                if((fd_clock = open(DEV_CLOCK, O_RDWR)) == -1) {
                    100:                        fprintf(stderr, "ATclock: can't write %s.\n",
                    101:                          DEV_CLOCK);
                    102:                        exit(1);
                    103:                }
                    104:                set(argv[1]);                   /* initialize clkbuf[] */
                    105:                lseek(fd_clock, 0L, 0);
                    106:                if (write(fd_clock, clkbuf, CLKLEN) != CLKLEN) {
                    107:                        fprintf(stderr, "Can't write %d bytes to %s.\n",
                    108:                          CLKLEN, DEV_CLOCK);
                    109:                        exit(1);
                    110:                }
                    111:        } else
                    112:                clockcheck();                   /* check clock */
                    113: 
                    114:        /* Print formatted date. */
                    115:        printf("%d%d%d%d%d%d%d%d%d%d.%d%d\n",
                    116:                clkbuf[YEAR] >> 4, clkbuf[YEAR] & 15,
                    117:                clkbuf[MON]  >> 4, clkbuf[MON]  & 15,
                    118:                clkbuf[DAY]  >> 4, clkbuf[DAY]  & 15,
                    119:                clkbuf[HOUR] >> 4, clkbuf[HOUR] & 15,
                    120:                clkbuf[MIN]  >> 4, clkbuf[MIN]  & 15,
                    121:                clkbuf[SEC]  >> 4, clkbuf[SEC]  & 15
                    122:                );
                    123: 
                    124:        close(fd_cmos);
                    125:        close(fd_clock);
                    126:        exit (0);
                    127: }
                    128: 
                    129: /*
                    130:  * Change a numeric character string into two bcd digits.
                    131:  */
                    132: int
                    133: bcd(s) register char *s;
                    134: {
                    135:        if (('0' <= s[0]) && (s[0] <= '9') && ('0' <= s[1]) && (s[1] <= '9'))
                    136:                return (s[0] << 4) | (s[1] & 15);
                    137:        fatal("argument contains nondigit");
                    138: }
                    139: 
                    140: /*
                    141:  * Check the clkbuf[] for sanity.
                    142:  */
                    143: void
                    144: clockcheck()
                    145: {
                    146:        sanity(YEAR, 0, 99, "year");
                    147:        sanity(MON, 1, 12, "month");
                    148:        sanity(DAY, 1, 31, "day");
                    149:        sanity(HOUR, 0, 23, "hour");
                    150:        sanity(MIN, 0, 59, "minute");
                    151:        sanity(SEC, 0, 59, "second");
                    152: }
                    153: 
                    154: /*
                    155:  * Cry and die.
                    156:  */
                    157: void
                    158: fatal(args) char *args;
                    159: {
                    160:        fprintf(stderr, "/etc/ATclock: %r\n", &args);
                    161:        exit(1);
                    162: }
                    163: 
                    164: /*
                    165:  * Sanity check: make sure BCD clkbuf[i] is in the given range.
                    166:  */
                    167: void
                    168: sanity(i, min, max, msg) register int i; int min, max; char *msg;
                    169: {
                    170:        register int n;
                    171: 
                    172:        n = 10 * (clkbuf[i] >> 4) + (clkbuf[i] & 15);
                    173:        if (n < min || n > max)
                    174:                fatal("%s %d not in range %d to %d", msg, n, min, max);
                    175: }
                    176: 
                    177: /*
                    178:  * Set clkbuf[] according to the argument string.
                    179:  */
                    180: void
                    181: set(s) register char *s;
                    182: {
                    183:        register char *a;
                    184: 
                    185:        a = s + strlen(s);
                    186:        if ((&a[-3] >= s) && (a[-3] == '.')) {
                    187:                clkbuf[SEC] = bcd(a -= 2);
                    188:                a--;
                    189:        } else
                    190:                clkbuf[SEC] = 0;
                    191:        if (&a[-2] >= s)
                    192:                clkbuf[MIN] = bcd(a -= 2);
                    193:        if (&a[-2] >= s)
                    194:                clkbuf[HOUR] = bcd(a -= 2);
                    195:        if (&a[-2] >= s)
                    196:                clkbuf[DAY] = bcd(a -= 2);
                    197:        if (&a[-2] >= s)
                    198:                clkbuf[MON] = bcd(a -= 2);
                    199:        if (&a[-2] >= s)
                    200:                clkbuf[YEAR] = bcd(a -= 2);
                    201:        if (a != s)
                    202:                usage();
                    203:        clockcheck();
                    204: }
                    205: 
                    206: /*
                    207:  * Print a usage message and exit.
                    208:  */
                    209: void
                    210: usage()
                    211: {
                    212:        fprintf(stderr, USAGE);
                    213:        exit(1);
                    214: }
                    215: 
                    216: /* end of ATclock.c */

unix.superglobalmegacorp.com

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