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