diff options
Diffstat (limited to 'usr.sbin/sysinstall/devices.c')
-rw-r--r-- | usr.sbin/sysinstall/devices.c | 244 |
1 files changed, 214 insertions, 30 deletions
diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c index 0f57283..d45d2df 100644 --- a/usr.sbin/sysinstall/devices.c +++ b/usr.sbin/sysinstall/devices.c @@ -4,7 +4,7 @@ * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: install.c,v 1.2 1995/04/27 18:03:53 jkh Exp $ + * $Id: devices.c,v 1.1 1995/05/01 21:56:19 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -44,6 +44,9 @@ #include "sysinstall.h" #include "libdisk.h" +/* Where we start displaying chunk information on the screen */ +#define CHUNK_START_ROW 5 + /* Get all device information for a given device class */ Device * device_get_all(DeviceType which, int *ndevs) @@ -71,26 +74,78 @@ device_get_all(DeviceType which, int *ndevs) return devs; } -void -device_print_chunk(struct chunk *c1, int offset, int *row) +static struct chunk *chunk_info[10]; +static int current_chunk; + +static void +record_chunks(char *disk, struct disk *d) { - CHAR_N - - if (!c1) - return; - mvprintw(*row++, offset, "%10lu %10lu %10lu %-8s %d %-8s %4d %lx", - c1->offset, c1->size, c1->end, c1->name, c1->type, - chunk_n[c1->type], c1->subtype, c1->flags); - device_print_chunk(c1->part, offset + 2, row); - device_print_chunk(c1->next, offset, row); + struct chunk *c1; + int i = 0; + int last_free = 0; + if (!d->chunks) + msgFatal("No chunk list found for %s!", disk); + c1 = d->chunks->part; + while (c1) { + if (c1->type == unused && c1->size > last_free) { + last_free = c1->size; + current_chunk = i; + } + chunk_info[i++] = c1; + c1 = c1->next; + } + chunk_info[i] = NULL; } -int +static void +print_chunks(char *disk, struct disk *d) +{ + int row; + int i; + + attrset(A_NORMAL); + mvaddstr(0, 0, "Disk name:\t"); + attrset(A_BOLD); addstr(disk); attrset(A_NORMAL); + mvprintw(1, 0, + "BIOS Geometry:\t%lu cyls/%lu heads/%lu sectors", + d->bios_cyl, d->bios_hd, d->bios_sect); + mvprintw(3, 1, "%10s %10s %10s %8s %8s %8s %8s %8s", + "Offset", "Size", "End", "Name", "PType", "Desc", + "Subtype", "Flags"); + attrset(A_NORMAL); + for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) { + if (i == current_chunk) + attrset(A_BOLD); + mvprintw(row, 2, "%10lu %10lu %10lu %8s %8d %8s %8d %6lx", + chunk_info[i]->offset, chunk_info[i]->size, + chunk_info[i]->end, chunk_info[i]->name, + chunk_info[i]->type, chunk_n[chunk_info[i]->type], + chunk_info[i]->subtype, chunk_info[i]->flags); + if (i == current_chunk) + attrset(A_NORMAL); + } +} + +static void +print_command_summary() +{ + mvprintw(15, 0, "The following commands are supported (in upper or lower case):"); + mvprintw(17, 0, "C = Create New Partition D = Delete Partition"); + mvprintw(18, 0, "B = Scan For Bad Blocks U = Undo All Changes"); + mvprintw(19, 0, "ESC = Proceed to next screen"); + mvprintw(21, 0, "The currently selected partition is displayed in "); + attrset(A_BOLD); addstr("bold"); attrset(A_NORMAL); + move(0, 0); +} + +struct disk * device_slice_disk(char *disk) { struct disk *d; char *p; - int row; + int key = 0; + Boolean chunking; + char *msg = NULL; d = Open_Disk(disk); if (!d) @@ -100,23 +155,152 @@ device_slice_disk(char *disk) msgConfirm(p); free(p); } + dialog_clear(); - while (1) { + chunking = TRUE; + keypad(stdscr, TRUE); + + record_chunks(disk, d); + while (chunking) { clear(); - mvprintw(0, 0, "Disk name: %s, Flags: %lx", disk, d->flags); - mvprintw(1, 0, - "Real Geometry: %lu/%lu/%lu, BIOS Geometry: %lu/%lu/%lu [cyls/heads/sectors]", - d->real_cyl, d->real_hd, d->real_sect, - d->bios_cyl, d->bios_hd, d->bios_sect); - mvprintw(4, 0, "%10s %10s %10s %-8s %4s %-8s %4s %4s", - "Offset", "Size", "End", "Name", "PType", "Desc", - "Subtype", "Flags"); - row = 5; - device_print_chunk(d->chunks, 0, &row); - move(23, 0); - addstr("Done!"); - if (getch() == 'q') - return 0; + print_chunks(disk, d); + print_command_summary(); + if (msg) { + standout(); mvprintw(23, 0, msg); standend(); + beep(); + msg = NULL; + } + refresh(); + + key = getch(); + switch (key) { + case KEY_UP: + case '-': + if (current_chunk != 0) + --current_chunk; + break; + + case KEY_DOWN: + case '+': + case '\r': + case '\n': + if (chunk_info[current_chunk + 1]) + ++current_chunk; + break; + + case KEY_HOME: + current_chunk = 0; + break; + + case KEY_END: + while (chunk_info[current_chunk + 1]) + ++current_chunk; + break; + + case KEY_F(1): + case '?': + systemDisplayFile("slice.hlp"); + break; + + case 'B': + case 'b': + if (chunk_info[current_chunk]->type != freebsd) + msg = "Can only scan for bad blocks in FreeBSD partition."; + else + chunk_info[current_chunk]->flags |= CHUNK_BAD144; + break; + + case 'C': + case 'c': + if (chunk_info[current_chunk]->type != unused) + msg = "Partition in use, delete it first or move to an unused one."; + else { + char *val; + char tmp[20]; + int size; + + snprintf(tmp, 20, "%d", chunk_info[current_chunk]->size); + val = msgGetInput(tmp, "Please specify size for new FreeBSD partition"); + if (val && (size = atoi(val)) > 0) { + Create_Chunk(d, chunk_info[current_chunk]->offset, + size, + freebsd, + 3, + chunk_info[current_chunk]->flags); + record_chunks(disk, d); + } + } + break; + + case 'D': + case 'd': + if (chunk_info[current_chunk]->type == unused) + msg = "Partition is already unused!"; + else { + Delete_Chunk(d, chunk_info[current_chunk]); + record_chunks(disk, d); + } + break; + + case 'U': + case 'u': + Free_Disk(d); + d = Open_Disk(disk); + record_chunks(disk, d); + break; + + case 27: /* ESC */ + chunking = FALSE; + break; + + default: + msg = "Invalid character typed."; + break; + } + } + clear(); + refresh(); + return d; +} + +/* + * Create a menu listing all the devices in the system. The pass-in menu + * is expected to be a "prototype" from which the new menu is cloned. + */ +DMenu * +device_create_disk_menu(DMenu *menu, Device **rdevs, int (*hook)()) +{ + Device *devices; + int numdevs; + + devices = device_get_all(DEVICE_TYPE_DISK, &numdevs); + *rdevs = devices; + if (!devices) { + msgConfirm("No devices suitable for installation found!\n\nPlease verify that your disk controller (and attached drives) were detected properly. This can be done by selecting the ``Bootmsg'' option on the main menu and reviewing the boot messages carefully."); + return NULL; + } + else { + Device *start; + DMenu *tmp; + int i; + + tmp = (DMenu *)safe_malloc(sizeof(DMenu) + + (sizeof(DMenuItem) * (numdevs + 1))); + bcopy(menu, tmp, sizeof(DMenu)); + for (start = devices, i = 0; start->name[0]; start++, i++) { + tmp->items[i].title = start->name; + if (!strncmp(start->name, "sd", 2)) + tmp->items[i].prompt = "SCSI disk"; + else if (!strncmp(start->name, "wd", 2)) + tmp->items[i].prompt = "IDE/ESDI/MFM/ST506 disk"; + else + msgFatal("Unknown disk type: %s!", start->name); + tmp->items[i].type = DMENU_CALL; + tmp->items[i].ptr = hook; + tmp->items[i].disabled = FALSE; + } + tmp->items[i].type = DMENU_NOP; + tmp->items[i].title = NULL; + return tmp; } - return 0; } |