editor_modify(&label, &freeblocks, arg);
editor_modify(&label, &freesectors, arg);
editor(lp, f)	struct disklabel *lp;	int f;{	struct disklabel lastlabel, tmplabel, label = *lp;	u_int32_t freeblocks;	FILE *fp;	char buf[BUFSIZ], *cmd, *arg;	int i;	/* Set freeblocks based on initial label */	freeblocks = label.d_secperunit;	for (i = 0; i < label.d_npartitions; i++)		if (label.d_partitions[i].p_fstype != FS_UNUSED &&		    label.d_partitions[i].p_fstype != FS_BOOT &&		    label.d_partitions[i].p_size > 0)			freeblocks -= label.d_partitions[i].p_size;	puts("Initial label editor (enter '?' for help at any prompt)");	if (has_overlap(&label, &freeblocks, 1))		errx(1, "can't run when there is partition overlap.");	getdisktype(&label, "You need to specify a disk type for this disk.");#ifdef CYLCHECK	puts("This platform requires that partition offsets/sizes be on cylinder boundaries.\nPartition offsets/sizes will be rounded to the nearest cylinder automatically.");#endif	lastlabel = label;	for (;;) {		fputs("> ", stdout);		fflush(stdout);		rewind(stdin);		if (fgets(buf, sizeof(buf), stdin) == NULL) {			putchar('\n');			buf[0] = 'q';			buf[1] = '\0';		}		if ((cmd = strtok(buf, " \t\r\n")) == NULL)			continue;		arg = strtok(NULL, " \t\r\n");		switch (*cmd) {		case '?':		case 'h':			puts("Available commands:");			puts("\tp [unit]   - print label.");			puts("\tM          - show entire OpenBSD man page for disklabel.");			puts("\te          - edit drive parameters.");			puts("\ta [part]   - add new partition.");			puts("\tc [part]   - change partition size.");			puts("\td [part]   - delete partition.");			puts("\tm [part]   - modify existing partition.");			puts("\tu          - undo last change.");			puts("\ts [path]   - save label to file.");			puts("\tw          - write label to disk.");			puts("\tq          - quit and save changes.");			puts("\tx          - exit without saving changes.");			puts("\t?          - this message.");			puts("Numeric parameters may use suffixes to indicate units:\n\t'b' for bytes, 'c' for cylinders, 'k' for kilobytes, 'm' for megabytes,\n\t'g' for gigabytes or no suffix for blocks (usually 512 bytes).\n\tNon-block units will be rounded to the nearest cylinder.");			break;		case 'a':			tmplabel = lastlabel;			lastlabel = label;			editor_add(&label, &freeblocks, arg);			if (memcmp(&label, &lastlabel, sizeof(label)) == 0)				lastlabel = tmplabel;			break;		case 'c':			tmplabel = lastlabel;			lastlabel = label;			editor_change(&label, &freeblocks, arg);			if (memcmp(&label, &lastlabel, sizeof(label)) == 0)				lastlabel = tmplabel;			break;		case 'd':			tmplabel = lastlabel;			lastlabel = label;			editor_delete(&label, &freeblocks, arg);			if (memcmp(&label, &lastlabel, sizeof(label)) == 0)				lastlabel = tmplabel;			break;		case 'm':			tmplabel = lastlabel;			lastlabel = label;			editor_modify(&label, &freeblocks, arg);			if (memcmp(&label, &lastlabel, sizeof(label)) == 0)				lastlabel = tmplabel;			break;		case 'p':			editor_display(&label, &freeblocks, arg ? *arg : 0);			break;		case 'M':			fp = popen("/usr/bin/less", "w");			if (fp) {				extern char manpage[];				(void) fwrite(manpage, strlen(manpage), 1, fp);				pclose(fp);			}			break;		case 'q':			if (donothing) {				puts("In no change mode, not writing label.");				return(1);			}			if (memcmp(lp, &label, sizeof(label)) == 0) {				puts("No changes.");				return(1);			}			do {				arg = getstring(lp, "Save changes?",				    "Save changes you have made to the label?",				    "n");			} while (tolower(*arg) != 'y' && tolower(*arg) != 'n');			if (tolower(*arg) == 'y') {				*lp = label;				if (writelabel(f, bootarea, lp) == 0)					return(0);			}			return(1);			/* NOTREACHED */			break;		case 's':			if (arg == NULL) {				arg = getstring(lp, "Filename",				    "Name of the file to save label into.",				    NULL);				if (*arg == '\0')					break;			}			if ((fp = fopen(arg, "w")) == NULL) {				warn("cannot open %s", arg);			} else {				display(fp, &label);				(void)fclose(fp);			}			break;		case 'u':			if (memcmp(&label, &lastlabel, sizeof(label)) == 0) {				puts("Nothing to undo!");			} else {				tmplabel = label;				label = lastlabel;				lastlabel = tmplabel;				puts("Last change undone.");			}			break;		case 'w':			if (donothing)				puts("In no change mode, not writing label.");			else if (memcmp(lp, &label, sizeof(label)) == 0)				puts("No changes.");			else if (writelabel(f, bootarea, &label) != 0)				warnx("unable to write label");			else				*lp = label;			break;		case 'x':			return(1);			break;		case '\n':			break;		case 'e':			tmplabel = lastlabel;			lastlabel = label;			edit_parms(&label, &freeblocks);			if (memcmp(&label, &lastlabel, sizeof(label)) == 0)				lastlabel = tmplabel;			break;		default:			printf("Unknown option: %c ('?' for help)\n", *cmd);			break;		}	}}