1: /*
   2:  * Public domain, June 1995
   3:  *
   4:  *	@(#)disklabel.c	1.4 (2.11BSD GTE) 1996/5/2
   5: */
   6: 
   7: #define DKTYPENAMES
   8: #include "../h/param.h"
   9: #include "saio.h"
  10: 
  11:     int Nolabelerr = 1;     /* Inhibit spurious label error msgs */
  12:     char    module[] = "disklabel"; /* This program's name */
  13:     char    line[80], device[80];
  14: 
  15: extern  long    atol();
  16: extern  struct  iob iob[];
  17: extern  struct  devsw   devsw[];
  18: 
  19: main()
  20:     {
  21:     register int    f;
  22:     register struct disklabel *lp;
  23:     struct  iob *io;
  24: 
  25:     printf("%s\n", module);
  26: 
  27:     while   (1)
  28:         {
  29:         printf("Disk? ");
  30:         gets(line);
  31:         if  (!line[0])
  32:             continue;
  33:         strcpy(device, line);
  34:         f = open(device, F_WRITE);
  35:         if  (f < 0)
  36:             {
  37:             printf("Error opening '%s' for writing\n", device);
  38:             continue;
  39:             }
  40:         io = &iob[f - 3];
  41:         if  (io->i_flgs & F_TAPE)
  42:             {
  43:             printf("Can not label tapes.\n");
  44:             continue;
  45:             }
  46:         break;
  47:         }
  48: /*
  49:  * The open() will have retrieved the label sector.  This explicit read
  50:  * is for debugging and testing because the driver's open routine may be
  51:  * under development and the automatic retrieval of the label is commented
  52:  * out.
  53: */
  54:     if  (devlabel(io, READLABEL) < 0)
  55:         {
  56:         printf("Can not read label sector from '%s'\n", device);
  57:         return;     /* back to Boot */
  58:         }
  59:     lp = &io->i_label;
  60:     if  (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
  61:          dkcksum(lp))
  62:         {
  63:         printf("'%s' is unlabeled or the label is corrupt.\n", device);
  64:         printf("Proceed? [y/n] ");
  65:         if  (gyon() == 'n')
  66:             return;     /* back to Boot */
  67: /*
  68:  * We next call the driver's entry which attempts to identify the drive
  69:  * and set up a default (1 partition) label with the best guess as to
  70:  * geometry, etc.  If this call fails then the driver does not support
  71:  * labels ('nullsys' is being used in the device table).
  72: */
  73:         if  (devlabel(io, DEFAULTLABEL) < 0)
  74:             {
  75:             printf("The '%s' driver does not support labels.\n",
  76:                 devsw[io->i_ino.i_dev].dv_name);
  77:             return;     /* back to Boot */
  78:             }
  79:         }
  80:     doit(io);
  81:     return;
  82:     }
  83: 
  84: doit(io)
  85:     register struct iob *io;
  86:     {
  87:     int c, dirty = 0;
  88:     struct  disklabel *lp = &io->i_label;
  89: 
  90:     while   (1)
  91:         {
  92:         printf("d(isplay) D(efault) m(odify) w(rite) q(uit)? ");
  93:         c = egetchar("dDmwq");
  94:         switch  (c)
  95:             {
  96:             case    'm':
  97:                 modifylabel(lp);
  98:                 overlapchk(lp);
  99:                 (void)checklabel(lp);
 100: /*
 101:  * We make the assumption that the label was modified - the dirty
 102:  * flag is set so we can ask if the changes should be discarded on a 'q'.
 103: */
 104:                 dirty = 1;
 105:                 break;
 106:             case    'w':
 107:                 overlapchk(lp);
 108:                 (void)checklabel(lp);
 109:                 devlabel(io, WRITELABEL);
 110: /*
 111:  * Changed label was committed to disk so we can clear the dirty flag now
 112:  * and not ask the user if the changes should be kept when a 'q'uit is done.
 113: */
 114:                 dirty = 0;
 115:                 break;
 116:             case    'd':
 117:                 displaylabel(lp);
 118:                 break;
 119:             case    'D':
 120:                 devlabel(io, DEFAULTLABEL);
 121:                 dirty = 1;
 122:                 break;
 123:             case    'q':
 124:                 if  (!dirty)
 125:                     return;
 126:                 printf("Label changed. Discard changes [y/n]? ");
 127:                 if  (gyon() == 'n')
 128:                     break;
 129:                 return;
 130:             default:
 131:                 break;
 132:             }
 133:         }
 134: /* NOTREACHED */
 135:     }
 136: 
 137: modifylabel(lp)
 138:     register struct disklabel *lp;
 139:     {
 140:     register int    c;
 141: 
 142:     while   (1)
 143:         {
 144:         printf("modify\n");
 145:         printf("d(isplay) g(eometry) m(isc) p(artitions) q(uit)? ");
 146:         c = egetchar("dgmpq");
 147:         switch  (c)
 148:             {
 149:             case    'd':
 150:                 displaylabel(lp);
 151:                 break;
 152:             case    'g':
 153:                 dogeometry(lp);
 154:                 break;
 155:             case    'm':
 156:                 domisc(lp);
 157:                 break;
 158:             case    'p':
 159:                 dopartitions(lp);
 160:                 break;
 161:             case    'q':
 162:                 return;
 163:             default:
 164:                 break;
 165:             }
 166:         }
 167: /* NOTREACHED */
 168:     }
 169: 
 170: dogeometry(lp)
 171:     struct  disklabel *lp;
 172:     {
 173:     register int c;
 174: 
 175:     while   (1)
 176:         {
 177:         printf("modify geometry\n");
 178:         printf("d(isplay) s(ector/trk) t(rk/cyl) c(yl) S(ector/cyl) q(uit)? ");
 179:         c = egetchar("dstcSq");
 180:         switch  (c)
 181:             {
 182:             case    'd':
 183:                 displaylabel(lp);
 184:                 break;
 185:             case    's':
 186:                 fillin_int(&lp->d_nsectors,
 187:                     "sectors/track [%d]: ", 512);
 188:                 break;
 189:             case    't':
 190:                 fillin_int(&lp->d_ntracks,
 191:                     "tracks/cylinder [%d]: ", 127);
 192:                 break;
 193:             case    'c':
 194:                 fillin_int(&lp->d_ncylinders,
 195:                     "cylinders [%d]: ", 4096);
 196:                 break;
 197:             case    'S':
 198:                 lp->d_secpercyl= lp->d_nsectors * lp->d_ntracks;
 199:                 fillin_int(&lp->d_secpercyl,
 200:                     "sectors/cylinder [%d]: ", 65535);
 201:                 break;
 202:             case    'q':
 203:                 if  (lp->d_secpercyl == 0)
 204:                     lp->d_secpercyl = lp->d_nsectors *
 205:                             lp->d_ntracks;
 206:                 lp->d_secperunit = (long)lp->d_ncylinders *
 207:                             lp->d_secpercyl;
 208:                 return;
 209:             default:
 210:                 break;
 211:             }
 212:         }
 213: /* NOTREACHED */
 214:     }
 215: 
 216: domisc(lp)
 217:     register struct disklabel *lp;
 218:     {
 219:     register int c;
 220:     char    junk[32];
 221: 
 222:     while   (1)
 223:         {
 224:         printf("modify misc\n");
 225:         printf("d(isplay) t(ype) n(ame) l(abel) f(lags) r(pm) D(rivedata) q(uit)? ");
 226:         c = egetchar("dtnlfrDq");
 227:         switch  (c)
 228:             {
 229:             case    'd':
 230:                 displaylabel(lp);
 231:                 break;
 232:             case    't':
 233:                 if  (lp->d_type >= DKMAXTYPES)
 234:                     lp->d_type = 0;
 235:                 printf("type [%s]: ", dktypenames[lp->d_type]);
 236:                 gets(line);
 237:                 if  (line[0])
 238:                     lp->d_type = findtype(dktypenames,
 239:                                 line,
 240:                                 lp->d_type);
 241:                 break;
 242:             case    'n':
 243:                 strncpy(junk, lp->d_typename,
 244:                         sizeof (lp->d_typename));
 245:                 junk[sizeof (lp->d_typename)] = '\0';
 246:                 printf("disk [%s]: ", junk);
 247:                 gets(line);
 248:                 if  (line[0])
 249:                     strncpy(lp->d_typename, line,
 250:                         sizeof (lp->d_typename));
 251:                 break;
 252:             case    'l':
 253:                 strncpy(junk, lp->d_packname,
 254:                         sizeof (lp->d_packname));
 255:                 junk[sizeof (lp->d_packname)] = '\0';
 256:                 printf("label [%s]: ", junk);
 257:                 gets(line);
 258:                 if  (line[0])
 259:                     strncpy(lp->d_packname, line,
 260:                         sizeof (lp->d_packname));
 261:                 break;
 262:             case    'f':
 263:                 doflags(lp);
 264:                 break;
 265:             case    'r':
 266:                 fillin_int(&lp->d_rpm, "rpm [%d]: ", 32767);
 267:                 break;
 268:             case    'D':
 269:                 dodrivedata(lp);
 270:                 break;
 271:             case    'q':
 272:                 return;
 273:             default:
 274:                 break;
 275:             }
 276:         }
 277: /* NOTREACHED */
 278:     }
 279: 
 280: dodrivedata(lp)
 281:     struct disklabel *lp;
 282:     {
 283:     register u_long *ulp;
 284:     register int    i;
 285: 
 286:     for (i = 0, ulp = lp->d_drivedata; i < NDDATA; i++, ulp++)
 287:         {
 288:         printf("modify misc drivedata\n");
 289:         printf("drivedata #%d [%D]: ", i, *ulp);
 290:         gets(line);
 291:         if  (line[0])
 292:             *ulp = atol(line);
 293:         }
 294:     return;
 295:     }
 296: 
 297: doflags(lp)
 298:     register struct disklabel *lp;
 299:     {
 300:     register int    c;
 301: 
 302:     while   (1)
 303:         {
 304:         printf("modify misc flags\n");
 305:         printf("d(isplay) c(lear) e(cc) b(adsect) r(emovable) q(uit)? ");
 306:         c = egetchar("dcerbq");
 307:         switch  (c)
 308:             {
 309:             case    'c':
 310:                 lp->d_flags = 0;
 311:                 break;
 312:             case    'd':
 313:                 displaylabel(lp);
 314:                 break;
 315:             case    'r':
 316:                 lp->d_flags |= D_REMOVABLE;
 317:                 break;
 318:             case    'e':
 319:                 lp->d_flags |= D_ECC;
 320:                 break;
 321:             case    'b':
 322:                 lp->d_flags |= D_BADSECT;
 323:                 break;
 324:             case    'q':
 325:                 return;
 326:             default:
 327:                 break;
 328:             }
 329:         }
 330: /* NOTREACHED */
 331:     }
 332: 
 333: dopartitions(lp)
 334:     struct  disklabel *lp;
 335:     {
 336:     register int    c;
 337:     int i;
 338: 
 339:     while   (1)
 340:         {
 341:         printf("modify partitions\n");
 342:         printf("d(isplay) n(umber) s(elect) q(uit)? ");
 343:         c = egetchar("dsnq");
 344:         switch  (c)
 345:             {
 346:             case    'd':
 347:                 displaylabel(lp);
 348:                 break;
 349:             case    'n':
 350:                 printf("Number of partitions (%d max) [%d]? ",
 351:                     MAXPARTITIONS, lp->d_npartitions);
 352:                 gets(line);
 353:                 if  (line[0] == '\0')
 354:                     i = lp->d_npartitions;
 355:                 else
 356:                     i = atoi(line);
 357:                 if  (i > 0 && i <= MAXPARTITIONS)
 358:                     lp->d_npartitions = i;
 359:                 break;
 360:             case    's':
 361:                 printf("a b c d e f g h q(uit)? ");
 362:                 i = getpartnum();
 363:                 if  (i < 0)
 364:                     break;
 365:                 if  (i >= lp->d_npartitions)
 366:                     lp->d_npartitions = i + 1;
 367:                 dopartmods(lp, i);
 368:                 break;
 369:             case    'q':
 370:                 return;
 371:             default:
 372:                 break;
 373:             }
 374:         }
 375: /* NOTREACHED */
 376:     }
 377: 
 378: dopartmods(lp, part)
 379:     struct  disklabel *lp;
 380:     int part;
 381:     {
 382:     char    pname = 'a' + part;
 383:     int i, c;
 384:     register struct partition *pp = &lp->d_partitions[part];
 385:     u_int   cyl;
 386:     daddr_t off, sec, size;
 387: 
 388:     printf("sizes and offsets may be given as sectors, cylinders\n");
 389:     printf("or cylinders plus sectors:  6200, 32c, 19c10s respectively\n");
 390: 
 391:     while   (1)
 392:         {
 393:         printf("modify partition '%c'\n", pname);
 394:         printf("d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? ");
 395:         c = egetchar("dztosfFq");
 396:         switch  (c)
 397:             {
 398:             case    'z':
 399:                 pp->p_size = 0;
 400:                 pp->p_offset = 0;
 401:                 pp->p_fstype = FS_UNUSED;
 402:                 break;
 403:             case    'd':
 404:                 displaylabel(lp);
 405:                 break;
 406:             case    't':
 407:                 if  (pp->p_fstype >= FSMAXTYPES)
 408:                     pp->p_fstype = FS_UNUSED;
 409:                 printf("'%c' fstype [%s]: ", pname,
 410:                     fstypenames[pp->p_fstype]);
 411:                 gets(line);
 412:                 if  (line[0])
 413:                     pp->p_fstype = findtype(fstypenames,
 414:                                 line,
 415:                                 pp->p_fstype);
 416:                 break;
 417:             case    'o':
 418:                 printf("'%c' offset [%D]: ",pname,pp->p_offset);
 419:                 gets(line);
 420:                 if  (line[0] == '\0')
 421:                     break;
 422:                 i = parse_sec_cyl(lp, line, &sec, &cyl);
 423:                 if  (i < 0)
 424:                     break;
 425:                 if  (cyl)
 426:                     off = (long)lp->d_secpercyl * cyl;
 427:                 else
 428:                     off = 0;
 429:                 off += sec;
 430:                 pp->p_offset = off;
 431:                 break;
 432:             case    's':
 433:                 printf("'%c' size [%D]: ", pname, pp->p_size);
 434:                 gets(line);
 435:                 if  (line[0] == '\0')
 436:                     break;
 437:                 i = parse_sec_cyl(lp, line, &sec, &cyl);
 438:                 if  (i < 0)
 439:                     break;
 440:                 if  (cyl)
 441:                     size = (long)lp->d_secpercyl * cyl;
 442:                 else
 443:                     size = 0;
 444:                 size += sec;
 445:                 pp->p_size = size;
 446:                 break;
 447:             case    'f':
 448:                 printf("'%c' frags/fs-block [1]: ", pname);
 449:                 gets(line);
 450:                 if  (line[0] == '\0')
 451:                     break;
 452:                 i = atoi(line);
 453:                 if  (i <= 0 || i > 255)
 454:                     {
 455:                     printf("frags/block <= 0 || > 255\n");
 456:                     pp->p_frag = 1;
 457:                     }
 458:                 else
 459:                     pp->p_frag = i;
 460:                 break;
 461:             case    'F':    /* Not really used at the present */
 462:                 printf("'%c' frag size [1024]: ", pname);
 463:                 gets(line);
 464:                 if  (line[0] == '\0')
 465:                     break;
 466:                 i = atoi(line);
 467:                 if  (i <= 0 || (i % NBPG))
 468:                     {
 469:                     printf("fragsize <= 0 || ! % NBPG\n");
 470:                     pp->p_fsize = 0;
 471:                     }
 472:                 else
 473:                     pp->p_fsize = i;
 474:                 break;
 475:             case    'q':
 476:                 if  (pp->p_fsize == 0)
 477:                     pp->p_fsize = 1024;
 478:                 if  (pp->p_frag == 0)
 479:                     pp->p_frag = 1;
 480:                 return;
 481:             default:
 482:                 break;
 483:             }
 484:         }
 485: /* NOTREACHED */
 486:     }
 487: 
 488: getpartnum()
 489:     {
 490:     register int c;
 491: 
 492:     c = egetchar("abcdefghq");
 493:     if  (c == 'q')
 494:         return(-1);
 495:     return(c - 'a');
 496:     }
 497: 
 498: findtype(list, name, deflt)
 499:     char    **list;
 500:     char    *name;
 501:     int deflt;
 502:     {
 503:     register char **cpp;
 504:     int i;
 505: 
 506:     for (i = 0, cpp = list; *cpp; cpp++, i++)
 507:         {
 508:         if  (strcmp(*cpp, name) == 0)
 509:             return(i);
 510:         }
 511:     printf("%s not found in list.  The possible choices are:\n\n", name);
 512:     for (cpp = list; *cpp; cpp++)
 513:         printf("  %s\n", *cpp);
 514:     putchar('\n');
 515:     return(deflt);
 516:     }
 517: 
 518: /*
 519:  * Sizes and offsets can be specified in four ways:
 520:  *
 521:  *    Number of sectors:  32678
 522:  *    Number of cylinders:  110c
 523:  *    Number of cylinders and sectors:  29c14s
 524:  *    Number of sectors and cylinders:  22s134c
 525:  *
 526:  * The trailing 's' or 'c' can be left off in the last two cases.
 527:  *
 528:  * The geometry section of the label must have been filled in previously.
 529:  * A warning is issued if the cylinder or cylinder+sector forms are used
 530:  * and the necessary geometry information is not present.
 531: */
 532: 
 533: parse_sec_cyl(lp, line, sec, cyl)
 534:     struct  disklabel *lp;
 535:     char    line[];
 536:     daddr_t *sec;
 537:     u_int   *cyl;
 538:     {
 539:     register char   *cp;
 540:     int error = 0;
 541:     long    tmp, tmpcyl = 0, tmpsec = 0;
 542: 
 543:     for (tmp = 0, cp = line; *cp; cp++)
 544:         {
 545:         if  (*cp >= '0' && *cp <= '9')
 546:             {
 547:             tmp *= 10;
 548:             tmp += (*cp - '0');
 549:             }
 550:         else if (*cp == 'c')
 551:             {
 552:             if  (tmpcyl)
 553:                 {
 554:                 printf("duplicate 'c'ylinder specified\n");
 555:                 error = 1;
 556:                 break;
 557:                 }
 558:             tmpcyl = tmp;
 559:             tmp = 0;
 560:             }
 561:         else if (*cp == 's')
 562:             {
 563:             if  (tmpsec)
 564:                 {
 565:                 printf("duplicate 's'ector specified\n");
 566:                 error = 1;
 567:                 break;
 568:                 }
 569:             tmpsec = tmp;
 570:             tmp = 0;
 571:             }
 572:         else
 573:             {
 574:             printf("illegal character '%c'\n", *cp);
 575:             error = 1;
 576:             break;
 577:             }
 578:         }
 579:     if  (error)
 580:         return(-1);
 581: 
 582: /*
 583:  * At this point if either a 's' or 'c' was encountered in the string then
 584:  * one or both of 'tmpsec' and 'tmpcyl' will be non-zero.  If the trailing
 585:  * character was omitted we need to figure out which variable gets the
 586:  * contents left in 'tmp' when the terminating null character was seen. This
 587:  * is because "15c8" and "18s3" are both valid and indicate "15 cylinders +
 588:  * 8 sectors" and "18 sectors + 3 cylinders" respectively.
 589:  *
 590:  * If neither 'tmpsec' or 'tmpcyl' are nonzero then we have a simple sector
 591:  * number in 'tmp'.
 592: */
 593:     if  (tmpsec || tmpcyl)
 594:         {
 595:         if  (tmpsec)
 596:             tmpcyl = tmp;
 597:         else
 598:             tmpsec = tmp;
 599:         }
 600:     else
 601:         {
 602:         tmpsec = tmp;
 603:         tmpcyl = 0;
 604:         }
 605: /*
 606:  * It is an error condition to specify a number of cylinders and not
 607:  * have previously defined the geometry - it is impossible to calculate
 608:  * the number of sectors in the partition without geometry.
 609: */
 610:     if  (tmpcyl && lp->d_secpercyl == 0)
 611:         {
 612:         printf("# cylinders specified but no geometry info present!\n");
 613:         return(-1);
 614:         }
 615: 
 616: /*
 617:  * Sanity check to make sure erroneous number of cylinders is not believed
 618:  * due to truncation (number of cylinders is really a 'u_int')
 619: */
 620: 
 621:     if  (tmpcyl > 65535L)
 622:         {
 623:         printf("Number of cylinders specified (%D) is ridiculous!\n",
 624:             tmpcyl);
 625:         return(-1);
 626:         }
 627:     *cyl = (u_int)tmpcyl;
 628:     *sec = tmpsec;
 629:     return(0);
 630:     }
 631: 
 632: fillin_int(where, fmt, limit)
 633:     u_int   *where;
 634:     char    *fmt;
 635:     u_int   limit;
 636:     {
 637:     u_int   i;
 638: 
 639:     printf(fmt, *where);
 640:     gets(line);
 641:     if  (line[0])
 642:         {
 643:         i = (u_int)atoi(line);
 644:         if  (i > limit)
 645:             {
 646:             printf("%d is out of bounds (> %d)\n", i, limit);
 647:             return;
 648:             }
 649:         *where = i;
 650:         }
 651:     }
 652: 
 653: fillin_long(where, fmt, limit)
 654:     u_long  *where;
 655:     char    *fmt;
 656:     u_long  limit;
 657:     {
 658:     u_long  l;
 659: 
 660:     printf(fmt, *where);
 661:     gets(line);
 662:     if  (line[0])
 663:         {
 664:         l = (u_int)atol(line);
 665:         if  (l > limit)
 666:             {
 667:             printf("%D is out of bounds (> %D)\n", l, limit);
 668:             return;
 669:             }
 670:         *where = l;
 671:         }
 672:     }
 673: 
 674: gyon()
 675:     {
 676:     register int    c;
 677: 
 678:     c = egetchar("yYnN");
 679:     if  (c >= 'A' && c <= 'Z')
 680:         c += ('a' - 'A');
 681:     return(c);
 682:     }
 683: 
 684: egetchar(str)
 685:     char    *str;
 686:     {
 687:     register int c;
 688: 
 689:     while   (1)
 690:         {
 691:         c = getchar();
 692:         if  (index(str, c))
 693:             break;
 694:         putchar('\007');
 695:         }
 696:     putchar(c);
 697:     putchar('\n');
 698:     return(c);
 699:     }
 700: 
 701: /*
 702:  * Check disklabel for errors and fill in
 703:  * derived fields according to supplied values.
 704:  *
 705:  * Adapted from the disklabel utility.
 706:  */
 707: checklabel(lp)
 708:     register struct disklabel *lp;
 709:     {
 710:     register struct partition *pp;
 711:     int i, errors = 0;
 712:     char part;
 713: 
 714:     if  (lp->d_nsectors == 0)
 715:         {
 716:         printf("sectors/track %d\n", lp->d_nsectors);
 717:         return(1);
 718:         }
 719:     if  (lp->d_ntracks == 0)
 720:         {
 721:         printf("tracks/cylinder %d\n", lp->d_ntracks);
 722:         return(1);
 723:         }
 724:     if  (lp->d_ncylinders == 0)
 725:         {
 726:         printf("cylinders/unit %d\n", lp->d_ncylinders);
 727:         errors++;
 728:         }
 729:     if  (lp->d_rpm == 0)
 730:         Warning("revolutions/minute %d", lp->d_rpm);
 731:     if  (lp->d_secpercyl == 0)
 732:         lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
 733:     if  (lp->d_secperunit == 0)
 734:         lp->d_secperunit = (long) lp->d_secpercyl * lp->d_ncylinders;
 735: 
 736:     for (i = 0; i < lp->d_npartitions; i++)
 737:         {
 738:         part = 'a' + i;
 739:         pp = &lp->d_partitions[i];
 740:         if  (pp->p_size == 0 && pp->p_offset != 0)
 741:             Warning("partition %c: size 0, but offset %d",
 742:                 part, pp->p_offset);
 743: #ifdef notdef
 744:         if (pp->p_size % lp->d_secpercyl)
 745:             Warning("partition %c: size %% cylinder-size != 0",
 746:                 part);
 747:         if (pp->p_offset % lp->d_secpercyl)
 748:             Warning("partition %c: offset %% cylinder-size != 0",
 749:                 part);
 750: #endif
 751:         if  (pp->p_offset > lp->d_secperunit)
 752:             {
 753:             printf("partition %c: offset past end of unit %D %D\n",
 754:                 part, pp->p_offset, lp->d_secperunit);
 755:             errors++;
 756:             }
 757:         if  (pp->p_offset + pp->p_size > lp->d_secperunit)
 758:             {
 759:             printf("partition %c: extends past end of unit %D %D %D\n",
 760:                 part, pp->p_offset, pp->p_size, lp->d_secperunit);
 761:             errors++;
 762:             }
 763:         }
 764:     for (; i < MAXPARTITIONS; i++)
 765:         {
 766:         part = 'a' + i;
 767:         pp = &lp->d_partitions[i];
 768:         if  (pp->p_size || pp->p_offset)
 769:             Warning("unused partition %c: size %D offset %D",
 770:                 'a' + i, pp->p_size, pp->p_offset);
 771:         }
 772:     return(errors);
 773:     }
 774: 
 775: /*VARARGS1*/
 776: Warning(fmt, a1, a2, a3, a4, a5)
 777:     char *fmt;
 778:     {
 779: 
 780:     printf("Warning, ");
 781:     printf(fmt, a1, a2, a3, a4, a5);
 782:     printf("\n");
 783:     }

Defined functions

Warning defined in line 776; used 5 times
checklabel defined in line 707; used 2 times
dodrivedata defined in line 280; used 1 times
doflags defined in line 297; used 1 times
dogeometry defined in line 170; used 1 times
doit defined in line 84; used 1 times
  • in line 80
domisc defined in line 216; used 1 times
dopartitions defined in line 333; used 1 times
dopartmods defined in line 378; used 1 times
egetchar defined in line 684; used 9 times
fillin_int defined in line 632; used 5 times
fillin_long defined in line 653; never used
findtype defined in line 498; used 2 times
getpartnum defined in line 488; used 1 times
gyon defined in line 674; used 2 times
main defined in line 19; used 4 times
modifylabel defined in line 137; used 1 times
  • in line 97
parse_sec_cyl defined in line 533; used 2 times

Defined variables

Nolabelerr defined in line 11; never used
device defined in line 13; used 5 times
line defined in line 13; used 42 times
module defined in line 12; used 3 times

Defined macros

DKTYPENAMES defined in line 7; never used
Last modified: 1996-05-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5038
Valid CSS Valid XHTML 1.0 Strict