|
|
1.1 ! root 1: /* @(#)disktab.c 4.2 (Berkeley) 2/8/83 */ ! 2: ! 3: #include <disktab.h> ! 4: #include <stdio.h> ! 5: ! 6: static char *dgetstr(); ! 7: ! 8: struct disktab * ! 9: getdiskbyname(name) ! 10: char *name; ! 11: { ! 12: static struct disktab disk; ! 13: static char localbuf[100], *cp = localbuf; ! 14: register struct disktab *dp = &disk; ! 15: register struct partition *pp; ! 16: char p, psize[3], pbsize[3], pfsize[3]; ! 17: char buf[BUFSIZ]; ! 18: ! 19: if (dgetent(buf, name) <= 0) ! 20: return ((struct disktab *)0); ! 21: dp->d_name = cp; ! 22: strcpy(cp, name); ! 23: cp += strlen(name) + 1; ! 24: dp->d_type = dgetstr("ty", &cp); ! 25: dp->d_secsize = dgetnum("se"); ! 26: if (dp->d_secsize < 0) ! 27: dp->d_secsize = 512; ! 28: dp->d_ntracks = dgetnum("nt"); ! 29: dp->d_nsectors = dgetnum("ns"); ! 30: dp->d_ncylinders = dgetnum("nc"); ! 31: dp->d_rpm = dgetnum("rm"); ! 32: if (dp->d_rpm < 0) ! 33: dp->d_rpm = 3600; ! 34: strcpy(psize, "px"); ! 35: strcpy(pbsize, "bx"); ! 36: strcpy(pfsize, "fx"); ! 37: for (p = 'a'; p < 'i'; p++) { ! 38: psize[1] = pbsize[1] = pfsize[1] = p; ! 39: pp = &dp->d_partitions[p - 'a']; ! 40: pp->p_size = dgetnum(psize); ! 41: pp->p_bsize = dgetnum(pbsize); ! 42: pp->p_fsize = dgetnum(pfsize); ! 43: } ! 44: return (dp); ! 45: } ! 46: ! 47: #include <ctype.h> ! 48: ! 49: static char *tbuf; ! 50: static char *dskip(); ! 51: static char *ddecode(); ! 52: ! 53: /* ! 54: * Get an entry for disk name in buffer bp, ! 55: * from the diskcap file. Parse is very rudimentary; ! 56: * we just notice escaped newlines. ! 57: */ ! 58: static ! 59: dgetent(bp, name) ! 60: char *bp, *name; ! 61: { ! 62: register char *cp; ! 63: register int c; ! 64: register int i = 0, cnt = 0; ! 65: char ibuf[BUFSIZ]; ! 66: int tf; ! 67: ! 68: tbuf = bp; ! 69: tf = open(DISKTAB, 0); ! 70: if (tf < 0) ! 71: return (-1); ! 72: for (;;) { ! 73: cp = bp; ! 74: for (;;) { ! 75: if (i == cnt) { ! 76: cnt = read(tf, ibuf, BUFSIZ); ! 77: if (cnt <= 0) { ! 78: close(tf); ! 79: return (0); ! 80: } ! 81: i = 0; ! 82: } ! 83: c = ibuf[i++]; ! 84: if (c == '\n') { ! 85: if (cp > bp && cp[-1] == '\\'){ ! 86: cp--; ! 87: continue; ! 88: } ! 89: break; ! 90: } ! 91: if (cp >= bp+BUFSIZ) { ! 92: write(2,"Disktab entry too long\n", 23); ! 93: break; ! 94: } else ! 95: *cp++ = c; ! 96: } ! 97: *cp = 0; ! 98: ! 99: /* ! 100: * The real work for the match. ! 101: */ ! 102: if (dnamatch(name)) { ! 103: close(tf); ! 104: return (1); ! 105: } ! 106: } ! 107: } ! 108: ! 109: /* ! 110: * Dnamatch deals with name matching. The first field of the disktab ! 111: * entry is a sequence of names separated by |'s, so we compare ! 112: * against each such name. The normal : terminator after the last ! 113: * name (before the first field) stops us. ! 114: */ ! 115: static ! 116: dnamatch(np) ! 117: char *np; ! 118: { ! 119: register char *Np, *Bp; ! 120: ! 121: Bp = tbuf; ! 122: if (*Bp == '#') ! 123: return (0); ! 124: for (;;) { ! 125: for (Np = np; *Np && *Bp == *Np; Bp++, Np++) ! 126: continue; ! 127: if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) ! 128: return (1); ! 129: while (*Bp && *Bp != ':' && *Bp != '|') ! 130: Bp++; ! 131: if (*Bp == 0 || *Bp == ':') ! 132: return (0); ! 133: Bp++; ! 134: } ! 135: } ! 136: ! 137: /* ! 138: * Skip to the next field. Notice that this is very dumb, not ! 139: * knowing about \: escapes or any such. If necessary, :'s can be put ! 140: * into the diskcap file in octal. ! 141: */ ! 142: static char * ! 143: dskip(bp) ! 144: register char *bp; ! 145: { ! 146: ! 147: while (*bp && *bp != ':') ! 148: bp++; ! 149: if (*bp == ':') ! 150: bp++; ! 151: return (bp); ! 152: } ! 153: ! 154: /* ! 155: * Return the (numeric) option id. ! 156: * Numeric options look like ! 157: * li#80 ! 158: * i.e. the option string is separated from the numeric value by ! 159: * a # character. If the option is not found we return -1. ! 160: * Note that we handle octal numbers beginning with 0. ! 161: */ ! 162: static ! 163: dgetnum(id) ! 164: char *id; ! 165: { ! 166: register int i, base; ! 167: register char *bp = tbuf; ! 168: ! 169: for (;;) { ! 170: bp = dskip(bp); ! 171: if (*bp == 0) ! 172: return (-1); ! 173: if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) ! 174: continue; ! 175: if (*bp == '@') ! 176: return (-1); ! 177: if (*bp != '#') ! 178: continue; ! 179: bp++; ! 180: base = 10; ! 181: if (*bp == '0') ! 182: base = 8; ! 183: i = 0; ! 184: while (isdigit(*bp)) ! 185: i *= base, i += *bp++ - '0'; ! 186: return (i); ! 187: } ! 188: } ! 189: ! 190: /* ! 191: * Handle a flag option. ! 192: * Flag options are given "naked", i.e. followed by a : or the end ! 193: * of the buffer. Return 1 if we find the option, or 0 if it is ! 194: * not given. ! 195: */ ! 196: static ! 197: dgetflag(id) ! 198: char *id; ! 199: { ! 200: register char *bp = tbuf; ! 201: ! 202: for (;;) { ! 203: bp = dskip(bp); ! 204: if (!*bp) ! 205: return (0); ! 206: if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { ! 207: if (!*bp || *bp == ':') ! 208: return (1); ! 209: else if (*bp == '@') ! 210: return (0); ! 211: } ! 212: } ! 213: } ! 214: ! 215: /* ! 216: * Get a string valued option. ! 217: * These are given as ! 218: * cl=^Z ! 219: * Much decoding is done on the strings, and the strings are ! 220: * placed in area, which is a ref parameter which is updated. ! 221: * No checking on area overflow. ! 222: */ ! 223: static char * ! 224: dgetstr(id, area) ! 225: char *id, **area; ! 226: { ! 227: register char *bp = tbuf; ! 228: ! 229: for (;;) { ! 230: bp = dskip(bp); ! 231: if (!*bp) ! 232: return (0); ! 233: if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) ! 234: continue; ! 235: if (*bp == '@') ! 236: return (0); ! 237: if (*bp != '=') ! 238: continue; ! 239: bp++; ! 240: return (ddecode(bp, area)); ! 241: } ! 242: } ! 243: ! 244: /* ! 245: * Tdecode does the grung work to decode the ! 246: * string capability escapes. ! 247: */ ! 248: static char * ! 249: ddecode(str, area) ! 250: register char *str; ! 251: char **area; ! 252: { ! 253: register char *cp; ! 254: register int c; ! 255: register char *dp; ! 256: int i; ! 257: ! 258: cp = *area; ! 259: while ((c = *str++) && c != ':') { ! 260: switch (c) { ! 261: ! 262: case '^': ! 263: c = *str++ & 037; ! 264: break; ! 265: ! 266: case '\\': ! 267: dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; ! 268: c = *str++; ! 269: nextc: ! 270: if (*dp++ == c) { ! 271: c = *dp++; ! 272: break; ! 273: } ! 274: dp++; ! 275: if (*dp) ! 276: goto nextc; ! 277: if (isdigit(c)) { ! 278: c -= '0', i = 2; ! 279: do ! 280: c <<= 3, c |= *str++ - '0'; ! 281: while (--i && isdigit(*str)); ! 282: } ! 283: break; ! 284: } ! 285: *cp++ = c; ! 286: } ! 287: *cp++ = 0; ! 288: str = *area; ! 289: *area = cp; ! 290: return (str); ! 291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.