diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-09-30 17:54:18 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-09-30 17:54:18 +0000 |
commit | cc8c12348a659237c10770797cba17a197f16106 (patch) | |
tree | 752f21cdedf505768a5307500fbb162502b0d261 /sbin/disklabel/disklabel.c | |
parent | 9b5e4d74ac47423be76e44cc8b146e398905bc65 (diff) |
Implement "disklabel -E" -- a simple interactive label editor for
installs and new labels. Documentation to follow :-) Also, give
the user the option of writing the fictitious label if no on-disk
label exists with the -e, -E, and -w options.
Diffstat (limited to 'sbin/disklabel/disklabel.c')
-rw-r--r-- | sbin/disklabel/disklabel.c | 114 |
1 files changed, 101 insertions, 13 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index 3991b3670b3..ddafd1cdb8a 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disklabel.c,v 1.38 1997/09/26 04:10:28 millert Exp $ */ +/* $OpenBSD: disklabel.c,v 1.39 1997/09/30 17:54:15 millert Exp $ */ /* $NetBSD: disklabel.c,v 1.30 1996/03/14 19:49:24 ghudson Exp $ */ /* @@ -44,7 +44,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char rcsid[] = "$OpenBSD: disklabel.c,v 1.38 1997/09/26 04:10:28 millert Exp $"; +static char rcsid[] = "$OpenBSD: disklabel.c,v 1.39 1997/09/30 17:54:15 millert Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -104,7 +104,7 @@ char boot1[MAXPATHLEN]; #endif enum { - UNSPEC, EDIT, READ, RESTORE, SETWRITEABLE, WRITE, WRITEBOOT + UNSPEC, EDIT, EDITOR, READ, RESTORE, SETWRITEABLE, WRITE, WRITEBOOT } op = UNSPEC; int rflag; @@ -120,10 +120,12 @@ struct dos_partition *readmbr __P((int)); void makelabel __P((char *, char *, struct disklabel *)); int writelabel __P((int, char *, struct disklabel *)); void l_perror __P((char *)); +struct disklabel *newlabel __P((int)); struct disklabel *readlabel __P((int)); struct disklabel *makebootarea __P((char *, struct disklabel *, int)); void display __P((FILE *, struct disklabel *)); -void display_partition __P((FILE *, struct disklabel *, int)); +void display_partition __P((FILE *, struct disklabel *, int, char)); +int editor __P((struct disklabel *, int)); int edit __P((struct disklabel *, int)); int editit __P((void)); char *skip __P((char *)); @@ -133,6 +135,7 @@ int checklabel __P((struct disklabel *)); void setbootflag __P((struct disklabel *)); void usage __P((void)); u_short dkcksum __P((struct disklabel *)); +char get_yn __P((char *)); int main(argc, argv) @@ -143,7 +146,7 @@ main(argc, argv) struct disklabel *lp; FILE *t; - while ((ch = getopt(argc, argv, "BNRWb:ers:wnv")) != -1) + while ((ch = getopt(argc, argv, "BENRWb:ers:wnv")) != -1) switch (ch) { #if NUMBOOT > 0 case 'B': @@ -158,6 +161,11 @@ main(argc, argv) break; #endif #endif + case 'E': + if (op != UNSPEC) + usage(); + op = EDITOR; + break; case 'N': if (op != UNSPEC) usage(); @@ -240,13 +248,22 @@ main(argc, argv) case EDIT: if (argc != 1) usage(); - lp = readlabel(f); + if ((lp = newlabel(f)) == NULL) + exit(1); error = edit(lp, f); break; + case EDITOR: + if (argc != 1) + usage(); + if ((lp = newlabel(f)) == NULL) + exit(1); + error = editor(lp, f); + break; case READ: if (argc != 1) usage(); - lp = readlabel(f); + if ((lp = readlabel(f)) == NULL) + exit(1); display(stdout, lp); error = checklabel(lp); break; @@ -283,7 +300,8 @@ main(argc, argv) { struct disklabel tlab; - lp = readlabel(f); + if ((lp = newlabel(f)) == NULL) + exit(1); tlab = *lp; if (argc == 2) makelabel(argv[1], NULL, &lab); @@ -672,7 +690,8 @@ readlabel(f) msg = "disk label corrupted"; } } - errx(1, msg); + warnx(msg); + return(NULL); } else { lp = &lab; if (ioctl(f, DIOCGDINFO, lp) < 0) @@ -821,16 +840,45 @@ makebootarea(boot, dp, f) * Display a particular partion. */ void -display_partition(f, lp, i) +display_partition(f, lp, i, unit) FILE *f; struct disklabel *lp; int i; + char unit; { struct partition *pp = &lp->d_partitions[i]; + double p_size; + + unit = tolower(unit); + switch (unit) { + case 'b': + p_size = (double)pp->p_size * lp->d_secsize; + break; + + case 'c': + p_size = (double)pp->p_size / lp->d_secpercyl; + break; + + case 'k': + p_size = (double)pp->p_size / (1024 / lp->d_secsize); + break; + + case 'm': + p_size = (double)pp->p_size / (1048576 / lp->d_secsize); + break; + + default: + p_size = -1; /* no conversion */ + break; + } if (pp->p_size) { - fprintf(f, " %c: %8d %8d ", 'a' + i, - pp->p_size, pp->p_offset); + if (p_size < 0) + fprintf(f, " %c: %8u %8u ", 'a' + i, + pp->p_size, pp->p_offset); + else + fprintf(f, " %c: %8.2f%c %8u ", 'a' + i, + p_size, unit, pp->p_offset); if ((unsigned) pp->p_fstype < FSMAXTYPES) fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); else @@ -919,7 +967,7 @@ display(f, lp) fprintf(f, "# size offset fstype [fsize bsize cpg]\n"); for (i = 0; i < lp->d_npartitions; i++) - display_partition(f, lp, i); + display_partition(f, lp, i, 0); fflush(f); } @@ -1487,6 +1535,43 @@ setbootflag(lp) } #endif +/* + * Get existing label or create a new one if none exists. + */ +struct disklabel * +newlabel(f) + int f; +{ + int orflag = rflag; + struct disklabel fictlabel, *lp = NULL; + + rflag = 1; + if ((lp = readlabel(f)) == NULL) { + if (get_yn("No label found on disk, write a new one?") != 'y') + return(NULL); + + /* Read fake label */ + rflag = 0; + lp = readlabel(f); + fictlabel = *lp; + rflag = 1; + nwflag = 0; /* set by readlabel() */ + + /* Make boot area and fill in values from fictious label */ + lp = makebootarea(bootarea, &lab, f); + *lp = fictlabel; + + /* Write fake label to disk */ + if (checklabel(lp)) + warnx("you must correct these errors in the editor."); + if (writelabel(f, bootarea, lp)) + err(4, "unable to write new label"); + } + + rflag = orflag; + return(lp); +} + void usage() { @@ -1508,6 +1593,9 @@ usage() " disklabel [-nv] [-r] -e disk%s (edit)\n", blank); fprintf(stderr, + " disklabel [-nv] [-r] -E disk%s (simple editor)\n", + blank); + fprintf(stderr, " disklabel [-nv] [-r]%s -R disk proto (restore)\n", boot); fprintf(stderr, |