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*57996Sralph static char sccsid[] = "@(#)disklabel.c 5.23 (Berkeley) 02/15/93"; 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> 2951615Sbostic #include <ufs/ffs/fs.h> 30*57996Sralph #include <unistd.h> 3151615Sbostic #include <string.h> 3237261Sbostic #include <stdio.h> 3337261Sbostic #include <ctype.h> 3437261Sbostic #include "pathnames.h" 3530418Skarels 3630418Skarels /* 3730418Skarels * Disklabel: read and write disklabels. 3830418Skarels * The label is usually placed on one of the first sectors of the disk. 3930418Skarels * Many machines (VAX 11/750) also place a bootstrap in the same area, 4030418Skarels * in which case the label is embedded in the bootstrap. 4130418Skarels * The bootstrap source must leave space at the proper offset 4230418Skarels * for the label on such machines. 4330418Skarels */ 4430418Skarels 4553196Sralph #if defined(vax) || defined(i386) || defined(mips) 4630677Skarels #define RAWPARTITION 'c' 4730677Skarels #else 4830677Skarels #define RAWPARTITION 'a' 4930677Skarels #endif 5030677Skarels 5130677Skarels #ifndef BBSIZE 5230418Skarels #define BBSIZE 8192 /* size of boot area, with label */ 5330677Skarels #endif 5430418Skarels 5553196Sralph #if defined(vax) || defined(i386) || defined(mips) 5630418Skarels #define BOOT /* also have bootstrap in "boot area" */ 5737261Sbostic #define BOOTDIR _PATH_BOOTDIR /* source of boot binaries */ 5830677Skarels #else 5930677Skarels #ifdef lint 6030677Skarels #define BOOT 6130418Skarels #endif 6230677Skarels #endif 6330418Skarels 6438505Sbostic #define DEFEDITOR _PATH_VI 6530715Sbostic #define streq(a,b) (strcmp(a,b) == 0) 6630715Sbostic 6730715Sbostic #ifdef BOOT 6830418Skarels char *xxboot; 6930418Skarels char *bootxx; 7030715Sbostic #endif 7131617Skarels 7231617Skarels char *dkname; 7330418Skarels char *specname; 7437945Sbostic char tmpfil[] = _PATH_TMP; 7530418Skarels 7630418Skarels extern int errno; 7730418Skarels char namebuf[BBSIZE], *np = namebuf; 7831617Skarels struct disklabel lab; 7931617Skarels struct disklabel *readlabel(), *makebootarea(); 8030418Skarels char bootarea[BBSIZE]; 8134032Skarels char boot0[MAXPATHLEN]; 8234032Skarels char boot1[MAXPATHLEN]; 8330418Skarels 8434032Skarels enum { UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE } op = UNSPEC; 8530418Skarels 8630677Skarels int rflag; 8730677Skarels 8834032Skarels #ifdef DEBUG 8934032Skarels int debug; 90*57996Sralph #define GETOPT_FLAGS "NRWerwd" 91*57996Sralph #else 92*57996Sralph #define GETOPT_FLAGS "NRWerw" 9334032Skarels #endif 9434032Skarels 9530418Skarels main(argc, argv) 9630418Skarels int argc; 9730418Skarels char *argv[]; 9830418Skarels { 9934032Skarels extern int optind; 10030418Skarels register struct disklabel *lp; 10134032Skarels FILE *t; 10234641Skarels int ch, f, error = 0; 10330715Sbostic char *name = 0, *type; 10430418Skarels 105*57996Sralph while ((ch = getopt(argc, argv, GETOPT_FLAGS)) != EOF) 10634032Skarels switch (ch) { 10734032Skarels case 'N': 10834032Skarels if (op != UNSPEC) 10934032Skarels usage(); 11034032Skarels op = NOWRITE; 11134032Skarels break; 11230715Sbostic case 'R': 11334032Skarels if (op != UNSPEC) 11434032Skarels usage(); 11530715Sbostic op = RESTORE; 11630715Sbostic break; 11734032Skarels case 'W': 11834032Skarels if (op != UNSPEC) 11934032Skarels usage(); 12034032Skarels op = WRITEABLE; 12134032Skarels break; 12230715Sbostic case 'e': 12334032Skarels if (op != UNSPEC) 12434032Skarels usage(); 12530715Sbostic op = EDIT; 12630715Sbostic break; 12730715Sbostic case 'r': 12830715Sbostic ++rflag; 12930715Sbostic break; 13030715Sbostic case 'w': 13134032Skarels if (op != UNSPEC) 13234032Skarels usage(); 13330715Sbostic op = WRITE; 13430715Sbostic break; 13534032Skarels #ifdef DEBUG 13634032Skarels case 'd': 13734032Skarels debug++; 13834032Skarels break; 13934032Skarels #endif 14030715Sbostic case '?': 14130715Sbostic default: 14230715Sbostic usage(); 14330715Sbostic } 14430715Sbostic argc -= optind; 14530715Sbostic argv += optind; 14634032Skarels if (op == UNSPEC) 14734032Skarels op = READ; 14830715Sbostic if (argc < 1) 14930715Sbostic usage(); 15030715Sbostic 15130715Sbostic dkname = argv[0]; 15230418Skarels if (dkname[0] != '/') { 15337945Sbostic (void)sprintf(np, "%s/r%s%c", _PATH_DEV, dkname, RAWPARTITION); 15430418Skarels specname = np; 15530418Skarels np += strlen(specname) + 1; 15630418Skarels } else 15730418Skarels specname = dkname; 15830418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 15930418Skarels if (f < 0 && errno == ENOENT && dkname[0] != '/') { 16037945Sbostic (void)sprintf(specname, "%s/r%s", _PATH_DEV, dkname); 16130418Skarels np = namebuf + strlen(specname) + 1; 16230418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 16330418Skarels } 16430418Skarels if (f < 0) 16530418Skarels Perror(specname); 16630418Skarels 16730715Sbostic switch(op) { 16830715Sbostic case EDIT: 16930715Sbostic if (argc != 1) 17030715Sbostic usage(); 17134032Skarels lp = readlabel(f); 17234641Skarels error = edit(lp, f); 17330715Sbostic break; 17434032Skarels case NOWRITE: { 17534032Skarels int flag = 0; 17634032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 17734032Skarels Perror("ioctl DIOCWLABEL"); 17834032Skarels break; 17934032Skarels } 18030418Skarels case READ: 18130715Sbostic if (argc != 1) 18230715Sbostic usage(); 18334032Skarels lp = readlabel(f); 18430418Skarels display(stdout, lp); 18534641Skarels error = checklabel(lp); 18630418Skarels break; 18730715Sbostic case RESTORE: 18830715Sbostic #ifdef BOOT 18934032Skarels if (rflag) { 19034032Skarels if (argc == 4) { /* [ priboot secboot ] */ 19134032Skarels xxboot = argv[2]; 19234032Skarels bootxx = argv[3]; 19334032Skarels lab.d_secsize = DEV_BSIZE; /* XXX */ 19434032Skarels lab.d_bbsize = BBSIZE; /* XXX */ 19534032Skarels } 19634032Skarels else if (argc == 3) /* [ disktype ] */ 19734032Skarels makelabel(argv[2], (char *)NULL, &lab); 19834032Skarels else { 19934032Skarels fprintf(stderr, 20034032Skarels "Must specify either disktype or bootfiles with -r flag of RESTORE option\n"); 20134032Skarels exit(1); 20234032Skarels } 20334032Skarels } 20434032Skarels else 20531617Skarels #endif 20630715Sbostic if (argc != 2) 20730715Sbostic usage(); 20831617Skarels lp = makebootarea(bootarea, &lab); 20930715Sbostic if (!(t = fopen(argv[1],"r"))) 21030715Sbostic Perror(argv[1]); 21130715Sbostic if (getasciilabel(t, lp)) 21234641Skarels error = writelabel(f, bootarea, lp); 21330418Skarels break; 21430418Skarels case WRITE: 21530715Sbostic type = argv[1]; 21630715Sbostic #ifdef BOOT 21730715Sbostic if (argc > 5 || argc < 2) 21830715Sbostic usage(); 21930715Sbostic if (argc > 3) { 22030715Sbostic bootxx = argv[--argc]; 22130715Sbostic xxboot = argv[--argc]; 22230715Sbostic } 22330715Sbostic #else 22430715Sbostic if (argc > 3 || argc < 2) 22530715Sbostic usage(); 22630715Sbostic #endif 22730715Sbostic if (argc > 2) 228*57996Sralph name = argv[2]; 22930418Skarels makelabel(type, name, &lab); 23031617Skarels lp = makebootarea(bootarea, &lab); 23130418Skarels *lp = lab; 23230715Sbostic if (checklabel(lp) == 0) 23334641Skarels error = writelabel(f, bootarea, lp); 23430418Skarels break; 23534032Skarels case WRITEABLE: { 23634032Skarels int flag = 1; 23734032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 23834032Skarels Perror("ioctl DIOCWLABEL"); 23934032Skarels break; 24030418Skarels } 24134032Skarels } 24234641Skarels exit(error); 24330418Skarels } 24430418Skarels 24534032Skarels /* 24634032Skarels * Construct a prototype disklabel from /etc/disktab. As a side 24734032Skarels * effect, set the names of the primary and secondary boot files 24834032Skarels * if specified. 24934032Skarels */ 25030418Skarels makelabel(type, name, lp) 25130418Skarels char *type, *name; 25230418Skarels register struct disklabel *lp; 25330418Skarels { 25430418Skarels register struct disklabel *dp; 25534032Skarels char *strcpy(); 25630418Skarels 25730418Skarels dp = getdiskbyname(type); 25830418Skarels if (dp == NULL) { 25930418Skarels fprintf(stderr, "%s: unknown disk type\n", type); 26030418Skarels exit(1); 26130418Skarels } 26230418Skarels *lp = *dp; 26334032Skarels #ifdef BOOT 26434032Skarels /* 26534032Skarels * Check if disktab specifies the bootstraps (b0 or b1). 26634032Skarels */ 26734032Skarels if (!xxboot && lp->d_boot0) { 26834032Skarels if (*lp->d_boot0 != '/') 26934032Skarels (void)sprintf(boot0, "%s/%s", BOOTDIR, lp->d_boot0); 27034032Skarels else 27134032Skarels (void)strcpy(boot0, lp->d_boot0); 27234032Skarels xxboot = boot0; 27334032Skarels } 27434032Skarels if (!bootxx && lp->d_boot1) { 27534032Skarels if (*lp->d_boot1 != '/') 27634032Skarels (void)sprintf(boot1, "%s/%s", BOOTDIR, lp->d_boot1); 27734032Skarels else 27834032Skarels (void)strcpy(boot1, lp->d_boot1); 27934032Skarels bootxx = boot1; 28034032Skarels } 28134032Skarels /* 28234032Skarels * If bootstraps not specified anywhere, makebootarea() 28334032Skarels * will choose ones based on the name of the disk special 28434032Skarels * file. E.g. /dev/ra0 -> raboot, bootra 28534032Skarels */ 28634032Skarels #endif /*BOOT*/ 28734032Skarels /* d_packname is union d_boot[01], so zero */ 28834032Skarels bzero(lp->d_packname, sizeof(lp->d_packname)); 28930418Skarels if (name) 29034032Skarels (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname)); 29130418Skarels } 29230418Skarels 29330418Skarels writelabel(f, boot, lp) 29430418Skarels int f; 29530418Skarels char *boot; 29630418Skarels register struct disklabel *lp; 29730418Skarels { 29830715Sbostic register int i; 29934032Skarels int flag; 30030418Skarels 30130418Skarels lp->d_magic = DISKMAGIC; 30230418Skarels lp->d_magic2 = DISKMAGIC; 30330418Skarels lp->d_checksum = 0; 30430418Skarels lp->d_checksum = dkcksum(lp); 30530677Skarels if (rflag) { 30634032Skarels /* 30734032Skarels * First set the kernel disk label, 30834032Skarels * then write a label to the raw disk. 30934032Skarels * If the SDINFO ioctl fails because it is unimplemented, 31034032Skarels * keep going; otherwise, the kernel consistency checks 31134032Skarels * may prevent us from changing the current (in-core) 31234032Skarels * label. 31334032Skarels */ 31434032Skarels if (ioctl(f, DIOCSDINFO, lp) < 0 && 31534641Skarels errno != ENODEV && errno != ENOTTY) { 31634641Skarels l_perror("ioctl DIOCSDINFO"); 31734641Skarels return (1); 31834641Skarels } 319*57996Sralph (void)lseek(f, (off_t)0, SEEK_SET); 32034032Skarels /* 32134032Skarels * write enable label sector before write (if necessary), 32234032Skarels * disable after writing. 32334032Skarels */ 32434032Skarels flag = 1; 32534032Skarels if (ioctl(f, DIOCWLABEL, &flag) < 0) 32634032Skarels perror("ioctl DIOCWLABEL"); 32734641Skarels if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { 32834641Skarels perror("write"); 32934641Skarels return (1); 33034641Skarels } 33134032Skarels flag = 0; 33234032Skarels (void) ioctl(f, DIOCWLABEL, &flag); 33334641Skarels } else if (ioctl(f, DIOCWDINFO, lp) < 0) { 33434641Skarels l_perror("ioctl DIOCWDINFO"); 33534641Skarels return (1); 33634641Skarels } 33734032Skarels #ifdef vax 33830677Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 33930677Skarels daddr_t alt; 34030677Skarels 34130677Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 34230677Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 343*57996Sralph (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), 344*57996Sralph SEEK_SET); 34530677Skarels if (write(f, boot, lp->d_secsize) < lp->d_secsize) { 34630677Skarels int oerrno = errno; 34730677Skarels fprintf(stderr, "alternate label %d ", i/2); 34830677Skarels errno = oerrno; 34930677Skarels perror("write"); 35030677Skarels } 35130418Skarels } 35230418Skarels } 35330419Skarels #endif 35434641Skarels return (0); 35530418Skarels } 35630418Skarels 35734641Skarels l_perror(s) 35834641Skarels char *s; 35934641Skarels { 36034641Skarels int saverrno = errno; 36134641Skarels 36234641Skarels fprintf(stderr, "disklabel: %s: ", s); 36334641Skarels 36434641Skarels switch (saverrno) { 36534641Skarels 36634641Skarels case ESRCH: 36734641Skarels fprintf(stderr, "No disk label on disk;\n"); 36834641Skarels fprintf(stderr, 36934641Skarels "use \"disklabel -r\" to install initial label\n"); 37034641Skarels break; 37134641Skarels 37234641Skarels case EINVAL: 37334641Skarels fprintf(stderr, "Label magic number or checksum is wrong!\n"); 37434641Skarels fprintf(stderr, "(disklabel or kernel is out of date?)\n"); 37534641Skarels break; 37634641Skarels 37734641Skarels case EBUSY: 37834641Skarels fprintf(stderr, "Open partition would move or shrink\n"); 37934641Skarels break; 38034641Skarels 38134641Skarels case EXDEV: 38234641Skarels fprintf(stderr, 38334641Skarels "Labeled partition or 'a' partition must start at beginning of disk\n"); 38434641Skarels break; 38534641Skarels 38634641Skarels default: 38734641Skarels errno = saverrno; 38834641Skarels perror((char *)NULL); 38934641Skarels break; 39034641Skarels } 39134641Skarels } 39234641Skarels 39330418Skarels /* 39431617Skarels * Fetch disklabel for disk. 39531617Skarels * Use ioctl to get label unless -r flag is given. 39630418Skarels */ 39730418Skarels struct disklabel * 39834032Skarels readlabel(f) 39934032Skarels int f; 40030418Skarels { 40130418Skarels register struct disklabel *lp; 40230418Skarels 40334032Skarels if (rflag) { 40431617Skarels if (read(f, bootarea, BBSIZE) < BBSIZE) 40531401Skarels Perror(specname); 40631617Skarels for (lp = (struct disklabel *)bootarea; 40731617Skarels lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); 40830677Skarels lp = (struct disklabel *)((char *)lp + 16)) 40930677Skarels if (lp->d_magic == DISKMAGIC && 41030677Skarels lp->d_magic2 == DISKMAGIC) 41130677Skarels break; 41231617Skarels if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || 41330677Skarels lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || 41430677Skarels dkcksum(lp) != 0) { 41530677Skarels fprintf(stderr, 41630418Skarels "Bad pack magic number (label is damaged, or pack is unlabeled)\n"); 41734032Skarels /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */ 41834032Skarels exit (1); 41930677Skarels } 42034032Skarels } else { 42134032Skarels lp = &lab; 42234032Skarels if (ioctl(f, DIOCGDINFO, lp) < 0) 42334032Skarels Perror("ioctl DIOCGDINFO"); 42430418Skarels } 42530418Skarels return (lp); 42630418Skarels } 42730418Skarels 42830418Skarels struct disklabel * 42931617Skarels makebootarea(boot, dp) 43030418Skarels char *boot; 43130418Skarels register struct disklabel *dp; 43230418Skarels { 43330418Skarels struct disklabel *lp; 43430418Skarels register char *p; 43530418Skarels int b; 43630418Skarels #ifdef BOOT 43730715Sbostic char *dkbasename; 43834032Skarels #endif /*BOOT*/ 43930715Sbostic 44034032Skarels lp = (struct disklabel *)(boot + (LABELSECTOR * dp->d_secsize) + 44134032Skarels LABELOFFSET); 44234032Skarels #ifdef BOOT 44334032Skarels if (!rflag) 44434032Skarels return (lp); 44534032Skarels 44634032Skarels if (xxboot == NULL || bootxx == NULL) { 44730418Skarels dkbasename = np; 44830418Skarels if ((p = rindex(dkname, '/')) == NULL) 44930418Skarels p = dkname; 45030418Skarels else 45130418Skarels p++; 45230418Skarels while (*p && !isdigit(*p)) 45330418Skarels *np++ = *p++; 45430418Skarels *np++ = '\0'; 45530418Skarels 45634032Skarels if (xxboot == NULL) { 45734032Skarels (void)sprintf(np, "%s/%sboot", BOOTDIR, dkbasename); 45834032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 45934032Skarels dkbasename++; 46034032Skarels xxboot = np; 46134032Skarels (void)sprintf(xxboot, "%s/%sboot", BOOTDIR, dkbasename); 46234032Skarels np += strlen(xxboot) + 1; 46334032Skarels } 46434032Skarels if (bootxx == NULL) { 46534032Skarels (void)sprintf(np, "%s/boot%s", BOOTDIR, dkbasename); 46634032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 46734032Skarels dkbasename++; 46834032Skarels bootxx = np; 46934032Skarels (void)sprintf(bootxx, "%s/boot%s", BOOTDIR, dkbasename); 47034032Skarels np += strlen(bootxx) + 1; 47134032Skarels } 47230418Skarels } 47334032Skarels #ifdef DEBUG 47434032Skarels if (debug) 47534032Skarels fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n", 47634032Skarels xxboot, bootxx); 47734032Skarels #endif 47830418Skarels 47930418Skarels b = open(xxboot, O_RDONLY); 48030418Skarels if (b < 0) 48130418Skarels Perror(xxboot); 48230715Sbostic if (read(b, boot, (int)dp->d_secsize) < 0) 48330418Skarels Perror(xxboot); 48430418Skarels close(b); 48530418Skarels b = open(bootxx, O_RDONLY); 48630418Skarels if (b < 0) 48730418Skarels Perror(bootxx); 48830715Sbostic if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0) 48930418Skarels Perror(bootxx); 49030715Sbostic (void)close(b); 49134032Skarels #endif /*BOOT*/ 49230418Skarels 49330418Skarels for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) 49430418Skarels if (*p) { 49530418Skarels fprintf(stderr, 49630418Skarels "Bootstrap doesn't leave room for disk label\n"); 49730418Skarels exit(2); 49830418Skarels } 49930418Skarels return (lp); 50030418Skarels } 50130418Skarels 50230418Skarels display(f, lp) 50330418Skarels FILE *f; 50430418Skarels register struct disklabel *lp; 50530418Skarels { 50630715Sbostic register int i, j; 50730418Skarels register struct partition *pp; 50830418Skarels 50930418Skarels fprintf(f, "# %s:\n", specname); 51030418Skarels if ((unsigned) lp->d_type < DKMAXTYPES) 51130418Skarels fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 51230418Skarels else 51330418Skarels fprintf(f, "type: %d\n", lp->d_type); 51430418Skarels fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename); 51534032Skarels fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname); 51631401Skarels fprintf(f, "flags:"); 51730418Skarels if (lp->d_flags & D_REMOVABLE) 51831401Skarels fprintf(f, " removeable"); 51930418Skarels if (lp->d_flags & D_ECC) 52031401Skarels fprintf(f, " ecc"); 52130418Skarels if (lp->d_flags & D_BADSECT) 52231401Skarels fprintf(f, " badsect"); 52330418Skarels fprintf(f, "\n"); 52430418Skarels fprintf(f, "bytes/sector: %d\n", lp->d_secsize); 52530418Skarels fprintf(f, "sectors/track: %d\n", lp->d_nsectors); 52630418Skarels fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks); 52731386Skarels fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl); 52830418Skarels fprintf(f, "cylinders: %d\n", lp->d_ncylinders); 52930715Sbostic fprintf(f, "rpm: %d\n", lp->d_rpm); 53030418Skarels fprintf(f, "interleave: %d\n", lp->d_interleave); 53130418Skarels fprintf(f, "trackskew: %d\n", lp->d_trackskew); 53230418Skarels fprintf(f, "cylinderskew: %d\n", lp->d_cylskew); 53330418Skarels fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); 53430418Skarels fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); 53530418Skarels fprintf(f, "drivedata: "); 53630418Skarels for (i = NDDATA - 1; i >= 0; i--) 53730418Skarels if (lp->d_drivedata[i]) 53830418Skarels break; 53930418Skarels if (i < 0) 54030418Skarels i = 0; 54130418Skarels for (j = 0; j <= i; j++) 54230418Skarels fprintf(f, "%d ", lp->d_drivedata[j]); 54330418Skarels fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions); 54430863Skarels fprintf(f, 54530863Skarels "# size offset fstype [fsize bsize cpg]\n"); 54630418Skarels pp = lp->d_partitions; 54730418Skarels for (i = 0; i < lp->d_npartitions; i++, pp++) { 54830418Skarels if (pp->p_size) { 54930863Skarels fprintf(f, " %c: %8d %8d ", 'a' + i, 55030863Skarels pp->p_size, pp->p_offset); 55130418Skarels if ((unsigned) pp->p_fstype < FSMAXTYPES) 55230418Skarels fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 55330418Skarels else 55430418Skarels fprintf(f, "%8d", pp->p_fstype); 55530863Skarels switch (pp->p_fstype) { 55630863Skarels 55730863Skarels case FS_UNUSED: /* XXX */ 55830863Skarels fprintf(f, " %5d %5d %5.5s ", 55930863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, ""); 56030863Skarels break; 56130863Skarels 56230863Skarels case FS_BSDFFS: 56330863Skarels fprintf(f, " %5d %5d %5d ", 56430863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, 56530863Skarels pp->p_cpg); 56630863Skarels break; 56730863Skarels 56830863Skarels default: 56930863Skarels fprintf(f, "%20.20s", ""); 57030863Skarels break; 57130863Skarels } 57230418Skarels fprintf(f, "\t# (Cyl. %4d", 57330418Skarels pp->p_offset / lp->d_secpercyl); 57430418Skarels if (pp->p_offset % lp->d_secpercyl) 57530418Skarels putc('*', f); 57630418Skarels else 57730418Skarels putc(' ', f); 57830418Skarels fprintf(f, "- %d", 57930418Skarels (pp->p_offset + 58030418Skarels pp->p_size + lp->d_secpercyl - 1) / 58130418Skarels lp->d_secpercyl - 1); 58230418Skarels if (pp->p_size % lp->d_secpercyl) 58330418Skarels putc('*', f); 58430863Skarels fprintf(f, ")\n"); 58530418Skarels } 58630418Skarels } 58732121Stef fflush(f); 58830418Skarels } 58930418Skarels 59034641Skarels edit(lp, f) 59130715Sbostic struct disklabel *lp; 59234641Skarels int f; 59330418Skarels { 59430715Sbostic register int c; 59530715Sbostic struct disklabel label; 59630715Sbostic FILE *fd; 59730715Sbostic char *mktemp(); 59830715Sbostic 59930715Sbostic (void) mktemp(tmpfil); 60030715Sbostic fd = fopen(tmpfil, "w"); 60130715Sbostic if (fd == NULL) { 60230715Sbostic fprintf(stderr, "%s: Can't create\n", tmpfil); 60334641Skarels return (1); 60430715Sbostic } 60530715Sbostic (void)fchmod(fd, 0600); 60630715Sbostic display(fd, lp); 60730715Sbostic fclose(fd); 60830715Sbostic for (;;) { 60930715Sbostic if (!editit()) 61030715Sbostic break; 61130715Sbostic fd = fopen(tmpfil, "r"); 61230715Sbostic if (fd == NULL) { 61334032Skarels fprintf(stderr, "%s: Can't reopen for reading\n", 61434032Skarels tmpfil); 61530715Sbostic break; 61630715Sbostic } 61730863Skarels bzero((char *)&label, sizeof(label)); 61830715Sbostic if (getasciilabel(fd, &label)) { 61930715Sbostic *lp = label; 62034641Skarels if (writelabel(f, bootarea, lp) == 0) { 62134641Skarels (void) unlink(tmpfil); 62234641Skarels return (0); 62334641Skarels } 62430715Sbostic } 62530715Sbostic printf("re-edit the label? [y]: "); fflush(stdout); 62630715Sbostic c = getchar(); 62730715Sbostic if (c != EOF && c != (int)'\n') 62830715Sbostic while (getchar() != (int)'\n') 62930715Sbostic ; 63030715Sbostic if (c == (int)'n') 63130715Sbostic break; 63230715Sbostic } 63330715Sbostic (void) unlink(tmpfil); 63434641Skarels return (1); 63530418Skarels } 63630418Skarels 63730715Sbostic editit() 63830715Sbostic { 63930715Sbostic register int pid, xpid; 64030715Sbostic int stat, omask; 64130715Sbostic extern char *getenv(); 64230418Skarels 64330715Sbostic omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 64430715Sbostic while ((pid = fork()) < 0) { 64530715Sbostic extern int errno; 64630715Sbostic 64730715Sbostic if (errno == EPROCLIM) { 64830715Sbostic fprintf(stderr, "You have too many processes\n"); 64930715Sbostic return(0); 65030715Sbostic } 65130715Sbostic if (errno != EAGAIN) { 65230715Sbostic perror("fork"); 65330715Sbostic return(0); 65430715Sbostic } 65530715Sbostic sleep(1); 65630715Sbostic } 65730715Sbostic if (pid == 0) { 65830715Sbostic register char *ed; 65930715Sbostic 66030715Sbostic sigsetmask(omask); 66130715Sbostic setgid(getgid()); 66230715Sbostic setuid(getuid()); 66330715Sbostic if ((ed = getenv("EDITOR")) == (char *)0) 66430715Sbostic ed = DEFEDITOR; 66530715Sbostic execlp(ed, ed, tmpfil, 0); 66630715Sbostic perror(ed); 66730715Sbostic exit(1); 66830715Sbostic } 66930715Sbostic while ((xpid = wait(&stat)) >= 0) 67030715Sbostic if (xpid == pid) 67130715Sbostic break; 67230715Sbostic sigsetmask(omask); 67330715Sbostic return(!stat); 67430715Sbostic } 67530715Sbostic 67630715Sbostic char * 67730715Sbostic skip(cp) 67830715Sbostic register char *cp; 67930715Sbostic { 68030715Sbostic 68130715Sbostic while (*cp != '\0' && isspace(*cp)) 68230715Sbostic cp++; 68330715Sbostic if (*cp == '\0' || *cp == '#') 68430715Sbostic return ((char *)NULL); 68530715Sbostic return (cp); 68630715Sbostic } 68730715Sbostic 68830715Sbostic char * 68930715Sbostic word(cp) 69030715Sbostic register char *cp; 69130715Sbostic { 69230715Sbostic register char c; 69330715Sbostic 69431401Skarels while (*cp != '\0' && !isspace(*cp) && *cp != '#') 69531401Skarels cp++; 69630715Sbostic if ((c = *cp) != '\0') { 69730715Sbostic *cp++ = '\0'; 69830715Sbostic if (c != '#') 69930715Sbostic return (skip(cp)); 70030715Sbostic } 70130715Sbostic return ((char *)NULL); 70230715Sbostic } 70330715Sbostic 70430418Skarels /* 70530418Skarels * Read an ascii label in from fd f, 70630418Skarels * in the same format as that put out by display(), 70730418Skarels * and fill in lp. 70830418Skarels */ 70930418Skarels getasciilabel(f, lp) 71030715Sbostic FILE *f; 71130418Skarels register struct disklabel *lp; 71230418Skarels { 71330715Sbostic register char **cpp, *cp; 71430863Skarels register struct partition *pp; 71530715Sbostic char *tp, *s, line[BUFSIZ]; 71630715Sbostic int v, lineno = 0, errors = 0; 71730715Sbostic 71830715Sbostic lp->d_bbsize = BBSIZE; /* XXX */ 71930715Sbostic lp->d_sbsize = SBSIZE; /* XXX */ 72030715Sbostic while (fgets(line, sizeof(line) - 1, f)) { 72130715Sbostic lineno++; 72230715Sbostic if (cp = index(line,'\n')) 72330715Sbostic *cp = '\0'; 72430715Sbostic cp = skip(line); 72530715Sbostic if (cp == NULL) 72630715Sbostic continue; 72730715Sbostic tp = index(cp, ':'); 72830715Sbostic if (tp == NULL) { 72930715Sbostic fprintf(stderr, "line %d: syntax error\n", lineno); 73030715Sbostic errors++; 73130715Sbostic continue; 73230715Sbostic } 73330715Sbostic *tp++ = '\0', tp = skip(tp); 73430715Sbostic if (streq(cp, "type")) { 73530715Sbostic if (tp == NULL) 73630715Sbostic tp = "unknown"; 73730715Sbostic cpp = dktypenames; 73830715Sbostic for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) 73930715Sbostic if ((s = *cpp) && streq(s, tp)) { 74030715Sbostic lp->d_type = cpp - dktypenames; 74130715Sbostic goto next; 74230715Sbostic } 74330715Sbostic v = atoi(tp); 74430715Sbostic if ((unsigned)v >= DKMAXTYPES) 74530715Sbostic fprintf(stderr, "line %d:%s %d\n", lineno, 74630715Sbostic "Warning, unknown disk type", v); 74730715Sbostic lp->d_type = v; 74830715Sbostic continue; 74930715Sbostic } 75030715Sbostic if (streq(cp, "flags")) { 75134032Skarels for (v = 0; (cp = tp) && *cp != '\0';) { 75234032Skarels tp = word(cp); 75330715Sbostic if (streq(cp, "removeable")) 75430715Sbostic v |= D_REMOVABLE; 75530715Sbostic else if (streq(cp, "ecc")) 75630715Sbostic v |= D_ECC; 75730715Sbostic else if (streq(cp, "badsect")) 75830715Sbostic v |= D_BADSECT; 75930715Sbostic else { 76030715Sbostic fprintf(stderr, 76130715Sbostic "line %d: %s: bad flag\n", 76230715Sbostic lineno, cp); 76330715Sbostic errors++; 76430715Sbostic } 76530715Sbostic } 76630715Sbostic lp->d_flags = v; 76730715Sbostic continue; 76830715Sbostic } 76930715Sbostic if (streq(cp, "drivedata")) { 77030715Sbostic register int i; 77130715Sbostic 77231386Skarels for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { 77330715Sbostic lp->d_drivedata[i++] = atoi(cp); 77431386Skarels tp = word(cp); 77530715Sbostic } 77630715Sbostic continue; 77730715Sbostic } 77830715Sbostic if (sscanf(cp, "%d partitions", &v) == 1) { 77930863Skarels if (v == 0 || (unsigned)v > MAXPARTITIONS) { 78030715Sbostic fprintf(stderr, 78130715Sbostic "line %d: bad # of partitions\n", lineno); 78230863Skarels lp->d_npartitions = MAXPARTITIONS; 78330863Skarels errors++; 78430863Skarels } else 78530715Sbostic lp->d_npartitions = v; 78630715Sbostic continue; 78730715Sbostic } 78830715Sbostic if (tp == NULL) 78930715Sbostic tp = ""; 79030715Sbostic if (streq(cp, "disk")) { 79130715Sbostic strncpy(lp->d_typename, tp, sizeof (lp->d_typename)); 79230715Sbostic continue; 79330715Sbostic } 79430715Sbostic if (streq(cp, "label")) { 79534032Skarels strncpy(lp->d_packname, tp, sizeof (lp->d_packname)); 79630715Sbostic continue; 79730715Sbostic } 79830715Sbostic if (streq(cp, "bytes/sector")) { 79930715Sbostic v = atoi(tp); 80030715Sbostic if (v <= 0 || (v % 512) != 0) { 80130715Sbostic fprintf(stderr, 80230715Sbostic "line %d: %s: bad sector size\n", 80330715Sbostic lineno, tp); 80430715Sbostic errors++; 80530715Sbostic } else 80630715Sbostic lp->d_secsize = v; 80730715Sbostic continue; 80830715Sbostic } 80930715Sbostic if (streq(cp, "sectors/track")) { 81030715Sbostic v = atoi(tp); 81130715Sbostic if (v <= 0) { 81230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 81330715Sbostic lineno, tp, cp); 81430715Sbostic errors++; 81530715Sbostic } else 81630715Sbostic lp->d_nsectors = v; 81730715Sbostic continue; 81830715Sbostic } 81931386Skarels if (streq(cp, "sectors/cylinder")) { 82031386Skarels v = atoi(tp); 82131386Skarels if (v <= 0) { 82231386Skarels fprintf(stderr, "line %d: %s: bad %s\n", 82331386Skarels lineno, tp, cp); 82431386Skarels errors++; 82531386Skarels } else 82631386Skarels lp->d_secpercyl = v; 82731386Skarels continue; 82831386Skarels } 82930715Sbostic if (streq(cp, "tracks/cylinder")) { 83030715Sbostic v = atoi(tp); 83130715Sbostic if (v <= 0) { 83230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 83330715Sbostic lineno, tp, cp); 83430715Sbostic errors++; 83530715Sbostic } else 83630715Sbostic lp->d_ntracks = v; 83730715Sbostic continue; 83830715Sbostic } 83930715Sbostic if (streq(cp, "cylinders")) { 84030715Sbostic v = atoi(tp); 84130715Sbostic if (v <= 0) { 84230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 84330715Sbostic lineno, tp, cp); 84430715Sbostic errors++; 84530715Sbostic } else 84630715Sbostic lp->d_ncylinders = v; 84730715Sbostic continue; 84830715Sbostic } 84930715Sbostic if (streq(cp, "rpm")) { 85030715Sbostic v = atoi(tp); 85130715Sbostic if (v <= 0) { 85230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 85330715Sbostic lineno, tp, cp); 85430715Sbostic errors++; 85530715Sbostic } else 85630715Sbostic lp->d_rpm = v; 85730715Sbostic continue; 85830715Sbostic } 85930715Sbostic if (streq(cp, "interleave")) { 86030715Sbostic v = atoi(tp); 86130715Sbostic if (v <= 0) { 86230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 86330715Sbostic lineno, tp, cp); 86430715Sbostic errors++; 86530715Sbostic } else 86630715Sbostic lp->d_interleave = v; 86730715Sbostic continue; 86830715Sbostic } 86930715Sbostic if (streq(cp, "trackskew")) { 87030715Sbostic v = atoi(tp); 87130715Sbostic if (v < 0) { 87230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 87330715Sbostic lineno, tp, cp); 87430715Sbostic errors++; 87530715Sbostic } else 87630715Sbostic lp->d_trackskew = v; 87730715Sbostic continue; 87830715Sbostic } 87930715Sbostic if (streq(cp, "cylinderskew")) { 88030715Sbostic v = atoi(tp); 88130715Sbostic if (v < 0) { 88230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 88330715Sbostic lineno, tp, cp); 88430715Sbostic errors++; 88530715Sbostic } else 88630715Sbostic lp->d_cylskew = v; 88730715Sbostic continue; 88830715Sbostic } 88930715Sbostic if (streq(cp, "headswitch")) { 89030715Sbostic v = atoi(tp); 89130715Sbostic if (v < 0) { 89230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 89330715Sbostic lineno, tp, cp); 89430715Sbostic errors++; 89530715Sbostic } else 89630715Sbostic lp->d_headswitch = v; 89730715Sbostic continue; 89830715Sbostic } 89930715Sbostic if (streq(cp, "track-to-track seek")) { 90030715Sbostic v = atoi(tp); 90130715Sbostic if (v < 0) { 90230715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 90330715Sbostic lineno, tp, cp); 90430715Sbostic errors++; 90530715Sbostic } else 90630715Sbostic lp->d_trkseek = v; 90730715Sbostic continue; 90830715Sbostic } 90930715Sbostic if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { 91030863Skarels unsigned part = *cp - 'a'; 91130715Sbostic 91230863Skarels if (part > lp->d_npartitions) { 91330715Sbostic fprintf(stderr, 91430715Sbostic "line %d: bad partition name\n", lineno); 91530715Sbostic errors++; 91630715Sbostic continue; 91730715Sbostic } 91830863Skarels pp = &lp->d_partitions[part]; 91930863Skarels #define NXTNUM(n) { \ 92030863Skarels cp = tp, tp = word(cp); \ 92130863Skarels if (tp == NULL) \ 92230863Skarels tp = cp; \ 92330863Skarels (n) = atoi(cp); \ 92430863Skarels } 92530863Skarels 92630863Skarels NXTNUM(v); 92730715Sbostic if (v < 0) { 92830715Sbostic fprintf(stderr, 92930715Sbostic "line %d: %s: bad partition size\n", 93030715Sbostic lineno, cp); 93130715Sbostic errors++; 93230715Sbostic } else 93330863Skarels pp->p_size = v; 93430863Skarels NXTNUM(v); 93530715Sbostic if (v < 0) { 93630715Sbostic fprintf(stderr, 93730715Sbostic "line %d: %s: bad partition offset\n", 93830715Sbostic lineno, cp); 93930715Sbostic errors++; 94030715Sbostic } else 94130863Skarels pp->p_offset = v; 94230715Sbostic cp = tp, tp = word(cp); 94330715Sbostic cpp = fstypenames; 94430715Sbostic for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) 94530715Sbostic if ((s = *cpp) && streq(s, cp)) { 94630863Skarels pp->p_fstype = cpp - fstypenames; 94730863Skarels goto gottype; 94830715Sbostic } 94934032Skarels if (isdigit(*cp)) 95034032Skarels v = atoi(cp); 95134032Skarels else 95234032Skarels v = FSMAXTYPES; 95334032Skarels if ((unsigned)v >= FSMAXTYPES) { 95430715Sbostic fprintf(stderr, "line %d: %s %s\n", lineno, 95530715Sbostic "Warning, unknown filesystem type", cp); 95634032Skarels v = FS_UNUSED; 95734032Skarels } 95830863Skarels pp->p_fstype = v; 95930863Skarels gottype: 96030863Skarels 96130863Skarels switch (pp->p_fstype) { 96230863Skarels 96330863Skarels case FS_UNUSED: /* XXX */ 96430863Skarels NXTNUM(pp->p_fsize); 96530863Skarels if (pp->p_fsize == 0) 96630863Skarels break; 96730863Skarels NXTNUM(v); 96830863Skarels pp->p_frag = v / pp->p_fsize; 96930863Skarels break; 97030863Skarels 97130863Skarels case FS_BSDFFS: 97230863Skarels NXTNUM(pp->p_fsize); 97330863Skarels if (pp->p_fsize == 0) 97430863Skarels break; 97530863Skarels NXTNUM(v); 97630863Skarels pp->p_frag = v / pp->p_fsize; 97730863Skarels NXTNUM(pp->p_cpg); 97830863Skarels break; 97930863Skarels 98030863Skarels default: 98130863Skarels break; 98230863Skarels } 98330715Sbostic continue; 98430715Sbostic } 98530715Sbostic fprintf(stderr, "line %d: %s: Unknown disklabel field\n", 98630715Sbostic lineno, cp); 98730715Sbostic errors++; 98830715Sbostic next: 98930715Sbostic ; 99030715Sbostic } 99130715Sbostic errors += checklabel(lp); 99230715Sbostic return (errors == 0); 99330418Skarels } 99430418Skarels 99530715Sbostic /* 99630715Sbostic * Check disklabel for errors and fill in 99730715Sbostic * derived fields according to supplied values. 99830715Sbostic */ 99930715Sbostic checklabel(lp) 100030715Sbostic register struct disklabel *lp; 100130418Skarels { 100230715Sbostic register struct partition *pp; 100330715Sbostic int i, errors = 0; 100430715Sbostic char part; 100530418Skarels 100630715Sbostic if (lp->d_secsize == 0) { 100730715Sbostic fprintf(stderr, "sector size %d\n", lp->d_secsize); 100830715Sbostic return (1); 100930715Sbostic } 101030715Sbostic if (lp->d_nsectors == 0) { 101130715Sbostic fprintf(stderr, "sectors/track %d\n", lp->d_nsectors); 101230715Sbostic return (1); 101330715Sbostic } 101430715Sbostic if (lp->d_ntracks == 0) { 101530715Sbostic fprintf(stderr, "tracks/cylinder %d\n", lp->d_ntracks); 101630715Sbostic return (1); 101730715Sbostic } 101830715Sbostic if (lp->d_ncylinders == 0) { 101930715Sbostic fprintf(stderr, "cylinders/unit %d\n", lp->d_ncylinders); 102030715Sbostic errors++; 102130715Sbostic } 102230715Sbostic if (lp->d_rpm == 0) 102330715Sbostic Warning("revolutions/minute %d\n", lp->d_rpm); 102430715Sbostic if (lp->d_secpercyl == 0) 102530715Sbostic lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 102630715Sbostic if (lp->d_secperunit == 0) 102730715Sbostic lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; 102830715Sbostic if (lp->d_bbsize == 0) { 102930715Sbostic fprintf(stderr, "boot block size %d\n", lp->d_bbsize); 103030715Sbostic errors++; 103130715Sbostic } else if (lp->d_bbsize % lp->d_secsize) 103230715Sbostic Warning("boot block size %% sector-size != 0\n"); 103330715Sbostic if (lp->d_sbsize == 0) { 103430715Sbostic fprintf(stderr, "super block size %d\n", lp->d_sbsize); 103530715Sbostic errors++; 103630715Sbostic } else if (lp->d_sbsize % lp->d_secsize) 103730715Sbostic Warning("super block size %% sector-size != 0\n"); 103830715Sbostic if (lp->d_npartitions > MAXPARTITIONS) 103930715Sbostic Warning("number of partitions (%d) > MAXPARTITIONS (%d)\n", 104030715Sbostic lp->d_npartitions, MAXPARTITIONS); 104130715Sbostic for (i = 0; i < lp->d_npartitions; i++) { 104230715Sbostic part = 'a' + i; 104330715Sbostic pp = &lp->d_partitions[i]; 104430715Sbostic if (pp->p_size == 0 && pp->p_offset != 0) 104530715Sbostic Warning("partition %c: size 0, but offset %d\n", 104630715Sbostic part, pp->p_offset); 104730715Sbostic #ifdef notdef 104830715Sbostic if (pp->p_size % lp->d_secpercyl) 104930715Sbostic Warning("partition %c: size %% cylinder-size != 0\n", 105030715Sbostic part); 105130715Sbostic if (pp->p_offset % lp->d_secpercyl) 105230715Sbostic Warning("partition %c: offset %% cylinder-size != 0\n", 105330715Sbostic part); 105430715Sbostic #endif 105530715Sbostic if (pp->p_offset > lp->d_secperunit) { 105630715Sbostic fprintf(stderr, 105730715Sbostic "partition %c: offset past end of unit\n", part); 105830715Sbostic errors++; 105930715Sbostic } 106030715Sbostic if (pp->p_offset + pp->p_size > lp->d_secperunit) { 106130715Sbostic fprintf(stderr, 106230715Sbostic "partition %c: partition extends past end of unit\n", 106330715Sbostic part); 106430715Sbostic errors++; 106530715Sbostic } 106630715Sbostic } 106730715Sbostic for (; i < MAXPARTITIONS; i++) { 106830715Sbostic part = 'a' + i; 106930715Sbostic pp = &lp->d_partitions[i]; 107030715Sbostic if (pp->p_size || pp->p_offset) 107130715Sbostic Warning("unused partition %c: size %d offset %d\n", 107234032Skarels 'a' + i, pp->p_size, pp->p_offset); 107330715Sbostic } 107430715Sbostic return (errors); 107530715Sbostic } 107630715Sbostic 107730715Sbostic /*VARARGS1*/ 107830715Sbostic Warning(fmt, a1, a2, a3, a4, a5) 107930715Sbostic char *fmt; 108030715Sbostic { 108130715Sbostic 108230715Sbostic fprintf(stderr, "Warning, "); 108330715Sbostic fprintf(stderr, fmt, a1, a2, a3, a4, a5); 108430715Sbostic fprintf(stderr, "\n"); 108530715Sbostic } 108630715Sbostic 108730715Sbostic Perror(str) 108830715Sbostic char *str; 108930715Sbostic { 109030715Sbostic fputs("disklabel: ", stderr); perror(str); 109130418Skarels exit(4); 109230418Skarels } 109330715Sbostic 109430715Sbostic usage() 109530715Sbostic { 109630715Sbostic #ifdef BOOT 109734032Skarels fprintf(stderr, "%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n", 109830715Sbostic "usage: disklabel [-r] disk", "(to read label)", 109930715Sbostic "or disklabel -w [-r] disk type [ packid ] [ xxboot bootxx ]", "(to write label)", 110030715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 110134032Skarels "or disklabel -R [-r] disk protofile [ type | xxboot bootxx ]", "(to restore label)", 110234032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 110330715Sbostic #else 110434032Skarels fprintf(stderr, "%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n", 110530715Sbostic "usage: disklabel [-r] disk", "(to read label)", 110630715Sbostic "or disklabel -w [-r] disk type [ packid ]", "(to write label)", 110730715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 110834032Skarels "or disklabel -R [-r] disk protofile", "(to restore label)", 110934032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 111030715Sbostic #endif 111130715Sbostic exit(1); 111230715Sbostic } 1113