home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <newt.h>
- #include <popt.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/mount.h>
- #include <unistd.h>
-
- #include "dns.h"
- #include "fs.h"
- #include "hd.h"
- #include "intl.h"
- #include "install.h"
- #include "kickstart.h"
- #include "log.h"
- #include "methods.h"
- #include "net.h"
- #include "windows.h"
-
- /* This was split into two pieces to keep the initial install program small */
-
- static int nfsPrepare(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int forceSupp,
- struct driversLoaded ** dl);
- static int cdromPrepare(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int forceSupp,
- struct driversLoaded ** dl);
- static int nfsGetSetup(char ** hostptr, char ** dirptr);
- int floppyRoot(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int forceSupp,
- struct driversLoaded ** dl);
- static int totalMemory(void); /* in K */
-
- #define CDROM_METHOD_NUM 0
- #define NFS_METHOD_NUM 1
- /* We have a loop a bit later which translates the 'Local CDROM' language */
- static struct installMethod methods[] = {
- { "Local CDROM", "cdrom", 0, cdromPrepare, NULL, NULL,
- NULL, NULL, NULL },
- { "NFS image", "nfs", 0, nfsPrepare, NULL, NULL,
- NULL, NULL, NULL },
- { "hard drive", "hd", 0, floppyRoot, NULL, NULL,
- NULL, NULL, NULL },
- { "FTP", "ftp", 0, floppyRoot, NULL, NULL,
- NULL, NULL, NULL },
- #ifdef __i386__
- { "SMB image", "smb", 0, floppyRoot, NULL, NULL,
- NULL, NULL, NULL },
- #endif
- #if 0
- { "SCSI Tape Install", "tape", 0, floppyRoot, NULL, NULL,
- NULL, NULL, NULL },
- #endif
- } ;
- static int numMethods = sizeof(methods) / sizeof(struct installMethod);
- static int isMounted = 0;
-
- #define LOAD_BLOCK_COUNT 16
- static int loadRamdisk(char * todev, char * fromdev, int blocks,
- char * label) {
- newtComponent form, scale;
- char * topath, * frompath;
- char buf[LOAD_BLOCK_COUNT * 1024];
- int rc = 0;
- int i;
- int to, from;
-
- if (blocks % LOAD_BLOCK_COUNT) {
- logMessage("internal error: blocks in loadRamdisk() must be "
- "divisible by %d!!", LOAD_BLOCK_COUNT);
- return 1;
- }
-
- topath = alloca(strlen(todev) + 8);
- sprintf(topath, "/tmp/%s", todev);
-
- frompath = alloca(strlen(fromdev) + 8);
- sprintf(frompath, "/tmp/%s", fromdev);
-
- if (devMakeInode(todev, topath)) return 1;
- if (devMakeInode(fromdev, frompath)) {
- unlink(topath);
- return 1;
- }
-
- to = open(topath, O_WRONLY);
- if (to < 0) {
- logMessage("failed to open %s: %s", topath, strerror(errno));
- unlink(topath);
- unlink(frompath);
- return 1;
- }
-
- from = open(frompath, O_RDONLY);
- if (from < 0) {
- logMessage("failed to open %s: %s", frompath, strerror(errno));
- unlink(topath);
- unlink(frompath);
- return 1;
- }
-
- unlink(frompath);
- unlink(topath);
-
- logMessage("copying %d blocks from %s to %s", blocks, fromdev, todev);
-
- newtCenteredWindow(60, 5, "Loading");
-
- form = newtForm(NULL, NULL, 0);
-
- newtFormAddComponent(form, newtLabel(1, 1, label));
- scale = newtScale(1, 3, 58, blocks / LOAD_BLOCK_COUNT);
- newtFormAddComponent(form, scale);
- newtDrawForm(form);
- newtRefresh();
-
- for (i = 0; i < (blocks / LOAD_BLOCK_COUNT) && !rc; i++) {
- newtScaleSet(scale, i);
- newtRefresh();
-
- if (read(from, buf, sizeof(buf)) != sizeof(buf)) {
- logMessage("error reading from device: %s", strerror(errno));
- rc = 1;
- } else {
- if (write(to, buf, sizeof(buf)) != sizeof(buf)) {
- logMessage("error writing to device: %s", strerror(errno));
- rc = 1;
- }
- }
- }
-
- newtPopWindow();
- newtFormDestroy(form);
-
- close(from);
- close(to);
-
- return rc;
- }
-
- static int totalMemory(void) {
- int fd;
- int bytesRead;
- char buf[4096];
- char * chptr, * start;
- int total = 0;
-
- fd = open("/proc/meminfo", O_RDONLY);
- if (fd < 0) {
- logMessage("failed to open /proc/meminfo: %s", strerror(errno));
- return 0;
- }
-
- bytesRead = read(fd, buf, sizeof(buf) - 1);
- if (bytesRead < 0) {
- logMessage("failed to read from /proc/meminfo: %s", strerror(errno));
- close(fd);
- return 0;
- }
-
- close(fd);
- buf[bytesRead] = '\0';
-
- chptr = buf;
- while (*chptr && !total) {
- if (*chptr != '\n' || strncmp(chptr + 1, "MemTotal:", 9)) {
- chptr++;
- continue;
- }
-
- start = ++chptr ;
- while (*chptr && *chptr != '\n') chptr++;
-
- *chptr = '\0';
-
- logMessage("found total memory tag: \"%s\"", start);
-
- while (!isdigit(*start) && *start) start++;
- if (!*start) {
- logMessage("no number appears after MemTotal tag");
- return 0;
- }
-
- chptr = start;
- while (*chptr && isdigit(*chptr)) {
- total = (total * 10) + (*chptr - '0');
- chptr++;
- }
- }
-
- logMessage("%d kB are available", total);
-
- return total;
- }
-
- static int installMethodWindow(struct installMethod ** method,
- int showSuppBox,
- int * forceSuppPtr) {
- int i;
- newtComponent textbox, listbox, form, okay, back, result;
- newtGrid buttonBar, grid, middle;
- char forceSupp = showSuppBox ? '*' : ' ';
-
- textbox = newtTextboxReflowed(-1, -1, _("What type of media contains "
- "the packages to be installed?"), 30, 10,
- 0, 0);
-
- listbox = newtListbox(-1, -1, numMethods, NEWT_FLAG_RETURNEXIT);
-
- for (i = 0; i < numMethods; i++) {
- newtListboxAddEntry(listbox, _(methods[i].name), methods + i);
- }
-
- buttonBar = newtButtonBar(_("Ok"), &okay, _("Back"), &back, NULL);
-
- middle = newtCreateGrid(1, 2);
- newtGridSetField(middle, 0, 0, NEWT_GRID_COMPONENT, listbox,
- 0, 0, 0, 0, 0, 0);
-
- #ifdef __i386__
- if (expert || showSuppBox)
- newtGridSetField(middle, 0, 1, NEWT_GRID_COMPONENT,
- newtCheckbox(-1, -1, _("Force supplemental disk"),
- forceSupp, NULL, &forceSupp),
- 0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
- #endif
-
- grid = newtGridBasicWindow(textbox, middle, buttonBar);
- newtGridWrappedWindow(grid, _("Installation Method"));
-
- form = newtForm(NULL, 0, 0);
- newtGridAddComponentsToForm(grid, form, 1);
- newtGridFree(grid, 1);
-
- result = newtRunForm(form);
- newtPopWindow();
- if (result == back) {
- newtFormDestroy(form);
- return INST_CANCEL;
- }
-
- *method = newtListboxGetCurrent(listbox);
- newtFormDestroy(form);
-
- *forceSuppPtr = (forceSupp != ' ');
-
- return 0;
- }
-
- int chooseInstallMethod(int showSuppBox, struct installMethod ** method,
- struct netInfo * netc, struct intfInfo * intf,
- struct driversLoaded ** dl) {
- int rc;
- int forceSupp = 0;
-
- if (kickstart) {
- if (!ksGetCommand(KS_CMD_NFS, NULL, NULL, NULL)) {
- *method = methods + NFS_METHOD_NUM;
- return (*method)->prepareImage((*method), netc, intf, 0, dl);
- } else if (!ksGetCommand(KS_CMD_CDROM, NULL, NULL, NULL)) {
- *method = methods + CDROM_METHOD_NUM;
- return (*method)->prepareImage((*method), netc, intf, 0, dl);
- } else {
- logMessage("No kickstart method was specified.");
- kickstart = 0;
- }
- }
-
- do {
- rc = installMethodWindow(method, showSuppBox, &forceSupp);
- if (rc) return rc;
-
- if ((*method)->prepareImage) {
- rc = (*method)->prepareImage((*method), netc, intf, forceSupp, dl);
- if (rc == INST_ERROR) return rc;
- }
- } while (rc);
-
- return 0;
- }
-
- /* We could use newtWinEntries() here, if we didn't like those clever
- callbacks */
- static int nfsGetSetup(char ** hostptr, char ** dirptr) {
- newtComponent form, okay, cancel, answer, text;
- newtComponent siteLabel, dirLabel;
- newtGrid buttons, entryArea, grid;
- struct nfsMountCallbackInfo cbInfo;
- char * reflowedText;
- int width, height;
-
- if (*hostptr) {
- cbInfo.serverVal = *hostptr;
- cbInfo.netpathVal = *dirptr;
- } else {
- cbInfo.serverVal = "";
- cbInfo.netpathVal = "";
- }
-
- form = newtForm(NULL, NULL, 0);
- buttons = newtButtonBar(_("Ok"), &okay, _("Back"), &cancel, NULL);
-
- reflowedText = newtReflowText(
- _("Please enter the following information:\n"
- "\n"
- " o the name or IP number of your NFS server\n"
- " o the directory on that server containing\n"
- " Red Hat Linux for your architecture"),
- 60, 10, 10, &width, &height);
- text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text, reflowedText);
-
- free(reflowedText);
-
- entryArea = newtCreateGrid(2, 2);
- siteLabel = newtLabel(-1, -1, _("NFS server name:"));
- newtGridSetField(entryArea, 0, 0, NEWT_GRID_COMPONENT, siteLabel,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- dirLabel = newtLabel(-1, -1, _("Red Hat directory:"));
- newtGridSetField(entryArea, 0, 1, NEWT_GRID_COMPONENT, dirLabel,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
- cbInfo.server = newtEntry(-1, -1, cbInfo.serverVal, 24, &cbInfo.serverVal,
- NEWT_ENTRY_SCROLL);
- newtComponentAddCallback(cbInfo.server, nfsMountCallback, &cbInfo);
- cbInfo.netpath = newtEntry(-1, -1, cbInfo.netpathVal, 24,
- &cbInfo.netpathVal, NEWT_ENTRY_SCROLL);
- cbInfo.mntpoint = NULL;
-
- newtGridSetField(entryArea, 1, 0, NEWT_GRID_COMPONENT, cbInfo.server,
- 1, 0, 0, 0, 0, 0);
- newtGridSetField(entryArea, 1, 1, NEWT_GRID_COMPONENT, cbInfo.netpath,
- 1, 0, 0, 0, 0, 0);
-
- grid = newtCreateGrid(1, 3);
- newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
- 0, 0, 0, 0, 0, 0);
- newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, entryArea,
- 0, 1, 0, 1, 0, 0);
- newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
- 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
- newtGridWrappedWindow(grid, _("NFS Setup"));
-
- newtGridFree(grid, 1);
-
- newtFormAddComponents(form, text, cbInfo.server, cbInfo.netpath, okay,
- cancel, dirLabel, siteLabel, NULL);
-
- answer = newtRunForm(form);
- if (answer == cancel) {
- newtFormDestroy(form);
- newtPopWindow();
-
- return INST_CANCEL;
- }
-
- if (*hostptr) free(*hostptr);
- if (*dirptr) free(*dirptr);
- *hostptr = strdup(cbInfo.serverVal);
- *dirptr = strdup(cbInfo.netpathVal);
-
- newtFormDestroy(form);
- newtPopWindow();
-
- return 0;
- }
-
- static int cdromPrepare(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int useSupp,
- struct driversLoaded ** dl) {
- char * cddev;
- int rc;
-
- if (!kickstart)
- rc = newtWinChoice(_("Note"), _("Ok"), ("Back"),
- _("Insert your Red Hat CD into your CD drive now"));
-
- if (rc == 2) return INST_CANCEL;
-
- while (1) {
- /* this autoprobes already, so we don't need to do anything special
- for the kickstart :-) */
- rc = setupCDdevice(&cddev, dl);
- if (rc) return rc;
-
- if ((rc = loadFilesystem("isofs", "iso9660", dl))) return rc;
-
- rc = doMount(cddev, "/tmp/rhimage", "iso9660", 1, 0);
- if (rc) {
- removeCDmodule(dl);
- newtWinMessage(_("Error"), _("Ok"),
- _("I could not mount a CD on device /dev/%s"), cddev);
- return INST_CANCEL;
- }
-
- if (access("/tmp/rhimage/RedHat", R_OK)) {
- umount("/tmp/rhimage");
- removeCDmodule(dl);
- newtWinMessage(_("Error"), _("Ok"),
- _("That CDROM device does "
- "not seem to contain a Red Hat CDROM."));
- return INST_CANCEL;
- }
-
- rc = 0;
- while (useSupp) {
- rc = floppyRoot(NULL, NULL, NULL, 0, NULL);
-
- logMessage("got floppy root rc=%d", rc);
-
- if (rc == INST_CANCEL) {
- umount("/tmp/rhimage");
- break;
- } else if (!rc) {
- logMessage("breaking out of loop");
- break;
- }
- }
-
- if (!rc) break;
- }
-
- if (!useSupp) {
- if (!access("/tmp/rhimage/RedHat/instimage/lib", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/lib");
- symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
- }
-
- if (!access("/tmp/rhimage/RedHat/instimage/usr/bin", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/usr/bin");
- symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
- }
-
- if (!access("/tmp/rhimage/RedHat/instimage/usr/etc", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/usr/etc");
- symlink("/tmp/rhimage/RedHat/instimage/usr/etc", "/usr/etc");
- }
- }
-
- logMessage("done here");
-
- return 0;
- }
-
- static int nfsPrepare(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int useSupp,
- struct driversLoaded ** dl) {
- char * host = NULL, * dir = NULL;
- char * buf;
- enum { NFS_STEP_NET, NFS_STEP_INFO, NFS_STEP_MOUNT, NFS_STEP_DONE }
- step = NFS_STEP_NET;
- int rc;
- int ksArgc;
- char ** ksArgv;
- poptContext optCon;
- int direction = 1;
- struct poptOption ksNfsOptions[] = {
- { "server", '\0', POPT_ARG_STRING, &host, 0 },
- { "dir", '\0', POPT_ARG_STRING, &dir, 0 },
- { 0, 0, 0, 0, 0 }
- };
-
-
- if (kickstart) {
- /* FIXME: there must be a better test to use here */
- if (!intf->set || !netc->set)
- if (bringUpNetworking(intf, netc, dl, 1)) return INST_ERROR;
-
- ksGetCommand(KS_CMD_NFS, NULL, &ksArgc, &ksArgv);
-
- optCon = poptGetContext(NULL, ksArgc, ksArgv, ksNfsOptions, 0);
-
- if ((rc = poptGetNextOpt(optCon)) < -1) {
- newtWinMessage(_("nfs command"), _("Ok"),
- _("bad argument to kickstart nfs command %s: %s"),
- poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
- poptStrerror(rc));
- }
-
- if (!host || !dir) {
- newtWinMessage(_("nfs command"), _("Ok"),
- _("nfs command incomplete"));
- } else {
- step = NFS_STEP_MOUNT;
- }
- }
-
- while (step != NFS_STEP_DONE) {
- switch (step) {
- case NFS_STEP_NET:
- rc = bringUpNetworking(intf, netc, dl, direction);
- if (rc) return rc;
- direction = 1;
- step = NFS_STEP_INFO;
- break;
-
- case NFS_STEP_INFO:
- if (!host && (intf->set & INTFINFO_HAS_BOOTSERVER))
- host = mygethostbyaddr(inet_ntoa(intf->bootServer));
- if (!dir && (intf->set & INTFINFO_HAS_BOOTFILE))
- dir = strdup(intf->bootFile);
-
- rc = nfsGetSetup(&host, &dir);
- if (rc == INST_CANCEL) {
- step = NFS_STEP_NET;
- direction = -1;
- } else if (rc == INST_ERROR)
- return INST_ERROR;
- else
- step = NFS_STEP_MOUNT;
- break;
-
- case NFS_STEP_MOUNT:
- if (!strlen(host) || !strlen(dir))
- rc = INST_ERROR;
- else {
- buf = malloc(strlen(host) + strlen(dir) + 10);
- strcpy(buf, host);
- strcat(buf, ":");
- strcat(buf, dir);
-
- if ((rc = loadFilesystem("nfs", "nfs", dl))) return rc;
-
- rc = doMount(buf, "/tmp/rhimage", "nfs", 1, 0);
- free(buf);
- }
-
- if (rc) {
- step = NFS_STEP_INFO;
- newtWinMessage(_("Error"), _("Ok"),
- _("I could not mount that directory from the server"));
- } else {
- if (access("/tmp/rhimage/RedHat", R_OK)) {
- step = NFS_STEP_INFO;
- newtWinMessage(_("Error"), _("Ok"),
- _("That directory does not seem to contain "
- "a Red Hat installation tree."));
- umount("/tmp/rhimage");
- } else
- step = NFS_STEP_DONE;
- }
-
- rc = 0;
- while (useSupp) {
- rc = floppyRoot(NULL, NULL, NULL, 0, NULL);
-
- if (rc == INST_CANCEL) {
- umount("/tmp/rhimage");
- break;
- } else if (!rc) {
- break;
- }
- }
-
- if (rc) {
- umount("/tmp/rhimage");
- step = NFS_STEP_INFO;
- }
-
- break;
-
- case NFS_STEP_DONE:
- break;
- }
- }
-
- if (!kickstart) {
- free(host);
- free(dir);
- }
-
- if (!useSupp) {
- if (!access("/tmp/rhimage/RedHat/instimage/lib", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/lib");
- symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
- }
-
- if (!access("/tmp/rhimage/RedHat/instimage/usr/bin", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/usr/bin");
- symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
- }
-
- if (!access("/tmp/rhimage/RedHat/instimage/usr/etc", X_OK)) {
- unlink("/tmp/rhimage/RedHat/instimage/usr/etc");
- symlink("/tmp/rhimage/RedHat/instimage/usr/etc", "/usr/etc");
- }
- }
-
- return 0;
- }
-
- int floppyRoot(struct installMethod * method, struct netInfo * netc,
- struct intfInfo * intf, int forceSuppDisk,
- struct driversLoaded ** dl) {
- int rc;
-
- if (!access("/usr/bin/runinstall2", R_OK)) {
- isMounted = 1;
- return 0;
- }
-
- do {
- rc = newtWinChoice(_("Supplemental Disk"), _("Ok"), _("Back"),
- _("This install method requires a second disk. Please remove "
- "the boot disk currently in your drive and replace it with "
- "the Red Hat Supplementary Install disk."));
- if (rc == 2) return INST_CANCEL;
-
- rc = loadFloppyRoot(method);
- } while (rc);
-
- return 0;
- }
-
- int loadFloppyRoot(struct installMethod * method) {
- int rc;
-
- if (isMounted) return 0;
-
- if (testing) return 0;
-
- while (doMount("fd0", "/tmp/image", "ext2", 1, 0) ||
- access("/tmp/image/usr/bin/runinstall2", R_OK)) {
- /* in case the mount succeeded */
- umount("/tmp/image");
-
- rc = newtWinChoice(_("Supplemental Disk"), _("Ok"), _("Cancel"),
- _("I failed to mount the floppy. Please insert the "
- "Red Hat Supplementary Install disk, or choose "
- "Cancel to pick a different installation process."));
- if (rc == 2) return INST_CANCEL;
- }
-
- if (totalMemory() > 8000) {
- umount("/tmp/image");
- loadRamdisk("ram2", "fd0", 1440, _("Loading supplemental disk..."));
- if (doMount("ram2", "/tmp/image", "ext2", 1, 0)) {
- errorWindow("Error mounting ramdisk. This shouldn't "
- "happen, and I'm rebooting your system now.");
- exit(1);
- }
- }
-
- symlink("/tmp/image/lib", "/lib");
- symlink("/tmp/image/etc", "/etc");
- symlink("/tmp/image/usr/bin", "/usr/bin");
- symlink("/tmp/image/usr/etc", "/usr/etc");
-
- isMounted = 1;
-
- return 0;
- }
-
-