#include #include #include #include #include #include #include #include #include "hd.h" #include "fs.h" #include "ftp.h" #include "install.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 ftpinstGetMappedFile(struct installMethod * method, char * name, char ** realName, int isPreskel); static int imageGetFile(struct installMethod * method, char * name, char ** realName, int isPreskel); static int singleimageSetSymlinks(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int hdMount(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int ftpSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int fileGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int fileGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static int scanGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int imageGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int imageGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static struct installMethod methods[] = { { "Local CDROM", "cdrom", 0, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL }, { "NFS image", "nfs", 0, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL }, { "hard drive", "hd", 0, NULL, hdMount, imageGetFile, scanGetPackageSet, imageGetComponentSet, NULL }, { "FTP", "ftp", 1, NULL, ftpSetup, ftpinstGetMappedFile, fileGetPackageSet, fileGetComponentSet, NULL }, } ; static int numMethods = sizeof(methods) / sizeof(struct installMethod); struct ftpinfo { char * address; char * login; char * password; char * prefix; int sock; }; struct installMethod * findInstallMethod(char * argptr) { int i; for (i = 0; i < numMethods; i++) if (!strcmp(argptr, methods[i].abbrev)) return (methods + i); return NULL; } static int imageGetFile(struct installMethod * method, char * name, char ** realName, int isPreskel) { static char buf[300]; if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") || !strcmp(name, "rpmconvert")) strcpy(buf, "/tmp/rhimage/RedHat/base/"); else strcpy(buf, "/tmp/rhimage/RedHat/RPMS/"); strcat(buf, name); *realName = buf; return 0; } static int hdMount(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { newtComponent okay, cancel, form, text, listbox, label, answer; int i; char buf[80]; struct partition * part = NULL; char * type; newtOpenWindow(10, 2, 64, 19, "Select Partition"); text = newtTextbox(1, 1, 62, 4, NEWT_TEXTBOX_WRAP); newtTextboxSetText(text, "What partition holds the RedHat/RPMS and " "RedHat/base directories?"); okay = newtButton(15, 15, "Ok"); cancel = newtButton(38, 15, "Cancel"); form = newtForm(NULL, NULL, 0); listbox = newtListbox(7, 7, 7, NEWT_LISTBOX_RETURNEXIT); label = newtLabel(5, 6, " Device Begin End Size (k)"); for (i = 0; i < table.count; i++) { if (table.parts[i].type == PART_EXT2 || table.parts[i].type == PART_DOS) { sprintf(buf, "/dev/%-5s %9d %9d %9d", table.parts[i].device, table.parts[i].begin, table.parts[i].end, table.parts[i].size); newtListboxAddEntry(listbox, buf, &table.parts[i]); } } newtFormAddComponents(form, text, label, listbox, okay, cancel, NULL); answer = newtRunForm(form); if (answer != cancel) { part = newtListboxGetCurrent(listbox); } newtFormDestroy(form); newtPopWindow(); if (answer == cancel) return INST_CANCEL; switch (part->type) { case PART_EXT2: type = "ext2"; break; case PART_DOS: type = "msdos"; break; default: return INST_ERROR; } if (doMount(part->device, "/tmp/rhimage", type, 1)) return INST_ERROR; return 0; } static int scanGetPackageSet(struct installMethod * method, struct pkgSet * ps) { return psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps); } static int imageGetPackageSet(struct installMethod * method, struct pkgSet * ps) { return psFromHeaderList("/tmp/rhimage/RedHat/base/hdlist", ps); } static int imageGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs); } static int singleimageSetSymlinks(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { logMessage("making symlink from /tmp/rhimage to image"); symlink("rhimage", "/tmp/image"); return 0; } static int ftpinstGetFile(struct ftpinfo * fi, char * filename, char * dest) { char * buf; newtComponent form; int fd, rc; logMessage("ftping %s as %s", filename, dest); newtOpenWindow(10, 10, 60, 3, "Installing"); buf = alloca(strlen(fi->prefix) + strlen(filename) + 30); sprintf(buf, "Retrieving %s...", filename); form = newtForm(NULL, NULL, 0); newtFormAddComponent(form, newtLabel(1, 1, buf)); newtDrawForm(form); newtRefresh(); fd = open(dest, O_WRONLY | O_CREAT, 0644); if (fd < 0) { messageWindow("Error", "open of %s failed: %s\n", dest, strerror(errno)); return INST_ERROR; } strcpy(buf, fi->prefix); strcat(buf, "/RedHat/"); strcat(buf, filename); rc = ftpGetFile(fi->sock, buf, fd); close(fd); newtFormDestroy(form); newtPopWindow(); if (rc) { messageWindow("ftp", "I cannot get file %s: %s\n", buf, ftpStrerror(rc)); return INST_ERROR; } return 0; } static int ftpSetupPanel(struct ftpinfo * fi) { newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text; char * site, * dir; if (fi->address) { site = fi->address; dir = fi->prefix; } else { site = ""; dir = ""; } newtOpenWindow(15, 4, 50, 14, "FTP Setup"); form = newtForm(NULL, NULL, 0); okay = newtButton(10, 10, "Ok"); cancel = newtButton(30, 10, "Cancel"); text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP); newtTextboxSetText(text, "Please enter the following information:\n" "\n" " o the name or IP number of your FTP server\n" " o the directory on that server containing\n" " Red Hat Linux for your architecture"); newtFormAddComponent(form, newtLabel(3, 7, "FTP site name :")); newtFormAddComponent(form, newtLabel(3, 8, "Red Hat directory:")); siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL); dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL); newtFormAddComponents(form, text, siteEntry, dirEntry, okay, cancel, NULL); answer = newtRunForm(form); if (answer == cancel) { newtFormDestroy(form); newtPopWindow(); return INST_CANCEL; } fi->login = "ftp"; fi->password = "rhinstall@unnamed.machine"; fi->address = strdup(site); fi->prefix = strdup(dir); newtFormDestroy(form); newtPopWindow(); return 0; } static int ftpSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { struct ftpinfo fi; enum { FTP_SETUP_NET, FTP_SETUP_FTP, FTP_SETUP_CHECK, FTP_SETUP_DONE } step = FTP_SETUP_NET; int rc; if (method->data) memcpy(&fi, method->data, sizeof(fi)); else memset(&fi, 0, sizeof(fi)); while (step != FTP_SETUP_DONE) { switch (step) { case FTP_SETUP_NET: rc = bringUpNetworking(intf, netc, dl); if (rc) return rc; step = FTP_SETUP_FTP; break; case FTP_SETUP_FTP: rc = ftpSetupPanel(&fi); if (rc == INST_ERROR) return rc; else if (rc) step = FTP_SETUP_NET; else step = FTP_SETUP_CHECK; break; case FTP_SETUP_CHECK: if ((fi.sock = ftpOpen(fi.address, fi.login, fi.password, NULL)) < 0) { messageWindow("ftp", "I cannot log into machine: %s\n", ftpStrerror(fi.sock)); step = FTP_SETUP_FTP; break; } if (ftpinstGetFile(&fi, "base/hdlist", "/tmp/hdlist")) { ftpClose(fi.sock); step = FTP_SETUP_FTP; break; } if (ftpinstGetFile(&fi, "base/comps", "/tmp/comps")) { ftpClose(fi.sock); step = FTP_SETUP_FTP; break; } step = FTP_SETUP_DONE; break; case FTP_SETUP_DONE: break; } } if (method->data) free(method->data); method->data = malloc(sizeof(fi)); memcpy(method->data, &fi, sizeof(fi)); return 0; } static int fileGetPackageSet(struct installMethod * method, struct pkgSet * ps) { return psFromHeaderList("/tmp/hdlist", ps); } static int fileGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { return psReadComponentsFile("/tmp/comps", ps, cs); } static int ftpinstGetMappedFile(struct installMethod * method, char * name, char ** realName, int isPreskel) { static char sbuf[300]; char * buf; int rc; struct ftpinfo * fi = method->data; if (isPreskel) strcpy(sbuf, "/mnt/"); else strcpy(sbuf, "/mnt/var/tmp/"); strcat(sbuf, name); *realName = sbuf; buf = alloca(strlen(name) + 30); if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") || !strcmp(name, "rpmconvert")) strcpy(buf, "base/"); else strcpy(buf, "RPMS/"); strcat(buf, name); rc = ftpinstGetFile(fi, buf, *realName); if (!rc) return 0; /* Try again, and relogin */ ftpClose(fi->sock); if ((fi->sock = ftpOpen(fi->address, fi->login, fi->password, NULL)) < 0) { messageWindow("ftp", "I cannot log into machine: %s\n", ftpStrerror(fi->sock)); free(fi); return INST_ERROR; } return ftpinstGetFile(fi, buf, *realName); }