Annotation of coherent/d/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:  *     Prints the current date and time in format 'YYMMDDHHMM.SS'.
                      9:  *     Author: Allan Cornish, INETCO Systems, Nov 1984.
                     10:  *     Modifications (c) Copyright INETCO Systems Ltd. (1985)
                     11:  *
                     12:  *     $Log:   /usr/src.inetco/etc/ATclock.c,v $
                     13:  * Revision 1.2        90/05/31  14:07:22      root
                     14:  * steve 5/31/90
                     15:  * Added sanity checking for values read from or written to clock;
                     16:  * the old source allowed out of range values without complaint.
                     17:  * Changed system call output to use stdio, bigger but saner.
                     18:  * Changed spacing, rearranged code, added #defines for clarity.
                     19:  * 
                     20:  *     86/07/16        Allan Cornish
                     21:  *     Validation of NVRAM contents is no longer performed.  It checked
                     22:  *     fields which were unused, and could incorrectly report errors.
                     23:  *
                     24:  *     85/09/??        Krish Nair
                     25:  *     Modified so that the ATclock may be set.
                     26:  *     The "set" format must be 'YYMMDDHHMM.SS'.
                     27:  *     The "read" format is always of type 'YYMMDDHHMM.SS'.
                     28:  */
                     29: 
                     30: #include <stdio.h>
                     31: 
                     32: #define        USAGE   "Usage: /etc/ATclock [YY[MM[DD[HH[MM[.SS]]]]]]\n"
                     33: 
                     34: /* Offsets within clock memory. */
                     35: #define        DIAG    14              /* Diagnostic port: bit(7) -> powerloss */
                     36:                                /*                  bit(2) -> bad time  */
                     37: #define        BADCLK  0x84
                     38: #define        STAT    10              /* Status port:     bit(7) -> updating  */
                     39: #define        UPDATE  0x80
                     40: #define        YEAR    9
                     41: #define        MON     8
                     42: #define        DAY     7
                     43: #define        HOUR    4
                     44: #define        MIN     2
                     45: #define        SEC     0
                     46: 
                     47: /* Forward. */
                     48: int    bcd();
                     49: void   clock();
                     50: void   clockcheck();
                     51: void   fatal();
                     52: void   sanity();
                     53: void   set();
                     54: void   usage();
                     55: /* ATclockas.s */
                     56: void   sphi();
                     57: void   splo();
                     58: int    zget();
                     59: void   zput();
                     60: 
                     61: /* Globals. */
                     62: unsigned char clkbuf[10];      /* Clock image buffer (ten BCD digits). */
                     63: 
                     64: main(argc, argv) int argc; char *argv[];
                     65: {
                     66:        register char *a, *s;
                     67: 
                     68:        if (argc > 2)
                     69:                usage();
                     70: 
                     71:        if (zget(DIAG) & BADCLK)
                     72:                fatal("bad clock");             /* check for valid clock */
                     73:        clock(0);                               /* read it to clkbuf[] */
                     74: 
                     75:        if (argc == 2) {
                     76:                set(argv[1]);                   /* initialize clkbuf[] */
                     77:                clock(1);                       /* and set the clock */
                     78:        } else
                     79:                clockcheck();                   /* check clock */
                     80: 
                     81:        /* Print formatted date. */
                     82:        printf("%d%d%d%d%d%d%d%d%d%d.%d%d\n",
                     83:                clkbuf[YEAR] >> 4, clkbuf[YEAR] & 15,
                     84:                clkbuf[MON]  >> 4, clkbuf[MON]  & 15,
                     85:                clkbuf[DAY]  >> 4, clkbuf[DAY]  & 15,
                     86:                clkbuf[HOUR] >> 4, clkbuf[HOUR] & 15,
                     87:                clkbuf[MIN]  >> 4, clkbuf[MIN]  & 15,
                     88:                clkbuf[SEC]  >> 4, clkbuf[SEC]  & 15
                     89:                );
                     90:        exit (0);
                     91: }
                     92: 
                     93: /*
                     94:  * Change a numeric character string into two bcd digits.
                     95:  */
                     96: int
                     97: bcd(s) register char *s;
                     98: {
                     99:        if (('0' <= s[0]) && (s[0] <= '9') && ('0' <= s[1]) && (s[1] <= '9'))
                    100:                return (s[0] << 4) | (s[1] & 15);
                    101:        fatal("argument contains nondigit");
                    102: }
                    103: 
                    104: /*
                    105:  * Check the clkbuf[] for sanity.
                    106:  */
                    107: void
                    108: clockcheck()
                    109: {
                    110:        sanity(YEAR, 0, 99, "year");
                    111:        sanity(MON, 1, 12, "month");
                    112:        sanity(DAY, 1, 31, "day");
                    113:        sanity(HOUR, 0, 23, "hour");
                    114:        sanity(MIN, 0, 59, "minute");
                    115:        sanity(SEC, 0, 59, "second");
                    116: }
                    117: 
                    118: /*
                    119:  * Wait for clock to stabilize or timeout to occur, then read or set it.
                    120:  */
                    121: void
                    122: clock(flag) register int flag;
                    123: {
                    124:        register int i;
                    125: 
                    126:        i = 0;
                    127:        do {
                    128:                splo();
                    129:                if (--i == 0)
                    130:                        fatal("bad clock");
                    131:                sphi();
                    132:        } while (zget(STAT) & UPDATE);
                    133: 
                    134:        if (flag == 0) {
                    135:                /* Read the clock. */
                    136:                for (i = 0; i < sizeof clkbuf; i++)
                    137:                        clkbuf[i] = zget(i);
                    138:        } else {
                    139:                /* Write the clock. */
                    140:                for (i = 0; i < sizeof clkbuf; i++)
                    141:                        zput(i, clkbuf[i]);
                    142:        }
                    143:        splo();
                    144: }
                    145: 
                    146: /*
                    147:  * Cry and die.
                    148:  */
                    149: void
                    150: fatal(args) char *args;
                    151: {
                    152:        fprintf(stderr, "/etc/ATclock: %r\n", &args);
                    153:        exit(1);
                    154: }
                    155: 
                    156: /*
                    157:  * Sanity check: make sure BCD clkbuf[i] is in the given range.
                    158:  */
                    159: void
                    160: sanity(i, min, max, msg) register int i; int min, max; char *msg;
                    161: {
                    162:        register int n;
                    163: 
                    164:        n = 10 * (clkbuf[i] >> 4) + (clkbuf[i] & 15);
                    165:        if (n < min || n > max)
                    166:                fatal("%s %d not in range %d to %d", msg, n, min, max);
                    167: }
                    168: 
                    169: /*
                    170:  * Set clkbuf[] according to the argument string.
                    171:  */
                    172: void
                    173: set(s) register char *s;
                    174: {
                    175:        register char *a;
                    176: 
                    177:        a = s + strlen(s);
                    178:        if ((&a[-3] >= s) && (a[-3] == '.')) {
                    179:                clkbuf[SEC] = bcd(a -= 2);
                    180:                a--;
                    181:        } else
                    182:                clkbuf[SEC] = 0;
                    183:        if (&a[-2] >= s)
                    184:                clkbuf[MIN] = bcd(a -= 2);
                    185:        if (&a[-2] >= s)
                    186:                clkbuf[HOUR] = bcd(a -= 2);
                    187:        if (&a[-2] >= s)
                    188:                clkbuf[DAY] = bcd(a -= 2);
                    189:        if (&a[-2] >= s)
                    190:                clkbuf[MON] = bcd(a -= 2);
                    191:        if (&a[-2] >= s)
                    192:                clkbuf[YEAR] = bcd(a -= 2);
                    193:        if (a != s)
                    194:                usage();
                    195:        clockcheck();
                    196: }
                    197: 
                    198: /*
                    199:  * Print a usage message and exit.
                    200:  */
                    201: void
                    202: usage()
                    203: {
                    204:        fprintf(stderr, USAGE);
                    205:        exit(1);
                    206: }
                    207: 
                    208: /* 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.