From 26b2d70e8e9bb21404d4e899fc36cda7d06e95fc Mon Sep 17 00:00:00 2001 From: Paul Richards Date: Wed, 19 Oct 1994 23:58:03 +0000 Subject: [PATCH] More code rearrangment, moved all mbr code into its own file so it can be used by other programs. Added all the necessary menus to take the user through the installation of the bootblocks. --- sbin/sysinstall/Makefile | 2 +- sbin/sysinstall/bootarea.c | 131 +++----------------- sbin/sysinstall/bootarea.h | 32 ++--- sbin/sysinstall/mbr.c | 193 ++++++++++++++++++++++++++++++ sbin/sysinstall/mbr.h | 83 +++++++++++++ sbin/sysinstall/sysinstall.c | 223 +++++++++++++++++++++++------------ 6 files changed, 451 insertions(+), 213 deletions(-) create mode 100644 sbin/sysinstall/mbr.c create mode 100644 sbin/sysinstall/mbr.h 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(); }