summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sysinstall/devices.c
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1995-05-04 03:51:22 +0000
committerjkh <jkh@FreeBSD.org>1995-05-04 03:51:22 +0000
commitd07e8dc78c2936d50c5e04702d9da353755417d7 (patch)
tree2839676961bb8accde9a8383e3b009d73528e91f /usr.sbin/sysinstall/devices.c
parent1e14740969b9cf0f109839c13be09afa0b42b96d (diff)
downloadFreeBSD-src-d07e8dc78c2936d50c5e04702d9da353755417d7.zip
FreeBSD-src-d07e8dc78c2936d50c5e04702d9da353755417d7.tar.gz
My latest round of changes - make the "slices" editor work.
Diffstat (limited to 'usr.sbin/sysinstall/devices.c')
-rw-r--r--usr.sbin/sysinstall/devices.c244
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;
}
OpenPOWER on IntegriCloud