|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.