diff options
author | phk <phk@FreeBSD.org> | 1994-10-20 05:00:00 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1994-10-20 05:00:00 +0000 |
commit | 218c2e4b59c765642cb4dcf912c0a1845d6614bf (patch) | |
tree | 9ff1f4416a908f34655710bf931e627772b58522 /sbin/sysinstall/stage1.c | |
parent | 29f810393aff6d91e6db3e0673334a2b9094175e (diff) | |
download | FreeBSD-src-218c2e4b59c765642cb4dcf912c0a1845d6614bf.zip FreeBSD-src-218c2e4b59c765642cb4dcf912c0a1845d6614bf.tar.gz |
Integrate my code a lot more with Pauls. (I have left sysinstall.c
here, even though it isn't used in the Makefile for Paul not to have
an heart-attack when he wakes up. :-)
Way to go still...
Diffstat (limited to 'sbin/sysinstall/stage1.c')
-rw-r--r-- | sbin/sysinstall/stage1.c | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/sbin/sysinstall/stage1.c b/sbin/sysinstall/stage1.c new file mode 100644 index 0000000..a946aad --- /dev/null +++ b/sbin/sysinstall/stage1.c @@ -0,0 +1,327 @@ +/* +#define DEBUG + * 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 <dialog.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdarg.h> +#include <ncurses.h> + +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/disklabel.h> +#include <sys/ioctl.h> +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <ufs/ffs/fs.h> +#include <machine/console.h> + +#include "mbr.h" +#include "bootarea.h" +#include "sysinstall.h" + +struct disklabel *avail_disklabels; +int *avail_fds; +unsigned char **options; +unsigned char **avail_disknames; +unsigned char *scratch; +unsigned char *errmsg; +unsigned char *bootblocks; +struct mbr *mbr; + +int no_disks = 0; +int inst_disk = 0; +int inst_part = 0; +int custom_install; +int dialog_active = 0; + +void exit_sysinstall(); +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]; + +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); + + avail_disklabels = (struct disklabel *) calloc(MAX_NO_DISKS, sizeof(struct disklabel)); + if (!avail_disklabels) + return(-1); + + avail_fds = (int *) calloc(MAX_NO_DISKS, sizeof(int)); + if (!avail_fds) + return(-1); + + avail_disknames = (unsigned char **) calloc(MAX_NO_DISKS, sizeof(char *)); + if (!avail_disknames) + return(-1); + for (i=0;i<MAX_NO_DISKS;i++) { + avail_disknames[i] = (char *) calloc(15, sizeof(char)); + if (!avail_disknames[i]) + 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); + } + + mbr = (struct mbr *) malloc(sizeof(struct mbr)); + if (!mbr) + return(-1); + + bootblocks = (char *) malloc(BBSIZE); + if (!bootblocks) + return(-1); + + return(0); +} + +void +free_memory() +{ + int i; + + free(scratch); + free(errmsg); + free(avail_disklabels); + free(avail_fds); + + for (i=0;i<MAX_NO_DISKS;i++) + free(avail_disknames[i]); + free(avail_disknames); + + for (i=0;i<MAX_NO_DISKS;i++) + free(options[i]); + free(options); + + free(mbr); + free(bootblocks); +} + + +void +query_disks() +{ + int i; + char disk[15]; + char diskname[5]; + 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); + if ((stat(disk, &st) == 0) && (st.st_mode & S_IFCHR)) + if ((fd = open(disk, O_RDWR)) != -1) { + avail_fds[no_disks] = fd; + bcopy(diskname, avail_disknames[no_disks], strlen(diskname)); + if (ioctl(fd, DIOCGDINFO, &avail_disklabels[no_disks++]) == -1) + no_disks--; + } + } + + for (i=0;i<10;i++) { + sprintf(diskname,"sd%d",i); + sprintf(disk,"/dev/r%sd",diskname); + if ((stat(disk, &st) == 0) && (st.st_mode & S_IFCHR)) + if ((fd = open(disk, O_RDWR)) != -1) { + avail_fds[no_disks] = fd; + bcopy(diskname, avail_disknames[no_disks], strlen(diskname)); + if (ioctl(fd, DIOCGDINFO, &avail_disklabels[no_disks++]) == -1) + no_disks--; + } + } +} + +int +select_disk() +{ + int i; + int valid; + + do { + valid = 1; + 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); + sprintf(options[(i*2)+1], "%s, (%dMb) -> %s",avail_disklabels[i].d_typename,disk_size(i),avail_disknames[i]); + } + + if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) { + sprintf(scratch,"You did not select a valid disk"); + AskAbort(scratch); + valid = 0; + } + clear(); + } while (!valid); + return(atoi(selection) - 1); +} + +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:"); + 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(TITLE, + scratch, 10, 75, 5, 5, options, selection)) { + sprintf(scratch,"You did not select a valid partition"); + AskAbort(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); +} + +void +stage1() +{ + int i; + int ok = 0; + int ready = 0; + + alloc_memory(); + 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) { + AskAbort(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]); + } + + inst_part = select_partition(inst_disk); + + 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 { + AskAbort(""); + 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]); + + 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(""); + 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) { + sprintf(errmsg, "Error on closing file descriptors: %s\n", + strerror(errno)); + Fatal(errmsg); + } + +} + |