130715Sbostic /* 235983Sbostic * Copyright (c) 1987 The Regents of the University of California. 335983Sbostic * All rights reserved. 435983Sbostic * 535983Sbostic * This code is derived from software contributed to Berkeley by 635983Sbostic * Symmetric Computer Systems. 735983Sbostic * 842698Sbostic * %sccs.include.redist.c% 930715Sbostic */ 1030715Sbostic 1130418Skarels #ifndef lint 1235983Sbostic char copyright[] = 1335983Sbostic "@(#) Copyright (c) 1987 The Regents of the University of California.\n\ 1435983Sbostic All rights reserved.\n"; 1535983Sbostic #endif /* not lint */ 1635983Sbostic 1735983Sbostic #ifndef lint 18*51615Sbostic static char sccsid[] = "@(#)disklabel.c 5.21 (Berkeley) 11/11/91"; 1930418Skarels /* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */ 2035983Sbostic #endif /* not lint */ 2130418Skarels 2230418Skarels #include <sys/param.h> 2330715Sbostic #include <sys/signal.h> 2430418Skarels #include <sys/errno.h> 2530418Skarels #include <sys/file.h> 2630715Sbostic #include <sys/ioctl.h> 2730418Skarels #define DKTYPENAMES 2830418Skarels #include <sys/disklabel.h> 29*51615Sbostic #include <ufs/ffs/fs.h> 30*51615Sbostic #include <string.h> 3137261Sbostic #include <stdio.h> 3237261Sbostic #include <ctype.h> 3337261Sbostic #include "pathnames.h" 3430418Skarels 3530418Skarels /* 3630418Skarels * Disklabel: read and write disklabels. 3730418Skarels * The label is usually placed on one of the first sectors of the disk. 3830418Skarels * Many machines (VAX 11/750) also place a bootstrap in the same area, 3930418Skarels * in which case the label is embedded in the bootstrap. 4030418Skarels * The bootstrap source must leave space at the proper offset 4130418Skarels * for the label on such machines. 4230418Skarels */ 4330418Skarels 4446345Swilliam #if defined(vax) || defined(i386) 4530677Skarels #define RAWPARTITION 'c' 4630677Skarels #else 4730677Skarels #define RAWPARTITION 'a' 4830677Skarels #endif 4930677Skarels 5030677Skarels #ifndef BBSIZE 5130418Skarels #define BBSIZE 8192 /* size of boot area, with label */ 5230677Skarels #endif 5330418Skarels 5446345Swilliam #if defined(vax) || defined(i386) 5530418Skarels #define BOOT /* also have bootstrap in "boot area" */ 5637261Sbostic #define BOOTDIR _PATH_BOOTDIR /* source of boot binaries */ 5730677Skarels #else 5830677Skarels #ifdef lint 5930677Skarels #define BOOT 6030418Skarels #endif 6130677Skarels #endif 6230418Skarels 6338505Sbostic #define DEFEDITOR _PATH_VI 6430715Sbostic #define streq(a,b) (strcmp(a,b) == 0) 6530715Sbostic 6630715Sbostic #ifdef BOOT 6730418Skarels char *xxboot; 6830418Skarels char *bootxx; 6930715Sbostic #endif 7031617Skarels 7131617Skarels char *dkname; 7230418Skarels char *specname; 7337945Sbostic char tmpfil[] = _PATH_TMP; 7430418Skarels 7530418Skarels extern int errno; 7630418Skarels char namebuf[BBSIZE], *np = namebuf; 7731617Skarels struct disklabel lab; 7831617Skarels struct disklabel *readlabel(), *makebootarea(); 7930418Skarels char bootarea[BBSIZE]; 8034032Skarels char boot0[MAXPATHLEN]; 8134032Skarels char boot1[MAXPATHLEN]; 8230418Skarels 8334032Skarels enum { UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE } op = UNSPEC; 8430418Skarels 8530677Skarels int rflag; 8630677Skarels 8734032Skarels #ifdef DEBUG 8834032Skarels int debug; 8934032Skarels #endif 9034032Skarels 9130418Skarels main(argc, argv) 9230418Skarels int argc; 9330418Skarels char *argv[]; 9430418Skarels { 9534032Skarels extern int optind; 9630418Skarels register struct disklabel *lp; 9734032Skarels FILE *t; 9834641Skarels int ch, f, error = 0; 9930715Sbostic char *name = 0, *type; 10030418Skarels 10134032Skarels while ((ch = getopt(argc, argv, "NRWerw")) != EOF) 10234032Skarels switch (ch) { 10334032Skarels case 'N': 10434032Skarels if (op != UNSPEC) 10534032Skarels usage(); 10634032Skarels op = NOWRITE; 10734032Skarels break; 10830715Sbostic case 'R': 10934032Skarels if (op != UNSPEC) 11034032Skarels usage(); 11130715Sbostic op = RESTORE; 11230715Sbostic break; 11334032Skarels case 'W': 11434032Skarels if (op != UNSPEC) 11534032Skarels usage(); 11634032Skarels op = WRITEABLE; 11734032Skarels break; 11830715Sbostic case 'e': 11934032Skarels if (op != UNSPEC) 12034032Skarels usage(); 12130715Sbostic op = EDIT; 12230715Sbostic break; 12330715Sbostic case 'r': 12430715Sbostic ++rflag; 12530715Sbostic break; 12630715Sbostic case 'w': 12734032Skarels if (op != UNSPEC) 12834032Skarels usage(); 12930715Sbostic op = WRITE; 13030715Sbostic break; 13134032Skarels #ifdef DEBUG 13234032Skarels case 'd': 13334032Skarels debug++; 13434032Skarels break; 13534032Skarels #endif 13630715Sbostic case '?': 13730715Sbostic default: 13830715Sbostic usage(); 13930715Sbostic } 14030715Sbostic argc -= optind; 14130715Sbostic argv += optind; 14234032Skarels if (op == UNSPEC) 14334032Skarels op = READ; 14430715Sbostic if (argc < 1) 14530715Sbostic usage(); 14630715Sbostic 14730715Sbostic dkname = argv[0]; 14830418Skarels if (dkname[0] != '/') { 14937945Sbostic (void)sprintf(np, "%s/r%s%c", _PATH_DEV, dkname, RAWPARTITION); 15030418Skarels specname = np; 15130418Skarels np += strlen(specname) + 1; 15230418Skarels } else 15330418Skarels specname = dkname; 15430418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 15530418Skarels if (f < 0 && errno == ENOENT && dkname[0] != '/') { 15637945Sbostic (void)sprintf(specname, "%s/r%s", _PATH_DEV, dkname); 15730418Skarels np = namebuf + strlen(specname) + 1; 15830418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 15930418Skarels } 16030418Skarels if (f < 0) 16130418Skarels Perror(specname); 16230418Skarels 16330715Sbostic switch(op) { 16430715Sbostic case EDIT: 16530715Sbostic if (argc != 1) 16630715Sbostic usage(); 16734032Skarels lp = readlabel(f); 16834641Skarels error = edit(lp, f); 16930715Sbostic break; 17034032Skarels case NOWRITE: { 17134032Skarels int flag = 0; 17234032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 17334032Skarels Perror("ioctl DIOCWLABEL"); 17434032Skarels break; 17534032Skarels } 17630418Skarels case READ: 17730715Sbostic if (argc != 1) 17830715Sbostic usage(); 17934032Skarels lp = readlabel(f); 18030418Skarels display(stdout, lp); 18134641Skarels error = checklabel(lp); 18230418Skarels break; 18330715Sbostic case RESTORE: 18430715Sbostic #ifdef BOOT 18534032Skarels if (rflag) { 18634032Skarels if (argc == 4) { /* [ priboot secboot ] */ 18734032Skarels xxboot = argv[2]; 18834032Skarels bootxx = argv[3]; 18934032Skarels lab.d_secsize = DEV_BSIZE; /* XXX */ 19034032Skarels lab.d_bbsize = BBSIZE; /* XXX */ 19134032Skarels } 19234032Skarels else if (argc == 3) /* [ disktype ] */ 19334032Skarels makelabel(argv[2], (char *)NULL, &lab); 19434032Skarels else { 19534032Skarels fprintf(stderr, 19634032Skarels "Must specify either disktype or bootfiles with -r flag of RESTORE option\n"); 19734032Skarels exit(1); 19834032Skarels } 19934032Skarels } 20034032Skarels else 20131617Skarels #endif 20230715Sbostic if (argc != 2) 20330715Sbostic usage(); 20431617Skarels lp = makebootarea(bootarea, &lab); 20530715Sbostic if (!(t = fopen(argv[1],"r"))) 20630715Sbostic Perror(argv[1]); 20730715Sbostic if (getasciilabel(t, lp)) 20834641Skarels error = writelabel(f, bootarea, lp); 20930418Skarels break; 21030418Skarels case WRITE: 21130715Sbostic type = argv[1]; 21230715Sbostic #ifdef BOOT 21330715Sbostic if (argc > 5 || argc < 2) 21430715Sbostic usage(); 21530715Sbostic if (argc > 3) { 21630715Sbostic bootxx = argv[--argc]; 21730715Sbostic xxboot = argv[--argc]; 21830715Sbostic } 21930715Sbostic #else 22030715Sbostic if (argc > 3 || argc < 2) 22130715Sbostic usage(); 22230715Sbostic #endif 22330715Sbostic if (argc > 2) 22430715Sbostic name = argv[--argc]; 22530418Skarels makelabel(type, name, &lab); 22631617Skarels lp = makebootarea(bootarea, &lab); 22730418Skarels *lp = lab; 22830715Sbostic if (checklabel(lp) == 0) 22934641Skarels error = writelabel(f, bootarea, lp); 23030418Skarels break; 23134032Skarels case WRITEABLE: { 23234032Skarels int flag = 1; 23334032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 23434032Skarels Perror("ioctl DIOCWLABEL"); 23534032Skarels break; 23630418Skarels } 23734032Skarels } 23834641Skarels exit(error); 23930418Skarels } 24030418Skarels 24134032Skarels /* 24234032Skarels * Construct a prototype disklabel from /etc/disktab. As a side 24334032Skarels * effect, set the names of the primary and secondary boot files 24434032Skarels * if specified. 24534032Skarels */ 24630418Skarels makelabel(type, name, lp) 24730418Skarels char *type, *name; 24830418Skarels register struct disklabel *lp; 24930418Skarels { 25030418Skarels register struct disklabel *dp; 25134032Skarels char *strcpy(); 25230418Skarels 25330418Skarels dp = getdiskbyname(type); 25430418Skarels if (dp == NULL) { 25530418Skarels fprintf(stderr, "%s: unknown disk type\n", type); 25630418Skarels exit(1); 25730418Skarels } 25830418Skarels *lp = *dp; 25934032Skarels #ifdef BOOT 26034032Skarels /* 26134032Skarels * Check if disktab specifies the bootstraps (b0 or b1). 26234032Skarels */ 26334032Skarels if (!xxboot && lp->d_boot0) { 26434032Skarels if (*lp->d_boot0 != '/') 26534032Skarels (void)sprintf(boot0, "%s/%s", BOOTDIR, lp->d_boot0); 26634032Skarels else 26734032Skarels (void)strcpy(boot0, lp->d_boot0); 26834032Skarels xxboot = boot0; 26934032Skarels } 27034032Skarels if (!bootxx && lp->d_boot1) { 27134032Skarels if (*lp->d_boot1 != '/') 27234032Skarels (void)sprintf(boot1, "%s/%s", BOOTDIR, lp->d_boot1); 27334032Skarels else 27434032Skarels (void)strcpy(boot1, lp->d_boot1); 27534032Skarels bootxx = boot1; 27634032Skarels } 27734032Skarels /* 27834032Skarels * If bootstraps not specified anywhere, makebootarea() 27934032Skarels * will choose ones based on the name of the disk special 28034032Skarels * file. E.g. /dev/ra0 -> raboot, bootra 28134032Skarels */ 28234032Skarels #endif /*BOOT*/ 28334032Skarels /* d_packname is union d_boot[01], so zero */ 28434032Skarels bzero(lp->d_packname, sizeof(lp->d_packname)); 28530418Skarels if (name) 28634032Skarels (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname)); 28730418Skarels } 28830418Skarels 28930418Skarels writelabel(f, boot, lp) 29030418Skarels int f; 29130418Skarels char *boot; 29230418Skarels register struct disklabel *lp; 29330418Skarels { 29430715Sbostic register int i; 29534032Skarels int flag; 29634032Skarels off_t lseek(); 29730418Skarels 29830418Skarels lp->d_magic = DISKMAGIC; 29930418Skarels lp->d_magic2 = DISKMAGIC; 30030418Skarels lp->d_checksum = 0; 30130418Skarels lp->d_checksum = dkcksum(lp); 30230677Skarels if (rflag) { 30334032Skarels /* 30434032Skarels * First set the kernel disk label, 30534032Skarels * then write a label to the raw disk. 30634032Skarels * If the SDINFO ioctl fails because it is unimplemented, 30734032Skarels * keep going; otherwise, the kernel consistency checks 30834032Skarels * may prevent us from changing the current (in-core) 30934032Skarels * label. 31034032Skarels */ 31134032Skarels if (ioctl(f, DIOCSDINFO, lp) < 0 && 31234641Skarels errno != ENODEV && errno != ENOTTY) { 31334641Skarels l_perror("ioctl DIOCSDINFO"); 31434641Skarels return (1); 31534641Skarels } 31631617Skarels (void)lseek(f, (off_t)0, L_SET); 31734032Skarels /* 31834032Skarels * write enable label sector before write (if necessary), 31934032Skarels * disable after writing. 32034032Skarels */ 32134032Skarels flag = 1; 32234032Skarels if (ioctl(f, DIOCWLABEL, &flag) < 0) 32334032Skarels perror("ioctl DIOCWLABEL"); 32434641Skarels if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { 32534641Skarels perror("write"); 32634641Skarels return (1); 32734641Skarels } 32834032Skarels flag = 0; 32934032Skarels (void) ioctl(f, DIOCWLABEL, &flag); 33034641Skarels } else if (ioctl(f, DIOCWDINFO, lp) < 0) { 33134641Skarels l_perror("ioctl DIOCWDINFO"); 33234641Skarels return (1); 33334641Skarels } 33434032Skarels #ifdef vax 33530677Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 33630677Skarels daddr_t alt; 33730677Skarels 33830677Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 33930677Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 34030715Sbostic (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), L_SET); 34130677Skarels if (write(f, boot, lp->d_secsize) < lp->d_secsize) { 34230677Skarels int oerrno = errno; 34330677Skarels fprintf(stderr, "alternate label %d ", i/2); 34430677Skarels errno = oerrno; 34530677Skarels perror("write"); 34630677Skarels } 34730418Skarels } 34830418Skarels } 34930419Skarels #endif 35034641Skarels return (0); 35130418Skarels } 35230418Skarels 35334641Skarels l_perror(s) 35434641Skarels char *s; 35534641Skarels { 35634641Skarels int saverrno = errno; 35734641Skarels 35834641Skarels fprintf(stderr, "disklabel: %s: ", s); 35934641Skarels 36034641Skarels switch (saverrno) { 36134641Skarels 36234641Skarels case ESRCH: 36334641Skarels fprintf(stderr, "No disk label on disk;\n"); 36434641Skarels fprintf(stderr, 36534641Skarels "use \"disklabel -r\" to install initial label\n"); 36634641Skarels break; 36734641Skarels 36834641Skarels case EINVAL: 36934641Skarels fprintf(stderr, "Label magic number or checksum is wrong!\n"); 37034641Skarels fprintf(stderr, "(disklabel or kernel is out of date?)\n"); 37134641Skarels break; 37234641Skarels 37334641Skarels case EBUSY: 37434641Skarels fprintf(stderr, "Open partition would move or shrink\n"); 37534641Skarels break; 37634641Skarels 37734641Skarels case EXDEV: 37834641Skarels fprintf(stderr, 37934641Skarels "Labeled partition or 'a' partition must start at beginning of disk\n"); 38034641Skarels break; 38134641Skarels 38234641Skarels default: 38334641Skarels errno = saverrno; 38434641Skarels perror((char *)NULL); 38534641Skarels break; 38634641Skarels } 38734641Skarels } 38834641Skarels 38930418Skarels /* 39031617Skarels * Fetch disklabel for disk. 39131617Skarels * Use ioctl to get label unless -r flag is given. 39230418Skarels */ 39330418Skarels struct disklabel * 39434032Skarels readlabel(f) 39534032Skarels int f; 39630418Skarels { 39730418Skarels register struct disklabel *lp; 39830418Skarels 39934032Skarels if (rflag) { 40031617Skarels if (read(f, bootarea, BBSIZE) < BBSIZE) 40131401Skarels Perror(specname); 40231617Skarels for (lp = (struct disklabel *)bootarea; 40331617Skarels lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); 40430677Skarels lp = (struct disklabel *)((char *)lp + 16)) 40530677Skarels if (lp->d_magic == DISKMAGIC && 40630677Skarels lp->d_magic2 == DISKMAGIC) 40730677Skarels break; 40831617Skarels if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || 40930677Skarels lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || 41030677Skarels dkcksum(lp) != 0) { 41130677Skarels fprintf(stderr, 41230418Skarels "Bad pack magic number (label is damaged, or pack is unlabeled)\n"); 41334032Skarels /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */ 41434032Skarels exit (1); 41530677Skarels } 41634032Skarels } else { 41734032Skarels lp = &lab; 41834032Skarels if (ioctl(f, DIOCGDINFO, lp) < 0) 41934032Skarels Perror("ioctl DIOCGDINFO"); 42030418Skarels } 42130418Skarels return (lp); 42230418Skarels } 42330418Skarels 42430418Skarels struct disklabel * 42531617Skarels makebootarea(boot, dp) 42630418Skarels char *boot; 42730418Skarels register struct disklabel *dp; 42830418Skarels { 42930418Skarels struct disklabel *lp; 43030418Skarels register char *p; 43130418Skarels int b; 43230418Skarels #ifdef BOOT 43330715Sbostic char *dkbasename; 43434032Skarels #endif /*BOOT*/ 43530715Sbostic 43634032Skarels lp = (struct disklabel *)(boot + (LABELSECTOR * dp->d_secsize) + 43734032Skarels LABELOFFSET); 43834032Skarels #ifdef BOOT 43934032Skarels if (!rflag) 44034032Skarels return (lp); 44134032Skarels 44234032Skarels if (xxboot == NULL || bootxx == NULL) { 44330418Skarels dkbasename = np; 44430418Skarels if ((p = rindex(dkname, '/')) == NULL) 44530418Skarels p = dkname; 44630418Skarels else 44730418Skarels p++; 44830418Skarels while (*p && !isdigit(*p)) 44930418Skarels *np++ = *p++; 45030418Skarels *np++ = '\0'; 45130418Skarels 45234032Skarels if (xxboot == NULL) { 45334032Skarels (void)sprintf(np, "%s/%sboot", BOOTDIR, dkbasename); 45434032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 45534032Skarels dkbasename++; 45634032Skarels xxboot = np; 45734032Skarels (void)sprintf(xxboot, "%s/%sboot", BOOTDIR, dkbasename); 45834032Skarels np += strlen(xxboot) + 1; 45934032Skarels } 46034032Skarels if (bootxx == NULL) { 46134032Skarels (void)sprintf(np, "%s/boot%s", BOOTDIR, dkbasename); 46234032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 46334032Skarels dkbasename++; 46434032Skarels bootxx = np; 46534032Skarels (void)sprintf(bootxx, "%s/boot%s", BOOTDIR, dkbasename); 46634032Skarels np += strlen(bootxx) + 1; 46734032Skarels } 46830418Skarels } 46934032Skarels #ifdef DEBUG 47034032Skarels if (debug) 47134032Skarels fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n", 47234032Skarels xxboot, bootxx); 47334032Skarels #endif 47430418Skarels 47530418Skarels b = open(xxboot, O_RDONLY); 47630418Skarels if (b < 0) 47730418Skarels Perror(xxboot); 47830715Sbostic if (read(b, boot, (int)dp->d_secsize) < 0) 47930418Skarels Perror(xxboot); 48030418Skarels close(b); 48130418Skarels b = open(bootxx, O_RDONLY); 48230418Skarels if (b < 0) 48330418Skarels Perror(bootxx); 48430715Sbostic if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0) 48530418Skarels Perror(bootxx); 48630715Sbostic (void)close(b); 48734032Skarels #endif /*BOOT*/ 48830418Skarels 48930418Skarels for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) 49030418Skarels if (*p) { 49130418Skarels fprintf(stderr, 49230418Skarels "Bootstrap doesn't leave room for disk label\n"); 49330418Skarels exit(2); 49430418Skarels } 49530418Skarels return (lp); 49630418Skarels } 49730418Skarels 49830418Skarels display(f, lp) 49930418Skarels FILE *f; 50030418Skarels register struct disklabel *lp; 50130418Skarels { 50230715Sbostic register int i, j; 50330418Skarels register struct partition *pp; 50430418Skarels 50530418Skarels fprintf(f, "# %s:\n", specname); 50630418Skarels if ((unsigned) lp->d_type < DKMAXTYPES) 50730418Skarels fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 50830418Skarels else 50930418Skarels fprintf(f, "type: %d\n", lp->d_type); 51030418Skarels fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename); 51134032Skarels fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname); 51231401Skarels fprintf(f, "flags:"); 51330418Skarels if (lp->d_flags & D_REMOVABLE) 51431401Skarels fprintf(f, " removeable"); 51530418Skarels if (lp->d_flags & D_ECC) 51631401Skarels fprintf(f, " ecc"); 51730418Skarels if (lp->d_flags & D_BADSECT) 51831401Skarels fprintf(f, " badsect"); 51930418Skarels fprintf(f, "\n"); 52030418Skarels fprintf(f, "bytes/sector: %d\n", lp->d_secsize); 52130418Skarels fprintf(f, "sectors/track: %d\n", lp->d_nsectors); 52230418Skarels fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks); 52331386Skarels fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl); 52430418Skarels fprintf(f, "cylinders: %d\n", lp->d_ncylinders); 52530715Sbostic fprintf(f, "rpm: %d\n", lp->d_rpm); 52630418Skarels fprintf(f, "interleave: %d\n", lp->d_interleave); 52730418Skarels fprintf(f, "trackskew: %d\n", lp->d_trackskew); 52830418Skarels fprintf(f, "cylinderskew: %d\n", lp->d_cylskew); 52930418Skarels fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); 53030418Skarels fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); 53130418Skarels fprintf(f, "drivedata: "); 53230418Skarels for (i = NDDATA - 1; i >= 0; i--) 53330418Skarels if (lp->d_drivedata[i]) 53430418Skarels break; 53530418Skarels if (i < 0) 53630418Skarels i = 0; 53730418Skarels for (j = 0; j <= i; j++) 53830418Skarels fprintf(f, "%d ", lp->d_drivedata[j]); 53930418Skarels fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions); 54030863Skarels fprintf(f, 54130863Skarels "# size offset fstype [fsize bsize cpg]\n"); 54230418Skarels pp = lp->d_partitions; 54330418Skarels for (i = 0; i < lp->d_npartitions; i++, pp++) { 54430418Skarels if (pp->p_size) { 54530863Skarels fprintf(f, " %c: %8d %8d ", 'a' + i, 54630863Skarels pp->p_size, pp->p_offset); 54730418Skarels if ((unsigned) pp->p_fstype < FSMAXTYPES) 54830418Skarels fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 54930418Skarels else 55030418Skarels fprintf(f, "%8d", pp->p_fstype); 55130863Skarels switch (pp->p_fstype) { 55230863Skarels 55330863Skarels case FS_UNUSED: /* XXX */ 55430863Skarels fprintf(f, " %5d %5d %5.5s ", 55530863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, ""); 55630863Skarels break; 55730863Skarels 55830863Skarels case FS_BSDFFS: 55930863Skarels fprintf(f, " %5d %5d %5d ", 56030863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, 56130863Skarels pp->p_cpg); 56230863Skarels break; 56330863Skarels 56430863Skarels default: 56530863Skarels fprintf(f, "%20.20s", ""); 56630863Skarels break; 56730863Skarels } 56830418Skarels fprintf(f, "\t# (Cyl. %4d", 56930418Skarels pp->p_offset / lp->d_secpercyl); 57030418Skarels if (pp->p_offset % lp->d_secpercyl) 57130418Skarels putc('*', f); 57230418Skarels else 57330418Skarels putc(' ', f); 57430418Skarels fprintf(f, "- %d", 57530418Skarels (pp->p_offset + 57630418Skarels pp->p_size + lp->d_secpercyl - 1) / 57730418Skarels lp->d_secpercyl - 1); 57830418Skarels if (pp->p_size % lp->d_secpercyl) 57930418Skarels putc('*', f); 58030863Skarels fprintf(f, ")\n"); 58130418Skarels } 58230418Skarels } 58332121Stef fflush(f); 58430418Skarels } 58530418Skarels 58634641Skarels edit(lp, f) 58730715Sbostic struct disklabel *lp; 58834641Skarels int f; 58930418Skarels { 59030715Sbostic register int c; 59130715Sbostic struct disklabel label; 59230715Sbostic FILE *fd; 59330715Sbostic char *mktemp(); 59430715Sbostic 59530715Sbostic (void) mktemp(tmpfil); 59630715Sbostic fd = fopen(tmpfil, "w"); 59730715Sbostic if (fd == NULL) { 59830715Sbostic fprintf(stderr, "%s: Can't create\n", tmpfil); 59934641Skarels return (1); 60030715Sbostic } 60130715Sbostic (void)fchmod(fd, 0600); 60230715Sbostic display(fd, lp); 60330715Sbostic fclose(fd); 60430715Sbostic for (;;) { 60530715Sbostic if (!editit()) 60630715Sbostic break; 60730715Sbostic fd = fopen(tmpfil, "r"); 60830715Sbostic if (fd == NULL) { 60934032Skarels fprintf(stderr, "%s: Can't reopen for reading\n", 61034032Skarels tmpfil); 61130715Sbostic break; 61230715Sbostic } 61330863Skarels bzero((char *)&label, sizeof(label)); 61430715Sbostic if (getasciilabel(fd, &label)) { 61530715Sbostic *lp = label; 61634641Skarels if (writelabel(f, bootarea, lp) == 0) { 61734641Skarels (void) unlink(tmpfil); 61834641Skarels return (0); 61934641Skarels } 62030715Sbostic } 62130715Sbostic printf("re-edit the label? [y]: "); fflush(stdout); 62230715Sbostic c = getchar(); 62330715Sbostic if (c != EOF && c != (int)'\n') 62430715Sbostic while (getchar() != (int)'\n') 62530715Sbostic ; 62630715Sbostic if (c == (int)'n') 62730715Sbostic break; 62830715Sbostic } 62930715Sbostic (void) unlink(tmpfil); 63034641Skarels return (1); 63130418Skarels } 63230418Skarels 63330715Sbostic editit() 63430715Sbostic { 63530715Sbostic register int pid, xpid; 63630715Sbostic int stat, omask; 63730715Sbostic extern char *getenv(); 63830418Skarels 63930715Sbostic omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 64030715Sbostic while ((pid = fork()) < 0) { 64130715Sbostic extern int errno; 64230715Sbostic 64330715Sbostic if (errno == EPROCLIM) { 64430715Sbostic fprintf(stderr, "You have too many processes\n"); 64530715Sbostic return(0); 64630715Sbostic } 64730715Sbostic if (errno != EAGAIN) { 64830715Sbostic perror("fork"); 64930715Sbostic return(0); 65030715Sbostic } 65130715Sbostic sleep(1); 65230715Sbostic } 65330715Sbostic if (pid == 0) { 65430715Sbostic register char *ed; 65530715Sbostic 65630715Sbostic sigsetmask(omask); 65730715Sbostic setgid(getgid()); 65830715Sbostic setuid(getuid()); 65930715Sbostic if ((ed = getenv("EDITOR")) == (char *)0) 66030715Sbostic ed = DEFEDITOR; 66130715Sbostic execlp(ed, ed, tmpfil, 0); 66230715Sbostic perror(ed); 66330715Sbostic exit(1); 66430715Sbostic } 66530715Sbostic while ((xpid = wait(&stat)) >= 0) 66630715Sbostic if (xpid == pid) 66730715Sbostic break; 66830715Sbostic sigsetmask(omask); 66930715Sbostic return(!stat); 67030715Sbostic } 67130715Sbostic 67230715Sbostic char * 67330715Sbostic skip(cp) 67430715Sbostic register char *cp; 67530715Sbostic { 67630715Sbostic 67730715Sbostic while (*cp != '\0' && isspace(*cp)) 67830715Sbostic cp++; 67930715Sbostic if (*cp == '\0' || *cp == '#') 68030715Sbostic return ((char *)NULL); 68130715Sbostic return (cp); 68230715Sbostic } 68330715Sbostic 68430715Sbostic char * 68530715Sbostic word(cp) 68630715Sbostic register char *cp; 68730715Sbostic { 68830715Sbostic register char c; 68930715Sbostic 69031401Skarels while (*cp != '\0' && !isspace(*cp) && *cp != '#') 69131401Skarels cp++; 69230715Sbostic if ((c = *cp) != '\0') { 69330715Sbostic *cp++ = '\0'; 69430715Sbostic if (c != '#') 69530715Sbostic return (skip(cp)); 69630715Sbostic } 69730715Sbostic return ((char *)NULL); 69830715Sbostic } 69930715Sbostic 70030418Skarels /* 70130418Skarels * Read an ascii label in from fd f, 70230418Skarels * in the same format as that put out by display(), 70330418Skarels * and fill in lp. 70430418Skarels */ 70530418Skarels getasciilabel(f, lp) 70630715Sbostic FILE *f; 70730418Skarels register struct disklabel *lp; 70830418Skarels { 70930715Sbostic register char **cpp, *cp; 71030863Skarels register struct partition *pp; 71130715Sbostic char *tp, *s, line[BUFSIZ]; 71230715Sbostic int v, lineno = 0, errors = 0; 71330715Sbostic 71430715Sbostic lp->d_bbsize = BBSIZE; /* XXX */ 71530715Sbostic lp->d_sbsize = SBSIZE; /* XXX */ 71630715Sbostic while (fgets(line, sizeof(line) - 1, f)) { 71730715Sbostic lineno++; 71830715Sbostic if (cp = index(line,'\n')) 71930715Sbostic *cp = '\0'; 72030715Sbostic cp = skip(line); 72130715Sbostic if (cp == NULL) 72230715Sbostic continue; 72330715Sbostic tp = index(cp, ':'); 72430715Sbostic if (tp == NULL) { 72530715Sbostic fprintf(stderr, "line %d: syntax error\n", lineno); 72630715Sbostic errors++; 72730715Sbostic continue; 72830715Sbostic } 72930715Sbostic *tp++ = '\0', tp = skip(tp); 73030715Sbostic if (streq(cp, "type")) { 73130715Sbostic if (tp == NULL) 73230715Sbostic tp = "unknown"; 73330715Sbostic cpp = dktypenames; 73430715Sbostic for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) 73530715Sbostic if ((s = *cpp) && streq(s, tp)) { 73630715Sbostic lp->d_type = cpp - dktypenames; 73730715Sbostic goto next; 73830715Sbostic } 73930715Sbostic v = atoi(tp); 74030715Sbostic if ((unsigned)v >= DKMAXTYPES) 74130715Sbostic fprintf(stderr, "line %d:%s %d\n", lineno, 74230715Sbostic "Warning, unknown disk type", v); 74330715Sbostic lp->d_type = v; 74430715Sbostic continue; 74530715Sbostic } 74630715Sbostic if (streq(cp, "flags")) { 74734032Skarels for (v = 0; (cp = tp) && *cp != '\0';) { 74834032Skarels tp = word(cp); 74930715Sbostic if (streq(cp, "removeable")) 75030715Sbostic v |= D_REMOVABLE; 75130715Sbostic else if (streq(cp, "ecc")) 75230715Sbostic v |= D_ECC; 75330715Sbostic else if (streq(cp, "badsect")) 75430715Sbostic v |= D_BADSECT; 75530715Sbostic else { 75630715Sbostic fprintf(stderr, 75730715Sbostic "line %d: %s: bad flag\n", 75830715Sbostic lineno, cp); 75930715Sbostic errors++; 76030715Sbostic } 76130715Sbostic } 76230715Sbostic lp->d_flags = v; 76330715Sbostic continue; 76430715Sbostic } 76530715Sbostic if (streq(cp, "drivedata")) { 76630715Sbostic register int i; 76730715Sbostic 76831386Skarels for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { 76930715Sbostic lp->d_drivedata[i++] = atoi(cp); 77031386Skarels tp = word(cp); 77130715Sbostic } 77230715Sbostic continue; 77330715Sbostic } 77430715Sbostic if (sscanf(cp, "%d partitions", &v) == 1) { 77530863Skarels if (v == 0 || (unsigned)v > MAXPARTITIONS) { 77630715Sbostic fprintf(stderr, 77730715Sbostic "line %d: bad # of partitions\n", lineno); 77830863Skarels lp->d_npartitions = MAXPARTITIONS; 77930863Skarels errors++; 78030863Skarels } else 78130715Sbostic lp->d_npartitions = v; 78230715Sbostic continue; 78330715Sbostic } 78430715Sbostic if (tp == NULL) 78530715Sbostic tp = ""; 78630715Sbostic if (streq(cp, "disk")) { 78730715Sbostic strncpy(lp->d_typename, tp, sizeof (lp->d_typename)); 78830715Sbostic continue; 78930715Sbostic } 79030715Sbostic if (streq(cp, "label")) { 79134032Skarels strncpy(lp->d_packname, tp, sizeof (lp->d_packname)); 79230715Sbostic continue; 79330715Sbostic } 79430715Sbostic if (streq(cp, "bytes/sector")) { 79530715Sbostic v = atoi(tp); 79630715Sbostic if (v <= 0 || (v % 512) != 0) { 79730715Sbostic fprintf(stderr, 79830715Sbostic "line %d: %s: bad sector size\n", 79930715Sbostic lineno, tp); 80030715Sbostic errors++; 80130715Sbostic } else 80230715Sbostic lp->d_secsize = v; 80330715Sbostic continue; 80430715Sbostic } 80530715Sbostic if (streq(cp, "sectors/track")) { 80630715Sbostic v = atoi(tp); 80730715Sbostic if (v <= 0) { 80830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 80930715Sbostic lineno, tp, cp); 81030715Sbostic errors++; 81130715Sbostic } else 81230715Sbostic lp->d_nsectors = v; 81330715Sbostic continue; 81430715Sbostic } 81531386Skarels if (streq(cp, "sectors/cylinder")) { 81631386Skarels v = atoi(tp); 81731386Skarels if (v <= 0) { 81831386Skarels fprintf(stderr, "line %d: %s: bad %s\n", 81931386Skarels lineno, tp, cp); 82031386Skarels errors++; 82131386Skarels } else 82231386Skarels lp->d_secpercyl = v; 82331386Skarels continue; 82431386Skarels } 82530715Sbostic if (streq(cp, "tracks/cylinder")) { 82630715Sbostic v = atoi(tp); 82730715Sbostic if (v <= 0) { 82830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 82930715Sbostic lineno, tp, cp); 83030715Sbostic errors++; 83130715Sbostic } else 83230715Sbostic lp->d_ntracks = v; 83330715Sbostic continue; 83430715Sbostic } 83530715Sbostic if (streq(cp, "cylinders")) { 83630715Sbostic v = atoi(tp); 83730715Sbostic if (v <= 0) { 83830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 83930715Sbostic lineno, tp, cp); 84030715Sbostic errors++; 84130715Sbostic } else 84230715Sbostic lp->d_ncylinders = v; 84330715Sbostic continue; 84430715Sbostic } 84530715Sbostic if (streq(cp, "rpm")) { 84630715Sbostic v = atoi(tp); 84730715Sbostic if (v <= 0) { 84830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 84930715Sbostic lineno, tp, cp); 85030715Sbostic errors++; 85130715Sbostic } else 85230715Sbostic lp->d_rpm = v; 85330715Sbostic continue; 85430715Sbostic } 85530715Sbostic if (streq(cp, "interleave")) { 85630715Sbostic v = atoi(tp); 85730715Sbostic if (v <= 0) { 85830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 85930715Sbostic lineno, tp, cp); 86030715Sbostic errors++; 86130715Sbostic } else 86230715Sbostic lp->d_interleave = v; 86330715Sbostic continue; 86430715Sbostic } 86530715Sbostic if (streq(cp, "trackskew")) { 86630715Sbostic v = atoi(tp); 86730715Sbostic if (v < 0) { 86830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 86930715Sbostic lineno, tp, cp); 87030715Sbostic errors++; 87130715Sbostic } else 87230715Sbostic lp->d_trackskew = v; 87330715Sbostic continue; 87430715Sbostic } 87530715Sbostic if (streq(cp, "cylinderskew")) { 87630715Sbostic v = atoi(tp); 87730715Sbostic if (v < 0) { 87830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 87930715Sbostic lineno, tp, cp); 88030715Sbostic errors++; 88130715Sbostic } else 88230715Sbostic lp->d_cylskew = v; 88330715Sbostic continue; 88430715Sbostic } 88530715Sbostic if (streq(cp, "headswitch")) { 88630715Sbostic v = atoi(tp); 88730715Sbostic if (v < 0) { 88830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 88930715Sbostic lineno, tp, cp); 89030715Sbostic errors++; 89130715Sbostic } else 89230715Sbostic lp->d_headswitch = v; 89330715Sbostic continue; 89430715Sbostic } 89530715Sbostic if (streq(cp, "track-to-track seek")) { 89630715Sbostic v = atoi(tp); 89730715Sbostic if (v < 0) { 89830715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 89930715Sbostic lineno, tp, cp); 90030715Sbostic errors++; 90130715Sbostic } else 90230715Sbostic lp->d_trkseek = v; 90330715Sbostic continue; 90430715Sbostic } 90530715Sbostic if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { 90630863Skarels unsigned part = *cp - 'a'; 90730715Sbostic 90830863Skarels if (part > lp->d_npartitions) { 90930715Sbostic fprintf(stderr, 91030715Sbostic "line %d: bad partition name\n", lineno); 91130715Sbostic errors++; 91230715Sbostic continue; 91330715Sbostic } 91430863Skarels pp = &lp->d_partitions[part]; 91530863Skarels #define NXTNUM(n) { \ 91630863Skarels cp = tp, tp = word(cp); \ 91730863Skarels if (tp == NULL) \ 91830863Skarels tp = cp; \ 91930863Skarels (n) = atoi(cp); \ 92030863Skarels } 92130863Skarels 92230863Skarels NXTNUM(v); 92330715Sbostic if (v < 0) { 92430715Sbostic fprintf(stderr, 92530715Sbostic "line %d: %s: bad partition size\n", 92630715Sbostic lineno, cp); 92730715Sbostic errors++; 92830715Sbostic } else 92930863Skarels pp->p_size = v; 93030863Skarels NXTNUM(v); 93130715Sbostic if (v < 0) { 93230715Sbostic fprintf(stderr, 93330715Sbostic "line %d: %s: bad partition offset\n", 93430715Sbostic lineno, cp); 93530715Sbostic errors++; 93630715Sbostic } else 93730863Skarels pp->p_offset = v; 93830715Sbostic cp = tp, tp = word(cp); 93930715Sbostic cpp = fstypenames; 94030715Sbostic for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) 94130715Sbostic if ((s = *cpp) && streq(s, cp)) { 94230863Skarels pp->p_fstype = cpp - fstypenames; 94330863Skarels goto gottype; 94430715Sbostic } 94534032Skarels if (isdigit(*cp)) 94634032Skarels v = atoi(cp); 94734032Skarels else 94834032Skarels v = FSMAXTYPES; 94934032Skarels if ((unsigned)v >= FSMAXTYPES) { 95030715Sbostic fprintf(stderr, "line %d: %s %s\n", lineno, 95130715Sbostic "Warning, unknown filesystem type", cp); 95234032Skarels v = FS_UNUSED; 95334032Skarels } 95430863Skarels pp->p_fstype = v; 95530863Skarels gottype: 95630863Skarels 95730863Skarels switch (pp->p_fstype) { 95830863Skarels 95930863Skarels case FS_UNUSED: /* XXX */ 96030863Skarels NXTNUM(pp->p_fsize); 96130863Skarels if (pp->p_fsize == 0) 96230863Skarels break; 96330863Skarels NXTNUM(v); 96430863Skarels pp->p_frag = v / pp->p_fsize; 96530863Skarels break; 96630863Skarels 96730863Skarels case FS_BSDFFS: 96830863Skarels NXTNUM(pp->p_fsize); 96930863Skarels if (pp->p_fsize == 0) 97030863Skarels break; 97130863Skarels NXTNUM(v); 97230863Skarels pp->p_frag = v / pp->p_fsize; 97330863Skarels NXTNUM(pp->p_cpg); 97430863Skarels break; 97530863Skarels 97630863Skarels default: 97730863Skarels break; 97830863Skarels } 97930715Sbostic continue; 98030715Sbostic } 98130715Sbostic fprintf(stderr, "line %d: %s: Unknown disklabel field\n", 98230715Sbostic lineno, cp); 98330715Sbostic errors++; 98430715Sbostic next: 98530715Sbostic ; 98630715Sbostic } 98730715Sbostic errors += checklabel(lp); 98830715Sbostic return (errors == 0); 98930418Skarels } 99030418Skarels 99130715Sbostic /* 99230715Sbostic * Check disklabel for errors and fill in 99330715Sbostic * derived fields according to supplied values. 99430715Sbostic */ 99530715Sbostic checklabel(lp) 99630715Sbostic register struct disklabel *lp; 99730418Skarels { 99830715Sbostic register struct partition *pp; 99930715Sbostic int i, errors = 0; 100030715Sbostic char part; 100130418Skarels 100230715Sbostic if (lp->d_secsize == 0) { 100330715Sbostic fprintf(stderr, "sector size %d\n", lp->d_secsize); 100430715Sbostic return (1); 100530715Sbostic } 100630715Sbostic if (lp->d_nsectors == 0) { 100730715Sbostic fprintf(stderr, "sectors/track %d\n", lp->d_nsectors); 100830715Sbostic return (1); 100930715Sbostic } 101030715Sbostic if (lp->d_ntracks == 0) { 101130715Sbostic fprintf(stderr, "tracks/cylinder %d\n", lp->d_ntracks); 101230715Sbostic return (1); 101330715Sbostic } 101430715Sbostic if (lp->d_ncylinders == 0) { 101530715Sbostic fprintf(stderr, "cylinders/unit %d\n", lp->d_ncylinders); 101630715Sbostic errors++; 101730715Sbostic } 101830715Sbostic if (lp->d_rpm == 0) 101930715Sbostic Warning("revolutions/minute %d\n", lp->d_rpm); 102030715Sbostic if (lp->d_secpercyl == 0) 102130715Sbostic lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 102230715Sbostic if (lp->d_secperunit == 0) 102330715Sbostic lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; 102430715Sbostic if (lp->d_bbsize == 0) { 102530715Sbostic fprintf(stderr, "boot block size %d\n", lp->d_bbsize); 102630715Sbostic errors++; 102730715Sbostic } else if (lp->d_bbsize % lp->d_secsize) 102830715Sbostic Warning("boot block size %% sector-size != 0\n"); 102930715Sbostic if (lp->d_sbsize == 0) { 103030715Sbostic fprintf(stderr, "super block size %d\n", lp->d_sbsize); 103130715Sbostic errors++; 103230715Sbostic } else if (lp->d_sbsize % lp->d_secsize) 103330715Sbostic Warning("super block size %% sector-size != 0\n"); 103430715Sbostic if (lp->d_npartitions > MAXPARTITIONS) 103530715Sbostic Warning("number of partitions (%d) > MAXPARTITIONS (%d)\n", 103630715Sbostic lp->d_npartitions, MAXPARTITIONS); 103730715Sbostic for (i = 0; i < lp->d_npartitions; i++) { 103830715Sbostic part = 'a' + i; 103930715Sbostic pp = &lp->d_partitions[i]; 104030715Sbostic if (pp->p_size == 0 && pp->p_offset != 0) 104130715Sbostic Warning("partition %c: size 0, but offset %d\n", 104230715Sbostic part, pp->p_offset); 104330715Sbostic #ifdef notdef 104430715Sbostic if (pp->p_size % lp->d_secpercyl) 104530715Sbostic Warning("partition %c: size %% cylinder-size != 0\n", 104630715Sbostic part); 104730715Sbostic if (pp->p_offset % lp->d_secpercyl) 104830715Sbostic Warning("partition %c: offset %% cylinder-size != 0\n", 104930715Sbostic part); 105030715Sbostic #endif 105130715Sbostic if (pp->p_offset > lp->d_secperunit) { 105230715Sbostic fprintf(stderr, 105330715Sbostic "partition %c: offset past end of unit\n", part); 105430715Sbostic errors++; 105530715Sbostic } 105630715Sbostic if (pp->p_offset + pp->p_size > lp->d_secperunit) { 105730715Sbostic fprintf(stderr, 105830715Sbostic "partition %c: partition extends past end of unit\n", 105930715Sbostic part); 106030715Sbostic errors++; 106130715Sbostic } 106230715Sbostic } 106330715Sbostic for (; i < MAXPARTITIONS; i++) { 106430715Sbostic part = 'a' + i; 106530715Sbostic pp = &lp->d_partitions[i]; 106630715Sbostic if (pp->p_size || pp->p_offset) 106730715Sbostic Warning("unused partition %c: size %d offset %d\n", 106834032Skarels 'a' + i, pp->p_size, pp->p_offset); 106930715Sbostic } 107030715Sbostic return (errors); 107130715Sbostic } 107230715Sbostic 107330715Sbostic /*VARARGS1*/ 107430715Sbostic Warning(fmt, a1, a2, a3, a4, a5) 107530715Sbostic char *fmt; 107630715Sbostic { 107730715Sbostic 107830715Sbostic fprintf(stderr, "Warning, "); 107930715Sbostic fprintf(stderr, fmt, a1, a2, a3, a4, a5); 108030715Sbostic fprintf(stderr, "\n"); 108130715Sbostic } 108230715Sbostic 108330715Sbostic Perror(str) 108430715Sbostic char *str; 108530715Sbostic { 108630715Sbostic fputs("disklabel: ", stderr); perror(str); 108730418Skarels exit(4); 108830418Skarels } 108930715Sbostic 109030715Sbostic usage() 109130715Sbostic { 109230715Sbostic #ifdef BOOT 109334032Skarels fprintf(stderr, "%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n", 109430715Sbostic "usage: disklabel [-r] disk", "(to read label)", 109530715Sbostic "or disklabel -w [-r] disk type [ packid ] [ xxboot bootxx ]", "(to write label)", 109630715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 109734032Skarels "or disklabel -R [-r] disk protofile [ type | xxboot bootxx ]", "(to restore label)", 109834032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 109930715Sbostic #else 110034032Skarels fprintf(stderr, "%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n", 110130715Sbostic "usage: disklabel [-r] disk", "(to read label)", 110230715Sbostic "or disklabel -w [-r] disk type [ packid ]", "(to write label)", 110330715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 110434032Skarels "or disklabel -R [-r] disk protofile", "(to restore label)", 110534032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 110630715Sbostic #endif 110730715Sbostic exit(1); 110830715Sbostic } 1109