130715Sbostic /* 230715Sbostic * Copyright (c) 1987 Regents of the University of California. 330715Sbostic * All rights reserved. The Berkeley software License Agreement 430715Sbostic * specifies the terms and conditions for redistribution. 530715Sbostic */ 630715Sbostic 730418Skarels #ifndef lint 8*34641Skarels static char sccsid[] = "@(#)disklabel.c 5.13 (Berkeley) 06/04/88"; 930418Skarels /* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */ 1030418Skarels #endif 1130418Skarels 1230418Skarels #include <stdio.h> 1330418Skarels #include <ctype.h> 1430418Skarels #include <sys/param.h> 1530715Sbostic #include <sys/signal.h> 1630418Skarels #include <sys/errno.h> 1730418Skarels #include <sys/file.h> 1830715Sbostic #include <sys/ioctl.h> 1930677Skarels #include <sys/fs.h> 2030715Sbostic #include <strings.h> 2130418Skarels #define DKTYPENAMES 2230418Skarels #include <sys/disklabel.h> 2330418Skarels 2430418Skarels /* 2530418Skarels * Disklabel: read and write disklabels. 2630418Skarels * The label is usually placed on one of the first sectors of the disk. 2730418Skarels * Many machines (VAX 11/750) also place a bootstrap in the same area, 2830418Skarels * in which case the label is embedded in the bootstrap. 2930418Skarels * The bootstrap source must leave space at the proper offset 3030418Skarels * for the label on such machines. 3130418Skarels */ 3230418Skarels 3330677Skarels #ifdef vax 3430677Skarels #define RAWPARTITION 'c' 3530677Skarels #else 3630677Skarels #define RAWPARTITION 'a' 3730677Skarels #endif 3830677Skarels 3930677Skarels #ifndef BBSIZE 4030418Skarels #define BBSIZE 8192 /* size of boot area, with label */ 4130677Skarels #endif 4230418Skarels 4330418Skarels #ifdef vax 4430418Skarels #define BOOT /* also have bootstrap in "boot area" */ 4530418Skarels #define BOOTDIR "/usr/mdec" /* source of boot binaries */ 4630677Skarels #else 4730677Skarels #ifdef lint 4830677Skarels #define BOOT 4930418Skarels #endif 5030677Skarels #endif 5130418Skarels 5230715Sbostic #define DEFEDITOR "/usr/ucb/vi" 5330715Sbostic #define streq(a,b) (strcmp(a,b) == 0) 5430715Sbostic 5530715Sbostic #ifdef BOOT 5630418Skarels char *xxboot; 5730418Skarels char *bootxx; 5830715Sbostic #endif 5931617Skarels 6031617Skarels char *dkname; 6130418Skarels char *specname; 6230715Sbostic char tmpfil[] = "/tmp/EdDk.aXXXXXX"; 6330418Skarels 6430418Skarels extern int errno; 6530418Skarels char namebuf[BBSIZE], *np = namebuf; 6631617Skarels struct disklabel lab; 6731617Skarels struct disklabel *readlabel(), *makebootarea(); 6830418Skarels char bootarea[BBSIZE]; 6934032Skarels char boot0[MAXPATHLEN]; 7034032Skarels char boot1[MAXPATHLEN]; 7130418Skarels 7234032Skarels enum { UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE } op = UNSPEC; 7330418Skarels 7430677Skarels int rflag; 7530677Skarels 7634032Skarels #ifdef DEBUG 7734032Skarels int debug; 7834032Skarels #endif 7934032Skarels 8030418Skarels main(argc, argv) 8130418Skarels int argc; 8230418Skarels char *argv[]; 8330418Skarels { 8434032Skarels extern int optind; 8530418Skarels register struct disklabel *lp; 8634032Skarels FILE *t; 87*34641Skarels int ch, f, error = 0; 8830715Sbostic char *name = 0, *type; 8930418Skarels 9034032Skarels while ((ch = getopt(argc, argv, "NRWerw")) != EOF) 9134032Skarels switch (ch) { 9234032Skarels case 'N': 9334032Skarels if (op != UNSPEC) 9434032Skarels usage(); 9534032Skarels op = NOWRITE; 9634032Skarels break; 9730715Sbostic case 'R': 9834032Skarels if (op != UNSPEC) 9934032Skarels usage(); 10030715Sbostic op = RESTORE; 10130715Sbostic break; 10234032Skarels case 'W': 10334032Skarels if (op != UNSPEC) 10434032Skarels usage(); 10534032Skarels op = WRITEABLE; 10634032Skarels break; 10730715Sbostic case 'e': 10834032Skarels if (op != UNSPEC) 10934032Skarels usage(); 11030715Sbostic op = EDIT; 11130715Sbostic break; 11230715Sbostic case 'r': 11330715Sbostic ++rflag; 11430715Sbostic break; 11530715Sbostic case 'w': 11634032Skarels if (op != UNSPEC) 11734032Skarels usage(); 11830715Sbostic op = WRITE; 11930715Sbostic break; 12034032Skarels #ifdef DEBUG 12134032Skarels case 'd': 12234032Skarels debug++; 12334032Skarels break; 12434032Skarels #endif 12530715Sbostic case '?': 12630715Sbostic default: 12730715Sbostic usage(); 12830715Sbostic } 12930715Sbostic argc -= optind; 13030715Sbostic argv += optind; 13134032Skarels if (op == UNSPEC) 13234032Skarels op = READ; 13330715Sbostic if (argc < 1) 13430715Sbostic usage(); 13530715Sbostic 13630715Sbostic dkname = argv[0]; 13730418Skarels if (dkname[0] != '/') { 13832439Sbostic (void)sprintf(np, "/dev/r%s%c", dkname, RAWPARTITION); 13930418Skarels specname = np; 14030418Skarels np += strlen(specname) + 1; 14130418Skarels } else 14230418Skarels specname = dkname; 14330418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 14430418Skarels if (f < 0 && errno == ENOENT && dkname[0] != '/') { 14532439Sbostic (void)sprintf(specname, "/dev/r%s", dkname); 14630418Skarels np = namebuf + strlen(specname) + 1; 14730418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 14830418Skarels } 14930418Skarels if (f < 0) 15030418Skarels Perror(specname); 15130418Skarels 15230715Sbostic switch(op) { 15330715Sbostic case EDIT: 15430715Sbostic if (argc != 1) 15530715Sbostic usage(); 15634032Skarels lp = readlabel(f); 157*34641Skarels error = edit(lp, f); 15830715Sbostic break; 15934032Skarels case NOWRITE: { 16034032Skarels int flag = 0; 16134032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 16234032Skarels Perror("ioctl DIOCWLABEL"); 16334032Skarels break; 16434032Skarels } 16530418Skarels case READ: 16630715Sbostic if (argc != 1) 16730715Sbostic usage(); 16834032Skarels lp = readlabel(f); 16930418Skarels display(stdout, lp); 170*34641Skarels error = checklabel(lp); 17130418Skarels break; 17230715Sbostic case RESTORE: 17330715Sbostic #ifdef BOOT 17434032Skarels if (rflag) { 17534032Skarels if (argc == 4) { /* [ priboot secboot ] */ 17634032Skarels xxboot = argv[2]; 17734032Skarels bootxx = argv[3]; 17834032Skarels lab.d_secsize = DEV_BSIZE; /* XXX */ 17934032Skarels lab.d_bbsize = BBSIZE; /* XXX */ 18034032Skarels } 18134032Skarels else if (argc == 3) /* [ disktype ] */ 18234032Skarels makelabel(argv[2], (char *)NULL, &lab); 18334032Skarels else { 18434032Skarels fprintf(stderr, 18534032Skarels "Must specify either disktype or bootfiles with -r flag of RESTORE option\n"); 18634032Skarels exit(1); 18734032Skarels } 18834032Skarels } 18934032Skarels else 19031617Skarels #endif 19130715Sbostic if (argc != 2) 19230715Sbostic usage(); 19331617Skarels lp = makebootarea(bootarea, &lab); 19430715Sbostic if (!(t = fopen(argv[1],"r"))) 19530715Sbostic Perror(argv[1]); 19630715Sbostic if (getasciilabel(t, lp)) 197*34641Skarels error = writelabel(f, bootarea, lp); 19830418Skarels break; 19930418Skarels case WRITE: 20030715Sbostic type = argv[1]; 20130715Sbostic #ifdef BOOT 20230715Sbostic if (argc > 5 || argc < 2) 20330715Sbostic usage(); 20430715Sbostic if (argc > 3) { 20530715Sbostic bootxx = argv[--argc]; 20630715Sbostic xxboot = argv[--argc]; 20730715Sbostic } 20830715Sbostic #else 20930715Sbostic if (argc > 3 || argc < 2) 21030715Sbostic usage(); 21130715Sbostic #endif 21230715Sbostic if (argc > 2) 21330715Sbostic name = argv[--argc]; 21430418Skarels makelabel(type, name, &lab); 21531617Skarels lp = makebootarea(bootarea, &lab); 21630418Skarels *lp = lab; 21730715Sbostic if (checklabel(lp) == 0) 218*34641Skarels error = writelabel(f, bootarea, lp); 21930418Skarels break; 22034032Skarels case WRITEABLE: { 22134032Skarels int flag = 1; 22234032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 22334032Skarels Perror("ioctl DIOCWLABEL"); 22434032Skarels break; 22530418Skarels } 22634032Skarels } 227*34641Skarels exit(error); 22830418Skarels } 22930418Skarels 23034032Skarels /* 23134032Skarels * Construct a prototype disklabel from /etc/disktab. As a side 23234032Skarels * effect, set the names of the primary and secondary boot files 23334032Skarels * if specified. 23434032Skarels */ 23530418Skarels makelabel(type, name, lp) 23630418Skarels char *type, *name; 23730418Skarels register struct disklabel *lp; 23830418Skarels { 23930418Skarels register struct disklabel *dp; 24034032Skarels char *strcpy(); 24130418Skarels 24230418Skarels dp = getdiskbyname(type); 24330418Skarels if (dp == NULL) { 24430418Skarels fprintf(stderr, "%s: unknown disk type\n", type); 24530418Skarels exit(1); 24630418Skarels } 24730418Skarels *lp = *dp; 24834032Skarels #ifdef BOOT 24934032Skarels /* 25034032Skarels * Check if disktab specifies the bootstraps (b0 or b1). 25134032Skarels */ 25234032Skarels if (!xxboot && lp->d_boot0) { 25334032Skarels if (*lp->d_boot0 != '/') 25434032Skarels (void)sprintf(boot0, "%s/%s", BOOTDIR, lp->d_boot0); 25534032Skarels else 25634032Skarels (void)strcpy(boot0, lp->d_boot0); 25734032Skarels xxboot = boot0; 25834032Skarels } 25934032Skarels if (!bootxx && lp->d_boot1) { 26034032Skarels if (*lp->d_boot1 != '/') 26134032Skarels (void)sprintf(boot1, "%s/%s", BOOTDIR, lp->d_boot1); 26234032Skarels else 26334032Skarels (void)strcpy(boot1, lp->d_boot1); 26434032Skarels bootxx = boot1; 26534032Skarels } 26634032Skarels /* 26734032Skarels * If bootstraps not specified anywhere, makebootarea() 26834032Skarels * will choose ones based on the name of the disk special 26934032Skarels * file. E.g. /dev/ra0 -> raboot, bootra 27034032Skarels */ 27134032Skarels #endif /*BOOT*/ 27234032Skarels /* d_packname is union d_boot[01], so zero */ 27334032Skarels bzero(lp->d_packname, sizeof(lp->d_packname)); 27430418Skarels if (name) 27534032Skarels (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname)); 27630418Skarels } 27730418Skarels 27830418Skarels writelabel(f, boot, lp) 27930418Skarels int f; 28030418Skarels char *boot; 28130418Skarels register struct disklabel *lp; 28230418Skarels { 28330715Sbostic register int i; 28434032Skarels int flag; 28534032Skarels off_t lseek(); 28630418Skarels 28730418Skarels lp->d_magic = DISKMAGIC; 28830418Skarels lp->d_magic2 = DISKMAGIC; 28930418Skarels lp->d_checksum = 0; 29030418Skarels lp->d_checksum = dkcksum(lp); 29130677Skarels if (rflag) { 29234032Skarels /* 29334032Skarels * First set the kernel disk label, 29434032Skarels * then write a label to the raw disk. 29534032Skarels * If the SDINFO ioctl fails because it is unimplemented, 29634032Skarels * keep going; otherwise, the kernel consistency checks 29734032Skarels * may prevent us from changing the current (in-core) 29834032Skarels * label. 29934032Skarels */ 30034032Skarels if (ioctl(f, DIOCSDINFO, lp) < 0 && 301*34641Skarels errno != ENODEV && errno != ENOTTY) { 302*34641Skarels l_perror("ioctl DIOCSDINFO"); 303*34641Skarels return (1); 304*34641Skarels } 30531617Skarels (void)lseek(f, (off_t)0, L_SET); 30634032Skarels /* 30734032Skarels * write enable label sector before write (if necessary), 30834032Skarels * disable after writing. 30934032Skarels */ 31034032Skarels flag = 1; 31134032Skarels if (ioctl(f, DIOCWLABEL, &flag) < 0) 31234032Skarels perror("ioctl DIOCWLABEL"); 313*34641Skarels if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { 314*34641Skarels perror("write"); 315*34641Skarels return (1); 316*34641Skarels } 31734032Skarels flag = 0; 31834032Skarels (void) ioctl(f, DIOCWLABEL, &flag); 319*34641Skarels } else if (ioctl(f, DIOCWDINFO, lp) < 0) { 320*34641Skarels l_perror("ioctl DIOCWDINFO"); 321*34641Skarels return (1); 322*34641Skarels } 32334032Skarels #ifdef vax 32430677Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 32530677Skarels daddr_t alt; 32630677Skarels 32730677Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 32830677Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 32930715Sbostic (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), L_SET); 33030677Skarels if (write(f, boot, lp->d_secsize) < lp->d_secsize) { 33130677Skarels int oerrno = errno; 33230677Skarels fprintf(stderr, "alternate label %d ", i/2); 33330677Skarels errno = oerrno; 33430677Skarels perror("write"); 33530677Skarels } 33630418Skarels } 33730418Skarels } 33830419Skarels #endif 339*34641Skarels return (0); 34030418Skarels } 34130418Skarels 342*34641Skarels l_perror(s) 343*34641Skarels char *s; 344*34641Skarels { 345*34641Skarels int saverrno = errno; 346*34641Skarels 347*34641Skarels fprintf(stderr, "disklabel: %s: ", s); 348*34641Skarels 349*34641Skarels switch (saverrno) { 350*34641Skarels 351*34641Skarels case ESRCH: 352*34641Skarels fprintf(stderr, "No disk label on disk;\n"); 353*34641Skarels fprintf(stderr, 354*34641Skarels "use \"disklabel -r\" to install initial label\n"); 355*34641Skarels break; 356*34641Skarels 357*34641Skarels case EINVAL: 358*34641Skarels fprintf(stderr, "Label magic number or checksum is wrong!\n"); 359*34641Skarels fprintf(stderr, "(disklabel or kernel is out of date?)\n"); 360*34641Skarels break; 361*34641Skarels 362*34641Skarels case EBUSY: 363*34641Skarels fprintf(stderr, "Open partition would move or shrink\n"); 364*34641Skarels break; 365*34641Skarels 366*34641Skarels case EXDEV: 367*34641Skarels fprintf(stderr, 368*34641Skarels "Labeled partition or 'a' partition must start at beginning of disk\n"); 369*34641Skarels break; 370*34641Skarels 371*34641Skarels default: 372*34641Skarels errno = saverrno; 373*34641Skarels perror((char *)NULL); 374*34641Skarels break; 375*34641Skarels } 376*34641Skarels } 377*34641Skarels 37830418Skarels /* 37931617Skarels * Fetch disklabel for disk. 38031617Skarels * Use ioctl to get label unless -r flag is given. 38130418Skarels */ 38230418Skarels struct disklabel * 38334032Skarels readlabel(f) 38434032Skarels int f; 38530418Skarels { 38630418Skarels register struct disklabel *lp; 38730418Skarels 38834032Skarels if (rflag) { 38931617Skarels if (read(f, bootarea, BBSIZE) < BBSIZE) 39031401Skarels Perror(specname); 39131617Skarels for (lp = (struct disklabel *)bootarea; 39231617Skarels lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); 39330677Skarels lp = (struct disklabel *)((char *)lp + 16)) 39430677Skarels if (lp->d_magic == DISKMAGIC && 39530677Skarels lp->d_magic2 == DISKMAGIC) 39630677Skarels break; 39731617Skarels if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || 39830677Skarels lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || 39930677Skarels dkcksum(lp) != 0) { 40030677Skarels fprintf(stderr, 40130418Skarels "Bad pack magic number (label is damaged, or pack is unlabeled)\n"); 40234032Skarels /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */ 40334032Skarels exit (1); 40430677Skarels } 40534032Skarels } else { 40634032Skarels lp = &lab; 40734032Skarels if (ioctl(f, DIOCGDINFO, lp) < 0) 40834032Skarels Perror("ioctl DIOCGDINFO"); 40930418Skarels } 41030418Skarels return (lp); 41130418Skarels } 41230418Skarels 41330418Skarels struct disklabel * 41431617Skarels makebootarea(boot, dp) 41530418Skarels char *boot; 41630418Skarels register struct disklabel *dp; 41730418Skarels { 41830418Skarels struct disklabel *lp; 41930418Skarels register char *p; 42030418Skarels int b; 42130418Skarels #ifdef BOOT 42230715Sbostic char *dkbasename; 42334032Skarels #endif /*BOOT*/ 42430715Sbostic 42534032Skarels lp = (struct disklabel *)(boot + (LABELSECTOR * dp->d_secsize) + 42634032Skarels LABELOFFSET); 42734032Skarels #ifdef BOOT 42834032Skarels if (!rflag) 42934032Skarels return (lp); 43034032Skarels 43134032Skarels if (xxboot == NULL || bootxx == NULL) { 43230418Skarels dkbasename = np; 43330418Skarels if ((p = rindex(dkname, '/')) == NULL) 43430418Skarels p = dkname; 43530418Skarels else 43630418Skarels p++; 43730418Skarels while (*p && !isdigit(*p)) 43830418Skarels *np++ = *p++; 43930418Skarels *np++ = '\0'; 44030418Skarels 44134032Skarels if (xxboot == NULL) { 44234032Skarels (void)sprintf(np, "%s/%sboot", BOOTDIR, dkbasename); 44334032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 44434032Skarels dkbasename++; 44534032Skarels xxboot = np; 44634032Skarels (void)sprintf(xxboot, "%s/%sboot", BOOTDIR, dkbasename); 44734032Skarels np += strlen(xxboot) + 1; 44834032Skarels } 44934032Skarels if (bootxx == NULL) { 45034032Skarels (void)sprintf(np, "%s/boot%s", BOOTDIR, dkbasename); 45134032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 45234032Skarels dkbasename++; 45334032Skarels bootxx = np; 45434032Skarels (void)sprintf(bootxx, "%s/boot%s", BOOTDIR, dkbasename); 45534032Skarels np += strlen(bootxx) + 1; 45634032Skarels } 45730418Skarels } 45834032Skarels #ifdef DEBUG 45934032Skarels if (debug) 46034032Skarels fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n", 46134032Skarels xxboot, bootxx); 46234032Skarels #endif 46330418Skarels 46430418Skarels b = open(xxboot, O_RDONLY); 46530418Skarels if (b < 0) 46630418Skarels Perror(xxboot); 46730715Sbostic if (read(b, boot, (int)dp->d_secsize) < 0) 46830418Skarels Perror(xxboot); 46930418Skarels close(b); 47030418Skarels b = open(bootxx, O_RDONLY); 47130418Skarels if (b < 0) 47230418Skarels Perror(bootxx); 47330715Sbostic if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0) 47430418Skarels Perror(bootxx); 47530715Sbostic (void)close(b); 47634032Skarels #endif /*BOOT*/ 47730418Skarels 47830418Skarels for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) 47930418Skarels if (*p) { 48030418Skarels fprintf(stderr, 48130418Skarels "Bootstrap doesn't leave room for disk label\n"); 48230418Skarels exit(2); 48330418Skarels } 48430418Skarels return (lp); 48530418Skarels } 48630418Skarels 48730418Skarels display(f, lp) 48830418Skarels FILE *f; 48930418Skarels register struct disklabel *lp; 49030418Skarels { 49130715Sbostic register int i, j; 49230418Skarels register struct partition *pp; 49330418Skarels 49430418Skarels fprintf(f, "# %s:\n", specname); 49530418Skarels if ((unsigned) lp->d_type < DKMAXTYPES) 49630418Skarels fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 49730418Skarels else 49830418Skarels fprintf(f, "type: %d\n", lp->d_type); 49930418Skarels fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename); 50034032Skarels fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname); 50131401Skarels fprintf(f, "flags:"); 50230418Skarels if (lp->d_flags & D_REMOVABLE) 50331401Skarels fprintf(f, " removeable"); 50430418Skarels if (lp->d_flags & D_ECC) 50531401Skarels fprintf(f, " ecc"); 50630418Skarels if (lp->d_flags & D_BADSECT) 50731401Skarels fprintf(f, " badsect"); 50830418Skarels fprintf(f, "\n"); 50930418Skarels fprintf(f, "bytes/sector: %d\n", lp->d_secsize); 51030418Skarels fprintf(f, "sectors/track: %d\n", lp->d_nsectors); 51130418Skarels fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks); 51231386Skarels fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl); 51330418Skarels fprintf(f, "cylinders: %d\n", lp->d_ncylinders); 51430715Sbostic fprintf(f, "rpm: %d\n", lp->d_rpm); 51530418Skarels fprintf(f, "interleave: %d\n", lp->d_interleave); 51630418Skarels fprintf(f, "trackskew: %d\n", lp->d_trackskew); 51730418Skarels fprintf(f, "cylinderskew: %d\n", lp->d_cylskew); 51830418Skarels fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); 51930418Skarels fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); 52030418Skarels fprintf(f, "drivedata: "); 52130418Skarels for (i = NDDATA - 1; i >= 0; i--) 52230418Skarels if (lp->d_drivedata[i]) 52330418Skarels break; 52430418Skarels if (i < 0) 52530418Skarels i = 0; 52630418Skarels for (j = 0; j <= i; j++) 52730418Skarels fprintf(f, "%d ", lp->d_drivedata[j]); 52830418Skarels fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions); 52930863Skarels fprintf(f, 53030863Skarels "# size offset fstype [fsize bsize cpg]\n"); 53130418Skarels pp = lp->d_partitions; 53230418Skarels for (i = 0; i < lp->d_npartitions; i++, pp++) { 53330418Skarels if (pp->p_size) { 53430863Skarels fprintf(f, " %c: %8d %8d ", 'a' + i, 53530863Skarels pp->p_size, pp->p_offset); 53630418Skarels if ((unsigned) pp->p_fstype < FSMAXTYPES) 53730418Skarels fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 53830418Skarels else 53930418Skarels fprintf(f, "%8d", pp->p_fstype); 54030863Skarels switch (pp->p_fstype) { 54130863Skarels 54230863Skarels case FS_UNUSED: /* XXX */ 54330863Skarels fprintf(f, " %5d %5d %5.5s ", 54430863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, ""); 54530863Skarels break; 54630863Skarels 54730863Skarels case FS_BSDFFS: 54830863Skarels fprintf(f, " %5d %5d %5d ", 54930863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, 55030863Skarels pp->p_cpg); 55130863Skarels break; 55230863Skarels 55330863Skarels default: 55430863Skarels fprintf(f, "%20.20s", ""); 55530863Skarels break; 55630863Skarels } 55730418Skarels fprintf(f, "\t# (Cyl. %4d", 55830418Skarels pp->p_offset / lp->d_secpercyl); 55930418Skarels if (pp->p_offset % lp->d_secpercyl) 56030418Skarels putc('*', f); 56130418Skarels else 56230418Skarels putc(' ', f); 56330418Skarels fprintf(f, "- %d", 56430418Skarels (pp->p_offset + 56530418Skarels pp->p_size + lp->d_secpercyl - 1) / 56630418Skarels lp->d_secpercyl - 1); 56730418Skarels if (pp->p_size % lp->d_secpercyl) 56830418Skarels putc('*', f); 56930863Skarels fprintf(f, ")\n"); 57030418Skarels } 57130418Skarels } 57232121Stef fflush(f); 57330418Skarels } 57430418Skarels 575*34641Skarels edit(lp, f) 57630715Sbostic struct disklabel *lp; 577*34641Skarels int f; 57830418Skarels { 57930715Sbostic register int c; 58030715Sbostic struct disklabel label; 58130715Sbostic FILE *fd; 58230715Sbostic char *mktemp(); 58330715Sbostic 58430715Sbostic (void) mktemp(tmpfil); 58530715Sbostic fd = fopen(tmpfil, "w"); 58630715Sbostic if (fd == NULL) { 58730715Sbostic fprintf(stderr, "%s: Can't create\n", tmpfil); 588*34641Skarels return (1); 58930715Sbostic } 59030715Sbostic (void)fchmod(fd, 0600); 59130715Sbostic display(fd, lp); 59230715Sbostic fclose(fd); 59330715Sbostic for (;;) { 59430715Sbostic if (!editit()) 59530715Sbostic break; 59630715Sbostic fd = fopen(tmpfil, "r"); 59730715Sbostic if (fd == NULL) { 59834032Skarels fprintf(stderr, "%s: Can't reopen for reading\n", 59934032Skarels tmpfil); 60030715Sbostic break; 60130715Sbostic } 60230863Skarels bzero((char *)&label, sizeof(label)); 60330715Sbostic if (getasciilabel(fd, &label)) { 60430715Sbostic *lp = label; 605*34641Skarels if (writelabel(f, bootarea, lp) == 0) { 606*34641Skarels (void) unlink(tmpfil); 607*34641Skarels return (0); 608*34641Skarels } 60930715Sbostic } 61030715Sbostic printf("re-edit the label? [y]: "); fflush(stdout); 61130715Sbostic c = getchar(); 61230715Sbostic if (c != EOF && c != (int)'\n') 61330715Sbostic while (getchar() != (int)'\n') 61430715Sbostic ; 61530715Sbostic if (c == (int)'n') 61630715Sbostic break; 61730715Sbostic } 61830715Sbostic (void) unlink(tmpfil); 619*34641Skarels return (1); 62030418Skarels } 62130418Skarels 62230715Sbostic editit() 62330715Sbostic { 62430715Sbostic register int pid, xpid; 62530715Sbostic int stat, omask; 62630715Sbostic extern char *getenv(); 62730418Skarels 62830715Sbostic omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 62930715Sbostic while ((pid = fork()) < 0) { 63030715Sbostic extern int errno; 63130715Sbostic 63230715Sbostic if (errno == EPROCLIM) { 63330715Sbostic fprintf(stderr, "You have too many processes\n"); 63430715Sbostic return(0); 63530715Sbostic } 63630715Sbostic if (errno != EAGAIN) { 63730715Sbostic perror("fork"); 63830715Sbostic return(0); 63930715Sbostic } 64030715Sbostic sleep(1); 64130715Sbostic } 64230715Sbostic if (pid == 0) { 64330715Sbostic register char *ed; 64430715Sbostic 64530715Sbostic sigsetmask(omask); 64630715Sbostic setgid(getgid()); 64730715Sbostic setuid(getuid()); 64830715Sbostic if ((ed = getenv("EDITOR")) == (char *)0) 64930715Sbostic ed = DEFEDITOR; 65030715Sbostic execlp(ed, ed, tmpfil, 0); 65130715Sbostic perror(ed); 65230715Sbostic exit(1); 65330715Sbostic } 65430715Sbostic while ((xpid = wait(&stat)) >= 0) 65530715Sbostic if (xpid == pid) 65630715Sbostic break; 65730715Sbostic sigsetmask(omask); 65830715Sbostic return(!stat); 65930715Sbostic } 66030715Sbostic 66130715Sbostic char * 66230715Sbostic skip(cp) 66330715Sbostic register char *cp; 66430715Sbostic { 66530715Sbostic 66630715Sbostic while (*cp != '\0' && isspace(*cp)) 66730715Sbostic cp++; 66830715Sbostic if (*cp == '\0' || *cp == '#') 66930715Sbostic return ((char *)NULL); 67030715Sbostic return (cp); 67130715Sbostic } 67230715Sbostic 67330715Sbostic char * 67430715Sbostic word(cp) 67530715Sbostic register char *cp; 67630715Sbostic { 67730715Sbostic register char c; 67830715Sbostic 67931401Skarels while (*cp != '\0' && !isspace(*cp) && *cp != '#') 68031401Skarels cp++; 68130715Sbostic if ((c = *cp) != '\0') { 68230715Sbostic *cp++ = '\0'; 68330715Sbostic if (c != '#') 68430715Sbostic return (skip(cp)); 68530715Sbostic } 68630715Sbostic return ((char *)NULL); 68730715Sbostic } 68830715Sbostic 68930418Skarels /* 69030418Skarels * Read an ascii label in from fd f, 69130418Skarels * in the same format as that put out by display(), 69230418Skarels * and fill in lp. 69330418Skarels */ 69430418Skarels getasciilabel(f, lp) 69530715Sbostic FILE *f; 69630418Skarels register struct disklabel *lp; 69730418Skarels { 69830715Sbostic register char **cpp, *cp; 69930863Skarels register struct partition *pp; 70030715Sbostic char *tp, *s, line[BUFSIZ]; 70130715Sbostic int v, lineno = 0, errors = 0; 70230715Sbostic 70330715Sbostic lp->d_bbsize = BBSIZE; /* XXX */ 70430715Sbostic lp->d_sbsize = SBSIZE; /* XXX */ 70530715Sbostic while (fgets(line, sizeof(line) - 1, f)) { 70630715Sbostic lineno++; 70730715Sbostic if (cp = index(line,'\n')) 70830715Sbostic *cp = '\0'; 70930715Sbostic cp = skip(line); 71030715Sbostic if (cp == NULL) 71130715Sbostic continue; 71230715Sbostic tp = index(cp, ':'); 71330715Sbostic if (tp == NULL) { 71430715Sbostic fprintf(stderr, "line %d: syntax error\n", lineno); 71530715Sbostic errors++; 71630715Sbostic continue; 71730715Sbostic } 71830715Sbostic *tp++ = '\0', tp = skip(tp); 71930715Sbostic if (streq(cp, "type")) { 72030715Sbostic if (tp == NULL) 72130715Sbostic tp = "unknown"; 72230715Sbostic cpp = dktypenames; 72330715Sbostic for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) 72430715Sbostic if ((s = *cpp) && streq(s, tp)) { 72530715Sbostic lp->d_type = cpp - dktypenames; 72630715Sbostic goto next; 72730715Sbostic } 72830715Sbostic v = atoi(tp); 72930715Sbostic if ((unsigned)v >= DKMAXTYPES) 73030715Sbostic fprintf(stderr, "line %d:%s %d\n", lineno, 73130715Sbostic "Warning, unknown disk type", v); 73230715Sbostic lp->d_type = v; 73330715Sbostic continue; 73430715Sbostic } 73530715Sbostic if (streq(cp, "flags")) { 73634032Skarels for (v = 0; (cp = tp) && *cp != '\0';) { 73734032Skarels tp = word(cp); 73830715Sbostic if (streq(cp, "removeable")) 73930715Sbostic v |= D_REMOVABLE; 74030715Sbostic else if (streq(cp, "ecc")) 74130715Sbostic v |= D_ECC; 74230715Sbostic else if (streq(cp, "badsect")) 74330715Sbostic v |= D_BADSECT; 74430715Sbostic else { 74530715Sbostic fprintf(stderr, 74630715Sbostic "line %d: %s: bad flag\n", 74730715Sbostic lineno, cp); 74830715Sbostic errors++; 74930715Sbostic } 75030715Sbostic } 75130715Sbostic lp->d_flags = v; 75230715Sbostic continue; 75330715Sbostic } 75430715Sbostic if (streq(cp, "drivedata")) { 75530715Sbostic register int i; 75630715Sbostic 75731386Skarels for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { 75830715Sbostic lp->d_drivedata[i++] = atoi(cp); 75931386Skarels tp = word(cp); 76030715Sbostic } 76130715Sbostic continue; 76230715Sbostic } 76330715Sbostic if (sscanf(cp, "%d partitions", &v) == 1) { 76430863Skarels if (v == 0 || (unsigned)v > MAXPARTITIONS) { 76530715Sbostic fprintf(stderr, 76630715Sbostic "line %d: bad # of partitions\n", lineno); 76730863Skarels lp->d_npartitions = MAXPARTITIONS; 76830863Skarels errors++; 76930863Skarels } else 77030715Sbostic lp->d_npartitions = v; 77130715Sbostic continue; 77230715Sbostic } 77330715Sbostic if (tp == NULL) 77430715Sbostic tp = ""; 77530715Sbostic if (streq(cp, "disk")) { 77630715Sbostic strncpy(lp->d_typename, tp, sizeof (lp->d_typename)); 77730715Sbostic continue; 77830715Sbostic } 77930715Sbostic if (streq(cp, "label")) { 78034032Skarels strncpy(lp->d_packname, tp, sizeof (lp->d_packname)); 78130715Sbostic continue; 78230715Sbostic } 78330715Sbostic if (streq(cp, "bytes/sector")) { 78430715Sbostic v = atoi(tp); 78530715Sbostic if (v <= 0 || (v % 512) != 0) { 78630715Sbostic fprintf(stderr, 78730715Sbostic "line %d: %s: bad sector size\n", 78830715Sbostic lineno, tp); 78930715Sbostic errors++; 79030715Sbostic } else 79130715Sbostic lp->d_secsize = v; 79230715Sbostic continue; 79330715Sbostic } 79430715Sbostic if (streq(cp, "sectors/track")) { 79530715Sbostic v = atoi(tp); 79630715Sbostic if (v <= 0) { 79730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 79830715Sbostic lineno, tp, cp); 79930715Sbostic errors++; 80030715Sbostic } else 80130715Sbostic lp->d_nsectors = v; 80230715Sbostic continue; 80330715Sbostic } 80431386Skarels if (streq(cp, "sectors/cylinder")) { 80531386Skarels v = atoi(tp); 80631386Skarels if (v <= 0) { 80731386Skarels fprintf(stderr, "line %d: %s: bad %s\n", 80831386Skarels lineno, tp, cp); 80931386Skarels errors++; 81031386Skarels } else 81131386Skarels lp->d_secpercyl = v; 81231386Skarels continue; 81331386Skarels } 81430715Sbostic if (streq(cp, "tracks/cylinder")) { 81530715Sbostic v = atoi(tp); 81630715Sbostic if (v <= 0) { 81730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 81830715Sbostic lineno, tp, cp); 81930715Sbostic errors++; 82030715Sbostic } else 82130715Sbostic lp->d_ntracks = v; 82230715Sbostic continue; 82330715Sbostic } 82430715Sbostic if (streq(cp, "cylinders")) { 82530715Sbostic v = atoi(tp); 82630715Sbostic if (v <= 0) { 82730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 82830715Sbostic lineno, tp, cp); 82930715Sbostic errors++; 83030715Sbostic } else 83130715Sbostic lp->d_ncylinders = v; 83230715Sbostic continue; 83330715Sbostic } 83430715Sbostic if (streq(cp, "rpm")) { 83530715Sbostic v = atoi(tp); 83630715Sbostic if (v <= 0) { 83730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 83830715Sbostic lineno, tp, cp); 83930715Sbostic errors++; 84030715Sbostic } else 84130715Sbostic lp->d_rpm = v; 84230715Sbostic continue; 84330715Sbostic } 84430715Sbostic if (streq(cp, "interleave")) { 84530715Sbostic v = atoi(tp); 84630715Sbostic if (v <= 0) { 84730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 84830715Sbostic lineno, tp, cp); 84930715Sbostic errors++; 85030715Sbostic } else 85130715Sbostic lp->d_interleave = v; 85230715Sbostic continue; 85330715Sbostic } 85430715Sbostic if (streq(cp, "trackskew")) { 85530715Sbostic v = atoi(tp); 85630715Sbostic if (v < 0) { 85730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 85830715Sbostic lineno, tp, cp); 85930715Sbostic errors++; 86030715Sbostic } else 86130715Sbostic lp->d_trackskew = v; 86230715Sbostic continue; 86330715Sbostic } 86430715Sbostic if (streq(cp, "cylinderskew")) { 86530715Sbostic v = atoi(tp); 86630715Sbostic if (v < 0) { 86730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 86830715Sbostic lineno, tp, cp); 86930715Sbostic errors++; 87030715Sbostic } else 87130715Sbostic lp->d_cylskew = v; 87230715Sbostic continue; 87330715Sbostic } 87430715Sbostic if (streq(cp, "headswitch")) { 87530715Sbostic v = atoi(tp); 87630715Sbostic if (v < 0) { 87730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 87830715Sbostic lineno, tp, cp); 87930715Sbostic errors++; 88030715Sbostic } else 88130715Sbostic lp->d_headswitch = v; 88230715Sbostic continue; 88330715Sbostic } 88430715Sbostic if (streq(cp, "track-to-track seek")) { 88530715Sbostic v = atoi(tp); 88630715Sbostic if (v < 0) { 88730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 88830715Sbostic lineno, tp, cp); 88930715Sbostic errors++; 89030715Sbostic } else 89130715Sbostic lp->d_trkseek = v; 89230715Sbostic continue; 89330715Sbostic } 89430715Sbostic if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { 89530863Skarels unsigned part = *cp - 'a'; 89630715Sbostic 89730863Skarels if (part > lp->d_npartitions) { 89830715Sbostic fprintf(stderr, 89930715Sbostic "line %d: bad partition name\n", lineno); 90030715Sbostic errors++; 90130715Sbostic continue; 90230715Sbostic } 90330863Skarels pp = &lp->d_partitions[part]; 90430863Skarels #define NXTNUM(n) { \ 90530863Skarels cp = tp, tp = word(cp); \ 90630863Skarels if (tp == NULL) \ 90730863Skarels tp = cp; \ 90830863Skarels (n) = atoi(cp); \ 90930863Skarels } 91030863Skarels 91130863Skarels NXTNUM(v); 91230715Sbostic if (v < 0) { 91330715Sbostic fprintf(stderr, 91430715Sbostic "line %d: %s: bad partition size\n", 91530715Sbostic lineno, cp); 91630715Sbostic errors++; 91730715Sbostic } else 91830863Skarels pp->p_size = v; 91930863Skarels NXTNUM(v); 92030715Sbostic if (v < 0) { 92130715Sbostic fprintf(stderr, 92230715Sbostic "line %d: %s: bad partition offset\n", 92330715Sbostic lineno, cp); 92430715Sbostic errors++; 92530715Sbostic } else 92630863Skarels pp->p_offset = v; 92730715Sbostic cp = tp, tp = word(cp); 92830715Sbostic cpp = fstypenames; 92930715Sbostic for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) 93030715Sbostic if ((s = *cpp) && streq(s, cp)) { 93130863Skarels pp->p_fstype = cpp - fstypenames; 93230863Skarels goto gottype; 93330715Sbostic } 93434032Skarels if (isdigit(*cp)) 93534032Skarels v = atoi(cp); 93634032Skarels else 93734032Skarels v = FSMAXTYPES; 93834032Skarels if ((unsigned)v >= FSMAXTYPES) { 93930715Sbostic fprintf(stderr, "line %d: %s %s\n", lineno, 94030715Sbostic "Warning, unknown filesystem type", cp); 94134032Skarels v = FS_UNUSED; 94234032Skarels } 94330863Skarels pp->p_fstype = v; 94430863Skarels gottype: 94530863Skarels 94630863Skarels switch (pp->p_fstype) { 94730863Skarels 94830863Skarels case FS_UNUSED: /* XXX */ 94930863Skarels NXTNUM(pp->p_fsize); 95030863Skarels if (pp->p_fsize == 0) 95130863Skarels break; 95230863Skarels NXTNUM(v); 95330863Skarels pp->p_frag = v / pp->p_fsize; 95430863Skarels break; 95530863Skarels 95630863Skarels case FS_BSDFFS: 95730863Skarels NXTNUM(pp->p_fsize); 95830863Skarels if (pp->p_fsize == 0) 95930863Skarels break; 96030863Skarels NXTNUM(v); 96130863Skarels pp->p_frag = v / pp->p_fsize; 96230863Skarels NXTNUM(pp->p_cpg); 96330863Skarels break; 96430863Skarels 96530863Skarels default: 96630863Skarels break; 96730863Skarels } 96830715Sbostic continue; 96930715Sbostic } 97030715Sbostic fprintf(stderr, "line %d: %s: Unknown disklabel field\n", 97130715Sbostic lineno, cp); 97230715Sbostic errors++; 97330715Sbostic next: 97430715Sbostic ; 97530715Sbostic } 97630715Sbostic errors += checklabel(lp); 97730715Sbostic return (errors == 0); 97830418Skarels } 97930418Skarels 98030715Sbostic /* 98130715Sbostic * Check disklabel for errors and fill in 98230715Sbostic * derived fields according to supplied values. 98330715Sbostic */ 98430715Sbostic checklabel(lp) 98530715Sbostic register struct disklabel *lp; 98630418Skarels { 98730715Sbostic register struct partition *pp; 98830715Sbostic int i, errors = 0; 98930715Sbostic char part; 99030418Skarels 99130715Sbostic if (lp->d_secsize == 0) { 99230715Sbostic fprintf(stderr, "sector size %d\n", lp->d_secsize); 99330715Sbostic return (1); 99430715Sbostic } 99530715Sbostic if (lp->d_nsectors == 0) { 99630715Sbostic fprintf(stderr, "sectors/track %d\n", lp->d_nsectors); 99730715Sbostic return (1); 99830715Sbostic } 99930715Sbostic if (lp->d_ntracks == 0) { 100030715Sbostic fprintf(stderr, "tracks/cylinder %d\n", lp->d_ntracks); 100130715Sbostic return (1); 100230715Sbostic } 100330715Sbostic if (lp->d_ncylinders == 0) { 100430715Sbostic fprintf(stderr, "cylinders/unit %d\n", lp->d_ncylinders); 100530715Sbostic errors++; 100630715Sbostic } 100730715Sbostic if (lp->d_rpm == 0) 100830715Sbostic Warning("revolutions/minute %d\n", lp->d_rpm); 100930715Sbostic if (lp->d_secpercyl == 0) 101030715Sbostic lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 101130715Sbostic if (lp->d_secperunit == 0) 101230715Sbostic lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; 101330715Sbostic if (lp->d_bbsize == 0) { 101430715Sbostic fprintf(stderr, "boot block size %d\n", lp->d_bbsize); 101530715Sbostic errors++; 101630715Sbostic } else if (lp->d_bbsize % lp->d_secsize) 101730715Sbostic Warning("boot block size %% sector-size != 0\n"); 101830715Sbostic if (lp->d_sbsize == 0) { 101930715Sbostic fprintf(stderr, "super block size %d\n", lp->d_sbsize); 102030715Sbostic errors++; 102130715Sbostic } else if (lp->d_sbsize % lp->d_secsize) 102230715Sbostic Warning("super block size %% sector-size != 0\n"); 102330715Sbostic if (lp->d_npartitions > MAXPARTITIONS) 102430715Sbostic Warning("number of partitions (%d) > MAXPARTITIONS (%d)\n", 102530715Sbostic lp->d_npartitions, MAXPARTITIONS); 102630715Sbostic for (i = 0; i < lp->d_npartitions; i++) { 102730715Sbostic part = 'a' + i; 102830715Sbostic pp = &lp->d_partitions[i]; 102930715Sbostic if (pp->p_size == 0 && pp->p_offset != 0) 103030715Sbostic Warning("partition %c: size 0, but offset %d\n", 103130715Sbostic part, pp->p_offset); 103230715Sbostic #ifdef notdef 103330715Sbostic if (pp->p_size % lp->d_secpercyl) 103430715Sbostic Warning("partition %c: size %% cylinder-size != 0\n", 103530715Sbostic part); 103630715Sbostic if (pp->p_offset % lp->d_secpercyl) 103730715Sbostic Warning("partition %c: offset %% cylinder-size != 0\n", 103830715Sbostic part); 103930715Sbostic #endif 104030715Sbostic if (pp->p_offset > lp->d_secperunit) { 104130715Sbostic fprintf(stderr, 104230715Sbostic "partition %c: offset past end of unit\n", part); 104330715Sbostic errors++; 104430715Sbostic } 104530715Sbostic if (pp->p_offset + pp->p_size > lp->d_secperunit) { 104630715Sbostic fprintf(stderr, 104730715Sbostic "partition %c: partition extends past end of unit\n", 104830715Sbostic part); 104930715Sbostic errors++; 105030715Sbostic } 105130715Sbostic } 105230715Sbostic for (; i < MAXPARTITIONS; i++) { 105330715Sbostic part = 'a' + i; 105430715Sbostic pp = &lp->d_partitions[i]; 105530715Sbostic if (pp->p_size || pp->p_offset) 105630715Sbostic Warning("unused partition %c: size %d offset %d\n", 105734032Skarels 'a' + i, pp->p_size, pp->p_offset); 105830715Sbostic } 105930715Sbostic return (errors); 106030715Sbostic } 106130715Sbostic 106230715Sbostic /*VARARGS1*/ 106330715Sbostic Warning(fmt, a1, a2, a3, a4, a5) 106430715Sbostic char *fmt; 106530715Sbostic { 106630715Sbostic 106730715Sbostic fprintf(stderr, "Warning, "); 106830715Sbostic fprintf(stderr, fmt, a1, a2, a3, a4, a5); 106930715Sbostic fprintf(stderr, "\n"); 107030715Sbostic } 107130715Sbostic 107230715Sbostic Perror(str) 107330715Sbostic char *str; 107430715Sbostic { 107530715Sbostic fputs("disklabel: ", stderr); perror(str); 107630418Skarels exit(4); 107730418Skarels } 107830715Sbostic 107930715Sbostic usage() 108030715Sbostic { 108130715Sbostic #ifdef BOOT 108234032Skarels fprintf(stderr, "%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n", 108330715Sbostic "usage: disklabel [-r] disk", "(to read label)", 108430715Sbostic "or disklabel -w [-r] disk type [ packid ] [ xxboot bootxx ]", "(to write label)", 108530715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 108634032Skarels "or disklabel -R [-r] disk protofile [ type | xxboot bootxx ]", "(to restore label)", 108734032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 108830715Sbostic #else 108934032Skarels fprintf(stderr, "%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n", 109030715Sbostic "usage: disklabel [-r] disk", "(to read label)", 109130715Sbostic "or disklabel -w [-r] disk type [ packid ]", "(to write label)", 109230715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 109334032Skarels "or disklabel -R [-r] disk protofile", "(to restore label)", 109434032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 109530715Sbostic #endif 109630715Sbostic exit(1); 109730715Sbostic } 1098