summaryrefslogtreecommitdiff
path: root/sbin/sysinstall/sysinstall.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/sysinstall/sysinstall.c')
-rw-r--r--sbin/sysinstall/sysinstall.c223
1 files changed, 148 insertions, 75 deletions
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 <string.h>
#include <unistd.h>
#include <stdarg.h>
+#include <ncurses.h>
#include <sys/types.h>
#include <sys/errno.h>
@@ -28,16 +30,15 @@
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/stat.h>
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <ufs/ffs/fs.h>
#include <machine/console.h>
+#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();
}