label.c revision 8549
18549Sjkh/* 28549Sjkh * The new sysinstall program. 38549Sjkh * 48549Sjkh * This is probably the last program in the `sysinstall' line - the next 58549Sjkh * generation being essentially a complete rewrite. 68549Sjkh * 78549Sjkh * $Id: disks.c,v 1.17 1995/05/11 09:01:28 jkh Exp $ 88549Sjkh * 98549Sjkh * Copyright (c) 1995 108549Sjkh * Jordan Hubbard. All rights reserved. 118549Sjkh * 128549Sjkh * Redistribution and use in source and binary forms, with or without 138549Sjkh * modification, are permitted provided that the following conditions 148549Sjkh * are met: 158549Sjkh * 1. Redistributions of source code must retain the above copyright 168549Sjkh * notice, this list of conditions and the following disclaimer, 178549Sjkh * verbatim and that no modifications are made prior to this 188549Sjkh * point in the file. 198549Sjkh * 2. Redistributions in binary form must reproduce the above copyright 208549Sjkh * notice, this list of conditions and the following disclaimer in the 218549Sjkh * documentation and/or other materials provided with the distribution. 228549Sjkh * 3. All advertising materials mentioning features or use of this software 238549Sjkh * must display the following acknowledgement: 248549Sjkh * This product includes software developed by Jordan Hubbard 258549Sjkh * for the FreeBSD Project. 268549Sjkh * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to 278549Sjkh * endorse or promote products derived from this software without specific 288549Sjkh * prior written permission. 298549Sjkh * 308549Sjkh * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 318549Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 328549Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 338549Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 348549Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 358549Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 368549Sjkh * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 378549Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 388549Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 398549Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 408549Sjkh * SUCH DAMAGE. 418549Sjkh * 428549Sjkh */ 438549Sjkh 448549Sjkh#include "sysinstall.h" 458549Sjkh#include <ctype.h> 468549Sjkh#include <sys/disklabel.h> 478549Sjkh 488549Sjkh/* 498549Sjkh * Everything to do with editing the contents of disk labels. 508549Sjkh */ 518549Sjkh 528549Sjkh/* A nice message we use a lot in the disklabel editor */ 538549Sjkh#define MSG_NOT_APPLICABLE "That option is not applicable here" 548549Sjkh 558549Sjkh/* 568549Sjkh * I make some pretty gross assumptions about having a max of 50 chunks 578549Sjkh * total - 8 slices and 42 partitions. I can't easily display many more 588549Sjkh * than that on the screen at once! 598549Sjkh * 608549Sjkh * For 2.1 I'll revisit this and try to make it more dynamic, but since 618549Sjkh * this will catch 99.99% of all possible cases, I'm not too worried. 628549Sjkh */ 638549Sjkh#define MAX_CHUNKS 50 648549Sjkh 658549Sjkh/* Where to start printing the freebsd slices */ 668549Sjkh#define CHUNK_SLICE_START_ROW 2 678549Sjkh#define CHUNK_PART_START_ROW 10 688549Sjkh 698549Sjkh/* The smallest filesystem we're willing to create */ 708549Sjkh#define FS_MIN_SIZE 2048 718549Sjkh 728549Sjkh 738549Sjkh/* All the chunks currently displayed on the screen */ 748549Sjkhstatic struct { 758549Sjkh struct disk *d; 768549Sjkh struct chunk *c; 778549Sjkh PartType type; 788549Sjkh} label_chunk_info[MAX_CHUNKS + 1]; 798549Sjkhstatic int here; 808549Sjkh 818549Sjkh/* See if we're already using a desired partition name */ 828549Sjkhstatic Boolean 838549Sjkhcheck_conflict(char *name) 848549Sjkh{ 858549Sjkh int i; 868549Sjkh 878549Sjkh for (i = 0; label_chunk_info[i].d; i++) 888549Sjkh if (label_chunk_info[i].type == PART_FILESYSTEM 898549Sjkh && label_chunk_info[i].c->private 908549Sjkh && !strcmp(((PartInfo *)label_chunk_info[i].c->private)->mountpoint, name)) 918549Sjkh return TRUE; 928549Sjkh return FALSE; 938549Sjkh} 948549Sjkh 958549Sjkh/* How much space is in this FreeBSD slice? */ 968549Sjkhstatic int 978549Sjkhspace_free(struct chunk *c) 988549Sjkh{ 998549Sjkh struct chunk *c1 = c->part; 1008549Sjkh int sz = c->size; 1018549Sjkh 1028549Sjkh while (c1) { 1038549Sjkh if (c1->type != unused) 1048549Sjkh sz -= c1->size; 1058549Sjkh c1 = c1->next; 1068549Sjkh } 1078549Sjkh if (sz < 0) 1088549Sjkh msgFatal("Partitions are larger than actual chunk??"); 1098549Sjkh return sz; 1108549Sjkh} 1118549Sjkh 1128549Sjkh/* Snapshot the current situation into the displayed chunks structure */ 1138549Sjkhstatic void 1148549Sjkhrecord_label_chunks() 1158549Sjkh{ 1168549Sjkh int i, j, p; 1178549Sjkh struct chunk *c1, *c2; 1188549Sjkh Device **devs; 1198549Sjkh 1208549Sjkh devs = deviceFind(NULL, DEVICE_TYPE_DISK); 1218549Sjkh if (!devs) { 1228549Sjkh msgConfirm("No disks found!"); 1238549Sjkh return; 1248549Sjkh } 1258549Sjkh 1268549Sjkh j = p = 0; 1278549Sjkh for (i = 0; devs[i]; i++) { 1288549Sjkh if (!((Disk *)devs[i]->private)->chunks) 1298549Sjkh msgFatal("No chunk list found for %s!", ((Disk *)devs[i]->private)->name); 1308549Sjkh 1318549Sjkh /* Put the freebsd chunks first */ 1328549Sjkh for (c1 = ((Disk *)devs[i]->private)->chunks->part; c1; c1 = c1->next) { 1338549Sjkh if (c1->type == freebsd) { 1348549Sjkh label_chunk_info[j].type = PART_SLICE; 1358549Sjkh label_chunk_info[j].d = ((Disk *)devs[i]->private); 1368549Sjkh label_chunk_info[j].c = c1; 1378549Sjkh ++j; 1388549Sjkh } 1398549Sjkh } 1408549Sjkh } 1418549Sjkh for (i = 0; ((Disk *)devs[i]->private); i++) { 1428549Sjkh /* Then buzz through and pick up the partitions */ 1438549Sjkh for (c1 = ((Disk *)devs[i]->private)->chunks->part; c1; c1 = c1->next) { 1448549Sjkh if (c1->type == freebsd) { 1458549Sjkh for (c2 = c1->part; c2; c2 = c2->next) { 1468549Sjkh if (c2->type == part) { 1478549Sjkh if (c2->subtype == FS_SWAP) 1488549Sjkh label_chunk_info[j].type = PART_SWAP; 1498549Sjkh else 1508549Sjkh label_chunk_info[j].type = PART_FILESYSTEM; 1518549Sjkh label_chunk_info[j].d = ((Disk *)devs[i]->private); 1528549Sjkh label_chunk_info[j].c = c2; 1538549Sjkh ++j; 1548549Sjkh } 1558549Sjkh } 1568549Sjkh } 1578549Sjkh else if (c1->type == fat) { 1588549Sjkh label_chunk_info[j].type = PART_FAT; 1598549Sjkh label_chunk_info[j].d = ((Disk *)devs[i]->private); 1608549Sjkh label_chunk_info[j].c = c1; 1618549Sjkh } 1628549Sjkh } 1638549Sjkh } 1648549Sjkh label_chunk_info[j].d = NULL; 1658549Sjkh label_chunk_info[j].c = NULL; 1668549Sjkh if (here >= j) 1678549Sjkh here = j ? j - 1 : 0; 1688549Sjkh} 1698549Sjkh 1708549Sjkh/* A new partition entry */ 1718549Sjkhstatic PartInfo * 1728549Sjkhnew_part(char *mpoint, Boolean newfs) 1738549Sjkh{ 1748549Sjkh PartInfo *ret; 1758549Sjkh 1768549Sjkh ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); 1778549Sjkh strncpy(ret->mountpoint, mpoint, FILENAME_MAX); 1788549Sjkh strcpy(ret->newfs_cmd, "newfs"); 1798549Sjkh ret->newfs = newfs; 1808549Sjkh return ret; 1818549Sjkh} 1828549Sjkh 1838549Sjkh/* Get the mountpoint for a partition and save it away */ 1848549SjkhPartInfo * 1858549Sjkhget_mountpoint(struct chunk *parent, struct chunk *me) 1868549Sjkh{ 1878549Sjkh char *val; 1888549Sjkh PartInfo *tmp; 1898549Sjkh 1908549Sjkh val = msgGetInput(me && me->private ? ((PartInfo *)me->private)->mountpoint : NULL, 1918549Sjkh "Please specify a mount point for the partition"); 1928549Sjkh if (val) { 1938549Sjkh /* Is it just the same value? */ 1948549Sjkh if (me && me->private && !strcmp(((PartInfo *)me->private)->mountpoint, val)) 1958549Sjkh return NULL; 1968549Sjkh if (check_conflict(val)) { 1978549Sjkh msgConfirm("You already have a mount point for %s assigned!", val); 1988549Sjkh return NULL; 1998549Sjkh } 2008549Sjkh else if (*val != '/') { 2018549Sjkh msgConfirm("Mount point must start with a / character"); 2028549Sjkh return NULL; 2038549Sjkh } 2048549Sjkh else if (!strcmp(val, "/")) { 2058549Sjkh if (parent) { 2068549Sjkh if (parent->flags & CHUNK_PAST_1024) { 2078549Sjkh msgConfirm("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!"); 2088549Sjkh return NULL; 2098549Sjkh } 2108549Sjkh else if (!(parent->flags & CHUNK_BSD_COMPAT)) { 2118549Sjkh msgConfirm("This region cannot be used for your root partition as\nthe FreeBSD boot code cannot deal with a root partition created in\nsuch a region. Please choose another partition for this."); 2128549Sjkh return NULL; 2138549Sjkh } 2148549Sjkh } 2158549Sjkh if (me) 2168549Sjkh me->flags |= CHUNK_IS_ROOT; 2178549Sjkh } 2188549Sjkh else if (me) 2198549Sjkh me->flags &= ~CHUNK_IS_ROOT; 2208549Sjkh safe_free(me ? me->private : NULL); 2218549Sjkh tmp = new_part(val, TRUE); 2228549Sjkh if (me) { 2238549Sjkh me->private = tmp; 2248549Sjkh me->private_free = safe_free; 2258549Sjkh } 2268549Sjkh return tmp; 2278549Sjkh } 2288549Sjkh return NULL; 2298549Sjkh} 2308549Sjkh 2318549Sjkh/* Get the type of the new partiton */ 2328549Sjkhstatic PartType 2338549Sjkhget_partition_type(void) 2348549Sjkh{ 2358549Sjkh char selection[20]; 2368549Sjkh static unsigned char *fs_types[] = { 2378549Sjkh "FS", 2388549Sjkh "A file system", 2398549Sjkh "Swap", 2408549Sjkh "A swap partition.", 2418549Sjkh }; 2428549Sjkh 2438549Sjkh if (!dialog_menu("Please choose a partition type", 2448549Sjkh "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)) { 2458549Sjkh if (!strcmp(selection, "FS")) 2468549Sjkh return PART_FILESYSTEM; 2478549Sjkh else if (!strcmp(selection, "Swap")) 2488549Sjkh return PART_SWAP; 2498549Sjkh } 2508549Sjkh return PART_NONE; 2518549Sjkh} 2528549Sjkh 2538549Sjkh/* If the user wants a special newfs command for this, set it */ 2548549Sjkhstatic void 2558549SjkhgetNewfsCmd(PartInfo *p) 2568549Sjkh{ 2578549Sjkh char *val; 2588549Sjkh 2598549Sjkh val = msgGetInput(p->newfs_cmd, 2608549Sjkh "Please enter the newfs command and options you'd like to use in\ncreating this file system."); 2618549Sjkh if (val) 2628549Sjkh strncpy(p->newfs_cmd, val, NEWFS_CMD_MAX); 2638549Sjkh} 2648549Sjkh 2658549Sjkh 2668549Sjkh#define MAX_MOUNT_NAME 12 2678549Sjkh 2688549Sjkh#define PART_PART_COL 0 2698549Sjkh#define PART_MOUNT_COL 8 2708549Sjkh#define PART_SIZE_COL (PART_MOUNT_COL + MAX_MOUNT_NAME + 3) 2718549Sjkh#define PART_NEWFS_COL (PART_SIZE_COL + 7) 2728549Sjkh#define PART_OFF 38 2738549Sjkh 2748549Sjkh/* How many mounted partitions to display in column before going to next */ 2758549Sjkh#define CHUNK_COLUMN_MAX 6 2768549Sjkh 2778549Sjkh/* stick this all up on the screen */ 2788549Sjkhstatic void 2798549Sjkhprint_label_chunks(void) 2808549Sjkh{ 2818549Sjkh int i, j, srow, prow, pcol; 2828549Sjkh int sz; 2838549Sjkh 2848549Sjkh attrset(A_REVERSE); 2858549Sjkh mvaddstr(0, 25, "FreeBSD Disklabel Editor"); 2868549Sjkh attrset(A_NORMAL); 2878549Sjkh 2888549Sjkh for (i = 0; i < 2; i++) { 2898549Sjkh attrset(A_UNDERLINE); 2908549Sjkh mvaddstr(CHUNK_PART_START_ROW - 1, PART_PART_COL + (i * PART_OFF), 2918549Sjkh "Part"); 2928549Sjkh attrset(A_NORMAL); 2938549Sjkh 2948549Sjkh attrset(A_UNDERLINE); 2958549Sjkh mvaddstr(CHUNK_PART_START_ROW - 1, PART_MOUNT_COL + (i * PART_OFF), 2968549Sjkh "Mount"); 2978549Sjkh attrset(A_NORMAL); 2988549Sjkh 2998549Sjkh attrset(A_UNDERLINE); 3008549Sjkh mvaddstr(CHUNK_PART_START_ROW - 1, PART_SIZE_COL + (i * PART_OFF) + 2, 3018549Sjkh "Size"); 3028549Sjkh attrset(A_NORMAL); 3038549Sjkh 3048549Sjkh attrset(A_UNDERLINE); 3058549Sjkh mvaddstr(CHUNK_PART_START_ROW - 1, PART_NEWFS_COL + (i * PART_OFF), 3068549Sjkh "Newfs"); 3078549Sjkh attrset(A_NORMAL); 3088549Sjkh } 3098549Sjkh 3108549Sjkh srow = CHUNK_SLICE_START_ROW; 3118549Sjkh prow = CHUNK_PART_START_ROW; 3128549Sjkh pcol = 0; 3138549Sjkh 3148549Sjkh for (i = 0; label_chunk_info[i].d; i++) { 3158549Sjkh if (i == here) 3168549Sjkh attrset(A_REVERSE); 3178549Sjkh /* Is it a slice entry displayed at the top? */ 3188549Sjkh if (label_chunk_info[i].type == PART_SLICE) { 3198549Sjkh sz = space_free(label_chunk_info[i].c); 3208549Sjkh mvprintw(srow++, 0, 3218549Sjkh "Disk: %s\tPartition name: %s\tFree: %d blocks (%dMB)", 3228549Sjkh label_chunk_info[i].d->name, 3238549Sjkh label_chunk_info[i].c->name, sz, (sz / 2048)); 3248549Sjkh } 3258549Sjkh /* Otherwise it's a DOS, swap or filesystem entry, at the bottom */ 3268549Sjkh else { 3278549Sjkh char onestr[PART_OFF], num[10], *mountpoint, *newfs; 3288549Sjkh 3298549Sjkh /* 3308549Sjkh * We copy this into a blank-padded string so that it looks like 3318549Sjkh * a solid bar in reverse-video 3328549Sjkh */ 3338549Sjkh memset(onestr, ' ', PART_OFF - 1); 3348549Sjkh onestr[PART_OFF - 1] = '\0'; 3358549Sjkh /* Go for two columns */ 3368549Sjkh if (prow == (CHUNK_PART_START_ROW + CHUNK_COLUMN_MAX)) { 3378549Sjkh pcol = PART_OFF; 3388549Sjkh prow = CHUNK_PART_START_ROW; 3398549Sjkh } 3408549Sjkh memcpy(onestr + PART_PART_COL, label_chunk_info[i].c->name, 3418549Sjkh strlen(label_chunk_info[i].c->name)); 3428549Sjkh /* If it's a filesystem, display the mountpoint */ 3438549Sjkh if (label_chunk_info[i].type == PART_FILESYSTEM) { 3448549Sjkh if (label_chunk_info[i].c->private == NULL) { 3458549Sjkh static int mnt = 0; 3468549Sjkh char foo[10]; 3478549Sjkh 3488549Sjkh /* 3498549Sjkh * Hmm! A partition that must have already been here. 3508549Sjkh * Fill in a fake mountpoint and register it 3518549Sjkh */ 3528549Sjkh sprintf(foo, "/mnt%d", mnt++); 3538549Sjkh label_chunk_info[i].c->private = new_part(foo, FALSE); 3548549Sjkh label_chunk_info[i].c->private_free = safe_free; 3558549Sjkh } 3568549Sjkh mountpoint = ((PartInfo *)label_chunk_info[i].c->private)->mountpoint; 3578549Sjkh newfs = ((PartInfo *)label_chunk_info[i].c->private)->newfs ? "Y" : "N"; 3588549Sjkh } 3598549Sjkh else if (label_chunk_info[i].type == PART_SWAP) { 3608549Sjkh mountpoint = "swap"; 3618549Sjkh newfs = " "; 3628549Sjkh } 3638549Sjkh else if (label_chunk_info[i].type == PART_FAT) { 3648549Sjkh mountpoint = "DOS FAT"; 3658549Sjkh newfs = "*"; 3668549Sjkh } 3678549Sjkh else { 3688549Sjkh mountpoint = "<unknown>"; 3698549Sjkh newfs = "*"; 3708549Sjkh } 3718549Sjkh for (j = 0; j < MAX_MOUNT_NAME && mountpoint[j]; j++) 3728549Sjkh onestr[PART_MOUNT_COL + j] = mountpoint[j]; 3738549Sjkh snprintf(num, 10, "%4ldMB", label_chunk_info[i].c->size ? 3748549Sjkh label_chunk_info[i].c->size / 2048 : 0); 3758549Sjkh memcpy(onestr + PART_SIZE_COL, num, strlen(num)); 3768549Sjkh memcpy(onestr + PART_NEWFS_COL, newfs, strlen(newfs)); 3778549Sjkh onestr[PART_NEWFS_COL + strlen(newfs)] = '\0'; 3788549Sjkh mvaddstr(prow, pcol, onestr); 3798549Sjkh ++prow; 3808549Sjkh } 3818549Sjkh if (i == here) 3828549Sjkh attrset(A_NORMAL); 3838549Sjkh } 3848549Sjkh} 3858549Sjkh 3868549Sjkhstatic void 3878549Sjkhprint_command_summary() 3888549Sjkh{ 3898549Sjkh mvprintw(17, 0, 3908549Sjkh "The following commands are valid here (upper or lower case):"); 3918549Sjkh mvprintw(19, 0, "C = Create Partition D = Delete Partition M = Mount Partition"); 3928549Sjkh mvprintw(20, 0, "N = Newfs Options T = Toggle Newfs ESC = Finish Partitioning"); 3938549Sjkh mvprintw(21, 0, "The default target will be displayed in "); 3948549Sjkh 3958549Sjkh attrset(A_REVERSE); 3968549Sjkh addstr("reverse video."); 3978549Sjkh attrset(A_NORMAL); 3988549Sjkh mvprintw(22, 0, "Use F1 or ? to get more help, arrow keys to move."); 3998549Sjkh move(0, 0); 4008549Sjkh} 4018549Sjkh 4028549Sjkhvoid 4038549SjkhdiskLabelEditor(char *str) 4048549Sjkh{ 4058549Sjkh int sz, key = 0; 4068549Sjkh Boolean labeling; 4078549Sjkh char *msg = NULL; 4088549Sjkh PartInfo *p; 4098549Sjkh PartType type; 4108549Sjkh 4118549Sjkh dialog_clear(); 4128549Sjkh labeling = TRUE; 4138549Sjkh keypad(stdscr, TRUE); 4148549Sjkh record_label_chunks(); 4158549Sjkh 4168549Sjkh while (labeling) { 4178549Sjkh clear(); 4188549Sjkh print_label_chunks(); 4198549Sjkh print_command_summary(); 4208549Sjkh if (msg) { 4218549Sjkh attrset(A_REVERSE); mvprintw(23, 0, msg); attrset(A_NORMAL); 4228549Sjkh beep(); 4238549Sjkh msg = NULL; 4248549Sjkh } 4258549Sjkh refresh(); 4268549Sjkh key = toupper(getch()); 4278549Sjkh switch (key) { 4288549Sjkh 4298549Sjkh case KEY_UP: 4308549Sjkh case '-': 4318549Sjkh if (here != 0) 4328549Sjkh --here; 4338549Sjkh break; 4348549Sjkh 4358549Sjkh case KEY_DOWN: 4368549Sjkh case '+': 4378549Sjkh case '\r': 4388549Sjkh case '\n': 4398549Sjkh if (label_chunk_info[here + 1].d) 4408549Sjkh ++here; 4418549Sjkh break; 4428549Sjkh 4438549Sjkh case KEY_HOME: 4448549Sjkh here = 0; 4458549Sjkh break; 4468549Sjkh 4478549Sjkh case KEY_END: 4488549Sjkh while (label_chunk_info[here + 1].d) 4498549Sjkh ++here; 4508549Sjkh break; 4518549Sjkh 4528549Sjkh case KEY_F(1): 4538549Sjkh case '?': 4548549Sjkh systemDisplayFile("disklabel.hlp"); 4558549Sjkh break; 4568549Sjkh 4578549Sjkh case 'C': 4588549Sjkh if (label_chunk_info[here].type != PART_SLICE) { 4598549Sjkh msg = "You can only do this in a master partition (see top of screen)"; 4608549Sjkh break; 4618549Sjkh } 4628549Sjkh sz = space_free(label_chunk_info[here].c); 4638549Sjkh if (sz <= FS_MIN_SIZE) 4648549Sjkh msg = "Not enough space to create additional FreeBSD partition"; 4658549Sjkh else { 4668549Sjkh char *val, *cp, tmp[20]; 4678549Sjkh int size; 4688549Sjkh 4698549Sjkh snprintf(tmp, 20, "%d", sz); 4708549Sjkh val = msgGetInput(tmp, "Please specify the size for new FreeBSD partition in blocks, or append\na trailing `M' for megabytes (e.g. 20M)."); 4718549Sjkh if (val && (size = strtol(val, &cp, 0)) > 0) { 4728549Sjkh struct chunk *tmp; 4738549Sjkh u_long flags = 0; 4748549Sjkh 4758549Sjkh if (*cp && toupper(*cp) == 'M') 4768549Sjkh size *= 2048; 4778549Sjkh 4788549Sjkh type = get_partition_type(); 4798549Sjkh if (type == PART_NONE) 4808549Sjkh break; 4818549Sjkh else if (type == PART_FILESYSTEM) { 4828549Sjkh if ((p = get_mountpoint(label_chunk_info[here].c, NULL)) == NULL) 4838549Sjkh break; 4848549Sjkh else if (!strcmp(p->mountpoint, "/")) 4858549Sjkh flags |= CHUNK_IS_ROOT; 4868549Sjkh else 4878549Sjkh flags &= ~CHUNK_IS_ROOT; 4888549Sjkh } 4898549Sjkh else 4908549Sjkh p = NULL; 4918549Sjkh 4928549Sjkh tmp = Create_Chunk_DWIM(label_chunk_info[here].d, 4938549Sjkh label_chunk_info[here].c, 4948549Sjkh size, part, 4958549Sjkh (type == PART_SWAP) ? FS_SWAP : FS_BSDFFS, 4968549Sjkh flags); 4978549Sjkh if (!tmp) 4988549Sjkh msgConfirm("Unable to create the partition. Too big?"); 4998549Sjkh else { 5008549Sjkh tmp->private = p; 5018549Sjkh tmp->private_free = safe_free; 5028549Sjkh record_label_chunks(); 5038549Sjkh } 5048549Sjkh } 5058549Sjkh } 5068549Sjkh break; 5078549Sjkh 5088549Sjkh case 'D': /* delete */ 5098549Sjkh if (label_chunk_info[here].type == PART_SLICE) { 5108549Sjkh msg = MSG_NOT_APPLICABLE; 5118549Sjkh break; 5128549Sjkh } 5138549Sjkh else if (label_chunk_info[here].type == PART_FAT) { 5148549Sjkh msg = "Use the Disk Partition Editor to delete this"; 5158549Sjkh break; 5168549Sjkh } 5178549Sjkh Delete_Chunk(label_chunk_info[here].d, label_chunk_info[here].c); 5188549Sjkh record_label_chunks(); 5198549Sjkh break; 5208549Sjkh 5218549Sjkh case 'M': /* mount */ 5228549Sjkh switch(label_chunk_info[here].type) { 5238549Sjkh case PART_SLICE: 5248549Sjkh msg = MSG_NOT_APPLICABLE; 5258549Sjkh break; 5268549Sjkh 5278549Sjkh case PART_SWAP: 5288549Sjkh msg = "You don't need to specify a mountpoint for a swap partition."; 5298549Sjkh break; 5308549Sjkh 5318549Sjkh case PART_DOS: 5328549Sjkh case PART_FILESYSTEM: 5338549Sjkh p = get_mountpoint(NULL, label_chunk_info[here].c); 5348549Sjkh if (p) { 5358549Sjkh p->newfs = FALSE; 5368549Sjkh record_label_chunks(); 5378549Sjkh } 5388549Sjkh break; 5398549Sjkh 5408549Sjkh default: 5418549Sjkh msgFatal("Bogus partition under cursor???"); 5428549Sjkh break; 5438549Sjkh } 5448549Sjkh break; 5458549Sjkh 5468549Sjkh case 'N': /* Set newfs options */ 5478549Sjkh if (label_chunk_info[here].c->private && 5488549Sjkh ((PartInfo *)label_chunk_info[here].c->private)->newfs) 5498549Sjkh getNewfsCmd(label_chunk_info[here].c->private); 5508549Sjkh else 5518549Sjkh msg = MSG_NOT_APPLICABLE; 5528549Sjkh break; 5538549Sjkh 5548549Sjkh case 'T': /* Toggle newfs state */ 5558549Sjkh if (label_chunk_info[here].type == PART_FILESYSTEM && 5568549Sjkh label_chunk_info[here].c->private) 5578549Sjkh ((PartInfo *)label_chunk_info[here].c->private)->newfs = 5588549Sjkh !((PartInfo *)label_chunk_info[here].c->private)->newfs; 5598549Sjkh else 5608549Sjkh msg = MSG_NOT_APPLICABLE; 5618549Sjkh break; 5628549Sjkh 5638549Sjkh case 'W': 5648549Sjkh 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!")) { 5658549Sjkh int i; 5668549Sjkh Device **devs; 5678549Sjkh 5688549Sjkh clear(); 5698549Sjkh dialog_clear(); 5708549Sjkh end_dialog(); 5718549Sjkh DialogActive = FALSE; 5728549Sjkh devs = deviceFind(NULL, DEVICE_TYPE_DISK); 5738549Sjkh if (!devs) { 5748549Sjkh msgConfirm("Can't find any disk devicse!"); 5758549Sjkh break; 5768549Sjkh } 5778549Sjkh for (i = 0; ((Disk *)devs[i]->private); i++) 5788549Sjkh slice_wizard(((Disk *)devs[i]->private)); 5798549Sjkh clear(); 5808549Sjkh dialog_clear(); 5818549Sjkh DialogActive = TRUE; 5828549Sjkh record_label_chunks(); 5838549Sjkh } 5848549Sjkh else 5858549Sjkh msg = "A most prudent choice!"; 5868549Sjkh break; 5878549Sjkh 5888549Sjkh case 27: /* ESC */ 5898549Sjkh labeling = FALSE; 5908549Sjkh break; 5918549Sjkh 5928549Sjkh default: 5938549Sjkh beep(); 5948549Sjkh msg = "Type F1 or ? for help"; 5958549Sjkh break; 5968549Sjkh } 5978549Sjkh } 5988549Sjkh variable_set2(DISK_LABELLED, "yes"); 5998549Sjkh} 6008549Sjkh 6018549Sjkh 6028549Sjkh 603