/* * install.c * * This is the first half of the install. It does just enough to get the * second half going. It, and everything it needs, has to fit on one floppy * along with a kernel and modules. Needless to say, it's a bit tight. * * Erik Troan (ewt@redhat.com) * * Copyright 1997 Red Hat Software * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "devices.h" #include "fs.h" #include "install.h" #include "kbd.h" #include "log.h" #include "methods.h" #include "mono.h" #include "net.h" #include "newt.h" #include "perror.h" #include "run.h" #include "windows.h" int testing = 0; int hackdisk = 0; int debug = 1; char * welcomeText = "Welcome to Red Hat Linux!\n" "\n" "This installation process is outlined in detail in the Official Red " "Hat Linux User's Guide available from Red Hat Software. If you have " "access to this manual, you should read the installation section before " "continuing.\n\n" "If you have purchased Official Red Hat Linux, be sure to register your " "purchase through our web site, http://www.redhat.com." ; char * hackdiskText = "Would you like to use a hack disk now?"; void welcome(void) { if (!testing) winMessage(7, 4, 65, 16, "Red Hat Linux", welcomeText); } void mountFloppy() { if (!testing) { logMessage("mounting ext2 fs on floppy"); doMount("fd0", "/tmp/bootdisk", "ext2", 1, 0); logMessage("floppy filesystem mounted on /tmp/bootdisk"); } } void showmtab(void) { char buf[5000]; int fd, i; fd = open("/proc/mounts", O_RDONLY); if (fd < 0) { messageWindow("error", perrorstr("open /proc/mounts")); return; } i = read(fd, buf, sizeof(buf) - 1); if (i < 1) { close(fd); messageWindow("error", perrorstr("read /proc/mounts")); return; } close(fd); buf[i] = '\0'; messageWindow("/proc/mounts", buf); } void mountHackdisk() { if (hackdisk) { messageWindow("Hackdisk", "Insert hack disk"); if (!testing) { doMount("fd0", "/tmp/hackdisk", "ext2", 1, 0); symlink("/tmp/hackdisk/lib", "/lib"); symlink("/tmp/hackdisk/etc", "/etc"); /*showdir("/lib"); showdir("/tmp/hackdisk/bin");*/ logMessage("hackdisk filesystem mounted on /tmp/bootdisk"); if (!fork()) { execl("/tmp/hackdisk/bin/open", "open", "/tmp/hackdisk/bin/sh", NULL); logMessage(perrorstr("exec of sh failed")); } } } } static int pcmciaChoicePanel(int * havePCMCIA) { newtComponent label, f, answer; newtComponent yes, no; #if defined(__sparc__) || defined(__alpha__) *havePCMCIA = 0; return 0; #endif newtOpenWindow(21, 7, 35, 9, "PCMCIA Support"); label = newtLabel(2, 2, "Do you need PCMCIA support?"); yes = newtButton(5, 5, "Yes"); no = newtButton(22, 5, "No"); f = newtForm(NULL, NULL, 0); newtFormAddComponents(f, label, yes, no, NULL); newtFormSetCurrent(f, no); answer = newtRunForm(f); if (answer == f) answer = newtFormGetCurrent(f); newtFormDestroy(f); newtPopWindow(); if (answer == no) *havePCMCIA = 0; else *havePCMCIA = 1; return 0; } int setupPCMCIA(char ** arg) { int rc, doit; struct driversLoaded * dl = NULL; int status; char * args[] = { "/sbin/probe", NULL }; char * probeOutput; static char pcic[20]; pcmciaChoicePanel(&doit); if (!doit) return 0; if ((rc = floppyRoot(NULL))) return rc; if (testing) { sleep(2); return 0; } winStatus(35, 3, "PCMCIA", "Loading PCMCIA support..."); chdir("/modules"); unlink("53c7,8xx.o.gz"); unlink("3c59x.o.gz"); unlink("cdrom.o.gz"); unlink("aztcd.o.gz"); unlink("cdu31a.o.gz"); unlink("cm206.o.gz"); unlink("de4x5.o.gz"); unlink("sbpcd.o.gz"); unlink("sjcd.o.gz"); unlink("sonycd535.o.gz"); unlink("optcd.o.gz"); unlink("gscd.o.gz"); unlink("aic7xxx.o.gz"); unlink("eata_dma.o.gz"); unlink("eata_pio.o.gz"); unlink("pas_16.o.gz"); unlink("ultrastor.o.gz"); unlink("u14-34f.o.gz"); chdir("/"); system("gunzip < /tmp/image/pcmcia.cgz | cpio -iumd --quiet"); newtPopWindow(); winStatus(35, 3, "PCMCIA", "Probing PCMCIA controller..."); rc = runProgramIO(RUN_NOLOG, "/sbin/probe", args, NULL, &probeOutput); newtPopWindow(); if (rc || !probeOutput) { errorWindow("PCMCIA probe failed"); return INST_ERROR; } logMessage("pcmcia probe returned: %s", probeOutput); if (strstr(probeOutput, "TCIC")) { strcpy(pcic, "tcic"); } else strcpy(pcic, "i82365"); logMessage("pcmcia pcic type: %s", pcic); winStatus(40, 3, "PCMCIA", "Starting PCMCIA services..."); loadModule("pcmcia_core", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl); loadModule(pcic, DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl); loadModule("ds", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl); *arg = pcic; if (!fork()) { if (!fork()) { execl("/sbin/cardmgr", "/sbin/cardmgr", NULL); exit(-1); } exit(-1); } wait(&status); /* if cardmgr a chance to get going */ sleep(5); newtPopWindow(); return 0; } void doSuspend(void) { pid_t pid; int status; newtSuspend(); if (!(pid = fork())) { printf("\n\nType to return to the install program.\n\n"); execl("/bin/sh", "-/bin/sh", NULL); perror("error execing /bin/sh"); sleep(5); exit(1); } waitpid(pid, &status, 0); newtResume(); } void main(int argc, char ** argv) { char ** argptr; struct installMethod * method; int rc; char * pcmciaArg = NULL; int isRescue = 0; int isSerial; int force = 0; struct stat sb; argptr = argv + 1; while (*argptr) { if (!strcmp(*argptr, "--test")) { testing = 1; } else if (!strcmp(*argptr, "--force")) { force = 1; } else if (!strcmp(*argptr, "--rescue")) { isRescue = 1; } argptr++; } if (!testing && !force && (getpid() > 50)) { fprintf(stderr, "you're running me on a live system! that's "); fprintf(stderr, "incredibly stupid.\n"); exit(1); } openLog(); /* see if we're on a serial console -- if so, don't setup a keymap */ if (fstat(0, &sb)) { logMessage("error stat'ing stdin: %s", strerror(errno)); return; } if (!S_ISCHR(sb.st_mode)) { logMessage("stdin isn't a character device!!! ack!"); return; } isSerial = (major(sb.st_rdev) == 4 && minor(sb.st_dev) >= 64) || (major(sb.st_rdev) == 5 && minor(sb.st_dev) >= 64); if (!isRescue) logMessage("welcome to the Red Hat install " "(first stage, version " VERSION " built " __DATE__ " " __TIME__")"); setenv("NEWT_MONO", "1", 1); newtInit(); newtCls(); if (!access("/bin/sh", X_OK)) { newtSetSuspendCallback(doSuspend); } newtDrawRootText(0, 0, "Welcome to Red Hat Linux"); setColorState(); newtFinished(); newtInit(); newtCls(); newtDrawRootText(0, 0, "Welcome to Red Hat Linux"); if (!isRescue) welcome(); newtPushHelpLine(NULL); #ifndef __sparc__ if (!isSerial) setupKeyboard(); #endif do { rc = setupPCMCIA(&pcmciaArg); } while (rc); if (isRescue) { do { rc = floppyRoot(NULL); } while (rc); } else { chooseInstallMethod(&method); #if 0 if (!testing) { /* set up some symlinks */ symlink("/tmp/image/RedHat/instimage/lib", "/tmp/lib"); if (symlink("/tmp/image/RedHat/instimage/usr/bin", "/tmp/bin")) { messageWindow("Error", perrorstr("symlink 2")); } } #endif } mountHackdisk(); newtFinished(); closeLog(); if (testing) exit(0); if (isRescue) execl("/usr/bin/runinstall2", "runinstall2", "--rescue", NULL); else if (pcmciaArg) execl("/usr/bin/runinstall2", "runinstall2", "--method", method->abbrev, "--pcmcia", pcmciaArg, NULL); else execl("/usr/bin/runinstall2", "runinstall2", "--method", method->abbrev, NULL); rc = errno; openLog(); logMessage("error in exec of second stage loader :-("); logMessage("\terror:%s", strerror(rc)); while (1) ; exit(0); }