diff --git a/sbin/sysinstall/Makefile b/sbin/sysinstall/Makefile index 2dd748531ce7..addeab79a621 100644 --- a/sbin/sysinstall/Makefile +++ b/sbin/sysinstall/Makefile @@ -8,7 +8,7 @@ SRCS = stage1.c dkcksum.c bootarea.c mbr.c \ utils.c termcap.c exec.c \ stage0.c stage2.c stage3.c main.c -CFLAGS += -Wall +CFLAGS += -Wall -g LDADD = -ldialog -lncurses -lmytinfo DPADD = ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO} diff --git a/sbin/sysinstall/bootarea.c b/sbin/sysinstall/bootarea.c index a1fba2b18e8b..0e0cbb85305e 100644 --- a/sbin/sysinstall/bootarea.c +++ b/sbin/sysinstall/bootarea.c @@ -23,16 +23,16 @@ #include #include #include +#include #include "mbr.h" #include "bootarea.h" #include "sysinstall.h" -char boot1[] = BOOT1; -char boot2[] = BOOT2; - extern char *bootblocks; extern struct mbr *mbr; +extern char boot1[]; +extern char boot2[]; int enable_label(int fd) @@ -88,15 +88,17 @@ build_bootblocks(struct disklabel *label) int fd; + sprintf(scratch, "\nLoading boot code from %s\n", boot1); + dialog_msgbox(TITLE, scratch, 5, 60, 0); fd = open(boot1, O_RDONLY); if (fd < 0) { sprintf(errmsg, "Couldn't open boot file %s\n", boot1); return(-1); } - if (read(fd, bootblocks, (int)label->d_secsize) < 0) { + if (read(fd, bootblocks, MBRSIZE) < 0) { sprintf(errmsg, "Couldn't read from boot file %s\n", boot1); - return(-1); + return(-1); } if (close(fd) == -1) { @@ -104,14 +106,18 @@ build_bootblocks(struct disklabel *label) return(-1); } + dialog_clear(); + sprintf(scratch, "\nLoading boot code from %s\n", boot1); + dialog_msgbox(TITLE, scratch, 5, 60, 0); + fd = open(boot2, O_RDONLY); if (fd < 0) { sprintf(errmsg, "Couldn't open boot file %s\n", boot2); return(-1); } - if (read(fd, &bootblocks[label->d_secsize], - (int)(label->d_bbsize - label->d_secsize)) < 0) { + if (read(fd, &bootblocks[MBRSIZE], + (int)(label->d_bbsize - MBRSIZE)) < 0) { sprintf(errmsg, "Couldn't read from boot file %s\n", boot2); return(-1); } @@ -121,10 +127,12 @@ build_bootblocks(struct disklabel *label) return(-1); } - /* Write mbr partition table into bootblocks */ + /* Copy DOS partition area into bootblocks */ bcopy(mbr->dospart, &bootblocks[DOSPARTOFF], - sizeof(struct dos_partition) * NDOSPART); + sizeof(struct dos_partition) * 4); + + dialog_clear(); /* Write the disklabel into the bootblocks */ diff --git a/sbin/sysinstall/bootarea.h b/sbin/sysinstall/bootarea.h index bbb8e1bdcb8f..96413f6d7004 100644 --- a/sbin/sysinstall/bootarea.h +++ b/sbin/sysinstall/bootarea.h @@ -12,8 +12,8 @@ * its use. */ -#define BOOT1 "/usr/mdec/sdboot" -#define BOOT2 "/usr/mdec/bootsd" +#define BOOT1 "/stand/sdboot" +#define BOOT2 "/stand/bootsd" /* XXX -- calculate these, this is nasty */ #define DEFFSIZE 1024 diff --git a/sbin/sysinstall/mbr.c b/sbin/sysinstall/mbr.c index c0e73813daa0..912bb8746d29 100644 --- a/sbin/sysinstall/mbr.c +++ b/sbin/sysinstall/mbr.c @@ -13,17 +13,20 @@ */ #include +#include +#include +#include + #include #include #include -#include -#include #include "mbr.h" +#include "sysinstall.h" extern struct mbr *mbr; -extern char *errmsg; extern int inst_part; +extern int whole_disk; struct part_type part_types[] = PARTITION_TYPES @@ -50,7 +53,7 @@ read_mbr(int fd, struct mbr *mbr) sprintf(errmsg, "Couldn't seek for master boot record read\n"); return(-1); } - if (read(fd, &(mbr->bootcode), 512) == -1) { + if (read(fd, &(mbr->bootcode), MBRSIZE) == -1) { sprintf(errmsg, "Failed to read master boot record\n"); return(-1); } @@ -70,11 +73,17 @@ write_mbr(int fd, struct mbr *mbr) return(-1); } + if (enable_label(fd) == -1) + return(-1); + if (write(fd, mbr->bootcode, MBRSIZE) == -1) { sprintf(errmsg, "Failed to write master boot record\n"); return(-1); } + if(disable_label(fd) == -1) + return(-1); + return(0); } @@ -97,20 +106,20 @@ show_mbr(struct mbr *mbr) y = (i * 11) + 2; mvwprintw(window, y, x, "Partition %d: flags = %x", (i*2)+j, mbr->dospart[(i*2)+j].dp_flag); - mvwprintw(window, y+1, x, "Starting at (H%d, S%d, C%d)", + mvwprintw(window, y+1, x, "Starting at (C%d, H%d, S%d)", + mbr->dospart[(i*2)+j].dp_scyl, mbr->dospart[(i*2)+j].dp_shd, - mbr->dospart[(i*2)+j].dp_ssect, - mbr->dospart[(i*2)+j].dp_scyl); + mbr->dospart[(i*2)+j].dp_ssect); 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+3, x, "Ending at (C%d, H%d, S%d)", + mbr->dospart[(i*2)+j].dp_ecyl, + mbr->dospart[(i*2)+j].dp_ehd, + mbr->dospart[(i*2)+j].dp_esect); 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); + mvwprintw(window, y+5, x, "Size (in sectors) %ld", mbr->dospart[(i*2)+j].dp_size); } } refresh(); @@ -119,14 +128,40 @@ show_mbr(struct mbr *mbr) key = wgetch(window); delwin(window); + dialog_clear(); } -void -clear_mbr(struct mbr *mbr) +int +clear_mbr(struct mbr *mbr, char *bootcode) { int i; + int fd; + + /* + * If installing to the whole disk + * then clobber any existing bootcode. + */ + + sprintf(scratch, "\nLoading MBR code from %s\n", bootcode); + dialog_msgbox(TITLE, scratch, 5, 60, 0); + 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); + } + + if (close(fd) == -1) { + sprintf(errmsg, "Couldn't close boot file %s\n", bootcode); + return(-1); + } /* Create an empty partition table */ + for (i=0; i < NDOSPART; i++) { mbr->dospart[i].dp_flag = 0; mbr->dospart[i].dp_shd = 0; @@ -139,47 +174,49 @@ clear_mbr(struct mbr *mbr) mbr->dospart[i].dp_start = 0; mbr->dospart[i].dp_size = 0; } + + mbr->magic = MBR_MAGIC; + + dialog_clear(); + return(0); } int -build_mbr(struct mbr *mbr, struct disklabel *label) +build_mbr(struct mbr *mbr, char *bootcode, struct disklabel *lb) { int i; + struct dos_partition *dp = &mbr->dospart[inst_part]; - /* - * This is the biggie, need to spend some time getting all - * the different possibilities sorted out. - */ - - if (inst_part == -1) { + if (whole_disk) { /* 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); - } + if (clear_mbr(mbr, bootcode) == -1) + return(-1); + dp->dp_scyl = 0; + dp->dp_shd = 1; + dp->dp_ssect = 1; + dp->dp_ecyl = lb->d_ncylinders - 1; + dp->dp_ehd = lb->d_ntracks - 1; + dp->dp_esect = lb->d_nsectors; + dp->dp_start = (dp->dp_scyl * lb->d_ntracks * lb->d_nsectors) + + (dp->dp_shd * lb->d_nsectors) + + dp->dp_ssect - 1; + dp->dp_size = (lb->d_nsectors * lb->d_ntracks * lb->d_ncylinders) - dp->dp_start; + } + + /* Validate partition - XXX need to spend some time making this robust */ + if (!dp->dp_start) { + strcpy(errmsg, "The start address of the selected partition is 0\n"); + return(-1); } /* 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); + dp->dp_typ = DOSPTYP_386BSD; + dp->dp_flag = ACTIVE; + + return(0); } void diff --git a/sbin/sysinstall/mbr.h b/sbin/sysinstall/mbr.h index 45abad3d901d..ea4de0245553 100644 --- a/sbin/sysinstall/mbr.h +++ b/sbin/sysinstall/mbr.h @@ -78,6 +78,6 @@ 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 int clear_mbr(struct mbr *, char *); extern void edit_mbr(struct mbr *, struct disklabel *); -extern int build_mbr(struct mbr *, struct disklabel *); +extern int build_mbr(struct mbr *, char *, struct disklabel *); diff --git a/sbin/sysinstall/stage1.c b/sbin/sysinstall/stage1.c index 035ed86ece6a..9c2a160fbaaa 100644 --- a/sbin/sysinstall/stage1.c +++ b/sbin/sysinstall/stage1.c @@ -26,10 +26,7 @@ #include #include #include -#include -#include #include -#include #include #include @@ -49,7 +46,8 @@ struct mbr *mbr; int no_disks = 0; int inst_disk = 0; int inst_part = 0; -int custom_install; +int whole_disk = 0; +int custom_install = 0; int dialog_active = 0; void exit_sysinstall(); @@ -57,8 +55,9 @@ void exit_prompt(); extern char *part_type(int); extern int disk_size(int); -/* To make the binary as small as possible these should be malloc'd */ char selection[30]; +char boot1[] = BOOT1; +char boot2[] = BOOT2; int alloc_memory() @@ -184,7 +183,8 @@ select_disk() } if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) { - sprintf(scratch,"You did not select a valid disk"); + dialog_clear(); + sprintf(scratch,"\n\n\nYou did not select a valid disk.\n\n"); AskAbort(scratch); valid = 0; } @@ -216,18 +216,24 @@ select_partition(int disk) if (dialog_menu(TITLE, scratch, 10, 75, 5, 5, options, selection)) { sprintf(scratch,"You did not select a valid partition"); + dialog_clear(); AskAbort(scratch); valid = 0; } dialog_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)) + choice = atoi(selection) - 1; + if (choice == -1) { + whole_disk = 1; + choice = 0; + if (dialog_yesno(TITLE, "\n\nInstalling to the whole disk will erase all its current data.\n\nAre you sure you want to do this?", 10, 75)) { valid = 0; + whole_disk = 0; + } + } dialog_clear(); } while (!valid); - return(atoi(selection) - 1); + return(choice); } void @@ -237,31 +243,31 @@ stage1() int ok = 0; int ready = 0; + query_disks(); + 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); + sprintf(scratch, "The following error occured will 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?", 10, 75)) { dialog_clear(); - clear_mbr(mbr); + if (clear_mbr(mbr, boot1) == -1) { + sprintf(scratch, "\n\nCouldn't create new master boot record.\n\n%s", errmsg); + Fatal(scratch);; + } ok = 1; } + dialog_clear(); } } - + if (custom_install) if (!dialog_yesno(TITLE, "Do you wish to edit the DOS partition table?", 10, 75)) { @@ -269,33 +275,42 @@ stage1() edit_mbr(mbr, &avail_disklabels[inst_disk]); } + dialog_clear(); inst_part = select_partition(inst_disk); ok = 0; while (!ok) { - if (build_mbr(mbr, &avail_disklabels[inst_disk])) + if (build_mbr(mbr, boot1, &avail_disklabels[inst_disk]) != -1) { + ready = 1; ok = 1; - else { - sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\n\nDo you wish to edit it by hand?", errmsg); + } else { + sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\nDo you wish to edit it by hand?", errmsg); if (!dialog_yesno(TITLE, scratch, 10, 75)) { - edit_mbr(mbr, &avail_disklabels[inst_disk]); dialog_clear(); + edit_mbr(mbr, &avail_disklabels[inst_disk]); } else { - AskAbort(""); + dialog_clear(); + AskAbort("Installation cannot proceed without\na valid master boot record\n"); ok = 1; ready = 0; } } + dialog_clear(); } - default_disklabel(&avail_disklabels[inst_disk], + if (ready) { + default_disklabel(&avail_disklabels[inst_disk], mbr->dospart[inst_part].dp_size, mbr->dospart[inst_part].dp_start); - build_bootblocks(&avail_disklabels[inst_disk]); + if (build_bootblocks(&avail_disklabels[inst_disk]) == -1) + Fatal(errmsg); + } + /* ready could have been reset above */ 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)) { - AskAbort(""); + dialog_clear(); + AskAbort("Do you want to quit?"); ready = 0; } dialog_clear(); @@ -303,15 +318,12 @@ stage1() } /* Write master boot record and bootblocks */ - write_mbr(avail_fds[inst_disk], mbr); - write_bootblocks(avail_fds[inst_disk], + if (write_mbr(avail_fds[inst_disk], mbr) == -1) + Fatal(errmsg); + if (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 + avail_disklabels[inst_disk].d_bbsize) == -1) + Fatal(errmsg); /* close all the open disks */ for (i=0; i < no_disks; i++) @@ -320,6 +332,4 @@ stage1() strerror(errno)); Fatal(errmsg); } - } - diff --git a/sbin/sysinstall/sysinstall.h b/sbin/sysinstall/sysinstall.h index b92bffd1fa69..a1efd3fe612b 100644 --- a/sbin/sysinstall/sysinstall.h +++ b/sbin/sysinstall/sysinstall.h @@ -29,22 +29,6 @@ #define COPYRIGHT_FILE "/COPYRIGHT" #define README_FILE "/README" -#define STATUSFILE "sysinstall.stat" -#define NOT_INSTALLED 0 -#define DISK_READY 1 -#define INSTALLED_BASE 2 - -struct sysinstall -{ - char media[90]; - int status; - char seq_name[64]; - int seq_size; - int seq_no; - char archive[64]; - char root_dev[90]; -}; - #ifndef EXTERN # define EXTERN extern #endif @@ -62,12 +46,14 @@ extern struct disklabel *avail_disklabels; extern u_short dkcksum(struct disklabel *); /* utils.c */ +void Abort __P((void)); +void ExitSysinstall __P((void)); void TellEm __P((char *fmt, ...)); void stage0 __P((void)); void *Malloc __P((size_t size)); char *StrAlloc __P((char *str)); void Fatal __P((char *fmt, ...)); -int AskAbort __P((char *fmt, ...)); +void AskAbort __P((char *fmt, ...)); void MountUfs __P((char *device, char *prefix, char *mountpoint, int do_mkdir)); void Mkdir __P((char *path)); diff --git a/sbin/sysinstall/utils.c b/sbin/sysinstall/utils.c index 5a4e9e5e2346..7f4900123adc 100644 --- a/sbin/sysinstall/utils.c +++ b/sbin/sysinstall/utils.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: utils.c,v 1.5 1994/10/21 02:14:54 phk Exp $ + * $Id: utils.c,v 1.6 1994/10/21 04:43:07 ache Exp $ * */ @@ -23,6 +23,7 @@ #include #include #include +#include #include "sysinstall.h" @@ -36,6 +37,7 @@ TellEm(char *fmt, ...) vsnprintf(p, 2048, fmt, ap); va_end(ap); dialog_msgbox("Progress", p, 3, 75, 0); + dialog_clear(); free(p); } @@ -43,36 +45,68 @@ void Fatal(char *fmt, ...) { char *p; - int i = errno; va_list ap; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); - sprintf(p+strlen(p),"\nErrno= %d, %s.",i,strerror(i)); if (dialog_active) { dialog_msgbox("Fatal", p, 12, 75, 1); end_dialog(); } else fprintf(stderr, "Fatal -- %s", p); free(p); - exit(7); + ExitSysinstall(); } -int +void AskAbort(char *fmt, ...) { char *p; va_list ap; - int i; p = Malloc(2048); va_start(ap,fmt); vsnprintf(p, 2048, fmt, ap); va_end(ap); - i = dialog_yesno("Abort", p, 12, 75); + strcat(p, "\n\nDo you wish to abort the installation?"); + if (!dialog_yesno("Abort", p, 15, 60)) { + dialog_clear(); + Abort(); + } + dialog_clear(); free(p); - return i; +} + +void +Abort() +{ + if (dialog_yesno("Exit sysinstall","\n\nAre you sure you want to quit?", + 10, 40)) { + dialog_clear(); + return; + } + ExitSysinstall(); +} + +void +ExitSysinstall() +{ + if (getpid() == 1) { + clear(); + if (reboot(RB_AUTOBOOT) == -1) + if (dialog_active) { + dialog_clear(); + dialog_msgbox(TITLE, "\n\nCan't reboot machine -- hit reset button", + 5,30,0); + } else + fprintf(stderr, "Can't reboot the machine -- hit the reset button"); + while(1); + } else + clear(); + refresh(); + end_dialog(); + exit(0); } void * @@ -121,7 +155,7 @@ MountUfs(char *device, char *prefix, char *mountpoint, int do_mkdir) TellEm("mount /dev/%s /mnt%s",dbuf,pbuf); ufsargs.fspec = dbuf; if (mount(MOUNT_UFS,pbuf, 0, (caddr_t) &ufsargs) == -1) { - Fatal("Error mounting %s on : %s\n", + Fatal("Error mounting %s on %s : %s\n", dbuf, pbuf, strerror(errno)); } }