diff --git a/sbin/sysinstall/Makefile b/sbin/sysinstall/Makefile index 610a1f367c11..fda713c5828a 100644 --- a/sbin/sysinstall/Makefile +++ b/sbin/sysinstall/Makefile @@ -1,19 +1,19 @@ PROG = sysinstall MANEXT = 1 NOMAN= yet .PATH: /usr/src/sbin/disklabel SRCS = bootarea.c editor.c exec.c dkcksum.c label.c main.c mbr.c \ stage0.c stage1.c stage2.c stage3.c stage4.c stage5.c \ termcap.c utils.c makedevs.c ourcurses.c CFLAGS += -Wall -g -static -I${.CURDIR}/../../sys/ -LDADD = -ldialog -lncurses -lmytinfo -lforms +LDADD = -ldialog -lncurses -lmytinfo DPADD = ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO} makedevs.c: dev2c.sh sh ${.CURDIR}/dev2c.sh ${DESTDIR}/dev > makedevs.c ; \ .include diff --git a/sbin/sysinstall/editor.c b/sbin/sysinstall/editor.c index 572c18c735d6..c1cd6905c448 100644 --- a/sbin/sysinstall/editor.c +++ b/sbin/sysinstall/editor.c @@ -1,53 +1,216 @@ #include #include #include #include "editor.h" int disp_fields(WINDOW *window, struct field field[], int no_fields) { int i, j; int len; - wattrset(window, dialog_attr); for (i=0; i < no_fields; i++) { - len=strlen(field[i].field); wmove(window, field[i].y, field[i].x); - for (j=0; j < field[i].width; j++) - if (j < len) - waddch(window, field[i].field[j]); - else - waddch(window, ' '); + switch (field[i].type) { + case F_TITLE: + case F_EDIT: + if (field[i].type == F_TITLE) + wattrset(window, title_attr); + else + wattrset(window, dialog_attr); + len=strlen(field[i].field); + for (j=0; j < field[i].width; j++) + if (j < len) + waddch(window, field[i].field[j]); + else + waddch(window, ' '); + break; + case F_BUTTON: + print_button(window, field[i].field, + field[i].y, + field[i].x, + FALSE); + break; + } } wrefresh(window); + return (0); } int change_field(struct field field, int key) { int next; switch(key) { case KEY_UP: next = field.up; break; case KEY_DOWN: next = field.down; break; case '\t': next = field.right; break; case KEY_BTAB: next = field.left; break; case '\n': case '\r': next = field.next; break; default: next = -1; break; } return (next); } + +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': + case '\r': + case ' ': + 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); + wstandend(window); + field[len] = 0; + wrefresh(window); + return (key); +} diff --git a/sbin/sysinstall/editor.h b/sbin/sysinstall/editor.h index c3375a41b1a1..79dd6a62e907 100644 --- a/sbin/sysinstall/editor.h +++ b/sbin/sysinstall/editor.h @@ -1,18 +1,25 @@ #define ESC 27 #define TAB 9 struct field { int y; int x; int width; int maxlen; int next; int up; int down; int left; int right; char field[80]; + int type; }; +#define F_EDIT 0 +#define F_TITLE 1 +#define F_BUTTON 2 +#define F_TOGGLE 3 + int disp_fields(WINDOW *, struct field *, int); int change_field(struct field, int); +int edit_line(WINDOW *, int, int, char *, int, int); diff --git a/sbin/sysinstall/label.c b/sbin/sysinstall/label.c index 1592d210021f..9dc8c3883d33 100644 --- a/sbin/sysinstall/label.c +++ b/sbin/sysinstall/label.c @@ -1,304 +1,342 @@ #define DKTYPENAMES #include #include #include #include #include #include #include #include #include #include #include #include #include "disk.h" #include "sysinstall.h" #include "editor.h" #include "label.h" /* Forward decls */ int disk_size(struct disklabel *); int getfstype(char *); int sectstoMb(int, int); char *partname[MAXPARTITIONS] = {"a", "b", "c", "d", "e", "f", "g", "h"}; extern char boot1[]; extern char boot2[]; int disk_size(struct disklabel *lbl) { - int size; - - size = lbl->d_secsize * lbl->d_nsectors * + int size; + + size = lbl->d_secsize * lbl->d_nsectors * lbl->d_ntracks * lbl->d_ncylinders; - return (size / 1024 / 1024); + return (size / 1024 / 1024); } int sectstoMb(int nsects, int secsize) { - int size; - - size = nsects * secsize; - if (size) + int size; + + size = nsects * secsize; + if (size) size /= 1024 * 1024; - return (size); + return (size); } int Mbtosects(int Mb, int secsize) { - int nsects; + int nsects; - nsects = (Mb * 1024 * 1024) / secsize; - return(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); + int nocyls; + + nocyls = size / secpercyl; + if ((nocyls * secpercyl) < size) + nocyls++; + return (nocyls * secpercyl); } char * diskname(int disk) { sprintf(scratch, "/dev/r%s%dd", disk_list[disk].devconf->dc_name, disk_list[disk].devconf->dc_unit); return (scratch); } int read_disklabel(int disk) { int fd; if ((fd = open(diskname(disk), O_RDONLY)) == -1) { sprintf(errmsg, "Couldn't open %s to read disklabel\n%s\n", scratch,strerror(errno)); return (-1); } if (ioctl(fd, DIOCGDINFO, &disk_list[disk].lbl) == -1) { sprintf(errmsg, "Couldn't get disklabel from %s\n%s\n", scratch, strerror(errno)); return (-1); } if (close(fd) == -1) { sprintf(errmsg, "Couldn't close %s after reading disklabel\n%s\n", scratch, strerror(errno)); return (-1); } return (0); } int edit_disklabel(int disk) { WINDOW *window; int key = 0; int next; int cur_field; + int cur_part; int i; struct disklabel *lbl = &disk_list[disk].lbl; - int offset; - int nsects; - int avail_sects; + int offset, slop; + int nsects, hog; + int avail_sects, free; 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 = 8; - /* Inialise the fstab entries */ + /* Initialise the entries */ for (i=0; i < MAXPARTITIONS; i++) { disk_list[disk].mounts[i].fs_spec = (char *)malloc(label_field[i*5].maxlen+1); if (!disk_list[disk].mounts[i].fs_spec) { sprintf(errmsg, "Couldn't allocate memory for device mounts\n"); return (-1); } sprintf(disk_list[disk].mounts[i].fs_spec, "%s%d%s", disk_list[disk].devconf->dc_name, disk_list[disk].devconf->dc_unit, partname[i]); disk_list[disk].mounts[i].fs_mntops = (char *)malloc(label_field[(i*5)+1].maxlen+1); if (!disk_list[disk].mounts[i].fs_mntops) { sprintf(errmsg, "Couldn't allocate memory for mount options\n"); return (-1); } sprintf(disk_list[disk].mounts[i].fs_mntops, "%s", "YES"); disk_list[disk].mounts[i].fs_file = (char *)malloc(label_field[(i*5)+4].maxlen+1); if (!disk_list[disk].mounts[i].fs_file) { sprintf(errmsg, "Couldn't allocate memory for mount points\n"); return (-1); } sprintf(disk_list[disk].mounts[i].fs_file, "%s", "Not Mounted"); + + sprintf(label_field[(i*5)+3].field, "%d", + sectstoMb(lbl->d_partitions[i].p_size, lbl->d_secsize)); } if (!(window = newwin(24, 79, 0, 0))) { sprintf(errmsg, "Failed to open window for disklabel editor\n"); return (-1); } keypad(window, TRUE); draw_box(window, 0, 0, 24, 79, dialog_attr, border_attr); - cur_field = 1; while (key != ESC) { - for (i=0; i < MAXPARTITIONS; i++) { - sprintf(label_field[(i*5)].field, "%s", - disk_list[disk].mounts[i].fs_spec); - sprintf(label_field[(i*5)+1].field, "%s", - disk_list[disk].mounts[i].fs_mntops); - sprintf(label_field[(i*5)+2].field, "%s", - fstypenames[lbl->d_partitions[i].p_fstype]); - sprintf(label_field[(i*5)+3].field, "%d", - sectstoMb(lbl->d_partitions[i].p_size,lbl->d_secsize)); - sprintf(label_field[(i*5)+4].field, "%s", - disk_list[disk].mounts[i].fs_file); - } - disp_fields(window, label_field, sizeof(label_field)/sizeof(struct field)); - key = line_edit(window, label_field[cur_field].y, - label_field[cur_field].x, - label_field[cur_field].width, - label_field[cur_field].maxlen, - item_selected_attr, - 1, - label_field[cur_field].field); - next = change_field(label_field[cur_field], key); - if (next == -1) - beep(); - else - cur_field = next; - - /* Update label */ - for (i=0; id_partitions[OURPART].p_size; offset = lbl->d_partitions[OURPART].p_offset; + slop = rndtocylbdry(offset, lbl->d_secpercyl) - offset; for (i=0; i < MAXPARTITIONS; i++) { if (i == OURPART) continue; if (i == RAWPART) continue; lbl->d_partitions[i].p_offset = offset; nsects = atoi(label_field[(i*5)+3].field); nsects = Mbtosects(nsects, lbl->d_secsize); + nsects = rndtocylbdry(nsects, lbl->d_secpercyl); + if (slop) { + nsects += slop; + slop = 0; + } if (nsects > avail_sects) nsects = avail_sects; avail_sects -= nsects; offset += nsects; if (nsects == 0) lbl->d_partitions[i].p_offset = 0; lbl->d_partitions[i].p_size = nsects; lbl->d_partitions[i].p_fsize = DEFFSIZE; lbl->d_partitions[i].p_frag = DEFFRAG; } + + for (i=0; i < MAXPARTITIONS; i++) { + sprintf(label_field[(i*5)].field, "%s", + disk_list[disk].mounts[i].fs_spec); + sprintf(label_field[(i*5)+1].field, "%s", + disk_list[disk].mounts[i].fs_mntops); + sprintf(label_field[(i*5)+2].field, "%s", + fstypenames[lbl->d_partitions[i].p_fstype]); + sprintf(label_field[(i*5)+3].field, "%d", + sectstoMb(lbl->d_partitions[i].p_size,lbl->d_secsize)); + sprintf(label_field[(i*5)+4].field, "%s", + disk_list[disk].mounts[i].fs_file); + } + + sprintf(label_field[47].field, "%d", + sectstoMb(avail_sects, lbl->d_secsize)); + + disp_fields(window, label_field, + sizeof(label_field)/sizeof(struct field)); + + do { + next = change_field(label_field[cur_field], key); + if (next == -1) { + beep(); + break; + } else + cur_field = next; + cur_part = cur_field/5; + } while ((cur_part == OURPART) || (cur_part == RAWPART)); + + if (label_field[cur_field].type == F_EDIT) + key = edit_line(window, label_field[cur_field].y, + label_field[cur_field].x, + label_field[cur_field].field, + label_field[cur_field].width, + label_field[cur_field].maxlen); + if (label_field[cur_field].type == F_TOGGLE) { + /* There's ony one fortunately */ + key = edit_line(window, label_field[cur_field].y, + label_field[cur_field].x, + label_field[cur_field].field, + label_field[cur_field].width, + label_field[cur_field].maxlen); + if (key == ' ') { + if (strcmp(label_field[cur_field].field, "YES")) + strcpy(label_field[cur_field].field, "NO"); + } else + strcpy(label_field[cur_field].field, "YES"); + } + /* + * Skip certain partitions. + * XXX - This isn't very elegant. + */ + /* Update mount info */ + + for (i=0; id_typename); mvwprintw(window, 3, 2, "magic = %lu",lbl->d_magic); mvwprintw(window, 3, 22, "type = %x",lbl->d_type); mvwprintw(window, 3, 32, "subtype = %x\n",lbl->d_subtype); mvwprintw(window, 4, 2, "Typename = %s",lbl->d_typename); mvwprintw(window, 4, 38, "Packname = %s",lbl->d_packname); mvwprintw(window, 5, 74, "boot0 = %s",lbl->d_boot0); mvwprintw(window, 5, 50, "boot1 = %s\n",lbl->d_boot1); mvwprintw(window, 5, 2, "secsize = %ld",lbl->d_secsize); mvwprintw(window, 5, 20, "nsectors = %ld",lbl->d_nsectors); mvwprintw(window, 5, 30, "ntracks = %ld",lbl->d_ntracks); mvwprintw(window, 5, 50, "ncylinders = %ld\n",lbl->d_ncylinders); mvwprintw(window, 6, 2, "secpercyl = %ld",lbl->d_secpercyl); mvwprintw(window, 6, 40, "secperunit = %ld\n",lbl->d_secperunit); mvwprintw(window, 7, 2, "sparespertrack = %d",lbl->d_sparespertrack); mvwprintw(window, 7, 20, "sparespercyl = %d",lbl->d_sparespercyl); mvwprintw(window, 7, 40, "acylinders = %ld\n",lbl->d_acylinders); mvwprintw(window, 8, 2, "rpm = %d",lbl->d_rpm); mvwprintw(window, 8, 20, "interleave = %d",lbl->d_interleave); mvwprintw(window, 8, 40, "trackskew = %d",lbl->d_trackskew); mvwprintw(window, 8, 60, "cylskew = %d\n",lbl->d_cylskew); mvwprintw(window, 9, 2, "headswitch = %ld",lbl->d_headswitch); mvwprintw(window, 9, 30, "trkseek = %ld",lbl->d_trkseek); mvwprintw(window, 9, 55, "flags = %ld\n",lbl->d_flags); mvwprintw(window, 10, 2, "Drivedata"); for (i=0; i< NDDATA; i++) { mvwprintw(window, 10, 11 + (i*10), " : %d = %ld",i,lbl->d_drivedata[i]); } mvwprintw(window, 11, 2, "Spare"); for (i=0; i< NSPARE; i++) { mvwprintw(window, 11, 7 + (i*10), " : %d = %ld",i,lbl->d_spare[i]); } mvwprintw(window, 12, 2, "magic2 = %lu",lbl->d_magic2); mvwprintw(window, 12, 40, "checksum = %d\n",lbl->d_checksum); mvwprintw(window, 13, 2, "npartitions = %d",lbl->d_npartitions); mvwprintw(window, 13, 25, "bbsize = %lu",lbl->d_bbsize); mvwprintw(window, 13, 50, "sbsize = %lu\n",lbl->d_sbsize); for (i=0; i< MAXPARTITIONS; i++) { mvwprintw(window, 14+i, 2, "%d: size: %ld",i,lbl->d_partitions[i].p_size); mvwprintw(window, 14+i, 20, "offset: %ld",lbl->d_partitions[i].p_offset); mvwprintw(window, 14+i, 36, "fsize: %ld",lbl->d_partitions[i].p_fsize); mvwprintw(window, 14+i, 49, "fstype: %d",lbl->d_partitions[i].p_fstype); mvwprintw(window, 14+i, 60, "frag: %d",lbl->d_partitions[i].p_frag); mvwprintw(window, 14+i, 70, "cpg: %d",lbl->d_partitions[i].p_cpg); } dialog_update(); while (key != '\n' && key != ' ' && key != '\033') key = wgetch(window); delwin(window); dialog_clear(); } diff --git a/sbin/sysinstall/label.h b/sbin/sysinstall/label.h index 365b6edae86a..f95d0c979762 100644 --- a/sbin/sysinstall/label.h +++ b/sbin/sysinstall/label.h @@ -1,48 +1,52 @@ struct field label_field[] = { - { 4, 02, 10, 10, -1, -1, -1, -1, -1, "wd0a"}, - { 4, 16, 3, 3, 2, 36, 6, -1, 2, "YES"}, - { 4, 27, 6, 30, 3, 37, 7, -1, 3, "MSDOS"}, - { 4, 39, 5, 5, 4, 38, 8, -1, 4, "1000"}, - { 4, 47, 30, 80, 6, 39, 9, -1, 1, "/an/example/mountpoint"}, - { 6, 02, 4, 4, -1, -1, -1, -1, -1, "wd0b"}, - { 6, 16, 3, 3, 7, 1, 11, -1, 7, "YES"}, - { 6, 27, 6, 20, 8, 2, 12, -1, 8, "MSDOS"}, - { 6, 39, 5, 5, 9, 3, 13, -1, 9, "1000"}, - { 6, 47, 30, 80, 11, 4, 14, -1, 6, "/an/example/mountpoint"}, - { 8, 02, 10, 10, -1, -1, -1, -1, -1, "wd0c"}, - { 8, 16, 3, 3, 12, 6, 16, -1, 12, "YES"}, - { 8, 27, 6, 20, 13, 7, 17, -1, 13, "MSDOS"}, - { 8, 39, 5, 5, 14, 8, 18, -1, 14, "1000"}, - { 8, 47, 30, 80, 16, 9, 19, -1, 11, "/an/example/mountpoint"}, - {10, 02, 10, 10, -1, -1, -1, -1, -1, "wd0d"}, - {10, 16, 3, 3, 17, 11, 21, -1, 17, "YES"}, - {10, 27, 6, 20, 18, 12, 22, -1, 18, "MSDOS"}, - {10, 39, 5, 5, 19, 13, 23, -1, 19, "1000"}, - {10, 47, 30, 80, 21, 14, 24, -1, 16, "/an/example/mountpoint"}, - {12, 02, 10, 10, -1, -1, -1, -1, -1, "wd0e"}, - {12, 16, 3, 3, 22, 16, 26, -1, 22, "YES"}, - {12, 27, 6, 20, 23, 17, 27, -1, 23, "MSDOS"}, - {12, 39, 5, 5, 24, 18, 28, -1, 24, "1000"}, - {12, 47, 30, 80, 26, 19, 29, -1, 21, "/an/example/mountpoint"}, - {14, 02, 10, 10, -1, -1, -1, -1, -1, "wd0f"}, - {14, 16, 3, 3, 27, 21, 31, -1, 27, "YES"}, - {14, 27, 6, 20, 28, 22, 32, -1, 28, "MSDOS"}, - {14, 39, 5, 5, 29, 23, 33, -1, 29, "1000"}, - {14, 47, 30, 80, 31, 24, 34, -1, 26, "/an/example/mountpoint"}, - {16, 02, 10, 10, -1, -1, -1, -1, -1, "wd0g"}, - {16, 16, 3, 3, 32, 26, 36, -1, 32, "YES"}, - {16, 27, 6, 20, 33, 27, 37, -1, 33, "MSDOS"}, - {16, 39, 5, 5, 34, 28, 38, -1, 34, "1000"}, - {16, 47, 30, 80, 36, 29, 39, -1, 31, "/an/example/mountpoint"}, - {18, 02, 10, 10, -1, -1, -1, -1, -1, "wd0h"}, - {18, 16, 3, 3, 37, 31, 1, -1, 37, "YES"}, - {18, 27, 6, 20, 38, 32, 2, -1, 38, "MSDOS"}, - {18, 39, 5, 5, 39, 33, 3, -1, 39, "1000"}, - {18, 47, 30, 80, 1, 34, 4, -1, 36, "/an/example/mountpoint"}, - { 0, 18, 17, 17, -1, -1, -1, -1, -1, "Disk label editor"}, - { 2, 2, 11, 11, -1, -1, -1, -1, -1, "Partition"}, - { 2, 14, 8, 8, -1, -1, -1, -1, -1, "Preserve"}, - { 2, 25, 10, 10, -1, -1, -1, -1, -1, "Filesystem"}, - { 2, 39, 5, 5, -1, -1, -1, -1, -1, "Size"}, - { 2, 47, 10, 10, -1, -1, -1, -1, -1, "Mountpoint"} + { 6, 02, 10, 10, -1, -1, -1, -1, -1, "wd0a", F_EDIT}, + { 6, 16, 3, 3, 2, 1, 6, -1, 2, "YES", F_TOGGLE}, + { 6, 27, 6, 30, 3, 1, 7, -1, 3, "MSDOS", F_EDIT}, + { 6, 39, 5, 5, 4, 1, 8, -1, 4, "1000", F_EDIT}, + { 6, 47, 30, 80, 6, 1, 9, -1, 1, "/an/example/mountpoint", F_EDIT}, + { 8, 02, 4, 4, -1, -1, -1, -1, -1, "wd0b", F_EDIT}, + { 8, 16, 3, 3, 7, 1, 11, -1, 7, "YES", F_TOGGLE}, + { 8, 27, 6, 20, 8, 2, 12, -1, 8, "MSDOS", F_EDIT}, + { 8, 39, 5, 5, 9, 3, 13, -1, 9, "1000", F_EDIT}, + { 8, 47, 30, 80, 11, 4, 14, -1, 6, "/an/example/mountpoint", F_EDIT}, + {10, 02, 10, 10, -1, -1, -1, -1, -1, "wd0c", F_EDIT}, + {10, 16, 3, 3, 12, 6, 16, -1, 12, "YES", F_TOGGLE}, + {10, 27, 6, 20, 13, 7, 17, -1, 13, "MSDOS", F_EDIT}, + {10, 39, 5, 5, 14, 8, 18, -1, 14, "1000", F_EDIT}, + {10, 47, 30, 80, 16, 9, 19, -1, 11, "/an/example/mountpoint", F_EDIT}, + {12, 02, 10, 10, -1, -1, -1, -1, -1, "wd0d", F_EDIT}, + {12, 16, 3, 3, 17, 11, 21, -1, 17, "YES", F_TOGGLE}, + {12, 27, 6, 20, 18, 12, 22, -1, 18, "MSDOS", F_EDIT}, + {12, 39, 5, 5, 19, 13, 23, -1, 19, "1000", F_EDIT}, + {12, 47, 30, 80, 21, 14, 24, -1, 16, "/an/example/mountpoint", F_EDIT}, + {14, 02, 10, 10, -1, -1, -1, -1, -1, "wd0e", F_EDIT}, + {14, 16, 3, 3, 22, 16, 26, -1, 22, "YES", F_TOGGLE}, + {14, 27, 6, 20, 23, 17, 27, -1, 23, "MSDOS", F_EDIT}, + {14, 39, 5, 5, 24, 18, 28, -1, 24, "1000", F_EDIT}, + {14, 47, 30, 80, 26, 19, 29, -1, 21, "/an/example/mountpoint", F_EDIT}, + {16, 02, 10, 10, -1, -1, -1, -1, -1, "wd0f", F_EDIT}, + {16, 16, 3, 3, 27, 21, 31, -1, 27, "YES", F_TOGGLE}, + {16, 27, 6, 20, 28, 22, 32, -1, 28, "MSDOS", F_EDIT}, + {16, 39, 5, 5, 29, 23, 33, -1, 29, "1000", F_EDIT}, + {16, 47, 30, 80, 31, 24, 34, -1, 26, "/an/example/mountpoint", F_EDIT}, + {18, 02, 10, 10, -1, -1, -1, -1, -1, "wd0g", F_EDIT}, + {18, 16, 3, 3, 32, 26, 36, -1, 32, "YES", F_TOGGLE}, + {18, 27, 6, 20, 33, 27, 37, -1, 33, "MSDOS", F_EDIT}, + {18, 39, 5, 5, 34, 28, 38, -1, 34, "1000", F_EDIT}, + {18, 47, 30, 80, 36, 29, 39, -1, 31, "/an/example/mountpoint", F_EDIT}, + {20, 02, 10, 10, -1, -1, -1, -1, -1, "wd0h", F_EDIT}, + {20, 16, 3, 3, 37, 31, 1, -1, 37, "YES", F_TOGGLE}, + {20, 27, 6, 20, 38, 32, 1, -1, 38, "MSDOS", F_EDIT}, + {20, 39, 5, 5, 39, 33, 1, -1, 39, "1000", F_EDIT}, + {20, 47, 30, 80, 1, 34, 1, -1, 1, "/an/example/mountpoint", F_EDIT}, + { 0, 27, 17, 17, -1, -1, -1, -1, -1, "Disk label editor", F_TITLE}, + { 4, 2, 11, 11, -1, -1, -1, -1, -1, "Partition", F_TITLE}, + { 4, 14, 8, 8, -1, -1, -1, -1, -1, "Preserve", F_TITLE}, + { 4, 25, 10, 10, -1, -1, -1, -1, -1, "Filesystem", F_TITLE}, + { 4, 39, 5, 5, -1, -1, -1, -1, -1, "Size", F_TITLE}, + { 4, 47, 10, 10, -1, -1, -1, -1, -1, "Mountpoint", F_TITLE}, + { 2, 34, 11, 11, -1, -1, -1, -1, -1, "Free space:", F_EDIT}, + { 2, 47, 6, 6, -1, -1, -1, -1, -1, "000000", F_EDIT}, + {22, 30, 2, 2, -1, -1, -1, -1, -1, "OK", F_BUTTON}, + {22, 50, 2, 2, -1, -1, -1, -1, -1, "Cancel", F_BUTTON}, }; diff --git a/sbin/sysinstall/mbr.c b/sbin/sysinstall/mbr.c index 5ddd0c0840bf..f6644dd235bf 100644 --- a/sbin/sysinstall/mbr.c +++ b/sbin/sysinstall/mbr.c @@ -1,396 +1,408 @@ /* * Copyright (c) 1994, Paul Richards. * * All rights reserved. * * This software may be used, modified, copied, distributed, and * sold, in both source and binary form provided that the above * copyright and these terms are retained, verbatim, as the first * lines of this file. Under no circumstances is the author * responsible for the proper functioning of this software, nor does * the author assume any responsibility for damages incurred with * its use. */ #include #include #include #include #include #ifdef __i386__ /* temp measure delete nov 15 1994 */ #define i386 1 #else #warning FOO #endif #include #include #include #include #include "sysinstall.h" #include "disk.h" #include "editor.h" #include "mbr.h" char *part_type(int); int write_mbr(char *, struct mbr *); int read_mbr(char *, struct mbr *); void show_mbr(struct mbr *); int clear_mbr(struct mbr *, char *); int build_mbr(struct mbr *, char *, struct disklabel *); extern char boot1[]; extern struct disk disk_list[]; struct part_type part_types[] = PARTITION_TYPES struct field *last_field; char * part_type(int type) { int num_types = (sizeof(part_types)/sizeof(struct part_type)); int next_type = 0; struct part_type *ptr = part_types; while (next_type < num_types) { if(ptr->type == type) return(ptr->name); ptr++; next_type++; } return("Unknown"); } int read_mbr(char *device, struct mbr *mbr) { int fd; if ((fd = open(device, O_RDONLY)) == -1) { sprintf(errmsg, "Couldn't open device %s to read master boot record\n", device); return(-1); } if (lseek(fd, 0, SEEK_SET) == -1) { sprintf(errmsg, "Couldn't seek to track 0 of device %s to read master boot record\n", device); return(-1); } if (read(fd, &(mbr->bootcode), MBRSIZE) == -1) { sprintf(errmsg, "Failed to read master boot record from device %s\n", device); return(-1); } if (close(fd) == -1) { sprintf(errmsg, "Couldn't close device %s after reading master boot record\n", device); return(-1); } return(0); } int write_mbr(char *device, struct mbr *mbr) { int fd; if ((fd = open(device, O_WRONLY)) == -1) { sprintf(errmsg, "Couldn't open device %s to write master boot record\n", device); return(-1); } if (lseek(fd, 0, SEEK_SET) == -1) { sprintf(errmsg, "Couldn't seek to track 0 of device %s to write master boot record\n", device); return(-1); } if (enable_label(fd) == -1) { sprintf(errmsg, "Couldn't write enable MBR area of device %s\n", device); return(-1); } if (write(fd, mbr->bootcode, MBRSIZE) == -1) { sprintf(errmsg, "Failed to write master boot record to device %s\n", device); return(-1); } if (disable_label(fd) == -1) { sprintf(errmsg, "Couldn't write disable MBR area of device %s\n", device); return(-1); } if (close(fd) == -1) { sprintf(errmsg, "Couldn't close device %s after reading master boot record\n", device); return(-1); } return(0); } int clear_mbr(struct mbr *mbr, char *bootcode) { int i; int fd; /* - * If installing to the whole disk - * then clobber any existing bootcode. + * Must replace any old bootcode that was read + * from disk with our bootblocks. */ - TellEm("Loading MBR code from %s", bootcode); - fd = open(bootcode, O_RDONLY); - if (fd < 0) { - sprintf(errmsg, "Couldn't open boot file %s\n", bootcode); - return(-1); - } - - if (read(fd, mbr->bootcode, MBRSIZE) < 0) { - sprintf(errmsg, "Couldn't read from boot file %s\n", bootcode); - return(-1); - } + TellEm("Loading MBR code from %s", bootcode); + fd = open(bootcode, O_RDONLY); + if (fd < 0) { + sprintf(errmsg, "Couldn't open boot file %s\n", bootcode); + return(-1); + } - if (close(fd) == -1) { - sprintf(errmsg, "Couldn't close boot file %s\n", bootcode); - return(-1); - } + if (read(fd, mbr->bootcode, MBRSIZE) < 0) { + sprintf(errmsg, "Couldn't read from boot file %s\n", bootcode); + return(-1); + } - /* Create an empty partition table */ + if (close(fd) == -1) { + sprintf(errmsg, "Couldn't close boot file %s\n", bootcode); + return(-1); + } - for (i=0; i < NDOSPART; i++) { - mbr->dospart[i].dp_flag = 0; - mbr->dospart[i].dp_shd = 0; - mbr->dospart[i].dp_ssect = 0; - mbr->dospart[i].dp_scyl = 0; - mbr->dospart[i].dp_typ = 0; - mbr->dospart[i].dp_ehd = 0; - mbr->dospart[i].dp_esect = 0; - mbr->dospart[i].dp_ecyl = 0; - mbr->dospart[i].dp_start = 0; - mbr->dospart[i].dp_size = 0; - } + /* Create an empty partition table */ + + for (i=0; i < NDOSPART; i++) { + mbr->dospart[i].dp_flag = 0; + mbr->dospart[i].dp_shd = 0; + mbr->dospart[i].dp_ssect = 0; + mbr->dospart[i].dp_scyl = 0; + mbr->dospart[i].dp_typ = 0; + mbr->dospart[i].dp_ehd = 0; + mbr->dospart[i].dp_esect = 0; + mbr->dospart[i].dp_ecyl = 0; + mbr->dospart[i].dp_start = 0; + mbr->dospart[i].dp_size = 0; + } - mbr->magic = MBR_MAGIC; - - dialog_clear(); - return(0); + mbr->magic = MBR_MAGIC; + + dialog_clear(); + return(0); } int dedicated_mbr(struct mbr *mbr, char *bootcode, struct disklabel *lbl) { struct dos_partition *dp = &mbr->dospart[0]; if (clear_mbr(mbr, bootcode) == -1) return(-1); dp->dp_scyl = 0; dp->dp_shd = 1; dp->dp_ssect = 1; dp->dp_ecyl = lbl->d_ncylinders - 1; dp->dp_ehd = lbl->d_ntracks - 1; dp->dp_esect = lbl->d_nsectors; dp->dp_start = (dp->dp_scyl * lbl->d_ntracks * lbl->d_nsectors) + (dp->dp_shd * lbl->d_nsectors) + dp->dp_ssect - 1; dp->dp_size = (lbl->d_nsectors * lbl->d_ntracks * lbl->d_ncylinders) - dp->dp_start; - dp->dp_typ = DOSPTYP_386BSD; + dp->dp_typ = MBR_PTYPE_FreeBSD; dp->dp_flag = ACTIVE; return(0); } int get_geom_values(int disk) { WINDOW *window; struct disklabel *lbl = &disk_list[disk].lbl; int key = 0; int cur_field = 0; int next = 0; struct field field[] = { {2, 28, 06, 10, 01, 02, 01, -1, 01, "Unset"}, {4, 28, 06, 10, 02, 00, 02, -1, 02, "Unset"}, {6, 28, 06, 10, 00, 01, 00, -1, 00, "Unset"}, {0, 07, 24, 24, -1, -1, -1, -1, -1, "BIOS geometry parameters"}, {2, 02, 20, 20, -1, -1, -1, -1, -1, "Number of cylinders:"}, {4, 02, 25, 25, -1, -1, -1, -1, -1, "Number of tracks (heads):"}, {6, 02, 18, 18, -1, -1, -1, -1, -1, "Number of sectors:"} }; if (!(window = newwin(10, 40, 5, 20))) { sprintf(errmsg, "Failed to open window for geometry editor"); return (-1); }; keypad(window, TRUE); dialog_clear_norefresh(); draw_box(window, 0, 0, 9, 40, dialog_attr, border_attr); while (key != ESC) { sprintf(field[0].field, "%ld", lbl->d_ncylinders); sprintf(field[1].field, "%ld", lbl->d_ntracks); sprintf(field[2].field, "%ld", lbl->d_nsectors); disp_fields(window, field, sizeof(field)/sizeof(struct field)); - key = line_edit(window, field[cur_field].y, field[cur_field].x, - field[cur_field].width, - field[cur_field].maxlen, - item_selected_attr, - 1, - field[cur_field].field); + key = edit_line(window, field[cur_field].y, field[cur_field].x, + field[cur_field].field, field[cur_field].width, + field[cur_field].maxlen); next = change_field(field[cur_field], key); if (next == -1) beep(); else cur_field = next; lbl->d_ncylinders = atoi(field[0].field); lbl->d_ntracks = atoi(field[1].field); lbl->d_nsectors = atoi(field[2].field); } delwin(window); refresh(); return (0); } int edit_mbr(int disk) { WINDOW *window; int cur_field; int i; int ok; int next; int key = 0; struct mbr *mbr = &disk_list[disk].mbr; /* Confirm disk parameters */ #ifdef 0 - dialog_msgbox("BIOS disk geometry values", "In order to setup the boot area of the disk it is necessary to know the BIOS values for the disk geometry i.e. the number of cylinders, heads and sectors. These values may be different form the real geometry of the disk, depending on whether or not your system uses geometry translation. At this stage it is the entries from the BIOS that are needed. If you do not know these they can be found by rebooting the machine and entering th BIOS setup routine. See you BIOS manual for details", -1, -1, 1) + dialog_msgbox("\nBIOS disk geometry values", "In order to setup the boot area of the disk it is necessary to know the BIOS values for the disk geometry i.e. the number of cylinders, heads and sectors. These values may be different form the real geometry of the disk, depending on whether or not your system uses geometry translation. At this stage it is the entries from the BIOS that are needed. If you do not know these they can be found by rebooting the machine and entering th BIOS setup routine. See you BIOS manual for details.\n", -1, -1, 1) #endif if (get_geom_values(disk) == -1) return(-1); /* Read MBR from disk */ sprintf(scratch, "/dev/r%s%dd", disk_list[disk].devconf->dc_name, disk_list[disk].devconf->dc_unit); if (read_mbr(scratch, &disk_list[disk].mbr) == -1) { sprintf(scratch, "The following error occured while trying\nto read the master boot record:\n\n%s\nIn order to install FreeBSD a new master boot record\nwill have to be written which will mean all current\ndata on the hard disk will be lost.", errmsg); ok = 0; while (!ok) { AskAbort(scratch); if (!dialog_yesno(TITLE, - "Are you sure you wish to proceed ?", - -1, -1)) { + "\nAre you sure you wish to proceed ?\n", + -1, -1)) { + dialog_clear(); if (dedicated_mbr(mbr, boot1, &disk_list[disk].lbl) == -1) { - sprintf(scratch, "\n\nCouldn't create new master boot record.\n\n%s", errmsg); + sprintf(scratch, "\nCouldn't create new master boot record.\n\n%s", errmsg); return(-1); } ok = 1; } } } - sprintf(scratch, "Do you wish to dedicate the whole disk to FreeBSD?\n\nDoing so will overwrite any existing data on the disk."); + sprintf(scratch, "\nDo you wish to dedicate the whole disk to FreeBSD?\n\nDoing so will overwrite any existing data on the disk.\n"); dialog_clear_norefresh(); if (!dialog_yesno(TITLE, scratch, -1, -1)) if (dedicated_mbr(mbr, boot1, &disk_list[disk].lbl) == -1) { - sprintf(scratch, "\n\nCouldn't dedicate disk to FreeBSD.\n\n %s", errmsg); + sprintf(scratch, "\nCouldn't dedicate disk to FreeBSD.\n\n %s", errmsg); return(-1); } - /* Fill in fields with mbr data */ - - if (!(window = newwin(24, 79, 0, 0))) { sprintf(errmsg, "Failed to open window for MBR editor\n"); return (-1); }; keypad(window, TRUE); dialog_clear_norefresh(); draw_box(window, 0, 0, 24, 79, dialog_attr, border_attr); cur_field = 1; while (key != ESC) { for (i=0; i < NDOSPART; i++) { sprintf(mbr_field[(i*12)+1].field, "%s", part_type(mbr->dospart[i].dp_typ)); sprintf(mbr_field[(i*12)+2].field, "%ld", mbr->dospart[i].dp_start); sprintf(mbr_field[(i*12)+3].field, "%d", mbr->dospart[i].dp_scyl); sprintf(mbr_field[(i*12)+4].field, "%d", mbr->dospart[i].dp_shd); sprintf(mbr_field[(i*12)+5].field, "%d", mbr->dospart[i].dp_ssect); sprintf(mbr_field[(i*12)+6].field, "%d", 0); sprintf(mbr_field[(i*12)+7].field, "%d", mbr->dospart[i].dp_ecyl); sprintf(mbr_field[(i*12)+8].field, "%d", mbr->dospart[i].dp_ehd); sprintf(mbr_field[(i*12)+9].field, "%d", mbr->dospart[i].dp_esect); sprintf(mbr_field[(i*12)+10].field, "%ld", mbr->dospart[i].dp_size); sprintf(mbr_field[(i*12)+11].field, "%d", sectstoMb(mbr->dospart[i].dp_size, 512)); sprintf(mbr_field[(i*12)+12].field, "%d", mbr->dospart[i].dp_flag); } disp_fields(window, mbr_field, sizeof(mbr_field)/sizeof(struct field)); - key = line_edit(window, mbr_field[cur_field].y, mbr_field[cur_field].x, - mbr_field[cur_field].width, - mbr_field[cur_field].maxlen, - item_selected_attr, - 1, - mbr_field[cur_field].field); - - /* Propagate changes to MBR */ - for (i=0; i < NDOSPART; i++) { - mbr->dospart[i].dp_start = atoi(mbr_field[(i*12)+2].field); - mbr->dospart[i].dp_scyl = atoi(mbr_field[(i*12)+3].field); - mbr->dospart[i].dp_shd = atoi(mbr_field[(i*12)+4].field); - mbr->dospart[i].dp_ssect = atoi(mbr_field[(i*12)+5].field); - mbr->dospart[i].dp_ecyl = atoi(mbr_field[(i*12)+7].field); - mbr->dospart[i].dp_ehd = atoi(mbr_field[(i*12)+8].field); - mbr->dospart[i].dp_esect = atoi(mbr_field[(i*12)+9].field); - mbr->dospart[i].dp_size = atoi(mbr_field[(i*12)+10].field); + switch (mbr_field[cur_field].type) { + case F_EDIT: + key = edit_line(window, mbr_field[cur_field].y, + mbr_field[cur_field].x, + mbr_field[cur_field].field, mbr_field[cur_field].width, + mbr_field[cur_field].maxlen); + /* Propagate changes to MBR */ + for (i=0; i < NDOSPART; i++) { + mbr->dospart[i].dp_start = atoi(mbr_field[(i*12)+2].field); + mbr->dospart[i].dp_scyl = atoi(mbr_field[(i*12)+3].field); + mbr->dospart[i].dp_shd = atoi(mbr_field[(i*12)+4].field); + mbr->dospart[i].dp_ssect = atoi(mbr_field[(i*12)+5].field); + mbr->dospart[i].dp_ecyl = atoi(mbr_field[(i*12)+7].field); + mbr->dospart[i].dp_ehd = atoi(mbr_field[(i*12)+8].field); + mbr->dospart[i].dp_esect = atoi(mbr_field[(i*12)+9].field); + mbr->dospart[i].dp_size = atoi(mbr_field[(i*12)+10].field); + } + next = change_field(mbr_field[cur_field], key); + if (next == -1) + beep(); + else + cur_field = next; + break; + case F_TITLE: + default: + break; } + } - next = change_field(mbr_field[cur_field], key); - if (next == -1) - beep(); - else - cur_field = next; - } - - sprintf(scratch, "Writing a new master boot record can erase the current disk contents.\n\n Are you sure you want to write the new MBR?"); + sprintf(scratch, "\nWriting a new master boot record can erase the current disk contents.\n\n Are you sure you want to write the new MBR?\n"); dialog_clear_norefresh(); if (!dialog_yesno("Write new MBR?", scratch, -1, -1)) { sprintf(scratch, "/dev/r%s%dd", disk_list[disk].devconf->dc_name, disk_list[disk].devconf->dc_unit); if (write_mbr(scratch, mbr) == -1) { - sprintf(scratch, "The following error occured while trying to write the new MBR\n\n%s", errmsg); + sprintf(scratch, "\nThe following error occured while trying to write the new MBR.\n\n%s", errmsg); return(-1); } } + /* Find first FreeBSD partition, as kernel would upon boot */ + disk_list[disk].inst_part = -1; + for (i=0; i < NDOSPART; i++) + if (mbr->dospart[i].dp_typ == MBR_PTYPE_FreeBSD) { + disk_list[disk].inst_part = i; + break; + } + + if (disk_list[disk].inst_part == -1) { + sprintf(errmsg, "\nThere is no space allocated to FreeBSD on %s\n", + diskname(disk)); + return (-1); + } + delwin(window); dialog_clear(); return (0); } diff --git a/sbin/sysinstall/stage1.c b/sbin/sysinstall/stage1.c index 198f16e793f5..554061af6c1c 100644 --- a/sbin/sysinstall/stage1.c +++ b/sbin/sysinstall/stage1.c @@ -1,336 +1,244 @@ /* * Copyright (c) 1994, Paul Richards. * * All rights reserved. * * This software may be used, modified, copied, distributed, and * sold, in both source and binary form provided that the above * copyright and these terms are retained, verbatim, as the first * lines of this file. Under no circumstances is the author * responsible for the proper functioning of this software, nor does * the author assume any responsibility for damages incurred with * its use. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "disk.h" #include "sysinstall.h" unsigned char **options; unsigned char *scratch; unsigned char *errmsg; unsigned char *bootblocks; int dialog_active = 0; /* Forward decls */ void exit_sysinstall(void); void exit_prompt(void); extern char *part_type(int); char selection[30]; char *device_names[] = {"wd", "sd", "cd", "mcd", 0}; struct devconf *device_list[MAX_NO_DEVICES]; struct disk disk_list[MAX_NO_DEVICES]; int no_devices; int no_disks; int alloc_memory() { int i; scratch = (char *) calloc(SCRATCHSIZE, sizeof(char)); if (!scratch) return(-1); errmsg = (char *) calloc(ERRMSGSIZE, sizeof(char)); if (!errmsg) return(-1); options = (unsigned char **)calloc(MAX_NO_DISKS, sizeof(char *)); if (!options) return(-1); for (i = 0; i < MAX_NO_DISKS; i++) { options[i] = (char *)calloc(100, sizeof(char)); if (!options[i]) return(-1); } return(0); } void free_memory() { int i; free(scratch); free(errmsg); for (i = 0; i < MAX_NO_DEVICES; i++) free(device_list[i]); } int query_devices() { int i, j; int size, osize; int ndevs; int mib[8]; struct devconf *dev; mib[0] = CTL_HW; mib[1] = HW_DEVCONF; mib[2] = DEVCONF_NUMBER; size = sizeof ndevs; if (sysctl(mib, 3, &ndevs, &size, 0, 0) < 0) { sprintf(errmsg, "Couldn't get device info from kernel\n"); return(-1); } dev = 0; osize = 0; for (i=0; i <= ndevs; i++) { mib[2] = i; if (sysctl(mib, 3, 0, &size, 0, 0) < 0) /* Probably deleted device */ continue; if (size > osize) { dev = realloc(dev, size); if (!dev) { sprintf(errmsg, "Couldn't allocate memory for device information\n"); return(-1); } } osize = size; if (sysctl(mib, 3, dev, &size, 0, 0) < 0) { sprintf(errmsg, "Error getting information on device %d\n", i); return(-1); } for (j=0; device_names[j]; j++) if (!strcmp(device_names[j], dev->dc_name)) { device_list[no_devices++] = dev; dev = 0; osize = 0; break; } } return (0); } int -select_disk() +configure_disks() { char *disk_names[] = {"wd", "sd", 0}; char diskname[20]; int i, j; int fd; int valid=0; int choice; /* Search for possible installation targets */ no_disks = 0; for (i=0; i < no_devices; i++) for (j=0; disk_names[j]; j++) if (!strcmp(disk_names[j], device_list[i]->dc_name)) { /* Try getting drive info */ sprintf(diskname, "/dev/r%s%dd", device_list[i]->dc_name, device_list[i]->dc_unit); if ((fd = open(diskname, O_RDONLY)) == -1) continue; if (ioctl(fd, DIOCGDINFO, &disk_list[no_disks].lbl) == -1) { close(fd); continue; } disk_list[no_disks++].devconf = device_list[i]; close(fd); } do { if (no_disks == 1) sprintf(scratch,"There is %d disk available for installation: ", no_disks); else sprintf(scratch,"There are %d disks available for installation: ", no_disks); for (i = 0; i < no_disks; i++) { sprintf(options[(i*2)], "%d",i+1); if (disk_list[i].selected) sprintf(options[(i*2)+1], " ** %s, (%dMb) -> %s%d", disk_list[i].lbl.d_typename, disk_size(&disk_list[i].lbl), disk_list[i].devconf->dc_name, disk_list[i].devconf->dc_unit); else sprintf(options[(i*2)+1], " %s, (%dMb) -> %s%d", disk_list[i].lbl.d_typename, disk_size(&disk_list[i].lbl), disk_list[i].devconf->dc_name, disk_list[i].devconf->dc_unit); } sprintf(options[no_disks*2], "%d", no_disks+1); sprintf(options[(no_disks*2)+1], " Done"); dialog_clear_norefresh(); - if (dialog_menu("FreeBSD Installation", scratch, -1, -1, min(5,no_disks+1), no_disks+1, - options, selection)) { - sprintf(scratch,"You selected cancel."); + if (dialog_menu("FreeBSD Installation", scratch, -1, -1, + min(5, no_disks), no_disks, options, selection)) { + dialog_clear_norefresh(); + sprintf(scratch,"\nYou selected cancel.\n"); AskAbort(scratch); valid = 0; continue; } - choice = atoi(selection); - if (choice == no_disks+1) - valid = 1; - else - if (disk_list[choice-1].selected) - disk_list[choice-1].selected = 0; - else - disk_list[choice-1].selected = 1; - } while (!valid); - dialog_clear(); - return(0); -} - -void -configure_disks() -{ - int i; - int items; - int choice; - int valid=0; - int disks[MAX_NO_DEVICES]; - - do { - sprintf(scratch, "Select disk to configure"); - - items = 0; - for (i = 0; i < no_disks; i++) { - if (disk_list[i].selected) { - sprintf(options[(items*2)], "%d",items+1); - sprintf(options[(items*2)+1], "%s%d", - disk_list[i].devconf->dc_name, - disk_list[i].devconf->dc_unit); - disks[items] = i; - items++; - } - } - - sprintf(options[items*2], "%d", items+1); - sprintf(options[(items*2)+1], "Done"); - items++; - - dialog_clear_norefresh(); - if (dialog_menu("FreeBSD Installation", scratch, -1, -1, min(5,items), items, - options, selection)) { - sprintf(scratch,"You selected cancel."); - AskAbort(scratch); - valid = 0; - continue; - } - choice = atoi(selection); - if (choice == items) + if (choice == no_disks) valid = 1; else { - if (edit_mbr(disks[choice-1]) == -1) { - sprintf(scratch, "The following error occured while\nediting the master boot record.\n%s", errmsg); + if (edit_mbr(choice-1) == -1) { + sprintf(scratch, "\nThe following error occured while\nediting the master boot record.\n%s", errmsg); AskAbort(scratch); valid = 0; continue; }; - disk_list[disks[choice-1]].inst_part = select_partition(disks[choice-1]); - if (edit_disklabel(disks[choice-1]) == -1) { - sprintf(scratch, "The following error occured while\nediting the disklabel.\n%s", errmsg); + if (edit_disklabel(choice-1) == -1) { + sprintf(scratch, "\nThe following error occured while\nediting the disklabel.\n%s", errmsg); AskAbort(scratch); valid = 0; continue; } + disk_list[choice-1].selected = 1; } } while (!valid); - dialog_clear(); } -int -select_partition(int disk) -{ - int valid; - int i; - int choice; - - do { - valid = 1; - - sprintf(scratch,"Select one of the following areas to install to:"); - for (i=0; i < NDOSPART; i++) { - sprintf(options[(i*2)], "%d",i+1); - sprintf(options[(i*2)+1], "%s, (%ldMb)", - part_type(disk_list[disk].mbr.dospart[i].dp_typ), - disk_list[disk].mbr.dospart[i].dp_size * 512 / (1024 * 1024)); - } - dialog_clear_norefresh(); - if (dialog_menu(TITLE, - scratch, -1, -1, 4, 4, options, selection)) { - sprintf(scratch,"You did not select a valid partition"); - AskAbort(scratch); - valid = 0; - } - dialog_clear(); - choice = atoi(selection) - 1; - } while (!valid); - return(choice); -} - int stage1() { int i; int ok = 0; query_devices(); - - while (!ok) { - select_disk(); - for (i=0; i < no_disks; i++) - if (disk_list[i].selected) - ok = 1; - if (!ok) { - sprintf(scratch, "You did not select any disks to install to."); - AskAbort(scratch); - } - } - configure_disks(); exit(1); } diff --git a/sbin/sysinstall/utils.c b/sbin/sysinstall/utils.c index db7f3495b16d..1a062ed67f72 100644 --- a/sbin/sysinstall/utils.c +++ b/sbin/sysinstall/utils.c @@ -1,321 +1,322 @@ /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: utils.c,v 1.30 1994/11/17 23:36:49 ache Exp $ + * $Id: utils.c,v 1.31 1994/11/19 00:09:00 ache Exp $ * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sysinstall.h" void strip_trailing_newlines(char *p) { int len = strlen(p); while (len > 0 && p[len-1] == '\n') p[--len] = '\0'; } void Debug(char *fmt, ...) { char *p; va_list ap; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); write(debug_fd,"Debug <",7); write(debug_fd,p,strlen(p)); write(debug_fd,">\n\r",3); free(p); } void TellEm(char *fmt, ...) { char *p; va_list ap; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); strip_trailing_newlines(p); write(debug_fd,"Progress <",10); write(debug_fd,p,strlen(p)); write(debug_fd,">\n\r",3); dialog_clear_norefresh(); dialog_msgbox("Progress", p, -1, -1, 0); free(p); } void Fatal(char *fmt, ...) { char *p; va_list ap; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); strip_trailing_newlines(p); if (dialog_active) dialog_msgbox("Fatal", p, -1, -1, 1); else fprintf(stderr, "Fatal -- %s\n", p); free(p); ExitSysinstall(); } void AskAbort(char *fmt, ...) { char *p; va_list ap; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); - strcat(p, "\nDo you wish to abort the installation?"); - if (!dialog_yesno("Abort", p, -1, -1)) + strcat(p, "\nDo you wish to abort the installation?\n"); + if (!dialog_yesno("Abort", p, -1, -1)) { + dialog_clear_norefresh(); Abort(); - else + } else dialog_clear(); free(p); } void Abort() { - if (dialog_yesno("Exit sysinstall","Are you sure you want to quit?", + if (dialog_yesno("Exit sysinstall","\nAre you sure you want to quit?\n", -1, -1)) { dialog_clear(); return; } ExitSysinstall(); } void ExitSysinstall() { if (dialog_active) { clear(); dialog_update(); } if (getpid() == 1) { if (reboot(RB_AUTOBOOT) == -1) if (dialog_active) { clear(); dialog_msgbox(TITLE, "\n\nCan't reboot machine -- hit reset button", -1,-1,0); } else fprintf(stderr, "Can't reboot the machine -- hit the reset button"); while(1); } else { if (dialog_active) { end_dialog(); dialog_active = 0; } exit(0); } } void * Malloc(size_t size) { void *p = malloc(size); if (!p) { exit(7); /* XXX longjmp bad */ } return p; } char * StrAlloc(char *str) { char *p; p = (char *)Malloc(strlen(str) + 1); strcpy(p,str); return p; } void MountUfs(char *device, char *mountpoint, int do_mkdir, int flags) { struct ufs_args ufsargs; char dbuf[90]; memset(&ufsargs,0,sizeof ufsargs); if(do_mkdir && access(mountpoint,R_OK)) { Mkdir(mountpoint); } strcpy(dbuf,"/dev/"); strcat(dbuf,device); TellEm("mount %s %s",dbuf,mountpoint); ufsargs.fspec = dbuf; if (mount(MOUNT_UFS, mountpoint, flags, (caddr_t) &ufsargs) == -1) { Fatal("Error mounting %s on %s : %s\n", dbuf, mountpoint, strerror(errno)); } } void Mkdir(char *ipath) { struct stat sb; int final=0; char *p,*path=StrAlloc(ipath); Debug("mkdir(%s)",path); p = path; if (p[0] == '/') /* Skip leading '/'. */ ++p; for (;!final; ++p) { if (p[0] == '\0' || (p[0] == '/' && p[1] == '\0')) final++; else if (p[0] != '/') continue; *p = '\0'; if (stat(path, &sb)) { if (errno != ENOENT) Fatal("Couldn't stat directory %s: %s\n", path,strerror(errno)); Debug("mkdir(%s..)",path); if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0) Fatal("Couldn't create directory %s: %s\n", path,strerror(errno)); } *p = '/'; } free(path); return; } void Link(char *from, char *to) { TellEm("ln %s %s", from, to); if (link(from, to) == -1) Fatal("Couldn't create link: %s -> %s\n", from, to); } void CopyFile(char *p1, char *p2) { char buf[BUFSIZ]; int fd1,fd2; int i; struct stat st; TellEm("Copy %s to %s",p1,p2); fd1 = open(p1,O_RDONLY); if (fd1 < 0) Fatal("Couldn't open %s: %s\n",p1,strerror(errno)); fd2 = open(p2,O_TRUNC|O_CREAT|O_WRONLY,0200); if (fd2 < 0) Fatal("Couldn't open %s: %s\n",p2,strerror(errno)); for(;;) { i = read(fd1,buf,sizeof buf); if (i > 0) if (i != write(fd2,buf,i)) { Fatal("Write errror on %s: %s\n", p2,strerror(errno)); } if (i != sizeof buf) break; } fstat(fd1,&st); fchmod(fd2,st.st_mode & 07777); fchown(fd2,st.st_uid,st.st_gid); close(fd1); close(fd2); } u_long PartMb(struct disklabel *lbl,int part) { u_long l; l = 1024*1024/lbl->d_secsize; return (lbl->d_partitions[part].p_size + l/2)/l; } void CleanMount(int disk, int part) { int i = MP[disk][part]; if (Fmount[i]) { free(Fmount[i]); Fmount[i] = 0; } if (Fname[i]) { free(Fname[i]); Fname[i] = 0; } if (Ftype[i]) { free(Ftype[i]); Ftype[i] = 0; } MP[disk][part] = 0; } char * SetMount(int disk, int part, char *path) { int k; char buf[80]; CleanMount(disk,part); for (k = 1; k < MAX_NO_FS; k++) if (!Fmount[k]) break; if (k >= MAX_NO_FS) return "Maximum number of filesystems exceeded"; Fmount[k] = StrAlloc(path); sprintf(buf, "%s%c", Dname[disk], part + 'a'); Fname[k] = StrAlloc(buf); switch (Dlbl[disk]->d_partitions[part].p_fstype) { case FS_BSDFFS: Ftype[k] = StrAlloc("ufs"); break; case FS_MSDOS: Ftype[k] = StrAlloc("msdos"); break; case FS_SWAP: Ftype[k] = StrAlloc("swap"); break; default: CleanMount(disk,part); return "Unknown filesystem-type"; } Fsize[k] = (Dlbl[disk]->d_partitions[part].p_size+1024)/2048; MP[disk][part] = k; return NULL; }