# 2.11BSD#431 - /usr/src/lib/libc/gen/disklabel.c

##### Functions

    getdiskbyname     X

##### Macros

    DKTYPENAMES       X
    getnumdflt        X

       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, with or without
       6:  * modification, are permitted provided that the following conditions
       7:  * are met:
       8:  * 1. Redistributions of source code must retain the above copyright
       9:  *    notice, this list of conditions and the following disclaimer.
      10:  * 2. Redistributions in binary form must reproduce the above copyright
      11:  *    notice, this list of conditions and the following disclaimer in the
      12:  *    documentation and/or other materials provided with the distribution.
      13:  * 3. All advertising materials mentioning features or use of this software
      14:  *    must display the following acknowledgement:
      15:  *	This product includes software developed by the University of
      16:  *	California, Berkeley and its contributors.
      17:  * 4. Neither the name of the University nor the names of its contributors
      18:  *    may be used to endorse or promote products derived from this software
      19:  *    without specific prior written permission.
      20:  *
      21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31:  * SUCH DAMAGE.
      32:  */
      33:
      34: #if defined(LIBC_SCCS) && !defined(lint)
      35: static char sccsid[] = "@(#)disklabel.c	5.17.1 (2.11BSD) 4/10/95";
      36: #endif /* LIBC_SCCS and not lint */
      37:
      38: #include <sys/param.h>
      39: #include <sys/errno.h>
      40: #include <sys/fs.h>
      41: #include <sys/file.h>
      42: #include <sys/uio.h>
      43:
      44: #define DKTYPENAMES
      45: #include <sys/disklabel.h>
      46: #include <stdio.h>
      47: #include <string.h>
      48:
      49: extern  int errno;
      50:
      51: static  char *dgetstr();
      52: static  dgetent();
      53: static  dnamatch();
      54: static  long dgetnum(), _gtnumdflt();
      55: static  dgetflag();
      56: static  gettype();
      57: static  error();
      58:
      59: #define getnumdflt(field, dname, dflt) field=_gtnumdflt(dname,(long)dflt)
      60:
      61: struct disklabel *
      62: getdiskbyname(name)
      63:     char *name;
      64: {
      65:     static struct   disklabel disk;
      66:     static char     boot[MAXPATHLEN];
      67:     char    localbuf[256];  /* BUFSIZ reduced to save stack space */
      68:     char    buf[BUFSIZ];
      69:     char    *cp, *cq;   /* can't be register */
      70:     register struct disklabel *dp = &disk;
      71:     register struct partition *pp;
      72:     char    p, max, psize[3], pbsize[3],
      73:         pfsize[3], poffset[3], ptype[3];
      74:     u_long  *dx;
      75:
      76:     if (dgetent(buf, name) <= 0)
      77:         return ((struct disklabel *)0);
      78:     bzero((char *)&disk, sizeof(disk));
      79:     /*
      80: 	 * typename
      81: 	 */
      82:     cq = dp->d_typename;
      83:     cp = buf;
      84:     while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 &&
      85:         (*cq = *cp) && *cq != '|' && *cq != ':')
      86:         cq++, cp++;
      87:     *cq = '\0';
      88:     /*
      89: 	 * boot name (optional)  xxboot
      90: 	 */
      91:     cp = boot;
      92:     dp->d_boot0 = dgetstr("b0", &cp);
      93:     cp = localbuf;
      94:     cq = dgetstr("ty", &cp);
      95:     if (cq && strcmp(cq, "removable") == 0)
      96:         dp->d_flags |= D_REMOVABLE;
      97:     else  if (cq && strcmp(cq, "simulated") == 0)
      98:         dp->d_flags |= D_RAMDISK;
      99:     if (dgetflag("sf"))
     100:         dp->d_flags |= D_BADSECT;
     101:
     102: /*
     103:  *	Have to do this because anything except 512 will cause chaos in
     104:  *	disklabel(8).  disklabel(8) tries to protect itself against this
     105:  *	but the safest thing is to fix the sector size here.  The only thing
     106:  *	which ever used a value other than 512 was the RL02 and RL01
     107:  *	disktab entries and they have been fixed.
     108: */
     109:
     110: #ifdef  corrupt_filesystems
     111:     getnumdflt(dp->d_secsize, "se", 512);
     112: #endif
     113:     dp->d_secsize = 512;
     114:
     115:     dp->d_ntracks = dgetnum("nt");
     116:     dp->d_nsectors = dgetnum("ns");
     117:     dp->d_ncylinders = dgetnum("nc");
     118:     cq = dgetstr("dt", &cp);
     119:     if (cq)
     120:         dp->d_type = gettype(cq, dktypenames);
     121:     else
     122:         getnumdflt(dp->d_type, "dt", 0);
     123:     getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks);
     124:     getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders);
     125:     getnumdflt(dp->d_sparespertrack, "rt", 0);
     126:     getnumdflt(dp->d_sparespercyl, "rc", 0);
     127:     getnumdflt(dp->d_acylinders, "ac", 0);
     128:     getnumdflt(dp->d_rpm, "rm", 3600);
     129:     getnumdflt(dp->d_interleave, "il", 1);
     130:     getnumdflt(dp->d_trackskew, "sk", 0);
     131:     getnumdflt(dp->d_cylskew, "cs", 0);
     132:     getnumdflt(dp->d_headswitch, "hs", 0);
     133:     getnumdflt(dp->d_trkseek, "ts", 0);
     134:
     135: /*
     136:  * See the comments in src/bin/disklabel.c for a more detailed explaination
     137:  * which the 'bbsize' is set to 512.  The simple explanation is that the
     138:  * designers of disklabeling confused 'sectors' and 'filesystem blocks'.
     139:  * BBSIZE is set to 1024 even though the real boot area (what the boot roms
     140:  * will read) is 512.
     141: */
     142: #ifdef  boot_area_really_is_1k
     143:     getnumdflt(dp->d_bbsize, "bs", BBSIZE);
     144: #endif
     145:     dp->d_bbsize = 512;
     146:
     147:     getnumdflt(dp->d_sbsize, "sb", SBSIZE);
     148:     strcpy(psize, "px");
     149:     strcpy(pbsize, "bx");
     150:     strcpy(pfsize, "fx");
     151:     strcpy(poffset, "ox");
     152:     strcpy(ptype, "tx");
     153:     max = 'a' - 1;
     154:     pp = &dp->d_partitions[0];
     155:     for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) {
     156:         psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p;
     157:         pp->p_size = dgetnum(psize);
     158:         if (pp->p_size == -1L)
     159:             pp->p_size = 0L;
     160:         else {
     161:             pp->p_offset = dgetnum(poffset);
     162:             getnumdflt(pp->p_fsize, pfsize, 0);
     163:             if (pp->p_fsize)
     164:                 pp->p_frag = dgetnum(pbsize) / pp->p_fsize;
     165:             getnumdflt(pp->p_fstype, ptype, 0);
     166:             if (pp->p_fstype == 0 && (cq = dgetstr(ptype, &cp)))
     167:                 pp->p_fstype = gettype(cq, fstypenames);
     168:             max = p;
     169:         }
     170:     }
     171:     dp->d_npartitions = max + 1 - 'a';
     172:     (void)strcpy(psize, "dx");
     173:     dx = dp->d_drivedata;
     174:     for (p = '0'; p < '0' + NDDATA; p++, dx++) {
     175:         psize[1] = p;
     176:         getnumdflt(*dx, psize, 0);
     177:     }
     178:     dp->d_magic = DISKMAGIC;
     179:     dp->d_magic2 = DISKMAGIC;
     180:     return (dp);
     181: }
     182:
     183: #include <ctype.h>
     184:
     185: static  char *tbuf;
     186: static  char *dskip();
     187: static  char *ddecode();
     188:
     189: /*
     190:  * Get an entry for disk name in buffer bp,
     191:  * from the diskcap file.  Parse is very rudimentary;
     192:  * we just notice escaped newlines.
     193:  */
     194: static
     195: dgetent(bp, name)
     196:     char *bp, *name;
     197: {
     198:     register char *cp;
     199:     register int c;
     200:     register int i = 0, cnt = 0;
     201:     char ibuf[512];     /* BUFSIZE - reduced to conserve stack space */
     202:     int tf;
     203:
     204:     tbuf = bp;
     205:     tf = open(_PATH_DISKTAB, 0);
     206:     if (tf < 0) {
     207:         error(errno);
     208:         return (-1);
     209:     }
     210:     for (;;) {
     211:         cp = bp;
     212:         for (;;) {
     213:             if (i == cnt) {
     214:                 cnt = read(tf, ibuf, sizeof (ibuf));
     215:                 if (cnt <= 0) {
     216:                     error(errno);
     217:                     close(tf);
     218:                     return (0);
     219:                 }
     220:                 i = 0;
     221:             }
     222:             c = ibuf[i++];
     223:             if (c == '\n') {
     224:                 if (cp > bp && cp[-1] == '\\'){
     225:                     cp--;
     226:                     continue;
     227:                 }
     228:                 break;
     229:             }
     230:             if (cp >= bp+BUFSIZ) {
     231:                 error(EFTYPE);
     232:                 break;
     233:             } else
     234:                 *cp++ = c;
     235:         }
     236:         *cp = 0;
     237:
     238:         /*
     239: 		 * The real work for the match.
     240: 		 */
     241:         if (dnamatch(name)) {
     242:             close(tf);
     243:             return (1);
     244:         }
     245:     }
     246: }
     247:
     248: /*
     249:  * Dnamatch deals with name matching.  The first field of the disktab
     250:  * entry is a sequence of names separated by |'s, so we compare
     251:  * against each such name.  The normal : terminator after the last
     252:  * name (before the first field) stops us.
     253:  */
     254: static
     255: dnamatch(np)
     256:     char *np;
     257: {
     258:     register char *Np, *Bp;
     259:
     260:     Bp = tbuf;
     261:     if (*Bp == '#')
     262:         return (0);
     263:     for (;;) {
     264:         for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
     265:             continue;
     266:         if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
     267:             return (1);
     268:         while (*Bp && *Bp != ':' && *Bp != '|')
     269:             Bp++;
     270:         if (*Bp == 0 || *Bp == ':')
     271:             return (0);
     272:         Bp++;
     273:     }
     274: }
     275:
     276: /*
     277:  * Skip to the next field.  Notice that this is very dumb, not
     278:  * knowing about \: escapes or any such.  If necessary, :'s can be put
     279:  * into the diskcap file in octal.
     280:  */
     281: static char *
     282: dskip(bp)
     283:     register char *bp;
     284: {
     285:
     286:     while (*bp && *bp != ':')
     287:         bp++;
     288:     while (*bp == ':')
     289:         bp++;
     290:     return (bp);
     291: }
     292:
     293: /*
     294:  * Return the (numeric) option id.
     295:  * Numeric options look like
     296:  *	li#80
     297:  * i.e. the option string is separated from the numeric value by
     298:  * a # character.  If the option is not found we return -1.
     299:  * Note that we handle octal numbers beginning with 0.
     300:  */
     301: static long
     302: dgetnum(id)
     303:     char *id;
     304: {
     305:     register int base;
     306:     long i;
     307:     register char *bp = tbuf;
     308:
     309:     for (;;) {
     310:         bp = dskip(bp);
     311:         if (*bp == 0)
     312:             return (-1);
     313:         if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
     314:             continue;
     315:         if (*bp == '@')
     316:             return (-1);
     317:         if (*bp != '#')
     318:             continue;
     319:         bp++;
     320:         base = 10;
     321:         if (*bp == '0')
     322:             base = 8;
     323:         i = 0;
     324:         while (isdigit(*bp))
     325:             i *= base, i += *bp++ - '0';
     326:         return (i);
     327:     }
     328: }
     329:
     330: /*
     331:  * Handle a flag option.
     332:  * Flag options are given "naked", i.e. followed by a : or the end
     333:  * of the buffer.  Return 1 if we find the option, or 0 if it is
     334:  * not given.
     335:  */
     336: static
     337: dgetflag(id)
     338:     char *id;
     339: {
     340:     register char *bp = tbuf;
     341:
     342:     for (;;) {
     343:         bp = dskip(bp);
     344:         if (!*bp)
     345:             return (0);
     346:         if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
     347:             if (!*bp || *bp == ':')
     348:                 return (1);
     349:             else if (*bp == '@')
     350:                 return (0);
     351:         }
     352:     }
     353: }
     354:
     355: /*
     356:  * Get a string valued option.
     357:  * These are given as
     358:  *	cl=^Z
     359:  * Much decoding is done on the strings, and the strings are
     360:  * placed in area, which is a ref parameter which is updated.
     361:  * No checking on area overflow.
     362:  */
     363: static char *
     364: dgetstr(id, area)
     365:     char *id, **area;
     366: {
     367:     register char *bp = tbuf;
     368:
     369:     for (;;) {
     370:         bp = dskip(bp);
     371:         if (!*bp)
     372:             return (0);
     373:         if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
     374:             continue;
     375:         if (*bp == '@')
     376:             return (0);
     377:         if (*bp != '=')
     378:             continue;
     379:         bp++;
     380:         return (ddecode(bp, area));
     381:     }
     382: }
     383:
     384: /*
     385:  * Tdecode does the grung work to decode the
     386:  * string capability escapes.
     387:  */
     388: static char *
     389: ddecode(str, area)
     390:     register char *str;
     391:     char **area;
     392: {
     393:     register char *cp;
     394:     register int c;
     395:     register char *dp;
     396:     int i;
     397:
     398:     cp = *area;
     399:     while ((c = *str++) && c != ':') {
     400:         switch (c) {
     401:
     402:         case '^':
     403:             c = *str++ & 037;
     404:             break;
     405:
     406:         case '\\':
     407:             dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
     408:             c = *str++;
     409: nextc:
     410:             if (*dp++ == c) {
     411:                 c = *dp++;
     412:                 break;
     413:             }
     414:             dp++;
     415:             if (*dp)
     416:                 goto nextc;
     417:             if (isdigit(c)) {
     418:                 c -= '0', i = 2;
     419:                 do
     420:                     c <<= 3, c |= *str++ - '0';
     421:                 while (--i && isdigit(*str));
     422:             }
     423:             break;
     424:         }
     425:         *cp++ = c;
     426:     }
     427:     *cp++ = 0;
     428:     str = *area;
     429:     *area = cp;
     430:     return (str);
     431: }
     432:
     433: static
     434: gettype(t, names)
     435:     char *t;
     436:     char **names;
     437: {
     438:     register char **nm;
     439:
     440:     for (nm = names; *nm; nm++)
     441:         if (strcasecmp(t, *nm) == 0)
     442:             return (nm - names);
     443:     if (isdigit(*t))
     444:         return (atoi(t));
     445:     return (0);
     446: }
     447:
     448: static
     449: error(err)
     450:     int err;
     451: {
     452:     struct iovec iov[4];
     453:
     454:     iov[0].iov_base = "disktab: ";
     455:     iov[0].iov_len = 9;
     456:     iov[1].iov_base = _PATH_DISKTAB;
     457:     iov[1].iov_len = sizeof (_PATH_DISKTAB) -  1;
     458:     iov[2].iov_base = strerror(err);
     459:     iov[2].iov_len = strlen(iov[2].iov_base);
     460:     iov[3].iov_base = "\n";
     461:     iov[3].iov_len = 1;
     462:     (void)writev(fileno(stderr), &iov, 4);
     463: }
     464:
     465: static long
     466: _gtnumdflt(dname, dflt)
     467:     char *dname;
     468:     long dflt;
     469:     {
     470:     long f;
     471:
     472:     f = dgetnum(dname);
     473:     if  (f == -1L)
     474:         f = dflt;
     475:     return(f);
     476:     }

#### Defined functions

_gtnumdflt defined in line 465; used 2 times

- in line 54-59(2)

ddecode defined in line 388; used 2 times

- in line 187, 380

dgetent defined in line 194; used 2 times

- in line 52, 76

dgetflag defined in line 336; used 2 times

- in line 55, 99

dgetnum defined in line 301; used 8 times

- in line 54, 115-117(3), 157-164(3), 472

dgetstr defined in line 363; used 5 times

- in line 51, 92-94(2), 118, 166

dnamatch defined in line 254; used 2 times

- in line 53, 241

dskip defined in line 281; used 4 times

- in line 186, 310, 343, 370

error defined in line 448; used 4 times

- in line 57, 207, 216, 231

getdiskbyname defined in line 61; used 3 times

- in /usr/src/bin/disklabel/disklabel.c line 285
- in /usr/src/sbin/newfs/newfs.c line 214-217(2)

gettype defined in line 433; used 3 times

- in line 56, 120, 167

#### Defined variables

sccsid defined in line 35; never used
tbuf defined in line 185; used 5 times

- in line 204, 260, 307, 340, 367

#### Defined macros

DKTYPENAMES defined in line 44; never used
getnumdflt defined in line 59; used 18 times

- in line 111, 122-133(12), 143-147(2), 162-165(2), 176

Last modified: 1995-04-13 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1238 |