summaryrefslogtreecommitdiffstats
path: root/sbin/sysinstall/stage1.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-10-20 05:00:00 +0000
committerphk <phk@FreeBSD.org>1994-10-20 05:00:00 +0000
commit218c2e4b59c765642cb4dcf912c0a1845d6614bf (patch)
tree9ff1f4416a908f34655710bf931e627772b58522 /sbin/sysinstall/stage1.c
parent29f810393aff6d91e6db3e0673334a2b9094175e (diff)
downloadFreeBSD-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.c327
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);
+ }
+
+}
+
OpenPOWER on IntegriCloud