summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/sysinstall/label.c428
-rw-r--r--sbin/sysinstall/sysinstall.h4
2 files changed, 432 insertions, 0 deletions
diff --git a/sbin/sysinstall/label.c b/sbin/sysinstall/label.c
index 13d18ad6273f..f7965cfada48 100644
--- a/sbin/sysinstall/label.c
+++ b/sbin/sysinstall/label.c
@@ -1,9 +1,437 @@
#define DKTYPENAMES
#include <sys/param.h>
+#define DKTYPENAMES
+#include <sys/param.h>
+#include <ufs/ffs/fs.h>
#include <sys/types.h>
+#include <string.h>
#include <sys/disklabel.h>
#include <ufs/ffs/fs.h>
+int disk_size(struct disklabel *);
+int sectstoMb(int, int);
+
+char *partname[MAXPARTITIONS] = {"a", "b", "c", "d", "e", "f", "g", "h"};
+
+#define EDITABLES 3
+#define FSTYPE 0
+#define UPARTSIZES 1
+#define MOUNTPOINTS 2
+struct field {
+ int y;
+ int x;
+ int width;
+ char field[80];
+} field;
+
+struct field label_fields[MAXPARTITIONS][EDITABLES];
+
+void
+setup_label_fields(struct disklabel *lbl)
+{
+ int i;
+
+ for (i=0; i < MAXPARTITIONS; i++) {
+ label_fields[i][0].y = 4 + (i * 2);
+ label_fields[i][0].x = 15;
+ label_fields[i][0].width = 15;
+ sprintf(label_fields[i][0].field, "%s",
+ fstypenames[lbl->d_partitions[i].p_fstype]);
+ label_fields[i][1].y = 4 + (i * 2);
+ label_fields[i][1].x = 35;
+ label_fields[i][1].width = 9;
+ sprintf(label_fields[i][1].field, "%d",
+ sectstoMb(lbl->d_partitions[i].p_size, lbl->d_secsize));
+ label_fields[i][2].y = 4 + (i * 2);
+ label_fields[i][2].x = 45;
+ label_fields[i][2].width = 30;
+ }
+ sprintf(label_fields[0][2].field, "%s", "/");
+ sprintf(label_fields[1][2].field, "%s", "swap");
+ sprintf(label_fields[4][2].field, "%s", "/usr");
+}
+
+void
+update_label_form(WINDOW *window, struct disklabel *lbl)
+{
+ int i;
+
+ mvwprintw(window, 2, 2, "Partition");
+ mvwprintw(window, 2, 15, "Filesystem Type");
+ mvwprintw(window, 2, 35, "Size");
+ mvwprintw(window, 2, 45, "Mount point");
+ for (i=0; i < MAXPARTITIONS; i++) {
+ mvwprintw(window, 4+(i*2), 6, "%s", partname[i]);
+ mvwprintw(window, label_fields[i][0].y, label_fields[i][0].x, "%s",
+ &label_fields[i][0].field);
+ mvwprintw(window, label_fields[i][1].y, label_fields[i][1].x, "%s",
+ &label_fields[i][1].field);
+ if (label_fields[i][2].field)
+ mvwprintw(window, label_fields[i][2].y, label_fields[i][2].x, "%s",
+ &label_fields[i][2].field);
+ }
+ wrefresh(window);
+}
+
+int
+edit_line(WINDOW *window, int y, int x, char *field, int width, int maxlen)
+{
+ int len;
+ int key = 0;
+ int fpos, dispos, curpos;
+ int i;
+ int done = 0;
+
+ len = strlen(field);
+ if (len < width) {
+ fpos = len;
+ curpos = len;
+ dispos = 0;
+ } else {
+ fpos = width;
+ curpos = width;
+ dispos = len - width;
+ };
+
+
+ do {
+ wattrset(window, item_selected_attr);
+ wmove(window, y, x);
+ for (i=0; i < width; i++)
+ if (i < (len - dispos))
+ waddch(window, field[dispos+i]);
+ else
+ waddch(window, ' ');
+ wmove(window, y, x + curpos);
+ wrefresh(window);
+
+ key = wgetch(window);
+ switch (key) {
+ case TAB:
+ case KEY_BTAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case ESC:
+ case '\n':
+ done = 1;
+ break;
+ case KEY_HOME:
+ if (len < width) {
+ fpos = len;
+ curpos = len;
+ dispos = 0;
+ } else {
+ fpos = width;
+ curpos = width;
+ dispos = len - width;
+ };
+ break;
+ case KEY_END:
+ if (len < width) {
+ dispos = 0;
+ curpos = len - 1;
+ } else {
+ dispos = len - width - 1;
+ curpos = width - 1;
+ }
+ fpos = len - 1;
+ break;
+ case KEY_LEFT:
+ if ((!curpos) && (!dispos)) {
+ beep();
+ break;
+ }
+ if (--curpos < 0) {
+ curpos = 0;
+ if (--dispos < 0)
+ dispos = 0;
+ }
+ if (--fpos < 0)
+ fpos = 0;
+ break;
+ case KEY_RIGHT:
+ if ((curpos + dispos) == len) {
+ beep();
+ break;
+ }
+ if ((curpos == (width-1)) && (dispos == (maxlen - width -1))) {
+ beep();
+ break;
+ }
+ if (++curpos >= width) {
+ curpos = width - 1;
+ dispos++;
+ }
+ if (dispos >= len)
+ dispos = len - 1;
+ if (++fpos >= len) {
+ fpos = len;
+ }
+ break;
+ case KEY_BACKSPACE:
+ case KEY_DC:
+ if ((!curpos) && (!dispos)) {
+ beep();
+ break;
+ }
+ if (fpos > 0) {
+ memmove(field+fpos-1, field+fpos, len - fpos);
+ len--;
+ fpos--;
+ if (curpos > 0)
+ --curpos;
+ if (!curpos)
+ --dispos;
+ if (dispos < 0)
+ dispos = 0;
+ } else
+ beep();
+ break;
+ default:
+ if (len < maxlen - 1) {
+ memmove(field+fpos+1, field+fpos, len - fpos);
+ field[fpos] = key;
+ len++;
+ fpos++;
+ if (++curpos == width) {
+ --curpos;
+ dispos++;
+ }
+ if (len == (maxlen - 1)) {
+ dispos = (maxlen - width - 1);
+ }
+ } else
+ beep();
+ break;
+ }
+ } while (!done);
+ wattrset(window, dialog_attr);
+ wmove(window, y, x);
+ for (i=0; i < width; i++)
+ if (i < (len - dispos))
+ waddch(window, field[dispos+i]);
+ else
+ waddch(window, ' ');
+ wmove(window, y, x + curpos);
+ wrefresh(window);
+ field[len] = 0;
+ delwin(window);
+ refresh();
+ return (key);
+}
+
+int
+disk_size(struct disklabel *lbl)
+{
+ int size;
+
+ size = lbl->d_secsize * lbl->d_nsectors *
+ lbl->d_ntracks * lbl->d_ncylinders;
+ return (size / 1024 / 1024);
+}
+
+int
+sectstoMb(int nsects, int secsize)
+{
+ int size;
+
+ size = nsects * secsize;
+ if (size)
+ size /= 1024 * 1024;
+ return (size);
+}
+
+int
+Mbtosects(int Mb, int secsize)
+{
+ int nsects;
+
+ nsects = (Mb * 1024 * 1024) / secsize;
+ return(nsects);
+}
+
+int
+rndtocylbdry(int size, int secpercyl)
+{
+ int nocyls;
+
+ nocyls = size / secpercyl;
+ if ((nocyls * secpercyl) < size)
+ nocyls++;
+ return (nocyls * secpercyl);
+}
+
+void
+default_disklabel(struct disklabel *lbl, int avail_sects, int offset)
+{
+ int nsects;
+
+ /* Fill in default label entries */
+
+ lbl->d_magic = DISKMAGIC;
+ bcopy("INSTALLATION", lbl->d_typename, strlen("INSTALLATION"));
+ lbl->d_rpm = 3600;
+ lbl->d_interleave = 1;
+ lbl->d_trackskew = 0;
+ lbl->d_cylskew = 0;
+ lbl->d_magic2 = DISKMAGIC;
+ lbl->d_checksum = 0;
+ lbl->d_bbsize = BBSIZE;
+ lbl->d_sbsize = SBSIZE;
+ lbl->d_npartitions = 5;
+
+ /* Set up c and d as raw partitions for now */
+ lbl->d_partitions[2].p_size = avail_sects;
+ lbl->d_partitions[2].p_offset = offset;
+ lbl->d_partitions[2].p_fsize = DEFFSIZE; /* XXX */
+ lbl->d_partitions[2].p_fstype = FS_UNUSED;
+ lbl->d_partitions[2].p_frag = DEFFRAG;
+
+ lbl->d_partitions[3].p_size = lbl->d_secperunit;
+ lbl->d_partitions[3].p_offset = 0;
+ lbl->d_partitions[3].p_fsize = DEFFSIZE;
+ lbl->d_partitions[3].p_fstype = FS_UNUSED;
+ lbl->d_partitions[3].p_frag = DEFFRAG;
+
+ /* Default root */
+ nsects = rndtocylbdry(Mbtosects(DEFROOTSIZE, lbl->d_secsize),
+ lbl->d_secpercyl);
+ offset = rndtocylbdry(offset, lbl->d_secpercyl);
+
+ lbl->d_partitions[0].p_size = nsects;
+ lbl->d_partitions[0].p_offset = offset;
+ lbl->d_partitions[0].p_fsize = DEFFSIZE;
+ lbl->d_partitions[0].p_fstype = FS_BSDFFS;
+ lbl->d_partitions[0].p_frag = DEFFRAG;
+
+ avail_sects -= nsects;
+ offset += nsects;
+ nsects = rndtocylbdry(Mbtosects(DEFSWAPSIZE, lbl->d_secsize),
+ lbl->d_secpercyl);
+
+ lbl->d_partitions[1].p_size = nsects;
+ lbl->d_partitions[1].p_offset = offset;
+ lbl->d_partitions[1].p_fsize = DEFFSIZE;
+ lbl->d_partitions[1].p_fstype = FS_SWAP;
+ lbl->d_partitions[1].p_frag = DEFFRAG;
+
+ avail_sects -= nsects;
+ offset += nsects;
+ nsects = rndtocylbdry(Mbtosects(DEFUSRSIZE, lbl->d_secsize),
+ lbl->d_secpercyl);
+
+ if (avail_sects > nsects)
+ nsects = avail_sects;
+
+ lbl->d_partitions[4].p_size = nsects;
+ lbl->d_partitions[4].p_offset = offset;
+ lbl->d_partitions[4].p_fsize = DEFFSIZE;
+ lbl->d_partitions[4].p_fstype = FS_BSDFFS;
+ lbl->d_partitions[4].p_frag = DEFFRAG;
+}
+
+
+void
+edit_disklabel(struct disklabel *lbl)
+{
+ int key=0;
+ int x_pos = 0;
+ int y_pos = 0;
+ WINDOW *window;
+
+ if (use_shadow)
+ draw_shadow(stdscr, 1, 1, LINES-3, COLS-5);
+
+ window = newwin(LINES - 2, COLS - 4, 0, 0);
+ keypad(window, TRUE);
+
+ draw_box(window, 1, 1, LINES - 3, COLS - 5, dialog_attr, border_attr);
+ wattrset(window, dialog_attr);
+
+ setup_label_fields(lbl);
+ do {
+ update_label_form(window, lbl);
+ key = edit_line(window, label_fields[y_pos][x_pos].y,
+ label_fields[y_pos][x_pos].x,
+ label_fields[y_pos][x_pos].field,
+ label_fields[y_pos][x_pos].width,
+ 20);
+ switch(key) {
+ case KEY_UP:
+ if (y_pos != 0)
+ y_pos--;
+ break;
+ case KEY_DOWN:
+ if (y_pos != MAXPARTITIONS)
+ y_pos++;
+ break;
+ case TAB:
+ x_pos++;
+ if (x_pos == EDITABLES)
+ x_pos = 0;
+ break;
+ case KEY_BTAB:
+ x_pos--;
+ if (x_pos < 0)
+ x_pos = EDITABLES - 1;
+ break;
+ case '\n':
+ ++y_pos;
+ if (y_pos == MAXPARTITIONS) {
+ y_pos = 0;
+ if (++x_pos == EDITABLES)
+ x_pos = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ } while (key != '\033');
+ dialog_clear();
+}
+
+int
+build_disklabel(struct disklabel *lbl)
+{
+ int i, offset;
+ int nsects;
+ int total_sects;
+ int mounts = 0;
+
+ /* Get start of FreeBSD partition from default label */
+ offset = lbl->d_partitions[2].p_offset;
+
+ for (i=0; i < MAXPARTITIONS; i++) {
+ if (strlen(label_fields[i][MOUNTPOINTS].field)) {
+ sprintf(scratch, "%s%s", avail_disknames[inst_disk], partname[i]);
+ devicename[mounts] = StrAlloc(scratch);
+ mountpoint[mounts] = StrAlloc(label_fields[i][MOUNTPOINTS].field);
+ mounts++;
+ nsects = Mbtosects(atoi(label_fields[i][UPARTSIZES].field),
+ lbl->d_secsize);
+ nsects = rndtocylbdry(nsects, lbl->d_secpercyl);
+ offset = rndtocylbdry(offset, lbl->d_secpercyl);
+ lbl->d_partitions[i].p_size = nsects;
+ lbl->d_partitions[i].p_offset = offset;
+ offset += nsects;
+ total_sects += nsects;
+ lbl->d_partitions[i].p_fstype =
+ getfstype(label_fields[i][FSTYPE].field);
+ }
+ }
+}
+
+int
+getfstype(char *fstype)
+{
+ int i;
+
+ for (i=0; i < FSMAXTYPES; i++)
+ if (!strcasecmp(fstype, fstypenames[i]))
+ return(i);
+ return(FS_OTHER);
+}
+
#include <string.h>
#include <dialog.h>
#include "sysinstall.h"
diff --git a/sbin/sysinstall/sysinstall.h b/sbin/sysinstall/sysinstall.h
index 9904e88c6532..aedd3479ebd4 100644
--- a/sbin/sysinstall/sysinstall.h
+++ b/sbin/sysinstall/sysinstall.h
@@ -17,6 +17,9 @@
#define BOOT1 "/stand/sdboot"
#define BOOT2 "/stand/bootsd"
+#define BOOT1 "/stand/sdboot"
+#define BOOT2 "/stand/bootsd"
+
#define MAXFS 25
#define MAX_NO_DISKS 10
@@ -42,6 +45,7 @@ EXTERN char *devicename[MAXFS+1];
EXTERN char *mountpoint[MAXFS+1];
EXTERN int dialog_active;
+extern unsigned char **avail_disknames;
extern int no_disks;
extern int inst_disk;
extern unsigned char *scratch;