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: }

Defined functions

ddecode defined in line 258; used 2 times
dgetent defined in line 68; used 1 times
  • in line 27
dgetflag defined in line 206; used 2 times
dgetnum defined in line 172; used 8 times
dgetstr defined in line 233; used 2 times
dnamatch defined in line 125; used 1 times
dskip defined in line 152; used 4 times

Defined variables

sccsid defined in line 8; never used
tbuf defined in line 59; used 5 times
Last modified: 1986-03-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1612
Valid CSS Valid XHTML 1.0 Strict