summaryrefslogtreecommitdiff
path: root/sbin/disklabel
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2009-03-28 16:18:51 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2009-03-28 16:18:51 +0000
commit3095199658e2d3029559180a61e3418d506d1f96 (patch)
treed5d04e3a84fe76145a9a5778ae94b513baaf1256 /sbin/disklabel
parent37fdb79f001cf5c845b5a41606fed69239850cb4 (diff)
Add 'U' command to E(ditor). It reverts label to state it was in
when entering E(ditor) mode. Clean up 'u' code and make more effort to keep label and mountpoint info in sync. Makes 'u' undo-able so those with vi fingers can apply and revert changes (with perhaps a 'p' or two in between) to validate changes. 'U' suggested by deraadt@. ok deraadt@
Diffstat (limited to 'sbin/disklabel')
-rw-r--r--sbin/disklabel/editor.c135
1 files changed, 64 insertions, 71 deletions
diff --git a/sbin/disklabel/editor.c b/sbin/disklabel/editor.c
index 74a9d7a588c..eb2a37ec8c4 100644
--- a/sbin/disklabel/editor.c
+++ b/sbin/disklabel/editor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: editor.c,v 1.178 2009/03/28 07:08:32 otto Exp $ */
+/* $OpenBSD: editor.c,v 1.179 2009/03/28 16:18:50 krw Exp $ */
/*
* Copyright (c) 1997-2000 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -17,7 +17,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: editor.c,v 1.178 2009/03/28 07:08:32 otto Exp $";
+static char rcsid[] = "$OpenBSD: editor.c,v 1.179 2009/03/28 16:18:50 krw Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -109,7 +109,7 @@ void getdisktype(struct disklabel *, char *, char *);
void find_bounds(struct disklabel *);
void set_bounds(struct disklabel *);
struct diskchunk *free_chunks(struct disklabel *);
-char ** mpcopy(char **, char **);
+void mpcopy(char **, char **);
int micmp(const void *, const void *);
int mpequal(char **, char **);
int mpsave(struct disklabel *, char **, char *, char *);
@@ -136,17 +136,19 @@ static int expert;
int
editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
{
- struct disklabel lastlabel, tmplabel, label = *lp;
+ struct disklabel origlabel, lastlabel, tmplabel, label = *lp;
struct disklabel *disk_geop;
struct partition *pp;
FILE *fp;
char buf[BUFSIZ], *cmd, *arg;
- char **mountpoints = NULL, **omountpoints = NULL, **tmpmountpoints = NULL;
+ char **mountpoints = NULL, **omountpoints = NULL;
+ char **origmountpoints = NULL, **tmpmountpoints = NULL;
/* Alloc and init mount point info */
if (fstabfile) {
if (!(mountpoints = calloc(MAXPARTITIONS, sizeof(char *))) ||
!(omountpoints = calloc(MAXPARTITIONS, sizeof(char *))) ||
+ !(origmountpoints = calloc(MAXPARTITIONS, sizeof(char *))) ||
!(tmpmountpoints = calloc(MAXPARTITIONS, sizeof(char *))))
errx(4, "out of memory");
}
@@ -195,6 +197,9 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
if (label.d_interleave == 0)
label.d_interleave = 1;
+ /* Save the (U)ndo label, origmountpoints is already NULLs. */
+ origlabel = label;
+
if (aflag)
editor_allocspace(&label, mountpoints, 0);
@@ -211,101 +216,61 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
continue;
arg = strtok(NULL, " \t\r\n");
- switch (*cmd) {
+ if ((*cmd != 'u') && (*cmd != 'U')) {
+ /*
+ * Save undo info in case the command tries to make
+ * changes but decides not to.
+ */
+ tmplabel = lastlabel;
+ lastlabel = label;
+ if (mountpoints != NULL) {
+ mpcopy(tmpmountpoints, omountpoints);
+ mpcopy(omountpoints, mountpoints);
+ }
+ }
+ switch (*cmd) {
case '?':
case 'h':
editor_help(arg ? arg : "");
break;
case 'A':
- tmplabel = lastlabel;
- lastlabel = label;
editor_allocspace(&label, mountpoints, 1);
break;
case 'a':
- tmplabel = lastlabel;
- lastlabel = label;
- if (mountpoints != NULL) {
- mpcopy(tmpmountpoints, omountpoints);
- mpcopy(omountpoints, mountpoints);
- }
editor_add(&label, mountpoints, arg);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
- if (mountpoints != NULL && mpequal(omountpoints, tmpmountpoints))
- mpcopy(omountpoints, tmpmountpoints);
break;
case 'b':
- tmplabel = lastlabel;
- lastlabel = label;
set_bounds(&label);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
break;
case 'c':
- tmplabel = lastlabel;
- lastlabel = label;
editor_change(&label, arg);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
break;
case 'D':
- tmplabel = lastlabel;
- lastlabel = label;
- if (ioctl(f, DIOCGPDINFO, &label) == 0) {
+ if (ioctl(f, DIOCGPDINFO, &label) == 0)
dflag = 1;
- } else {
+ else
warn("unable to get default partition table");
- lastlabel = tmplabel;
- }
break;
case 'd':
- tmplabel = lastlabel;
- lastlabel = label;
- if (mountpoints != NULL) {
- mpcopy(tmpmountpoints, omountpoints);
- mpcopy(omountpoints, mountpoints);
- }
editor_delete(&label, mountpoints, arg);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
- if (mountpoints != NULL && mpequal(omountpoints, tmpmountpoints))
- mpcopy(omountpoints, tmpmountpoints);
break;
case 'e':
- tmplabel = lastlabel;
- lastlabel = label;
edit_parms(&label);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
break;
case 'g':
- tmplabel = lastlabel;
- lastlabel = label;
set_geometry(&label, disk_geop, lp, arg);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
break;
case 'm':
- tmplabel = lastlabel;
- lastlabel = label;
- if (mountpoints != NULL) {
- mpcopy(tmpmountpoints, omountpoints);
- mpcopy(omountpoints, mountpoints);
- }
editor_modify(&label, mountpoints, arg);
- if (memcmp(&label, &lastlabel, sizeof(label)) == 0)
- lastlabel = tmplabel;
- if (mountpoints != NULL && mpequal(omountpoints, tmpmountpoints))
- mpcopy(omountpoints, tmpmountpoints);
break;
case 'n':
@@ -314,11 +279,7 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
"without the -f flag.\n", stderr);
break;
}
- mpcopy(tmpmountpoints, omountpoints);
- mpcopy(omountpoints, mountpoints);
editor_name(&label, mountpoints, arg);
- if (mpequal(omountpoints, tmpmountpoints))
- mpcopy(omountpoints, tmpmountpoints);
break;
case 'p':
@@ -416,18 +377,40 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
}
break;
+ case 'U':
+ if (memcmp(&label, &origlabel, sizeof(label)) == 0 &&
+ (mountpoints == NULL ||
+ mpequal(mountpoints, origmountpoints))) {
+ puts("Nothing to undo!");
+ } else {
+ tmplabel = label;
+ label = origlabel;
+ lastlabel = tmplabel;
+ /* Restore mountpoints */
+ if (mountpoints != NULL) {
+ mpcopy(tmpmountpoints, mountpoints);
+ mpcopy(mountpoints, origmountpoints);
+ mpcopy(omountpoints, tmpmountpoints);
+ }
+ puts("All changes undone.");
+ }
+ break;
+
case 'u':
if (memcmp(&label, &lastlabel, sizeof(label)) == 0 &&
- mountpoints != NULL &&
- mpequal(mountpoints, omountpoints)) {
+ (mountpoints == NULL ||
+ mpequal(mountpoints, omountpoints))) {
puts("Nothing to undo!");
} else {
tmplabel = label;
label = lastlabel;
lastlabel = tmplabel;
/* Restore mountpoints */
- if (mountpoints != NULL)
+ if (mountpoints != NULL) {
+ mpcopy(tmpmountpoints, mountpoints);
mpcopy(mountpoints, omountpoints);
+ mpcopy(omountpoints, tmpmountpoints);
+ }
puts("Last change undone.");
}
break;
@@ -460,9 +443,9 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
break;
case 'z':
- tmplabel = lastlabel;
- lastlabel = label;
zero_partitions(&label);
+ if (mountpoints != NULL)
+ mpcopy(mountpoints, origmountpoints);
break;
case '\n':
@@ -472,6 +455,17 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag)
printf("Unknown option: %c ('?' for help)\n", *cmd);
break;
}
+
+ /*
+ * If no changes were made to label or mountpoints, then
+ * restore undo info.
+ */
+ if (memcmp(&label, &lastlabel, sizeof(label)) == 0 &&
+ (mountpoints == NULL ||
+ mpequal(mountpoints, omountpoints))) {
+ lastlabel = tmplabel;
+ mpcopy(omountpoints, tmpmountpoints);
+ }
}
}
@@ -1738,7 +1732,7 @@ editor_help(char *arg)
}
}
-char **
+void
mpcopy(char **to, char **from)
{
int i;
@@ -1758,7 +1752,6 @@ mpcopy(char **to, char **from)
to[i] = NULL;
}
}
- return(to);
}
int