disks.c revision 8408
1297627Sjmcneill/* 2297627Sjmcneill * The new sysinstall program. 3297627Sjmcneill * 4297627Sjmcneill * This is probably the last program in the `sysinstall' line - the next 5297627Sjmcneill * generation being essentially a complete rewrite. 6297627Sjmcneill * 7297627Sjmcneill * $Id: disks.c,v 1.14 1995/05/10 08:03:21 jkh Exp $ 8297627Sjmcneill * 9297627Sjmcneill * Copyright (c) 1995 10297627Sjmcneill * Jordan Hubbard. All rights reserved. 11297627Sjmcneill * 12297627Sjmcneill * Redistribution and use in source and binary forms, with or without 13297627Sjmcneill * modification, are permitted provided that the following conditions 14297627Sjmcneill * are met: 15297627Sjmcneill * 1. Redistributions of source code must retain the above copyright 16297627Sjmcneill * notice, this list of conditions and the following disclaimer, 17297627Sjmcneill * verbatim and that no modifications are made prior to this 18297627Sjmcneill * point in the file. 19297627Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright 20297627Sjmcneill * notice, this list of conditions and the following disclaimer in the 21297627Sjmcneill * documentation and/or other materials provided with the distribution. 22297627Sjmcneill * 3. All advertising materials mentioning features or use of this software 23297627Sjmcneill * must display the following acknowledgement: 24297627Sjmcneill * This product includes software developed by Jordan Hubbard 25297627Sjmcneill * for the FreeBSD Project. 26297627Sjmcneill * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to 27297627Sjmcneill * endorse or promote products derived from this software without specific 28297627Sjmcneill * prior written permission. 29297627Sjmcneill * 30297627Sjmcneill * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 31297627Sjmcneill * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32297627Sjmcneill * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33297627Sjmcneill * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 34297627Sjmcneill * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35297627Sjmcneill * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36297627Sjmcneill * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 37297627Sjmcneill * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38297627Sjmcneill * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39297627Sjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40297627Sjmcneill * SUCH DAMAGE. 41297627Sjmcneill * 42297627Sjmcneill */ 43297627Sjmcneill 44297627Sjmcneill#include "sysinstall.h" 45297627Sjmcneill#include <ctype.h> 46297627Sjmcneill#include <sys/disklabel.h> 47297627Sjmcneill 48297627Sjmcneill/* 49297627Sjmcneill * I make some pretty gross assumptions about having a max of 50 chunks 50297627Sjmcneill * total - 8 slices and 42 partitions. I can't easily display many more 51297627Sjmcneill * than that on the screen at once! 52308274Smanu * 53305436Smanu * For 2.1 I'll revisit this and try to make it more dynamic, but since 54297627Sjmcneill * this will catch 99.99% of all possible cases, I'm not too worried. 55297627Sjmcneill */ 56297627Sjmcneill 57297627Sjmcneill#define MAX_CHUNKS 50 58297627Sjmcneill 59297627Sjmcneill/* Where to start printing the freebsd slices */ 60297627Sjmcneill#define CHUNK_SLICE_START_ROW 2 61297627Sjmcneill#define CHUNK_PART_START_ROW 10 62297627Sjmcneill 63297627Sjmcneill/* The smallest filesystem we're willing to create */ 64297627Sjmcneill#define FS_MIN_SIZE 2048 65297627Sjmcneill 66297627Sjmcneill#define MSG_NOT_APPLICABLE "That option is not applicable here" 67297627Sjmcneill 68297627Sjmcneillstatic struct { 69297627Sjmcneill struct disk *d; 70297627Sjmcneill struct chunk *c; 71297627Sjmcneill PartType type; 72297627Sjmcneill} fbsd_chunk_info[MAX_CHUNKS + 1]; 73297627Sjmcneillstatic int current_chunk; 74297627Sjmcneill 75297627Sjmcneill 76297627Sjmcneillstatic Boolean 77297627Sjmcneillcheck_conflict(char *name) 78297627Sjmcneill{ 79297627Sjmcneill int i; 80297627Sjmcneill 81297627Sjmcneill for (i = 0; fbsd_chunk_info[i].d; i++) 82297627Sjmcneill if (fbsd_chunk_info[i].type == PART_FILESYSTEM && 83297627Sjmcneill fbsd_chunk_info[i].c->private && 84297627Sjmcneill !strcmp(((PartInfo *)fbsd_chunk_info[i].c->private)->mountpoint, 85297627Sjmcneill name)) 86297627Sjmcneill return TRUE; 87297627Sjmcneill return FALSE; 88297627Sjmcneill} 89297627Sjmcneill 90297627Sjmcneillstatic int 91297627Sjmcneillspace_free(struct chunk *c) 92297627Sjmcneill{ 93297627Sjmcneill struct chunk *c1 = c->part; 94297627Sjmcneill int sz = c->size; 95297627Sjmcneill 96297627Sjmcneill while (c1) { 97297627Sjmcneill if (c1->type != unused) 98297627Sjmcneill sz -= c1->size; 99297627Sjmcneill c1 = c1->next; 100297627Sjmcneill } 101297627Sjmcneill if (sz < 0) 102297627Sjmcneill msgFatal("Partitions are larger than actual chunk??"); 103297627Sjmcneill return sz; 104297627Sjmcneill} 105297627Sjmcneill 106305436Smanustatic void 107305436Smanurecord_fbsd_chunks() 108305436Smanu{ 109305436Smanu int i, j, p; 110305436Smanu struct chunk *c1, *c2; 111305436Smanu 112305436Smanu j = p = 0; 113299688Smanu for (i = 0; Disks[i]; i++) { 114299688Smanu if (!Disks[i]->chunks) 115299688Smanu msgFatal("No chunk list found for %s!", Disks[i]->name); 116299688Smanu 117299688Smanu /* Put the freebsd chunks first */ 118299688Smanu for (c1 = Disks[i]->chunks->part; c1; c1 = c1->next) { 119299688Smanu if (c1->type == freebsd) { 120299688Smanu fbsd_chunk_info[j].type = PART_SLICE; 121299688Smanu fbsd_chunk_info[j].d = Disks[i]; 122297627Sjmcneill fbsd_chunk_info[j].c = c1; 123297627Sjmcneill ++j; 124297627Sjmcneill } 125297627Sjmcneill } 126297627Sjmcneill } 127297627Sjmcneill for (i = 0; Disks[i]; i++) { 128297627Sjmcneill /* Then buzz through and pick up the partitions */ 129297627Sjmcneill for (c1 = Disks[i]->chunks->part; c1; c1 = c1->next) { 130297627Sjmcneill if (c1->type == freebsd) { 131297627Sjmcneill for (c2 = c1->part; c2; c2 = c2->next) { 132297627Sjmcneill if (c2->type == part) { 133297627Sjmcneill if (c2->subtype == FS_SWAP) 134297627Sjmcneill fbsd_chunk_info[j].type = PART_SWAP; 135297627Sjmcneill else 136297627Sjmcneill fbsd_chunk_info[j].type = PART_FILESYSTEM; 137297627Sjmcneill fbsd_chunk_info[j].d = Disks[i]; 138297627Sjmcneill fbsd_chunk_info[j].c = c2; 139297627Sjmcneill ++j; 140297627Sjmcneill } 141297627Sjmcneill } 142297627Sjmcneill } 143297627Sjmcneill } 144297627Sjmcneill } 145299113Sjmcneill fbsd_chunk_info[j].d = NULL; 146299113Sjmcneill fbsd_chunk_info[j].c = NULL; 147299113Sjmcneill if (current_chunk >= j) 148299113Sjmcneill current_chunk = j ? j - 1 : 0; 149299113Sjmcneill} 150299113Sjmcneill 151297627Sjmcneillstatic PartInfo * 152297627Sjmcneillnew_part(char *mpoint, Boolean newfs) 153297627Sjmcneill{ 154297627Sjmcneill PartInfo *ret; 155297627Sjmcneill 156297627Sjmcneill ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); 157297627Sjmcneill strncpy(ret->mountpoint, mpoint, FILENAME_MAX); 158297627Sjmcneill strcpy(ret->newfs_cmd, "newfs"); 159297627Sjmcneill ret->newfs = newfs; 160297627Sjmcneill return ret; 161297627Sjmcneill} 162297627Sjmcneill 163297627SjmcneillPartInfo * 164297627Sjmcneillget_mountpoint(struct chunk *c) 165297627Sjmcneill{ 166297627Sjmcneill char *val; 167297627Sjmcneill PartInfo *tmp; 168297627Sjmcneill 169297627Sjmcneill val = msgGetInput(c && c->private ? 170297627Sjmcneill ((PartInfo *)c->private)->mountpoint : NULL, 171305436Smanu "Please specify a mount point for the partition"); 172299688Smanu if (val) { 173297627Sjmcneill if (check_conflict(val)) { 174297627Sjmcneill msgConfirm("You already have a mount point for %s assigned!", val); 175299113Sjmcneill return NULL; 176297627Sjmcneill } 177297627Sjmcneill else if (*val != '/') { 178297627Sjmcneill msgConfirm("Mount point must start with a / character"); 179297627Sjmcneill return NULL; 180297627Sjmcneill } 181297627Sjmcneill else if (!strcmp(val, "/")) { 182297627Sjmcneill if (c && c->flags & CHUNK_PAST_1024) { 183297627SjmcneillmsgConfirm("This region cannot be used for your root partition as\nit is past the 1024'th cylinder mark and the system would not be\nable to boot from it. Please pick another location for your\nroot partition and try again!"); 184297627Sjmcneill return NULL; 185297627Sjmcneill } 186297627Sjmcneill else if (c) 187297627Sjmcneill c->flags |= CHUNK_IS_ROOT; 188297627Sjmcneill } 189297627Sjmcneill else if (c) 190297627Sjmcneill c->flags &= ~CHUNK_IS_ROOT; 191297627Sjmcneill safe_free(c ? c->private : NULL); 192297627Sjmcneill tmp = new_part(val, TRUE); 193297627Sjmcneill if (c) { 194297627Sjmcneill c->private = tmp; 195297627Sjmcneill c->private_free = safe_free; 196297627Sjmcneill } 197297627Sjmcneill return tmp; 198297627Sjmcneill } 199297627Sjmcneill return NULL; 200297627Sjmcneill} 201297627Sjmcneill 202297627Sjmcneillstatic PartType 203297627Sjmcneillget_partition_type(void) 204297627Sjmcneill{ 205297627Sjmcneill char selection[20]; 206297627Sjmcneill static unsigned char *fs_types[] = { 207297627Sjmcneill "FS", 208297627Sjmcneill "A file system", 209297627Sjmcneill "Swap", 210297627Sjmcneill "A swap partition.", 211297627Sjmcneill }; 212297627Sjmcneill 213297627Sjmcneill if (!dialog_menu("Please choose a partition type", 214297627Sjmcneill "If you want to use this partition for swap space, select Swap.\nIf you want to put a filesystem on it, choose FS.", -1, -1, 2, 2, fs_types, selection, NULL, NULL)) { 215297627Sjmcneill if (!strcmp(selection, "FS")) 216297627Sjmcneill return PART_FILESYSTEM; 217297627Sjmcneill else if (!strcmp(selection, "Swap")) 218297627Sjmcneill return PART_SWAP; 219297627Sjmcneill } 220297627Sjmcneill return PART_NONE; 221297627Sjmcneill} 222297627Sjmcneill 223297627Sjmcneillstatic void 224297627SjmcneillgetNewfsCmd(PartInfo *p) 225297627Sjmcneill{ 226297627Sjmcneill char *val; 227297627Sjmcneill 228297627Sjmcneill val = msgGetInput(p->newfs_cmd, 229297627Sjmcneill "Please enter the newfs command and options you'd like to use in\ncreating this file system."); 230297627Sjmcneill if (val) 231297627Sjmcneill strncpy(p->newfs_cmd, val, NEWFS_CMD_MAX); 232297627Sjmcneill} 233297627Sjmcneill 234297627Sjmcneill 235297627Sjmcneill#define MAX_MOUNT_NAME 12 236297627Sjmcneill 237297627Sjmcneill#define PART_PART_COL 0 238297627Sjmcneill#define PART_MOUNT_COL 8 239297627Sjmcneill#define PART_SIZE_COL (PART_MOUNT_COL + MAX_MOUNT_NAME + 3) 240297627Sjmcneill#define PART_NEWFS_COL (PART_SIZE_COL + 7) 241297627Sjmcneill#define PART_OFF 38 242297627Sjmcneill 243297627Sjmcneill/* How many mounted partitions to display in column before going to next */ 244297627Sjmcneill#define CHUNK_COLUMN_MAX 6 245297627Sjmcneill 246297627Sjmcneillstatic void 247297627Sjmcneillprint_fbsd_chunks(void) 248297627Sjmcneill{ 249297627Sjmcneill int i, j, srow, prow, pcol; 250297627Sjmcneill int sz; 251297627Sjmcneill 252297627Sjmcneill attrset(A_REVERSE); 253297627Sjmcneill mvaddstr(0, 25, "FreeBSD Partition Editor"); 254297627Sjmcneill attrset(A_NORMAL); 255297627Sjmcneill 256297627Sjmcneill for (i = 0; i < 2; i++) { 257297627Sjmcneill attrset(A_UNDERLINE); 258297627Sjmcneill mvaddstr(CHUNK_PART_START_ROW - 1, PART_PART_COL + (i * PART_OFF), 259297627Sjmcneill "Part"); 260297627Sjmcneill attrset(A_NORMAL); 261297627Sjmcneill 262297627Sjmcneill attrset(A_UNDERLINE); 263297627Sjmcneill mvaddstr(CHUNK_PART_START_ROW - 1, PART_MOUNT_COL + (i * PART_OFF), 264297627Sjmcneill "Mount"); 265297627Sjmcneill attrset(A_NORMAL); 266297627Sjmcneill 267297627Sjmcneill attrset(A_UNDERLINE); 268297627Sjmcneill mvaddstr(CHUNK_PART_START_ROW - 1, PART_SIZE_COL + (i * PART_OFF) + 2, 269297627Sjmcneill "Size"); 270297627Sjmcneill attrset(A_NORMAL); 271297627Sjmcneill 272297627Sjmcneill attrset(A_UNDERLINE); 273297627Sjmcneill mvaddstr(CHUNK_PART_START_ROW - 1, PART_NEWFS_COL + (i * PART_OFF), 274297627Sjmcneill "Newfs"); 275297627Sjmcneill attrset(A_NORMAL); 276297627Sjmcneill } 277297627Sjmcneill 278297627Sjmcneill srow = CHUNK_SLICE_START_ROW; 279297627Sjmcneill prow = CHUNK_PART_START_ROW; 280297627Sjmcneill pcol = 0; 281297627Sjmcneill 282297627Sjmcneill for (i = 0; fbsd_chunk_info[i].d; i++) { 283297627Sjmcneill if (i == current_chunk) 284297627Sjmcneill attrset(A_REVERSE); 285297627Sjmcneill /* Is it a slice entry displayed at the top? */ 286297627Sjmcneill if (fbsd_chunk_info[i].type == PART_SLICE) { 287297627Sjmcneill sz = space_free(fbsd_chunk_info[i].c); 288297627Sjmcneill mvprintw(srow++, 0, 289297627Sjmcneill "Disk: %s\tPartition name: %s\tFree: %d blocks (%dMB)", 290297627Sjmcneill fbsd_chunk_info[i].d->name, 291297627Sjmcneill fbsd_chunk_info[i].c->name, sz, (sz / 2048)); 292297627Sjmcneill } 293297627Sjmcneill /* Otherwise it's a swap or filesystem entry, at the bottom */ 294297627Sjmcneill else { 295297627Sjmcneill char onestr[PART_OFF], num[10], *mountpoint, *newfs; 296297627Sjmcneill 297297627Sjmcneill memset(onestr, ' ', PART_OFF - 1); 298297627Sjmcneill onestr[PART_OFF - 1] = '\0'; 299297627Sjmcneill /* Go for two columns */ 300297627Sjmcneill if (prow == (CHUNK_PART_START_ROW + CHUNK_COLUMN_MAX)) { 301297627Sjmcneill pcol = PART_OFF; 302297627Sjmcneill prow = CHUNK_PART_START_ROW; 303297627Sjmcneill } 304297627Sjmcneill memcpy(onestr + PART_PART_COL, fbsd_chunk_info[i].c->name, 305297627Sjmcneill strlen(fbsd_chunk_info[i].c->name)); 306297627Sjmcneill if (fbsd_chunk_info[i].type == PART_FILESYSTEM) { 307297627Sjmcneill if (fbsd_chunk_info[i].c->private) { 308297627Sjmcneill mountpoint = ((PartInfo *)fbsd_chunk_info[i].c->private)->mountpoint; 309297627Sjmcneill newfs = ((PartInfo *)fbsd_chunk_info[i].c->private)->newfs ? "Y" : "N"; 310297627Sjmcneill } 311297627Sjmcneill else { 312297627Sjmcneill fbsd_chunk_info[i].c->private = new_part("", FALSE); 313297627Sjmcneill fbsd_chunk_info[i].c->private_free = safe_free; 314297627Sjmcneill mountpoint = " "; 315297627Sjmcneill newfs = "N"; 316297627Sjmcneill } 317297627Sjmcneill } 318297627Sjmcneill else { 319297627Sjmcneill mountpoint = "swap"; 320297627Sjmcneill newfs = " "; 321297627Sjmcneill } 322297627Sjmcneill for (j = 0; j < MAX_MOUNT_NAME && mountpoint[j]; j++) 323297627Sjmcneill onestr[PART_MOUNT_COL + j] = mountpoint[j]; 324297627Sjmcneill sprintf(num, "%4ldMB", fbsd_chunk_info[i].c->size ? 325297627Sjmcneill fbsd_chunk_info[i].c->size / 2048 : 0); 326297627Sjmcneill memcpy(onestr + PART_SIZE_COL, num, strlen(num)); 327297627Sjmcneill memcpy(onestr + PART_NEWFS_COL, newfs, strlen(newfs)); 328297627Sjmcneill mvaddstr(prow, pcol, onestr); 329297627Sjmcneill ++prow; 330297627Sjmcneill } 331297627Sjmcneill if (i == current_chunk) 332297627Sjmcneill attrset(A_NORMAL); 333297627Sjmcneill } 334297627Sjmcneill} 335297627Sjmcneill 336297627Sjmcneillstatic void 337297627Sjmcneillprint_command_summary() 338297627Sjmcneill{ 339297627Sjmcneill mvprintw(17, 0, 340297627Sjmcneill "The following commands are valid here (upper or lower case):"); 341297627Sjmcneill mvprintw(19, 0, "C = Create Partition D = Delete Partition M = Mount Partition"); 342297627Sjmcneill mvprintw(20, 0, "N = Newfs Options T = Toggle Newfs ESC = Finish Partitioning"); 343297627Sjmcneill mvprintw(21, 0, "The default target will be displayed in "); 344297627Sjmcneill 345297627Sjmcneill attrset(A_REVERSE); 346297627Sjmcneill addstr("reverse video"); 347297627Sjmcneill attrset(A_NORMAL); 348297627Sjmcneill mvprintw(22, 0, "Use F1 or ? to get more help"); 349297627Sjmcneill move(0, 0); 350297627Sjmcneill} 351297627Sjmcneill 352297627Sjmcneillvoid 353297627Sjmcneillpartition_disks(void) 354297627Sjmcneill{ 355297627Sjmcneill int sz, key = 0; 356297627Sjmcneill Boolean partitioning; 357297627Sjmcneill char *msg = NULL; 358297627Sjmcneill PartInfo *p; 359297627Sjmcneill PartType type; 360297627Sjmcneill 361297627Sjmcneill dialog_clear(); 362297627Sjmcneill partitioning = TRUE; 363297627Sjmcneill keypad(stdscr, TRUE); 364297627Sjmcneill record_fbsd_chunks(); 365297627Sjmcneill 366297627Sjmcneill while (partitioning) { 367297627Sjmcneill clear(); 368297627Sjmcneill print_fbsd_chunks(); 369297627Sjmcneill print_command_summary(); 370297627Sjmcneill if (msg) { 371297627Sjmcneill attrset(A_REVERSE); mvprintw(23, 0, msg); attrset(A_NORMAL); 372297627Sjmcneill beep(); 373297627Sjmcneill msg = NULL; 374297627Sjmcneill } 375297627Sjmcneill refresh(); 376297627Sjmcneill key = toupper(getch()); 377297627Sjmcneill switch (key) { 378297627Sjmcneill 379297627Sjmcneill case KEY_UP: 380297627Sjmcneill case '-': 381297627Sjmcneill if (current_chunk != 0) 382297627Sjmcneill --current_chunk; 383297627Sjmcneill break; 384297627Sjmcneill 385297627Sjmcneill case KEY_DOWN: 386297627Sjmcneill case '+': 387297627Sjmcneill case '\r': 388297627Sjmcneill case '\n': 389297627Sjmcneill if (fbsd_chunk_info[current_chunk + 1].d) 390297627Sjmcneill ++current_chunk; 391297627Sjmcneill break; 392297627Sjmcneill 393297627Sjmcneill case KEY_HOME: 394297627Sjmcneill current_chunk = 0; 395297627Sjmcneill break; 396297627Sjmcneill 397297627Sjmcneill case KEY_END: 398297627Sjmcneill while (fbsd_chunk_info[current_chunk + 1].d) 399297627Sjmcneill ++current_chunk; 400297627Sjmcneill break; 401297627Sjmcneill 402297627Sjmcneill case KEY_F(1): 403297627Sjmcneill case '?': 404297627Sjmcneill systemDisplayFile("partitioning.hlp"); 405297627Sjmcneill break; 406297627Sjmcneill 407297627Sjmcneill case 'C': 408297627Sjmcneill if (fbsd_chunk_info[current_chunk].type != PART_SLICE) { 409297627Sjmcneill msg = "You can only do this in a master partition (see top of screen)"; 410297627Sjmcneill break; 411297627Sjmcneill } 412297627Sjmcneill sz = space_free(fbsd_chunk_info[current_chunk].c); 413297627Sjmcneill if (sz <= FS_MIN_SIZE) 414297627Sjmcneill msg = "Not enough space to create additional FreeBSD partition"; 415297627Sjmcneill else { 416297627Sjmcneill char *val, *cp, tmp[20]; 417297627Sjmcneill int size; 418297627Sjmcneill 419297627Sjmcneill snprintf(tmp, 20, "%d", sz); 420297627Sjmcneill val = msgGetInput(tmp, "Please specify the size for new FreeBSD partition in blocks, or append\na trailing `M' for megabytes (e.g. 20M)."); 421297627Sjmcneill if (val && (size = strtol(val, &cp, 0)) > 0) { 422297627Sjmcneill struct chunk *tmp; 423297627Sjmcneill u_long flags = 0; 424297627Sjmcneill 425297627Sjmcneill if (*cp && toupper(*cp) == 'M') 426297627Sjmcneill size *= 2048; 427297627Sjmcneill 428297627Sjmcneill type = get_partition_type(); 429297627Sjmcneill if (type == PART_NONE) 430297627Sjmcneill break; 431297627Sjmcneill else if (type == PART_FILESYSTEM) { 432297627Sjmcneill if ((p = get_mountpoint(NULL)) == NULL) 433297627Sjmcneill break; 434297627Sjmcneill else if (!strcmp(p->mountpoint, "/")) 435297627Sjmcneill flags |= CHUNK_IS_ROOT; 436297627Sjmcneill else 437297627Sjmcneill flags &= ~CHUNK_IS_ROOT; 438297627Sjmcneill } 439297627Sjmcneill else 440297627Sjmcneill p = NULL; 441297627Sjmcneill 442297627Sjmcneill tmp = Create_Chunk_DWIM(fbsd_chunk_info[current_chunk].d, 443297627Sjmcneill fbsd_chunk_info[current_chunk].c, 444297627Sjmcneill size, 445297627Sjmcneill part, 446297627Sjmcneill (type == PART_SWAP) ? 447297627Sjmcneill FS_SWAP : FS_BSDFFS, 448297627Sjmcneill flags); 449297627Sjmcneill if (!tmp) 450297627Sjmcneill msgConfirm("Unable to create the partition. Too big?"); 451297627Sjmcneill else { 452297627Sjmcneill tmp->private = p; 453297627Sjmcneill tmp->private_free = safe_free; 454297627Sjmcneill record_fbsd_chunks(); 455297627Sjmcneill } 456297627Sjmcneill } 457297627Sjmcneill } 458297627Sjmcneill break; 459297627Sjmcneill 460297627Sjmcneill case 'D': /* delete */ 461297627Sjmcneill if (fbsd_chunk_info[current_chunk].type == PART_SLICE) { 462297627Sjmcneill msg = MSG_NOT_APPLICABLE; 463297627Sjmcneill break; 464297627Sjmcneill } 465297627Sjmcneill Delete_Chunk(fbsd_chunk_info[current_chunk].d, 466297627Sjmcneill fbsd_chunk_info[current_chunk].c); 467297627Sjmcneill record_fbsd_chunks(); 468297627Sjmcneill break; 469297627Sjmcneill 470297627Sjmcneill case 'M': /* mount */ 471297627Sjmcneill switch(fbsd_chunk_info[current_chunk].type) { 472297627Sjmcneill case PART_SLICE: 473297627Sjmcneill msg = MSG_NOT_APPLICABLE; 474297627Sjmcneill break; 475305436Smanu 476305436Smanu case PART_SWAP: 477305436Smanu msg = "You don't need to specify a mountpoint for a swap partition."; 478305436Smanu break; 479305436Smanu 480305436Smanu case PART_FILESYSTEM: 481305436Smanu p = get_mountpoint(fbsd_chunk_info[current_chunk].c); 482305436Smanu if (p) { 483305436Smanu p->newfs = FALSE; 484305436Smanu record_fbsd_chunks(); 485305436Smanu } 486305436Smanu break; 487305436Smanu 488305436Smanu default: 489305436Smanu msgFatal("Bogus partition under cursor???"); 490305436Smanu break; 491305436Smanu } 492305436Smanu break; 493305436Smanu 494305436Smanu case 'N': /* Set newfs options */ 495305436Smanu if (fbsd_chunk_info[current_chunk].c->private && 496305436Smanu ((PartInfo *)fbsd_chunk_info[current_chunk].c->private)->newfs) 497305436Smanu getNewfsCmd(fbsd_chunk_info[current_chunk].c->private); 498305436Smanu else 499305436Smanu msg = MSG_NOT_APPLICABLE; 500305436Smanu break; 501305436Smanu 502305436Smanu case 'T': /* Toggle newfs state */ 503305436Smanu if (fbsd_chunk_info[current_chunk].c->private) 504305436Smanu ((PartInfo *)fbsd_chunk_info[current_chunk].c->private)->newfs = !((PartInfo *)fbsd_chunk_info[current_chunk].c->private)->newfs; 505305436Smanu else 506305436Smanu msg = MSG_NOT_APPLICABLE; 507305436Smanu break; 508305436Smanu 509305436Smanu case 'W': 510305436Smanu if (!msgYesNo("Are you sure you want to go into Wizard mode?\n\nThis is an entirely undocumented feature which you are not\nexpected to understand!")) { 511305436Smanu int i; 512305436Smanu 513305436Smanu clear(); 514305436Smanu dialog_clear(); 515305436Smanu end_dialog(); 516305436Smanu DialogActive = FALSE; 517305436Smanu for (i = 0; Disks[i]; i++) 518305436Smanu slice_wizard(Disks[i]); 519305436Smanu clear(); 520305436Smanu dialog_clear(); 521305436Smanu DialogActive = TRUE; 522305436Smanu record_fbsd_chunks(); 523305436Smanu } 524305436Smanu else 525305436Smanu msg = "A most prudent choice!"; 526305436Smanu break; 527305436Smanu 528305436Smanu case 27: /* ESC */ 529305436Smanu partitioning = FALSE; 530305436Smanu break; 531305436Smanu 532305436Smanu default: 533305436Smanu beep(); 534305436Smanu msg = "Type F1 or ? for help"; 535305436Smanu break; 536305436Smanu } 537305436Smanu } 538305436Smanu} 539305436Smanu 540305436Smanuint 541305436Smanuwrite_disks(void) 542305436Smanu{ 543305436Smanu int i; 544305436Smanu extern u_char boot1[], boot2[]; 545305436Smanu extern u_char mbr[], bteasy17[]; 546305436Smanu 547305436Smanu dialog_clear(); 548305436Smanu for (i = 0; Disks[i]; i++) { 549305436Smanu Set_Boot_Blocks(Disks[i], boot1, boot2); 550299688Smanu dialog_clear(); 551299688Smanu if (i == 0 && !msgYesNo("Would you like to install a boot manager?\n\nThis will allow you to easily select between other operating systems\non the first disk, or boot from a disk other than the first.")) 552299688Smanu Set_Boot_Mgr(Disks[i], bteasy17); 553299688Smanu else { 554299688Smanu dialog_clear(); 555299688Smanu if (i == 0 && !msgYesNo("Would you like to remove an existing boot manager?")) 556299688Smanu Set_Boot_Mgr(Disks[i], mbr); 557299688Smanu } 558299688Smanu dialog_clear(); 559299688Smanu if (!msgYesNo("Last Chance! Are you sure you want to write out\nall these changes to disk?")) { 560299688Smanu Write_Disk(Disks[i]); 561299688Smanu return 0; 562299688Smanu } 563299688Smanu } 564299688Smanu return 1; 565299688Smanu} 566299688Smanu