130715Sbostic /* 2*35983Sbostic * Copyright (c) 1987 The Regents of the University of California. 3*35983Sbostic * All rights reserved. 4*35983Sbostic * 5*35983Sbostic * This code is derived from software contributed to Berkeley by 6*35983Sbostic * Symmetric Computer Systems. 7*35983Sbostic * 8*35983Sbostic * Redistribution and use in source and binary forms are permitted 9*35983Sbostic * provided that the above copyright notice and this paragraph are 10*35983Sbostic * duplicated in all such forms and that any documentation, 11*35983Sbostic * advertising materials, and other materials related to such 12*35983Sbostic * distribution and use acknowledge that the software was developed 13*35983Sbostic * by the University of California, Berkeley. The name of the 14*35983Sbostic * University may not be used to endorse or promote products derived 15*35983Sbostic * from this software without specific prior written permission. 16*35983Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*35983Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*35983Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1930715Sbostic */ 2030715Sbostic 2130418Skarels #ifndef lint 22*35983Sbostic char copyright[] = 23*35983Sbostic "@(#) Copyright (c) 1987 The Regents of the University of California.\n\ 24*35983Sbostic All rights reserved.\n"; 25*35983Sbostic #endif /* not lint */ 26*35983Sbostic 27*35983Sbostic #ifndef lint 28*35983Sbostic static char sccsid[] = "@(#)disklabel.c 5.14 (Berkeley) 10/21/88"; 2930418Skarels /* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */ 30*35983Sbostic #endif /* not lint */ 3130418Skarels 3230418Skarels #include <stdio.h> 3330418Skarels #include <ctype.h> 3430418Skarels #include <sys/param.h> 3530715Sbostic #include <sys/signal.h> 3630418Skarels #include <sys/errno.h> 3730418Skarels #include <sys/file.h> 3830715Sbostic #include <sys/ioctl.h> 3930677Skarels #include <sys/fs.h> 4030715Sbostic #include <strings.h> 4130418Skarels #define DKTYPENAMES 4230418Skarels #include <sys/disklabel.h> 4330418Skarels 4430418Skarels /* 4530418Skarels * Disklabel: read and write disklabels. 4630418Skarels * The label is usually placed on one of the first sectors of the disk. 4730418Skarels * Many machines (VAX 11/750) also place a bootstrap in the same area, 4830418Skarels * in which case the label is embedded in the bootstrap. 4930418Skarels * The bootstrap source must leave space at the proper offset 5030418Skarels * for the label on such machines. 5130418Skarels */ 5230418Skarels 5330677Skarels #ifdef vax 5430677Skarels #define RAWPARTITION 'c' 5530677Skarels #else 5630677Skarels #define RAWPARTITION 'a' 5730677Skarels #endif 5830677Skarels 5930677Skarels #ifndef BBSIZE 6030418Skarels #define BBSIZE 8192 /* size of boot area, with label */ 6130677Skarels #endif 6230418Skarels 6330418Skarels #ifdef vax 6430418Skarels #define BOOT /* also have bootstrap in "boot area" */ 6530418Skarels #define BOOTDIR "/usr/mdec" /* source of boot binaries */ 6630677Skarels #else 6730677Skarels #ifdef lint 6830677Skarels #define BOOT 6930418Skarels #endif 7030677Skarels #endif 7130418Skarels 7230715Sbostic #define DEFEDITOR "/usr/ucb/vi" 7330715Sbostic #define streq(a,b) (strcmp(a,b) == 0) 7430715Sbostic 7530715Sbostic #ifdef BOOT 7630418Skarels char *xxboot; 7730418Skarels char *bootxx; 7830715Sbostic #endif 7931617Skarels 8031617Skarels char *dkname; 8130418Skarels char *specname; 8230715Sbostic char tmpfil[] = "/tmp/EdDk.aXXXXXX"; 8330418Skarels 8430418Skarels extern int errno; 8530418Skarels char namebuf[BBSIZE], *np = namebuf; 8631617Skarels struct disklabel lab; 8731617Skarels struct disklabel *readlabel(), *makebootarea(); 8830418Skarels char bootarea[BBSIZE]; 8934032Skarels char boot0[MAXPATHLEN]; 9034032Skarels char boot1[MAXPATHLEN]; 9130418Skarels 9234032Skarels enum { UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE } op = UNSPEC; 9330418Skarels 9430677Skarels int rflag; 9530677Skarels 9634032Skarels #ifdef DEBUG 9734032Skarels int debug; 9834032Skarels #endif 9934032Skarels 10030418Skarels main(argc, argv) 10130418Skarels int argc; 10230418Skarels char *argv[]; 10330418Skarels { 10434032Skarels extern int optind; 10530418Skarels register struct disklabel *lp; 10634032Skarels FILE *t; 10734641Skarels int ch, f, error = 0; 10830715Sbostic char *name = 0, *type; 10930418Skarels 11034032Skarels while ((ch = getopt(argc, argv, "NRWerw")) != EOF) 11134032Skarels switch (ch) { 11234032Skarels case 'N': 11334032Skarels if (op != UNSPEC) 11434032Skarels usage(); 11534032Skarels op = NOWRITE; 11634032Skarels break; 11730715Sbostic case 'R': 11834032Skarels if (op != UNSPEC) 11934032Skarels usage(); 12030715Sbostic op = RESTORE; 12130715Sbostic break; 12234032Skarels case 'W': 12334032Skarels if (op != UNSPEC) 12434032Skarels usage(); 12534032Skarels op = WRITEABLE; 12634032Skarels break; 12730715Sbostic case 'e': 12834032Skarels if (op != UNSPEC) 12934032Skarels usage(); 13030715Sbostic op = EDIT; 13130715Sbostic break; 13230715Sbostic case 'r': 13330715Sbostic ++rflag; 13430715Sbostic break; 13530715Sbostic case 'w': 13634032Skarels if (op != UNSPEC) 13734032Skarels usage(); 13830715Sbostic op = WRITE; 13930715Sbostic break; 14034032Skarels #ifdef DEBUG 14134032Skarels case 'd': 14234032Skarels debug++; 14334032Skarels break; 14434032Skarels #endif 14530715Sbostic case '?': 14630715Sbostic default: 14730715Sbostic usage(); 14830715Sbostic } 14930715Sbostic argc -= optind; 15030715Sbostic argv += optind; 15134032Skarels if (op == UNSPEC) 15234032Skarels op = READ; 15330715Sbostic if (argc < 1) 15430715Sbostic usage(); 15530715Sbostic 15630715Sbostic dkname = argv[0]; 15730418Skarels if (dkname[0] != '/') { 15832439Sbostic (void)sprintf(np, "/dev/r%s%c", dkname, RAWPARTITION); 15930418Skarels specname = np; 16030418Skarels np += strlen(specname) + 1; 16130418Skarels } else 16230418Skarels specname = dkname; 16330418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 16430418Skarels if (f < 0 && errno == ENOENT && dkname[0] != '/') { 16532439Sbostic (void)sprintf(specname, "/dev/r%s", dkname); 16630418Skarels np = namebuf + strlen(specname) + 1; 16730418Skarels f = open(specname, op == READ ? O_RDONLY : O_RDWR); 16830418Skarels } 16930418Skarels if (f < 0) 17030418Skarels Perror(specname); 17130418Skarels 17230715Sbostic switch(op) { 17330715Sbostic case EDIT: 17430715Sbostic if (argc != 1) 17530715Sbostic usage(); 17634032Skarels lp = readlabel(f); 17734641Skarels error = edit(lp, f); 17830715Sbostic break; 17934032Skarels case NOWRITE: { 18034032Skarels int flag = 0; 18134032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 18234032Skarels Perror("ioctl DIOCWLABEL"); 18334032Skarels break; 18434032Skarels } 18530418Skarels case READ: 18630715Sbostic if (argc != 1) 18730715Sbostic usage(); 18834032Skarels lp = readlabel(f); 18930418Skarels display(stdout, lp); 19034641Skarels error = checklabel(lp); 19130418Skarels break; 19230715Sbostic case RESTORE: 19330715Sbostic #ifdef BOOT 19434032Skarels if (rflag) { 19534032Skarels if (argc == 4) { /* [ priboot secboot ] */ 19634032Skarels xxboot = argv[2]; 19734032Skarels bootxx = argv[3]; 19834032Skarels lab.d_secsize = DEV_BSIZE; /* XXX */ 19934032Skarels lab.d_bbsize = BBSIZE; /* XXX */ 20034032Skarels } 20134032Skarels else if (argc == 3) /* [ disktype ] */ 20234032Skarels makelabel(argv[2], (char *)NULL, &lab); 20334032Skarels else { 20434032Skarels fprintf(stderr, 20534032Skarels "Must specify either disktype or bootfiles with -r flag of RESTORE option\n"); 20634032Skarels exit(1); 20734032Skarels } 20834032Skarels } 20934032Skarels else 21031617Skarels #endif 21130715Sbostic if (argc != 2) 21230715Sbostic usage(); 21331617Skarels lp = makebootarea(bootarea, &lab); 21430715Sbostic if (!(t = fopen(argv[1],"r"))) 21530715Sbostic Perror(argv[1]); 21630715Sbostic if (getasciilabel(t, lp)) 21734641Skarels error = writelabel(f, bootarea, lp); 21830418Skarels break; 21930418Skarels case WRITE: 22030715Sbostic type = argv[1]; 22130715Sbostic #ifdef BOOT 22230715Sbostic if (argc > 5 || argc < 2) 22330715Sbostic usage(); 22430715Sbostic if (argc > 3) { 22530715Sbostic bootxx = argv[--argc]; 22630715Sbostic xxboot = argv[--argc]; 22730715Sbostic } 22830715Sbostic #else 22930715Sbostic if (argc > 3 || argc < 2) 23030715Sbostic usage(); 23130715Sbostic #endif 23230715Sbostic if (argc > 2) 23330715Sbostic name = argv[--argc]; 23430418Skarels makelabel(type, name, &lab); 23531617Skarels lp = makebootarea(bootarea, &lab); 23630418Skarels *lp = lab; 23730715Sbostic if (checklabel(lp) == 0) 23834641Skarels error = writelabel(f, bootarea, lp); 23930418Skarels break; 24034032Skarels case WRITEABLE: { 24134032Skarels int flag = 1; 24234032Skarels if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) 24334032Skarels Perror("ioctl DIOCWLABEL"); 24434032Skarels break; 24530418Skarels } 24634032Skarels } 24734641Skarels exit(error); 24830418Skarels } 24930418Skarels 25034032Skarels /* 25134032Skarels * Construct a prototype disklabel from /etc/disktab. As a side 25234032Skarels * effect, set the names of the primary and secondary boot files 25334032Skarels * if specified. 25434032Skarels */ 25530418Skarels makelabel(type, name, lp) 25630418Skarels char *type, *name; 25730418Skarels register struct disklabel *lp; 25830418Skarels { 25930418Skarels register struct disklabel *dp; 26034032Skarels char *strcpy(); 26130418Skarels 26230418Skarels dp = getdiskbyname(type); 26330418Skarels if (dp == NULL) { 26430418Skarels fprintf(stderr, "%s: unknown disk type\n", type); 26530418Skarels exit(1); 26630418Skarels } 26730418Skarels *lp = *dp; 26834032Skarels #ifdef BOOT 26934032Skarels /* 27034032Skarels * Check if disktab specifies the bootstraps (b0 or b1). 27134032Skarels */ 27234032Skarels if (!xxboot && lp->d_boot0) { 27334032Skarels if (*lp->d_boot0 != '/') 27434032Skarels (void)sprintf(boot0, "%s/%s", BOOTDIR, lp->d_boot0); 27534032Skarels else 27634032Skarels (void)strcpy(boot0, lp->d_boot0); 27734032Skarels xxboot = boot0; 27834032Skarels } 27934032Skarels if (!bootxx && lp->d_boot1) { 28034032Skarels if (*lp->d_boot1 != '/') 28134032Skarels (void)sprintf(boot1, "%s/%s", BOOTDIR, lp->d_boot1); 28234032Skarels else 28334032Skarels (void)strcpy(boot1, lp->d_boot1); 28434032Skarels bootxx = boot1; 28534032Skarels } 28634032Skarels /* 28734032Skarels * If bootstraps not specified anywhere, makebootarea() 28834032Skarels * will choose ones based on the name of the disk special 28934032Skarels * file. E.g. /dev/ra0 -> raboot, bootra 29034032Skarels */ 29134032Skarels #endif /*BOOT*/ 29234032Skarels /* d_packname is union d_boot[01], so zero */ 29334032Skarels bzero(lp->d_packname, sizeof(lp->d_packname)); 29430418Skarels if (name) 29534032Skarels (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname)); 29630418Skarels } 29730418Skarels 29830418Skarels writelabel(f, boot, lp) 29930418Skarels int f; 30030418Skarels char *boot; 30130418Skarels register struct disklabel *lp; 30230418Skarels { 30330715Sbostic register int i; 30434032Skarels int flag; 30534032Skarels off_t lseek(); 30630418Skarels 30730418Skarels lp->d_magic = DISKMAGIC; 30830418Skarels lp->d_magic2 = DISKMAGIC; 30930418Skarels lp->d_checksum = 0; 31030418Skarels lp->d_checksum = dkcksum(lp); 31130677Skarels if (rflag) { 31234032Skarels /* 31334032Skarels * First set the kernel disk label, 31434032Skarels * then write a label to the raw disk. 31534032Skarels * If the SDINFO ioctl fails because it is unimplemented, 31634032Skarels * keep going; otherwise, the kernel consistency checks 31734032Skarels * may prevent us from changing the current (in-core) 31834032Skarels * label. 31934032Skarels */ 32034032Skarels if (ioctl(f, DIOCSDINFO, lp) < 0 && 32134641Skarels errno != ENODEV && errno != ENOTTY) { 32234641Skarels l_perror("ioctl DIOCSDINFO"); 32334641Skarels return (1); 32434641Skarels } 32531617Skarels (void)lseek(f, (off_t)0, L_SET); 32634032Skarels /* 32734032Skarels * write enable label sector before write (if necessary), 32834032Skarels * disable after writing. 32934032Skarels */ 33034032Skarels flag = 1; 33134032Skarels if (ioctl(f, DIOCWLABEL, &flag) < 0) 33234032Skarels perror("ioctl DIOCWLABEL"); 33334641Skarels if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { 33434641Skarels perror("write"); 33534641Skarels return (1); 33634641Skarels } 33734032Skarels flag = 0; 33834032Skarels (void) ioctl(f, DIOCWLABEL, &flag); 33934641Skarels } else if (ioctl(f, DIOCWDINFO, lp) < 0) { 34034641Skarels l_perror("ioctl DIOCWDINFO"); 34134641Skarels return (1); 34234641Skarels } 34334032Skarels #ifdef vax 34430677Skarels if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { 34530677Skarels daddr_t alt; 34630677Skarels 34730677Skarels alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; 34830677Skarels for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { 34930715Sbostic (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), L_SET); 35030677Skarels if (write(f, boot, lp->d_secsize) < lp->d_secsize) { 35130677Skarels int oerrno = errno; 35230677Skarels fprintf(stderr, "alternate label %d ", i/2); 35330677Skarels errno = oerrno; 35430677Skarels perror("write"); 35530677Skarels } 35630418Skarels } 35730418Skarels } 35830419Skarels #endif 35934641Skarels return (0); 36030418Skarels } 36130418Skarels 36234641Skarels l_perror(s) 36334641Skarels char *s; 36434641Skarels { 36534641Skarels int saverrno = errno; 36634641Skarels 36734641Skarels fprintf(stderr, "disklabel: %s: ", s); 36834641Skarels 36934641Skarels switch (saverrno) { 37034641Skarels 37134641Skarels case ESRCH: 37234641Skarels fprintf(stderr, "No disk label on disk;\n"); 37334641Skarels fprintf(stderr, 37434641Skarels "use \"disklabel -r\" to install initial label\n"); 37534641Skarels break; 37634641Skarels 37734641Skarels case EINVAL: 37834641Skarels fprintf(stderr, "Label magic number or checksum is wrong!\n"); 37934641Skarels fprintf(stderr, "(disklabel or kernel is out of date?)\n"); 38034641Skarels break; 38134641Skarels 38234641Skarels case EBUSY: 38334641Skarels fprintf(stderr, "Open partition would move or shrink\n"); 38434641Skarels break; 38534641Skarels 38634641Skarels case EXDEV: 38734641Skarels fprintf(stderr, 38834641Skarels "Labeled partition or 'a' partition must start at beginning of disk\n"); 38934641Skarels break; 39034641Skarels 39134641Skarels default: 39234641Skarels errno = saverrno; 39334641Skarels perror((char *)NULL); 39434641Skarels break; 39534641Skarels } 39634641Skarels } 39734641Skarels 39830418Skarels /* 39931617Skarels * Fetch disklabel for disk. 40031617Skarels * Use ioctl to get label unless -r flag is given. 40130418Skarels */ 40230418Skarels struct disklabel * 40334032Skarels readlabel(f) 40434032Skarels int f; 40530418Skarels { 40630418Skarels register struct disklabel *lp; 40730418Skarels 40834032Skarels if (rflag) { 40931617Skarels if (read(f, bootarea, BBSIZE) < BBSIZE) 41031401Skarels Perror(specname); 41131617Skarels for (lp = (struct disklabel *)bootarea; 41231617Skarels lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); 41330677Skarels lp = (struct disklabel *)((char *)lp + 16)) 41430677Skarels if (lp->d_magic == DISKMAGIC && 41530677Skarels lp->d_magic2 == DISKMAGIC) 41630677Skarels break; 41731617Skarels if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || 41830677Skarels lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || 41930677Skarels dkcksum(lp) != 0) { 42030677Skarels fprintf(stderr, 42130418Skarels "Bad pack magic number (label is damaged, or pack is unlabeled)\n"); 42234032Skarels /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */ 42334032Skarels exit (1); 42430677Skarels } 42534032Skarels } else { 42634032Skarels lp = &lab; 42734032Skarels if (ioctl(f, DIOCGDINFO, lp) < 0) 42834032Skarels Perror("ioctl DIOCGDINFO"); 42930418Skarels } 43030418Skarels return (lp); 43130418Skarels } 43230418Skarels 43330418Skarels struct disklabel * 43431617Skarels makebootarea(boot, dp) 43530418Skarels char *boot; 43630418Skarels register struct disklabel *dp; 43730418Skarels { 43830418Skarels struct disklabel *lp; 43930418Skarels register char *p; 44030418Skarels int b; 44130418Skarels #ifdef BOOT 44230715Sbostic char *dkbasename; 44334032Skarels #endif /*BOOT*/ 44430715Sbostic 44534032Skarels lp = (struct disklabel *)(boot + (LABELSECTOR * dp->d_secsize) + 44634032Skarels LABELOFFSET); 44734032Skarels #ifdef BOOT 44834032Skarels if (!rflag) 44934032Skarels return (lp); 45034032Skarels 45134032Skarels if (xxboot == NULL || bootxx == NULL) { 45230418Skarels dkbasename = np; 45330418Skarels if ((p = rindex(dkname, '/')) == NULL) 45430418Skarels p = dkname; 45530418Skarels else 45630418Skarels p++; 45730418Skarels while (*p && !isdigit(*p)) 45830418Skarels *np++ = *p++; 45930418Skarels *np++ = '\0'; 46030418Skarels 46134032Skarels if (xxboot == NULL) { 46234032Skarels (void)sprintf(np, "%s/%sboot", BOOTDIR, dkbasename); 46334032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 46434032Skarels dkbasename++; 46534032Skarels xxboot = np; 46634032Skarels (void)sprintf(xxboot, "%s/%sboot", BOOTDIR, dkbasename); 46734032Skarels np += strlen(xxboot) + 1; 46834032Skarels } 46934032Skarels if (bootxx == NULL) { 47034032Skarels (void)sprintf(np, "%s/boot%s", BOOTDIR, dkbasename); 47134032Skarels if (access(np, F_OK) < 0 && dkbasename[0] == 'r') 47234032Skarels dkbasename++; 47334032Skarels bootxx = np; 47434032Skarels (void)sprintf(bootxx, "%s/boot%s", BOOTDIR, dkbasename); 47534032Skarels np += strlen(bootxx) + 1; 47634032Skarels } 47730418Skarels } 47834032Skarels #ifdef DEBUG 47934032Skarels if (debug) 48034032Skarels fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n", 48134032Skarels xxboot, bootxx); 48234032Skarels #endif 48330418Skarels 48430418Skarels b = open(xxboot, O_RDONLY); 48530418Skarels if (b < 0) 48630418Skarels Perror(xxboot); 48730715Sbostic if (read(b, boot, (int)dp->d_secsize) < 0) 48830418Skarels Perror(xxboot); 48930418Skarels close(b); 49030418Skarels b = open(bootxx, O_RDONLY); 49130418Skarels if (b < 0) 49230418Skarels Perror(bootxx); 49330715Sbostic if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0) 49430418Skarels Perror(bootxx); 49530715Sbostic (void)close(b); 49634032Skarels #endif /*BOOT*/ 49730418Skarels 49830418Skarels for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) 49930418Skarels if (*p) { 50030418Skarels fprintf(stderr, 50130418Skarels "Bootstrap doesn't leave room for disk label\n"); 50230418Skarels exit(2); 50330418Skarels } 50430418Skarels return (lp); 50530418Skarels } 50630418Skarels 50730418Skarels display(f, lp) 50830418Skarels FILE *f; 50930418Skarels register struct disklabel *lp; 51030418Skarels { 51130715Sbostic register int i, j; 51230418Skarels register struct partition *pp; 51330418Skarels 51430418Skarels fprintf(f, "# %s:\n", specname); 51530418Skarels if ((unsigned) lp->d_type < DKMAXTYPES) 51630418Skarels fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 51730418Skarels else 51830418Skarels fprintf(f, "type: %d\n", lp->d_type); 51930418Skarels fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename); 52034032Skarels fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname); 52131401Skarels fprintf(f, "flags:"); 52230418Skarels if (lp->d_flags & D_REMOVABLE) 52331401Skarels fprintf(f, " removeable"); 52430418Skarels if (lp->d_flags & D_ECC) 52531401Skarels fprintf(f, " ecc"); 52630418Skarels if (lp->d_flags & D_BADSECT) 52731401Skarels fprintf(f, " badsect"); 52830418Skarels fprintf(f, "\n"); 52930418Skarels fprintf(f, "bytes/sector: %d\n", lp->d_secsize); 53030418Skarels fprintf(f, "sectors/track: %d\n", lp->d_nsectors); 53130418Skarels fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks); 53231386Skarels fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl); 53330418Skarels fprintf(f, "cylinders: %d\n", lp->d_ncylinders); 53430715Sbostic fprintf(f, "rpm: %d\n", lp->d_rpm); 53530418Skarels fprintf(f, "interleave: %d\n", lp->d_interleave); 53630418Skarels fprintf(f, "trackskew: %d\n", lp->d_trackskew); 53730418Skarels fprintf(f, "cylinderskew: %d\n", lp->d_cylskew); 53830418Skarels fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); 53930418Skarels fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); 54030418Skarels fprintf(f, "drivedata: "); 54130418Skarels for (i = NDDATA - 1; i >= 0; i--) 54230418Skarels if (lp->d_drivedata[i]) 54330418Skarels break; 54430418Skarels if (i < 0) 54530418Skarels i = 0; 54630418Skarels for (j = 0; j <= i; j++) 54730418Skarels fprintf(f, "%d ", lp->d_drivedata[j]); 54830418Skarels fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions); 54930863Skarels fprintf(f, 55030863Skarels "# size offset fstype [fsize bsize cpg]\n"); 55130418Skarels pp = lp->d_partitions; 55230418Skarels for (i = 0; i < lp->d_npartitions; i++, pp++) { 55330418Skarels if (pp->p_size) { 55430863Skarels fprintf(f, " %c: %8d %8d ", 'a' + i, 55530863Skarels pp->p_size, pp->p_offset); 55630418Skarels if ((unsigned) pp->p_fstype < FSMAXTYPES) 55730418Skarels fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 55830418Skarels else 55930418Skarels fprintf(f, "%8d", pp->p_fstype); 56030863Skarels switch (pp->p_fstype) { 56130863Skarels 56230863Skarels case FS_UNUSED: /* XXX */ 56330863Skarels fprintf(f, " %5d %5d %5.5s ", 56430863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, ""); 56530863Skarels break; 56630863Skarels 56730863Skarels case FS_BSDFFS: 56830863Skarels fprintf(f, " %5d %5d %5d ", 56930863Skarels pp->p_fsize, pp->p_fsize * pp->p_frag, 57030863Skarels pp->p_cpg); 57130863Skarels break; 57230863Skarels 57330863Skarels default: 57430863Skarels fprintf(f, "%20.20s", ""); 57530863Skarels break; 57630863Skarels } 57730418Skarels fprintf(f, "\t# (Cyl. %4d", 57830418Skarels pp->p_offset / lp->d_secpercyl); 57930418Skarels if (pp->p_offset % lp->d_secpercyl) 58030418Skarels putc('*', f); 58130418Skarels else 58230418Skarels putc(' ', f); 58330418Skarels fprintf(f, "- %d", 58430418Skarels (pp->p_offset + 58530418Skarels pp->p_size + lp->d_secpercyl - 1) / 58630418Skarels lp->d_secpercyl - 1); 58730418Skarels if (pp->p_size % lp->d_secpercyl) 58830418Skarels putc('*', f); 58930863Skarels fprintf(f, ")\n"); 59030418Skarels } 59130418Skarels } 59232121Stef fflush(f); 59330418Skarels } 59430418Skarels 59534641Skarels edit(lp, f) 59630715Sbostic struct disklabel *lp; 59734641Skarels int f; 59830418Skarels { 59930715Sbostic register int c; 60030715Sbostic struct disklabel label; 60130715Sbostic FILE *fd; 60230715Sbostic char *mktemp(); 60330715Sbostic 60430715Sbostic (void) mktemp(tmpfil); 60530715Sbostic fd = fopen(tmpfil, "w"); 60630715Sbostic if (fd == NULL) { 60730715Sbostic fprintf(stderr, "%s: Can't create\n", tmpfil); 60834641Skarels return (1); 60930715Sbostic } 61030715Sbostic (void)fchmod(fd, 0600); 61130715Sbostic display(fd, lp); 61230715Sbostic fclose(fd); 61330715Sbostic for (;;) { 61430715Sbostic if (!editit()) 61530715Sbostic break; 61630715Sbostic fd = fopen(tmpfil, "r"); 61730715Sbostic if (fd == NULL) { 61834032Skarels fprintf(stderr, "%s: Can't reopen for reading\n", 61934032Skarels tmpfil); 62030715Sbostic break; 62130715Sbostic } 62230863Skarels bzero((char *)&label, sizeof(label)); 62330715Sbostic if (getasciilabel(fd, &label)) { 62430715Sbostic *lp = label; 62534641Skarels if (writelabel(f, bootarea, lp) == 0) { 62634641Skarels (void) unlink(tmpfil); 62734641Skarels return (0); 62834641Skarels } 62930715Sbostic } 63030715Sbostic printf("re-edit the label? [y]: "); fflush(stdout); 63130715Sbostic c = getchar(); 63230715Sbostic if (c != EOF && c != (int)'\n') 63330715Sbostic while (getchar() != (int)'\n') 63430715Sbostic ; 63530715Sbostic if (c == (int)'n') 63630715Sbostic break; 63730715Sbostic } 63830715Sbostic (void) unlink(tmpfil); 63934641Skarels return (1); 64030418Skarels } 64130418Skarels 64230715Sbostic editit() 64330715Sbostic { 64430715Sbostic register int pid, xpid; 64530715Sbostic int stat, omask; 64630715Sbostic extern char *getenv(); 64730418Skarels 64830715Sbostic omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 64930715Sbostic while ((pid = fork()) < 0) { 65030715Sbostic extern int errno; 65130715Sbostic 65230715Sbostic if (errno == EPROCLIM) { 65330715Sbostic fprintf(stderr, "You have too many processes\n"); 65430715Sbostic return(0); 65530715Sbostic } 65630715Sbostic if (errno != EAGAIN) { 65730715Sbostic perror("fork"); 65830715Sbostic return(0); 65930715Sbostic } 66030715Sbostic sleep(1); 66130715Sbostic } 66230715Sbostic if (pid == 0) { 66330715Sbostic register char *ed; 66430715Sbostic 66530715Sbostic sigsetmask(omask); 66630715Sbostic setgid(getgid()); 66730715Sbostic setuid(getuid()); 66830715Sbostic if ((ed = getenv("EDITOR")) == (char *)0) 66930715Sbostic ed = DEFEDITOR; 67030715Sbostic execlp(ed, ed, tmpfil, 0); 67130715Sbostic perror(ed); 67230715Sbostic exit(1); 67330715Sbostic } 67430715Sbostic while ((xpid = wait(&stat)) >= 0) 67530715Sbostic if (xpid == pid) 67630715Sbostic break; 67730715Sbostic sigsetmask(omask); 67830715Sbostic return(!stat); 67930715Sbostic } 68030715Sbostic 68130715Sbostic char * 68230715Sbostic skip(cp) 68330715Sbostic register char *cp; 68430715Sbostic { 68530715Sbostic 68630715Sbostic while (*cp != '\0' && isspace(*cp)) 68730715Sbostic cp++; 68830715Sbostic if (*cp == '\0' || *cp == '#') 68930715Sbostic return ((char *)NULL); 69030715Sbostic return (cp); 69130715Sbostic } 69230715Sbostic 69330715Sbostic char * 69430715Sbostic word(cp) 69530715Sbostic register char *cp; 69630715Sbostic { 69730715Sbostic register char c; 69830715Sbostic 69931401Skarels while (*cp != '\0' && !isspace(*cp) && *cp != '#') 70031401Skarels cp++; 70130715Sbostic if ((c = *cp) != '\0') { 70230715Sbostic *cp++ = '\0'; 70330715Sbostic if (c != '#') 70430715Sbostic return (skip(cp)); 70530715Sbostic } 70630715Sbostic return ((char *)NULL); 70730715Sbostic } 70830715Sbostic 70930418Skarels /* 71030418Skarels * Read an ascii label in from fd f, 71130418Skarels * in the same format as that put out by display(), 71230418Skarels * and fill in lp. 71330418Skarels */ 71430418Skarels getasciilabel(f, lp) 71530715Sbostic FILE *f; 71630418Skarels register struct disklabel *lp; 71730418Skarels { 71830715Sbostic register char **cpp, *cp; 71930863Skarels register struct partition *pp; 72030715Sbostic char *tp, *s, line[BUFSIZ]; 72130715Sbostic int v, lineno = 0, errors = 0; 72230715Sbostic 72330715Sbostic lp->d_bbsize = BBSIZE; /* XXX */ 72430715Sbostic lp->d_sbsize = SBSIZE; /* XXX */ 72530715Sbostic while (fgets(line, sizeof(line) - 1, f)) { 72630715Sbostic lineno++; 72730715Sbostic if (cp = index(line,'\n')) 72830715Sbostic *cp = '\0'; 72930715Sbostic cp = skip(line); 73030715Sbostic if (cp == NULL) 73130715Sbostic continue; 73230715Sbostic tp = index(cp, ':'); 73330715Sbostic if (tp == NULL) { 73430715Sbostic fprintf(stderr, "line %d: syntax error\n", lineno); 73530715Sbostic errors++; 73630715Sbostic continue; 73730715Sbostic } 73830715Sbostic *tp++ = '\0', tp = skip(tp); 73930715Sbostic if (streq(cp, "type")) { 74030715Sbostic if (tp == NULL) 74130715Sbostic tp = "unknown"; 74230715Sbostic cpp = dktypenames; 74330715Sbostic for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) 74430715Sbostic if ((s = *cpp) && streq(s, tp)) { 74530715Sbostic lp->d_type = cpp - dktypenames; 74630715Sbostic goto next; 74730715Sbostic } 74830715Sbostic v = atoi(tp); 74930715Sbostic if ((unsigned)v >= DKMAXTYPES) 75030715Sbostic fprintf(stderr, "line %d:%s %d\n", lineno, 75130715Sbostic "Warning, unknown disk type", v); 75230715Sbostic lp->d_type = v; 75330715Sbostic continue; 75430715Sbostic } 75530715Sbostic if (streq(cp, "flags")) { 75634032Skarels for (v = 0; (cp = tp) && *cp != '\0';) { 75734032Skarels tp = word(cp); 75830715Sbostic if (streq(cp, "removeable")) 75930715Sbostic v |= D_REMOVABLE; 76030715Sbostic else if (streq(cp, "ecc")) 76130715Sbostic v |= D_ECC; 76230715Sbostic else if (streq(cp, "badsect")) 76330715Sbostic v |= D_BADSECT; 76430715Sbostic else { 76530715Sbostic fprintf(stderr, 76630715Sbostic "line %d: %s: bad flag\n", 76730715Sbostic lineno, cp); 76830715Sbostic errors++; 76930715Sbostic } 77030715Sbostic } 77130715Sbostic lp->d_flags = v; 77230715Sbostic continue; 77330715Sbostic } 77430715Sbostic if (streq(cp, "drivedata")) { 77530715Sbostic register int i; 77630715Sbostic 77731386Skarels for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { 77830715Sbostic lp->d_drivedata[i++] = atoi(cp); 77931386Skarels tp = word(cp); 78030715Sbostic } 78130715Sbostic continue; 78230715Sbostic } 78330715Sbostic if (sscanf(cp, "%d partitions", &v) == 1) { 78430863Skarels if (v == 0 || (unsigned)v > MAXPARTITIONS) { 78530715Sbostic fprintf(stderr, 78630715Sbostic "line %d: bad # of partitions\n", lineno); 78730863Skarels lp->d_npartitions = MAXPARTITIONS; 78830863Skarels errors++; 78930863Skarels } else 79030715Sbostic lp->d_npartitions = v; 79130715Sbostic continue; 79230715Sbostic } 79330715Sbostic if (tp == NULL) 79430715Sbostic tp = ""; 79530715Sbostic if (streq(cp, "disk")) { 79630715Sbostic strncpy(lp->d_typename, tp, sizeof (lp->d_typename)); 79730715Sbostic continue; 79830715Sbostic } 79930715Sbostic if (streq(cp, "label")) { 80034032Skarels strncpy(lp->d_packname, tp, sizeof (lp->d_packname)); 80130715Sbostic continue; 80230715Sbostic } 80330715Sbostic if (streq(cp, "bytes/sector")) { 80430715Sbostic v = atoi(tp); 80530715Sbostic if (v <= 0 || (v % 512) != 0) { 80630715Sbostic fprintf(stderr, 80730715Sbostic "line %d: %s: bad sector size\n", 80830715Sbostic lineno, tp); 80930715Sbostic errors++; 81030715Sbostic } else 81130715Sbostic lp->d_secsize = v; 81230715Sbostic continue; 81330715Sbostic } 81430715Sbostic if (streq(cp, "sectors/track")) { 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_nsectors = v; 82230715Sbostic continue; 82330715Sbostic } 82431386Skarels if (streq(cp, "sectors/cylinder")) { 82531386Skarels v = atoi(tp); 82631386Skarels if (v <= 0) { 82731386Skarels fprintf(stderr, "line %d: %s: bad %s\n", 82831386Skarels lineno, tp, cp); 82931386Skarels errors++; 83031386Skarels } else 83131386Skarels lp->d_secpercyl = v; 83231386Skarels continue; 83331386Skarels } 83430715Sbostic if (streq(cp, "tracks/cylinder")) { 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_ntracks = v; 84230715Sbostic continue; 84330715Sbostic } 84430715Sbostic if (streq(cp, "cylinders")) { 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_ncylinders = v; 85230715Sbostic continue; 85330715Sbostic } 85430715Sbostic if (streq(cp, "rpm")) { 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_rpm = v; 86230715Sbostic continue; 86330715Sbostic } 86430715Sbostic if (streq(cp, "interleave")) { 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_interleave = v; 87230715Sbostic continue; 87330715Sbostic } 87430715Sbostic if (streq(cp, "trackskew")) { 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_trackskew = v; 88230715Sbostic continue; 88330715Sbostic } 88430715Sbostic if (streq(cp, "cylinderskew")) { 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_cylskew = v; 89230715Sbostic continue; 89330715Sbostic } 89430715Sbostic if (streq(cp, "headswitch")) { 89530715Sbostic v = atoi(tp); 89630715Sbostic if (v < 0) { 89730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 89830715Sbostic lineno, tp, cp); 89930715Sbostic errors++; 90030715Sbostic } else 90130715Sbostic lp->d_headswitch = v; 90230715Sbostic continue; 90330715Sbostic } 90430715Sbostic if (streq(cp, "track-to-track seek")) { 90530715Sbostic v = atoi(tp); 90630715Sbostic if (v < 0) { 90730715Sbostic fprintf(stderr, "line %d: %s: bad %s\n", 90830715Sbostic lineno, tp, cp); 90930715Sbostic errors++; 91030715Sbostic } else 91130715Sbostic lp->d_trkseek = v; 91230715Sbostic continue; 91330715Sbostic } 91430715Sbostic if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { 91530863Skarels unsigned part = *cp - 'a'; 91630715Sbostic 91730863Skarels if (part > lp->d_npartitions) { 91830715Sbostic fprintf(stderr, 91930715Sbostic "line %d: bad partition name\n", lineno); 92030715Sbostic errors++; 92130715Sbostic continue; 92230715Sbostic } 92330863Skarels pp = &lp->d_partitions[part]; 92430863Skarels #define NXTNUM(n) { \ 92530863Skarels cp = tp, tp = word(cp); \ 92630863Skarels if (tp == NULL) \ 92730863Skarels tp = cp; \ 92830863Skarels (n) = atoi(cp); \ 92930863Skarels } 93030863Skarels 93130863Skarels NXTNUM(v); 93230715Sbostic if (v < 0) { 93330715Sbostic fprintf(stderr, 93430715Sbostic "line %d: %s: bad partition size\n", 93530715Sbostic lineno, cp); 93630715Sbostic errors++; 93730715Sbostic } else 93830863Skarels pp->p_size = v; 93930863Skarels NXTNUM(v); 94030715Sbostic if (v < 0) { 94130715Sbostic fprintf(stderr, 94230715Sbostic "line %d: %s: bad partition offset\n", 94330715Sbostic lineno, cp); 94430715Sbostic errors++; 94530715Sbostic } else 94630863Skarels pp->p_offset = v; 94730715Sbostic cp = tp, tp = word(cp); 94830715Sbostic cpp = fstypenames; 94930715Sbostic for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) 95030715Sbostic if ((s = *cpp) && streq(s, cp)) { 95130863Skarels pp->p_fstype = cpp - fstypenames; 95230863Skarels goto gottype; 95330715Sbostic } 95434032Skarels if (isdigit(*cp)) 95534032Skarels v = atoi(cp); 95634032Skarels else 95734032Skarels v = FSMAXTYPES; 95834032Skarels if ((unsigned)v >= FSMAXTYPES) { 95930715Sbostic fprintf(stderr, "line %d: %s %s\n", lineno, 96030715Sbostic "Warning, unknown filesystem type", cp); 96134032Skarels v = FS_UNUSED; 96234032Skarels } 96330863Skarels pp->p_fstype = v; 96430863Skarels gottype: 96530863Skarels 96630863Skarels switch (pp->p_fstype) { 96730863Skarels 96830863Skarels case FS_UNUSED: /* XXX */ 96930863Skarels NXTNUM(pp->p_fsize); 97030863Skarels if (pp->p_fsize == 0) 97130863Skarels break; 97230863Skarels NXTNUM(v); 97330863Skarels pp->p_frag = v / pp->p_fsize; 97430863Skarels break; 97530863Skarels 97630863Skarels case FS_BSDFFS: 97730863Skarels NXTNUM(pp->p_fsize); 97830863Skarels if (pp->p_fsize == 0) 97930863Skarels break; 98030863Skarels NXTNUM(v); 98130863Skarels pp->p_frag = v / pp->p_fsize; 98230863Skarels NXTNUM(pp->p_cpg); 98330863Skarels break; 98430863Skarels 98530863Skarels default: 98630863Skarels break; 98730863Skarels } 98830715Sbostic continue; 98930715Sbostic } 99030715Sbostic fprintf(stderr, "line %d: %s: Unknown disklabel field\n", 99130715Sbostic lineno, cp); 99230715Sbostic errors++; 99330715Sbostic next: 99430715Sbostic ; 99530715Sbostic } 99630715Sbostic errors += checklabel(lp); 99730715Sbostic return (errors == 0); 99830418Skarels } 99930418Skarels 100030715Sbostic /* 100130715Sbostic * Check disklabel for errors and fill in 100230715Sbostic * derived fields according to supplied values. 100330715Sbostic */ 100430715Sbostic checklabel(lp) 100530715Sbostic register struct disklabel *lp; 100630418Skarels { 100730715Sbostic register struct partition *pp; 100830715Sbostic int i, errors = 0; 100930715Sbostic char part; 101030418Skarels 101130715Sbostic if (lp->d_secsize == 0) { 101230715Sbostic fprintf(stderr, "sector size %d\n", lp->d_secsize); 101330715Sbostic return (1); 101430715Sbostic } 101530715Sbostic if (lp->d_nsectors == 0) { 101630715Sbostic fprintf(stderr, "sectors/track %d\n", lp->d_nsectors); 101730715Sbostic return (1); 101830715Sbostic } 101930715Sbostic if (lp->d_ntracks == 0) { 102030715Sbostic fprintf(stderr, "tracks/cylinder %d\n", lp->d_ntracks); 102130715Sbostic return (1); 102230715Sbostic } 102330715Sbostic if (lp->d_ncylinders == 0) { 102430715Sbostic fprintf(stderr, "cylinders/unit %d\n", lp->d_ncylinders); 102530715Sbostic errors++; 102630715Sbostic } 102730715Sbostic if (lp->d_rpm == 0) 102830715Sbostic Warning("revolutions/minute %d\n", lp->d_rpm); 102930715Sbostic if (lp->d_secpercyl == 0) 103030715Sbostic lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 103130715Sbostic if (lp->d_secperunit == 0) 103230715Sbostic lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; 103330715Sbostic if (lp->d_bbsize == 0) { 103430715Sbostic fprintf(stderr, "boot block size %d\n", lp->d_bbsize); 103530715Sbostic errors++; 103630715Sbostic } else if (lp->d_bbsize % lp->d_secsize) 103730715Sbostic Warning("boot block size %% sector-size != 0\n"); 103830715Sbostic if (lp->d_sbsize == 0) { 103930715Sbostic fprintf(stderr, "super block size %d\n", lp->d_sbsize); 104030715Sbostic errors++; 104130715Sbostic } else if (lp->d_sbsize % lp->d_secsize) 104230715Sbostic Warning("super block size %% sector-size != 0\n"); 104330715Sbostic if (lp->d_npartitions > MAXPARTITIONS) 104430715Sbostic Warning("number of partitions (%d) > MAXPARTITIONS (%d)\n", 104530715Sbostic lp->d_npartitions, MAXPARTITIONS); 104630715Sbostic for (i = 0; i < lp->d_npartitions; i++) { 104730715Sbostic part = 'a' + i; 104830715Sbostic pp = &lp->d_partitions[i]; 104930715Sbostic if (pp->p_size == 0 && pp->p_offset != 0) 105030715Sbostic Warning("partition %c: size 0, but offset %d\n", 105130715Sbostic part, pp->p_offset); 105230715Sbostic #ifdef notdef 105330715Sbostic if (pp->p_size % lp->d_secpercyl) 105430715Sbostic Warning("partition %c: size %% cylinder-size != 0\n", 105530715Sbostic part); 105630715Sbostic if (pp->p_offset % lp->d_secpercyl) 105730715Sbostic Warning("partition %c: offset %% cylinder-size != 0\n", 105830715Sbostic part); 105930715Sbostic #endif 106030715Sbostic if (pp->p_offset > lp->d_secperunit) { 106130715Sbostic fprintf(stderr, 106230715Sbostic "partition %c: offset past end of unit\n", part); 106330715Sbostic errors++; 106430715Sbostic } 106530715Sbostic if (pp->p_offset + pp->p_size > lp->d_secperunit) { 106630715Sbostic fprintf(stderr, 106730715Sbostic "partition %c: partition extends past end of unit\n", 106830715Sbostic part); 106930715Sbostic errors++; 107030715Sbostic } 107130715Sbostic } 107230715Sbostic for (; i < MAXPARTITIONS; i++) { 107330715Sbostic part = 'a' + i; 107430715Sbostic pp = &lp->d_partitions[i]; 107530715Sbostic if (pp->p_size || pp->p_offset) 107630715Sbostic Warning("unused partition %c: size %d offset %d\n", 107734032Skarels 'a' + i, pp->p_size, pp->p_offset); 107830715Sbostic } 107930715Sbostic return (errors); 108030715Sbostic } 108130715Sbostic 108230715Sbostic /*VARARGS1*/ 108330715Sbostic Warning(fmt, a1, a2, a3, a4, a5) 108430715Sbostic char *fmt; 108530715Sbostic { 108630715Sbostic 108730715Sbostic fprintf(stderr, "Warning, "); 108830715Sbostic fprintf(stderr, fmt, a1, a2, a3, a4, a5); 108930715Sbostic fprintf(stderr, "\n"); 109030715Sbostic } 109130715Sbostic 109230715Sbostic Perror(str) 109330715Sbostic char *str; 109430715Sbostic { 109530715Sbostic fputs("disklabel: ", stderr); perror(str); 109630418Skarels exit(4); 109730418Skarels } 109830715Sbostic 109930715Sbostic usage() 110030715Sbostic { 110130715Sbostic #ifdef BOOT 110234032Skarels fprintf(stderr, "%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n%-62s%s\n", 110330715Sbostic "usage: disklabel [-r] disk", "(to read label)", 110430715Sbostic "or disklabel -w [-r] disk type [ packid ] [ xxboot bootxx ]", "(to write label)", 110530715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 110634032Skarels "or disklabel -R [-r] disk protofile [ type | xxboot bootxx ]", "(to restore label)", 110734032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 110830715Sbostic #else 110934032Skarels fprintf(stderr, "%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n%-43s%s\n", 111030715Sbostic "usage: disklabel [-r] disk", "(to read label)", 111130715Sbostic "or disklabel -w [-r] disk type [ packid ]", "(to write label)", 111230715Sbostic "or disklabel -e [-r] disk", "(to edit label)", 111334032Skarels "or disklabel -R [-r] disk protofile", "(to restore label)", 111434032Skarels "or disklabel [-NW] disk", "(to write disable/enable label)"); 111530715Sbostic #endif 111630715Sbostic exit(1); 111730715Sbostic } 1118