diff --git a/sbin/sysinstall/Makefile b/sbin/sysinstall/Makefile index ae718fcbafce..8ab1f792f112 100644 --- a/sbin/sysinstall/Makefile +++ b/sbin/sysinstall/Makefile @@ -4,7 +4,7 @@ NOMAN= yet .PATH: /usr/src/sbin/disklabel -SRCS = sysinstall.c dkcksum.c bootarea.c +SRCS = sysinstall.c dkcksum.c bootarea.c mbr.c CFLAGS += -Wall LDADD = -ldialog -lncurses -lmytinfo diff --git a/sbin/sysinstall/bootarea.c b/sbin/sysinstall/bootarea.c index a22b996199d1..a1fba2b18e8b 100644 --- a/sbin/sysinstall/bootarea.c +++ b/sbin/sysinstall/bootarea.c @@ -24,63 +24,21 @@ #include #include +#include "mbr.h" #include "bootarea.h" #include "sysinstall.h" char boot1[] = BOOT1; char boot2[] = BOOT2; -struct part_type part_types[] = -{ - {0x00, "unused"} - ,{0x01, "Primary DOS with 12 bit FAT"} - ,{0x02, "XENIX / filesystem"} - ,{0x03, "XENIX /usr filesystem"} - ,{0x04, "Primary DOS with 16 bit FAT"} - ,{0x05, "Extended DOS"} - ,{0x06, "Primary 'big' DOS (> 32MB)"} - ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} - ,{0x08, "AIX filesystem"} - ,{0x09, "AIX boot partition or Coherent"} - ,{0x0A, "OS/2 Boot Manager or OPUS"} - ,{0x10, "OPUS"} - ,{0x40, "VENIX 286"} - ,{0x50, "DM"} - ,{0x51, "DM"} - ,{0x52, "CP/M or Microport SysV/AT"} - ,{0x56, "GB"} - ,{0x61, "Speed"} - ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} - ,{0x64, "Novell Netware 2.xx"} - ,{0x65, "Novell Netware 3.xx"} - ,{0x75, "PCIX"} - ,{0x80, "Minix 1.1 ... 1.4a"} - ,{0x81, "Minix 1.4b ... 1.5.10"} - ,{0x82, "Linux"} - ,{0x93, "Amoeba filesystem"} - ,{0x94, "Amoeba bad block table"} - ,{0xA5, "386BSD"} - ,{0xB7, "BSDI BSD/386 filesystem"} - ,{0xB8, "BSDI BSD/386 swap"} - ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} - ,{0xE1, "Speed"} - ,{0xE3, "Speed"} - ,{0xE4, "Speed"} - ,{0xF1, "Speed"} - ,{0xF2, "DOS 3.3+ Secondary"} - ,{0xF4, "Speed"} - ,{0xFF, "BBT (Bad Blocks Table)"} -}; - extern char *bootblocks; -extern struct bootarea *bootarea; +extern struct mbr *mbr; int enable_label(int fd) -{ +{ int flag = 1; if (ioctl(fd, DIOCWLABEL, &flag) < 0) { - sprintf(errmsg, "Write enable of disk failed\n"); return(-1); } return(0); @@ -88,10 +46,9 @@ enable_label(int fd) int disable_label(int fd) -{ +{ int flag = 0; if (ioctl(fd, DIOCWLABEL, &flag) < 0) { - sprintf(errmsg, "Write disable of disk failed\n"); return(-1); } return(0); @@ -153,7 +110,8 @@ build_bootblocks(struct disklabel *label) return(-1); } - if (read(fd, &bootblocks[label->d_secsize], (int)(label->d_bbsize - label->d_secsize)) < 0) { + if (read(fd, &bootblocks[label->d_secsize], + (int)(label->d_bbsize - label->d_secsize)) < 0) { sprintf(errmsg, "Couldn't read from boot file %s\n", boot2); return(-1); } @@ -163,16 +121,23 @@ build_bootblocks(struct disklabel *label) return(-1); } + /* Write mbr partition table into bootblocks */ + + bcopy(mbr->dospart, &bootblocks[DOSPARTOFF], + sizeof(struct dos_partition) * NDOSPART); + /* Write the disklabel into the bootblocks */ label->d_checksum = dkcksum(label); - bcopy(label, &bootblocks[(LABELSECTOR * label->d_secsize) + LABELOFFSET], sizeof *label); + bcopy(label, &bootblocks[(LABELSECTOR * label->d_secsize) + LABELOFFSET], + sizeof *label); return(0); } +/* Convert a size in Mb to a round number of cylinders */ int -calc_sects(int size, struct disklabel *label) +Mb_to_cylbdry(int size, struct disklabel *label) { int nsects, ncyls; @@ -184,7 +149,7 @@ calc_sects(int size, struct disklabel *label) } void -build_disklabel(struct disklabel *label, int avail_sects, int offset) +default_disklabel(struct disklabel *label, int avail_sects, int offset) { int nsects; @@ -216,7 +181,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset) label->d_partitions[3].p_frag = DEFFRAG; /* Default root */ - nsects = calc_sects(DEFROOTSIZE, label); + nsects = Mb_to_cylbdry(DEFROOTSIZE, label); label->d_partitions[0].p_size = nsects; label->d_partitions[0].p_offset = offset; @@ -226,7 +191,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset) avail_sects -= nsects; offset += nsects; - nsects = calc_sects(DEFSWAPSIZE, label); + nsects = Mb_to_cylbdry(DEFSWAPSIZE, label); label->d_partitions[1].p_size = nsects; label->d_partitions[1].p_offset = offset; @@ -236,7 +201,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset) avail_sects -= nsects; offset += nsects; - nsects = calc_sects(DEFUSRSIZE, label); + nsects = Mb_to_cylbdry(DEFUSRSIZE, label); if (avail_sects > nsects) nsects = avail_sects; @@ -254,22 +219,6 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset) } -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("Uknown"); -} - int disk_size(int disk) { @@ -280,45 +229,3 @@ disk_size(int disk) * label->d_ntracks * label->d_ncylinders; return(size/1024/1024); } - -int -read_bootarea(int fd) -{ - if (lseek(fd, 0, SEEK_SET) == -1) { - sprintf(errmsg, "Couldn't seek for bootarea read\n"); - return(-1); - } - if (read(fd, &(bootarea->bootcode), 512) == -1) { - sprintf(errmsg, "Failed to read bootarea\n"); - return(-1); - } - /* Validate the bootarea */ - /* XXX -- need to validate contents too */ - if (bootarea->signature != BOOT_MAGIC) { - sprintf(errmsg, "Bootarea invalid\n"); - return(-1); - } - return(0); -} - -int -write_bootarea(int fd) -{ - if (lseek(fd, 0, SEEK_SET) == -1) { - sprintf(errmsg, "Couldn't seek for bootarea write\n"); - return(-1); - } - - if (enable_label(fd) == -1) - return(-1); - - if (write(fd, bootarea, sizeof(bootarea)) == -1) { - sprintf(errmsg, "Failed to write bootarea\n"); - return(-1); - } - - if (disable_label(fd) == -1) - return(-1); - - return(0); -} diff --git a/sbin/sysinstall/bootarea.h b/sbin/sysinstall/bootarea.h index 6b9414f4cbae..bbb8e1bdcb8f 100644 --- a/sbin/sysinstall/bootarea.h +++ b/sbin/sysinstall/bootarea.h @@ -12,8 +12,6 @@ * its use. */ -#define BOOT_MAGIC 0xAA55 -#define ACTIVE 0x80 #define BOOT1 "/usr/mdec/sdboot" #define BOOT2 "/usr/mdec/bootsd" @@ -21,26 +19,10 @@ #define DEFFSIZE 1024 #define DEFFRAG 8 -extern char *part_type(int); -extern int disk_size(int); -extern int enable_label(int); -extern int disable_label(int); -extern int write_bootblocks(int, off_t, int); -extern int build_bootblocks(struct disklabel *); -extern void build_disklabel(struct disklabel *, int, int); -extern int write_bootarea(int); -extern int read_bootarea(int); - -struct bootarea -{ - unsigned char padding[2]; /* force longs to be long aligned */ - unsigned char bootcode[DOSPARTOFF]; - struct dos_partition dospart[4]; - unsigned short signature; -}; - -struct part_type -{ - unsigned char type; - char *name; -}; +int enable_label(int); +int disable_label(int); +int write_bootblocks(int, off_t, int); +int build_bootblocks(struct disklabel *); +int Mb_to_cylbdry(int, struct disklabel *); +void default_disklabel(struct disklabel *, int, int); +int disk_size(int); diff --git a/sbin/sysinstall/mbr.c b/sbin/sysinstall/mbr.c new file mode 100644 index 000000000000..3c7f70de0039 --- /dev/null +++ b/sbin/sysinstall/mbr.c @@ -0,0 +1,193 @@ +/* + * 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 "mbr.h" + +extern struct mbr *mbr; +extern char *errmsg; +extern int inst_part; + +struct part_type part_types[] = PARTITION_TYPES + +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("Uknown"); +} + +int +read_mbr(int fd, struct mbr *mbr) +{ + if (lseek(fd, 0, SEEK_SET) == -1) { + sprintf(errmsg, "Couldn't seek for master boot record read\n"); + return(-1); + } + if (read(fd, &(mbr->bootcode), 512) == -1) { + sprintf(errmsg, "Failed to read master boot record\n"); + return(-1); + } + /* Validate the master boot record */ + if (mbr->magic != MBR_MAGIC) { + sprintf(errmsg, "Master boot record is invalid\n"); + return(-1); + } + return(0); +} + +int +write_mbr(int fd, struct mbr *mbr) +{ + if (lseek(fd, 0, SEEK_SET) == -1) { + sprintf(errmsg, "Couldn't seek for master boot record write\n"); + return(-1); + } + + if (write(fd, mbr->bootcode, MBRSIZE) == -1) { + sprintf(errmsg, "Failed to write master boot record\n"); + return(-1); + } + + return(0); +} + +void +show_mbr(struct mbr *mbr) +{ + int i, j, key = 0; + int x, y; + WINDOW *window; + + window = newwin(LINES, COLS, 0, 0); + keypad(window, TRUE); + + draw_box(window, 0, 0, LINES - 1, COLS - 1, + COLOR_PAIR(COLOR_YELLOW), COLOR_PAIR(COLOR_BLUE)); + + for (i=0; idospart[(i*2)+j].dp_flag); + mvwprintw(window, y+1, x, "Starting at (H%d, S%d, C%d)", + mbr->dospart[(i*2)+j].dp_shd, + mbr->dospart[(i*2)+j].dp_ssect, + mbr->dospart[(i*2)+j].dp_scyl); + mvwprintw(window, y+2, x, "Type: %s (%x)", + part_type(mbr->dospart[(i*2)+j].dp_typ), + mbr->dospart[(i*2)+j].dp_typ); + mvwprintw(window, y+3, x, "Ending at (H%d, S%d, C%d)", + mbr->dospart[(i*2)+j].dp_shd, + mbr->dospart[(i*2)+j].dp_esect, + mbr->dospart[(i*2)+j].dp_ecyl); + mvwprintw(window, y+4, x, "Absolute start sector %ld", + mbr->dospart[(i*2)+j].dp_start); + mvwprintw(window, y+5, x, "Size %ld", mbr->dospart[(i*2)+j].dp_size); + } + } + refresh(); + + while (key != '\n') + key = wgetch(window); + + delwin(window); +} + +void +clear_mbr(struct mbr *mbr) +{ + int i; + + /* 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; + } +} + +int +build_mbr(struct mbr *mbr, struct disklabel *label) +{ + int i; + + /* + * This is the biggie, need to spend some time getting all + * the different possibilities sorted out. + */ + + if (inst_part == -1) { + /* Install to entire disk */ + clear_mbr(mbr); + mbr->dospart[0].dp_flag = ACTIVE; + mbr->dospart[0].dp_shd = 1; + mbr->dospart[0].dp_ssect = 0; + mbr->dospart[0].dp_scyl = 0; + mbr->dospart[0].dp_typ = DOSPTYP_386BSD ; + mbr->dospart[0].dp_ehd = label->d_ntracks; + mbr->dospart[0].dp_esect = label->d_nsectors; + mbr->dospart[0].dp_ecyl = label->d_ncylinders; + mbr->dospart[0].dp_start = 0; + mbr->dospart[0].dp_size = + label->d_ntracks * label->d_nsectors * label->d_ncylinders; + return(1); + } else { + /* Validate partition - XXX need to spend some time making this robust */ + if ((inst_part) && (!mbr->dospart[inst_part].dp_start)) { + strcpy(errmsg, "The start address of the selected partition is 0\n"); + return(0); + } + } + + /* Set partition type to FreeBSD and make it the only active partition */ + for (i=0; i < NDOSPART; i++) + mbr->dospart[i].dp_flag &= ~ACTIVE; + mbr->dospart[inst_part].dp_typ = DOSPTYP_386BSD; + mbr->dospart[inst_part].dp_flag = ACTIVE; + return(1); +} + +void +edit_mbr(struct mbr *mbr, struct disklabel *label) +{ + + dialog_msgbox("DOS partition table editor", + "This editor is still under construction :-)", 10, 75, 1); + show_mbr(mbr); +} diff --git a/sbin/sysinstall/mbr.h b/sbin/sysinstall/mbr.h new file mode 100644 index 000000000000..45abad3d901d --- /dev/null +++ b/sbin/sysinstall/mbr.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#define MBRSIZE 512 +#define MBR_MAGIC 0xAA55 +#define ACTIVE 0x80 + +struct mbr +{ + unsigned char padding[2]; /* force longs to be long aligned */ + unsigned char bootcode[DOSPARTOFF]; + struct dos_partition dospart[4]; + unsigned short magic; +}; + +struct part_type +{ + unsigned char type; + char *name; +}; + +#define PARTITION_TYPES \ +{ \ + {0x00, "Unused"} \ + ,{0x01, "Primary DOS with 12 bit FAT"} \ + ,{0x02, "XENIX / filesystem"} \ + ,{0x03, "XENIX /usr filesystem"} \ + ,{0x04, "Primary DOS with 16 bit FAT"} \ + ,{0x05, "Extended DOS"} \ + ,{0x06, "Primary 'big' DOS (> 32MB)"} \ + ,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} \ + ,{0x08, "AIX filesystem"} \ + ,{0x09, "AIX boot partition or Coherent"} \ + ,{0x0A, "OS/2 Boot Manager or OPUS"} \ + ,{0x10, "OPUS"} \ + ,{0x40, "VENIX 286"} \ + ,{0x50, "DM"} \ + ,{0x51, "DM"} \ + ,{0x52, "CP/M or Microport SysV/AT"} \ + ,{0x56, "GB"} \ + ,{0x61, "Speed"} \ + ,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} \ + ,{0x64, "Novell Netware 2.xx"} \ + ,{0x65, "Novell Netware 3.xx"} \ + ,{0x75, "PCIX"} \ + ,{0x80, "Minix 1.1 ... 1.4a"} \ + ,{0x81, "Minix 1.4b ... 1.5.10"} \ + ,{0x82, "Linux"} \ + ,{0x93, "Amoeba filesystem"} \ + ,{0x94, "Amoeba bad block table"} \ + ,{0xA5, "FreeBSD/NetBSD/386BSD"} \ + ,{0xB7, "BSDI BSD/386 filesystem"} \ + ,{0xB8, "BSDI BSD/386 swap"} \ + ,{0xDB, "Concurrent CPM or C.DOS or CTOS"} \ + ,{0xE1, "Speed"} \ + ,{0xE3, "Speed"} \ + ,{0xE4, "Speed"} \ + ,{0xF1, "Speed"} \ + ,{0xF2, "DOS 3.3+ Secondary"} \ + ,{0xF4, "Speed"} \ + ,{0xFF, "BBT (Bad Blocks Table)"} \ +}; + +extern char *part_type(int); +extern int enable_label(int); +extern int disable_label(int); +extern int write_mbr(int, struct mbr *); +extern int read_mbr(int, struct mbr *); +extern void show_mbr(struct mbr *); +extern void clear_mbr(struct mbr *); +extern void edit_mbr(struct mbr *, struct disklabel *); +extern int build_mbr(struct mbr *, struct disklabel *); diff --git a/sbin/sysinstall/sysinstall.c b/sbin/sysinstall/sysinstall.c index 91238361e16f..4e2f37ea8281 100644 --- a/sbin/sysinstall/sysinstall.c +++ b/sbin/sysinstall/sysinstall.c @@ -1,4 +1,5 @@ /* +#define DEBUG * Copyright (c) 1994, Paul Richards. * * All rights reserved. @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,16 +30,15 @@ #include #include #include +#include #include #include #include +#include "mbr.h" #include "bootarea.h" #include "sysinstall.h" -char xxboot[] = "/usr/mdec/sdboot"; -char bootxx[] = "/usr/mdec/bootsd"; - struct disklabel *avail_disklabels; int *avail_fds; unsigned char **options; @@ -45,7 +46,9 @@ unsigned char **avail_disknames; unsigned char *scratch; unsigned char *errmsg; unsigned char *bootblocks; -struct bootarea *bootarea; +struct mbr *mbr; +struct utsname utsname; +unsigned char *title = utsname.sysname; struct sysinstall *sysinstall; struct sysinstall *sequence; @@ -56,9 +59,9 @@ int inst_part = 0; int custom_install; int dialog_active = 0; -void leave_sysinstall(); -void abort_task(); -void cleanup(); +void exit_sysinstall(); +void abort_installation(char *); +void exit_prompt(); void fatal(char *); extern char *part_type(int); extern int disk_size(int); @@ -67,26 +70,22 @@ extern int disk_size(int); char selection[30]; void -abort_task(char *prompt) +abort_installation(char *prompt) { - strcat(prompt,"\n\n Do you wish to abort the installation ?"); - if (!dialog_yesno("ABORT",prompt,10,75)) - leave_sysinstall(); + strcpy(scratch, prompt); + strcat(scratch,"\n\n Do you wish to abort the installation ?"); + if (!dialog_yesno("Abort installation ?",scratch,10,75)) + exit_prompt(); + clear(); } void -leave_sysinstall() +exit_prompt() { sprintf(scratch,"Are you sure you want to exit sysinstall?"); - if (!dialog_yesno("Exit sysinstall",scratch,10,75)) { - if (getpid() == 1) { - if (reboot(RB_AUTOBOOT) == -1) - fatal("Reboot failed!"); - } else { - cleanup(); - exit(0); - } - } + if (!dialog_yesno("Exit sysinstall",scratch,10,75)) + exit_sysinstall(); + clear(); } int @@ -128,8 +127,8 @@ alloc_memory() return(-1); } - bootarea = (struct bootarea *) malloc(sizeof(struct bootarea)); - if (!bootarea) + mbr = (struct mbr *) malloc(sizeof(struct mbr)); + if (!mbr) return(-1); bootblocks = (char *) malloc(BBSIZE); @@ -165,40 +164,42 @@ free_memory() free(options[i]); free(options); - free(bootarea); + free(mbr); free(bootblocks); free(sysinstall); free(sequence); } void -cleanup() +exit_sysinstall() { - free_memory(); - if (dialog_active) - end_dialog(); + if (getpid() == 1) { + if (reboot(RB_AUTOBOOT) == -1) + if (dialog_active) + while (1) + dialog_msgbox("Exit sysinstall", + "Reboot failed -- hit reset", + 10, 75, 20); + else { + fprintf(stderr, "Reboot failed -- hit reset"); + while (1); + } + } else { + free_memory(); + if (dialog_active) + end_dialog(); + exit(0); + } } void fatal(char *errmsg) { if (dialog_active) - dialog_msgbox("Fatal Error -- Aborting installation", errmsg, 10, 75, 20); + dialog_msgbox("Fatal Error -- Aborting installation", errmsg, 10, 75, 20); else fprintf(stderr, "Fatal Error -- Aborting installation:\n%s\n", errmsg); - if (getpid() == 1) { - if (reboot(RB_AUTOBOOT) == -1) - while (1) - if (dialog_active) - dialog_msgbox("Fatal Error -- Aborting installation", - "Reboot failed after a fatal error -- hit reset", 10, 75, 20); - else - fprintf(stderr, "Fatal Error -- Aborting installation:\n%s\n", - "Reboot failed after a fatal error -- hit reset"); - } else { - cleanup(); - exit(1); - } + exit_sysinstall(); } void @@ -210,6 +211,7 @@ query_disks() struct stat st; int fd; + no_disks = 0; for (i=0;i<10;i++) { sprintf(diskname,"wd%d",i); sprintf(disk,"/dev/r%sd",diskname); @@ -252,9 +254,10 @@ select_disk() if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) { sprintf(scratch,"You did not select a valid disk"); - abort_task(scratch); + abort_installation(scratch); valid = 0; } + clear(); } while (!valid); return(atoi(selection) - 1); } @@ -264,22 +267,33 @@ select_partition(int disk) { int valid; int i; + int choice; do { valid = 1; - sprintf(scratch,"The following partitions were found on this disk"); - for (i=0;i<4;i++) { - sprintf(options[(i*2)], "%d",i+1); - sprintf(options[(i*2)+1], "%s, (%ldMb)", - part_type(bootarea->dospart[i].dp_typ), - bootarea->dospart[i].dp_size * 512 / (1024 * 1024)); + sprintf(scratch,"Select one of the following areas to install to:"); + sprintf(options[0], "%d", 0); + sprintf(options[1], "%s, (%dMb)", "Install to entire disk", + disk_size(disk)); + for (i=0; i < NDOSPART; i++) { + sprintf(options[(i*2)+2], "%d",i+1); + sprintf(options[(i*2)+3], "%s, (%ldMb)", + part_type(mbr->dospart[i].dp_typ), + mbr->dospart[i].dp_size * 512 / (1024 * 1024)); } - if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, 4, options, selection)) { + if (dialog_menu(title, + scratch, 10, 75, 5, 5, options, selection)) { sprintf(scratch,"You did not select a valid partition"); - abort_task(scratch); + abort_installation(scratch); valid = 0; } + clear(); + choice = atoi(selection); + if (!choice) + if (dialog_yesno(title, "Installing to the whole disk will erase all its present data.\n\nAre you sure you want to do this?", 10, 75)) + valid = 0; + clear(); } while (!valid); return(atoi(selection) - 1); @@ -492,35 +506,86 @@ void stage1() { int i; + int ok = 0; + int ready = 0; struct ufs_args ufsargs; - query_disks(); - inst_disk = select_disk(); + while (!ready) { + ready = 1; + + query_disks(); + inst_disk = select_disk(); + +#ifdef DEBUG + read_mbr(avail_fds[inst_disk], mbr); + show_mbr(mbr); +#endif + + if (read_mbr(avail_fds[inst_disk], mbr) == -1) { + sprintf(scratch, "The following error occured will trying to read the master boot record:\n\n%s\n\nIn order to install FreeBSD a new master boot record will have to be written which will mean all current data on the hard disk will be lost.", errmsg); + ok = 0; + while (!ok) { + abort_installation(scratch); + if (!dialog_yesno(title, "Are you sure you wish to proceed?", + 10, 75)) { + clear(); + clear_mbr(mbr); + ok = 1; + } + } + } + + if (custom_install) + if (!dialog_yesno(title, "Do you wish to edit the DOS partition table?", + 10, 75)) { + clear(); + edit_mbr(mbr, &avail_disklabels[inst_disk]); + } - if (read_bootarea(avail_fds[inst_disk]) == -1) { - /* Invalid boot area */ - build_disklabel(&avail_disklabels[inst_disk], - avail_disklabels[inst_disk].d_secperunit, 0); - build_bootblocks(&avail_disklabels[inst_disk]); - write_bootblocks(avail_fds[inst_disk], 0, - avail_disklabels[inst_disk].d_bbsize); - } else { inst_part = select_partition(inst_disk); - /* Set partition to be FreeBSD and active */ - for (i=0; i < NDOSPART; i++) - bootarea->dospart[i].dp_flag &= ~ACTIVE; - bootarea->dospart[inst_part].dp_typ = DOSPTYP_386BSD; - bootarea->dospart[inst_part].dp_flag = ACTIVE; - write_bootarea(avail_fds[inst_disk]); - build_disklabel(&avail_disklabels[inst_disk], - bootarea->dospart[inst_part].dp_size, - bootarea->dospart[inst_part].dp_start); + + ok = 0; + while (!ok) { + if (build_mbr(mbr, &avail_disklabels[inst_disk])) + ok = 1; + else { + sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\n\nDo you wish to edit it by hand?", errmsg); + if (!dialog_yesno(title, scratch, 10, 75)) { + edit_mbr(mbr, &avail_disklabels[inst_disk]); + clear(); + } else { + abort_installation(""); + ok = 1; + ready = 0; + } + } + } + + default_disklabel(&avail_disklabels[inst_disk], + mbr->dospart[inst_part].dp_size, + mbr->dospart[inst_part].dp_start); build_bootblocks(&avail_disklabels[inst_disk]); - write_bootblocks(avail_fds[inst_disk], - bootarea->dospart[inst_part].dp_start, - avail_disklabels[inst_disk].d_bbsize); + + if (ready) { + if (dialog_yesno(title, "We are now ready to format the hard disk for FreeBSD.\n\nSome or all of the disk will be overwritten during this process.\n\nAre you sure you wish to proceed ?", 10, 75)) { + abort_installation(""); + ready = 0; + } + clear(); + } } + /* Write master boot record and bootblocks */ + write_mbr(avail_fds[inst_disk], mbr); + write_bootblocks(avail_fds[inst_disk], + mbr->dospart[inst_part].dp_start, + avail_disklabels[inst_disk].d_bbsize); + +#ifdef DEBUG + read_mbr(avail_fds[inst_disk], mbr); + show_mbr(mbr); +#endif + /* close all the open disks */ for (i=0; i < no_disks; i++) if (close(avail_fds[i]) == -1) { @@ -676,12 +741,20 @@ main(int argc, char **argv) setlogin("root"); } - /* /etc/termcap.small used, if TERM undefined */ if (set_termcap() == -1) fatal("Can't find terminal entry\n"); + if (alloc_memory() == -1) fatal("Couldn't allocate memory\n"); + + if (uname(&utsname) == -1) { + /* Fake uname entry */ + bcopy("FreeBSD", utsname.sysname, strlen("FreeBSD")); + } + + /* XXX - libdialog has particularly bad return value checking */ init_dialog(); + /* If we haven't crashed I guess dialog is running ! */ dialog_active = 1; strcpy(scratch, "/etc/"); @@ -711,5 +784,5 @@ main(int argc, char **argv) default: fatal("Unknown installation status"); } - leave_sysinstall(); + exit_sysinstall(); }