|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1987 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)disklabel.c 5.13 (Berkeley) 6/1/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <sys/param.h> ! 25: #include <ufs/fs.h> ! 26: #include <sys/file.h> ! 27: #define DKTYPENAMES ! 28: #include <sys/disklabel.h> ! 29: #include <stdio.h> ! 30: #include <string.h> ! 31: ! 32: static char *dgetstr(); ! 33: ! 34: struct disklabel * ! 35: getdiskbyname(name) ! 36: char *name; ! 37: { ! 38: static struct disklabel disk; ! 39: static char boot[BUFSIZ]; ! 40: char localbuf[BUFSIZ]; ! 41: char buf[BUFSIZ]; ! 42: char *cp, *cq; /* can't be register */ ! 43: register struct disklabel *dp = &disk; ! 44: register struct partition *pp; ! 45: char p, max, psize[3], pbsize[3], ! 46: pfsize[3], poffset[3], ptype[3]; ! 47: u_long *dx; ! 48: ! 49: if (dgetent(buf, name) <= 0) ! 50: return ((struct disklabel *)0); ! 51: bzero((char *)&disk, sizeof(disk)); ! 52: /* ! 53: * typename ! 54: */ ! 55: cq = dp->d_typename; ! 56: cp = buf; ! 57: while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && ! 58: (*cq = *cp) && *cq != '|' && *cq != ':') ! 59: cq++, cp++; ! 60: *cq = '\0'; ! 61: /* ! 62: * boot name (optional) xxboot, bootxx ! 63: */ ! 64: cp = boot; ! 65: dp->d_boot0 = dgetstr("b0", &cp); ! 66: dp->d_boot1 = dgetstr("b1", &cp); ! 67: cp = localbuf; ! 68: cq = dgetstr("ty", &cp); ! 69: if (cq && strcmp(cq, "removable") == 0) ! 70: dp->d_flags |= D_REMOVABLE; ! 71: else if (cq && strcmp(cq, "simulated") == 0) ! 72: dp->d_flags |= D_RAMDISK; ! 73: if (dgetflag("sf")) ! 74: dp->d_flags |= D_BADSECT; ! 75: ! 76: #define getnumdflt(field, dname, dflt) \ ! 77: { int f = dgetnum(dname); \ ! 78: (field) = f == -1 ? (dflt) : f; } ! 79: ! 80: getnumdflt(dp->d_secsize, "se", DEV_BSIZE); ! 81: dp->d_ntracks = dgetnum("nt"); ! 82: dp->d_nsectors = dgetnum("ns"); ! 83: dp->d_ncylinders = dgetnum("nc"); ! 84: cq = dgetstr("dt", &cp); ! 85: if (cq) ! 86: dp->d_type = gettype(cq, dktypenames); ! 87: else ! 88: getnumdflt(dp->d_type, "dt", 0); ! 89: getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); ! 90: getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); ! 91: getnumdflt(dp->d_rpm, "rm", 3600); ! 92: getnumdflt(dp->d_interleave, "il", 1); ! 93: getnumdflt(dp->d_trackskew, "sk", 0); ! 94: getnumdflt(dp->d_cylskew, "cs", 0); ! 95: getnumdflt(dp->d_headswitch, "hs", 0); ! 96: getnumdflt(dp->d_trkseek, "ts", 0); ! 97: getnumdflt(dp->d_bbsize, "bs", BBSIZE); ! 98: getnumdflt(dp->d_sbsize, "sb", SBSIZE); ! 99: strcpy(psize, "px"); ! 100: strcpy(pbsize, "bx"); ! 101: strcpy(pfsize, "fx"); ! 102: strcpy(poffset, "ox"); ! 103: strcpy(ptype, "tx"); ! 104: max = 'a' - 1; ! 105: pp = &dp->d_partitions[0]; ! 106: for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { ! 107: psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; ! 108: pp->p_size = dgetnum(psize); ! 109: if (pp->p_size == -1) ! 110: pp->p_size = 0; ! 111: else { ! 112: pp->p_offset = dgetnum(poffset); ! 113: getnumdflt(pp->p_fsize, pfsize, 0); ! 114: if (pp->p_fsize) ! 115: pp->p_frag = dgetnum(pbsize) / pp->p_fsize; ! 116: getnumdflt(pp->p_fstype, ptype, 0); ! 117: if (pp->p_fstype == 0 && (cq = dgetstr(ptype, &cp))) ! 118: pp->p_fstype = gettype(cq, fstypenames); ! 119: max = p; ! 120: } ! 121: } ! 122: dp->d_npartitions = max + 1 - 'a'; ! 123: (void)strcpy(psize, "dx"); ! 124: dx = dp->d_drivedata; ! 125: for (p = '0'; p < '0' + NDDATA; p++, dx++) { ! 126: psize[1] = p; ! 127: getnumdflt(*dx, psize, 0); ! 128: } ! 129: dp->d_magic = DISKMAGIC; ! 130: dp->d_magic2 = DISKMAGIC; ! 131: return (dp); ! 132: } ! 133: ! 134: #include <ctype.h> ! 135: ! 136: static char *tbuf; ! 137: static char *dskip(); ! 138: static char *ddecode(); ! 139: ! 140: /* ! 141: * Get an entry for disk name in buffer bp, ! 142: * from the diskcap file. Parse is very rudimentary; ! 143: * we just notice escaped newlines. ! 144: */ ! 145: static ! 146: dgetent(bp, name) ! 147: char *bp, *name; ! 148: { ! 149: register char *cp; ! 150: register int c; ! 151: register int i = 0, cnt = 0; ! 152: char ibuf[BUFSIZ]; ! 153: int tf; ! 154: ! 155: tbuf = bp; ! 156: tf = open(DISKTAB, 0); ! 157: if (tf < 0) ! 158: return (-1); ! 159: for (;;) { ! 160: cp = bp; ! 161: for (;;) { ! 162: if (i == cnt) { ! 163: cnt = read(tf, ibuf, BUFSIZ); ! 164: if (cnt <= 0) { ! 165: close(tf); ! 166: return (0); ! 167: } ! 168: i = 0; ! 169: } ! 170: c = ibuf[i++]; ! 171: if (c == '\n') { ! 172: if (cp > bp && cp[-1] == '\\'){ ! 173: cp--; ! 174: continue; ! 175: } ! 176: break; ! 177: } ! 178: if (cp >= bp+BUFSIZ) { ! 179: write(2,"Disktab entry too long\n", 23); ! 180: break; ! 181: } else ! 182: *cp++ = c; ! 183: } ! 184: *cp = 0; ! 185: ! 186: /* ! 187: * The real work for the match. ! 188: */ ! 189: if (dnamatch(name)) { ! 190: close(tf); ! 191: return (1); ! 192: } ! 193: } ! 194: } ! 195: ! 196: /* ! 197: * Dnamatch deals with name matching. The first field of the disktab ! 198: * entry is a sequence of names separated by |'s, so we compare ! 199: * against each such name. The normal : terminator after the last ! 200: * name (before the first field) stops us. ! 201: */ ! 202: static ! 203: dnamatch(np) ! 204: char *np; ! 205: { ! 206: register char *Np, *Bp; ! 207: ! 208: Bp = tbuf; ! 209: if (*Bp == '#') ! 210: return (0); ! 211: for (;;) { ! 212: for (Np = np; *Np && *Bp == *Np; Bp++, Np++) ! 213: continue; ! 214: if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) ! 215: return (1); ! 216: while (*Bp && *Bp != ':' && *Bp != '|') ! 217: Bp++; ! 218: if (*Bp == 0 || *Bp == ':') ! 219: return (0); ! 220: Bp++; ! 221: } ! 222: } ! 223: ! 224: /* ! 225: * Skip to the next field. Notice that this is very dumb, not ! 226: * knowing about \: escapes or any such. If necessary, :'s can be put ! 227: * into the diskcap file in octal. ! 228: */ ! 229: static char * ! 230: dskip(bp) ! 231: register char *bp; ! 232: { ! 233: ! 234: while (*bp && *bp != ':') ! 235: bp++; ! 236: if (*bp == ':') ! 237: bp++; ! 238: return (bp); ! 239: } ! 240: ! 241: /* ! 242: * Return the (numeric) option id. ! 243: * Numeric options look like ! 244: * li#80 ! 245: * i.e. the option string is separated from the numeric value by ! 246: * a # character. If the option is not found we return -1. ! 247: * Note that we handle octal numbers beginning with 0. ! 248: */ ! 249: static ! 250: dgetnum(id) ! 251: char *id; ! 252: { ! 253: register int i, base; ! 254: register char *bp = tbuf; ! 255: ! 256: for (;;) { ! 257: bp = dskip(bp); ! 258: if (*bp == 0) ! 259: return (-1); ! 260: if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) ! 261: continue; ! 262: if (*bp == '@') ! 263: return (-1); ! 264: if (*bp != '#') ! 265: continue; ! 266: bp++; ! 267: base = 10; ! 268: if (*bp == '0') ! 269: base = 8; ! 270: i = 0; ! 271: while (isdigit(*bp)) ! 272: i *= base, i += *bp++ - '0'; ! 273: return (i); ! 274: } ! 275: } ! 276: ! 277: /* ! 278: * Handle a flag option. ! 279: * Flag options are given "naked", i.e. followed by a : or the end ! 280: * of the buffer. Return 1 if we find the option, or 0 if it is ! 281: * not given. ! 282: */ ! 283: static ! 284: dgetflag(id) ! 285: char *id; ! 286: { ! 287: register char *bp = tbuf; ! 288: ! 289: for (;;) { ! 290: bp = dskip(bp); ! 291: if (!*bp) ! 292: return (0); ! 293: if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { ! 294: if (!*bp || *bp == ':') ! 295: return (1); ! 296: else if (*bp == '@') ! 297: return (0); ! 298: } ! 299: } ! 300: } ! 301: ! 302: /* ! 303: * Get a string valued option. ! 304: * These are given as ! 305: * cl=^Z ! 306: * Much decoding is done on the strings, and the strings are ! 307: * placed in area, which is a ref parameter which is updated. ! 308: * No checking on area overflow. ! 309: */ ! 310: static char * ! 311: dgetstr(id, area) ! 312: char *id, **area; ! 313: { ! 314: register char *bp = tbuf; ! 315: ! 316: for (;;) { ! 317: bp = dskip(bp); ! 318: if (!*bp) ! 319: return (0); ! 320: if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) ! 321: continue; ! 322: if (*bp == '@') ! 323: return (0); ! 324: if (*bp != '=') ! 325: continue; ! 326: bp++; ! 327: return (ddecode(bp, area)); ! 328: } ! 329: } ! 330: ! 331: /* ! 332: * Tdecode does the grung work to decode the ! 333: * string capability escapes. ! 334: */ ! 335: static char * ! 336: ddecode(str, area) ! 337: register char *str; ! 338: char **area; ! 339: { ! 340: register char *cp; ! 341: register int c; ! 342: register char *dp; ! 343: int i; ! 344: ! 345: cp = *area; ! 346: while ((c = *str++) && c != ':') { ! 347: switch (c) { ! 348: ! 349: case '^': ! 350: c = *str++ & 037; ! 351: break; ! 352: ! 353: case '\\': ! 354: dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; ! 355: c = *str++; ! 356: nextc: ! 357: if (*dp++ == c) { ! 358: c = *dp++; ! 359: break; ! 360: } ! 361: dp++; ! 362: if (*dp) ! 363: goto nextc; ! 364: if (isdigit(c)) { ! 365: c -= '0', i = 2; ! 366: do ! 367: c <<= 3, c |= *str++ - '0'; ! 368: while (--i && isdigit(*str)); ! 369: } ! 370: break; ! 371: } ! 372: *cp++ = c; ! 373: } ! 374: *cp++ = 0; ! 375: str = *area; ! 376: *area = cp; ! 377: return (str); ! 378: } ! 379: ! 380: static ! 381: gettype(t, names) ! 382: char *t; ! 383: char **names; ! 384: { ! 385: register char **nm; ! 386: ! 387: for (nm = names; *nm; nm++) ! 388: if (strcasecmp(t, *nm) == 0) ! 389: return (nm - names); ! 390: if (isdigit(*t)) ! 391: return (atoi(t)); ! 392: return (0); ! 393: } ! 394: ! 395: dkcksum(lp) ! 396: register struct disklabel *lp; ! 397: { ! 398: register u_short *start, *end; ! 399: register u_short sum = 0; ! 400: ! 401: start = (u_short *)lp; ! 402: end = (u_short *)&lp->d_partitions[lp->d_npartitions]; ! 403: while (start < end) ! 404: sum ^= *start++; ! 405: return (sum); ! 406: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.