#include #include #include #include #include #include #include #include #include #include #include #include "hd.h" #include "fs.h" #include "urlmethod.h" #include "install.h" #include "intl.h" #include "log.h" #include "methods.h" #include "net.h" #include "scsi.h" #include "windows.h" #include "smb.h" struct tapeCatalogEntry { char * filename; int size; }; struct tapeinfo { int fd; int offset; int curr; int catalogEntries; struct tapeCatalogEntry * catalog; }; /* This was split into two pieces to keep the initial install program small */ static int urlinstGetMappedFile(struct installMethod * method, char * name, char ** realName); static int imageGetFile(struct installMethod * method, char * name, char ** realName); static int singleimageSetSymlinks(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl); static int hdSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl); static int hdPrepareMedia(struct installMethod * method, struct fstab * fstab); static int hdGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int hdGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static int urlSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl); static int urlGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int urlGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static int imageGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int imageGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static inline int fileInBase(char * name); #if 0 /* disabled for now */ #ifdef __i386__ static int smbSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl); static int smbGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int smbGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); #endif #endif /* disabled */ static struct installMethod methods[] = { { "Local CDROM", "cdrom", 0, LOCAL, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL, NULL }, { "NFS image", "nfs", 0, NETWORK, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL, NULL }, { "hard drive", "hd", 0, LOCAL, NULL, hdSetup, imageGetFile, hdGetPackageSet, hdGetComponentSet, hdPrepareMedia, NULL }, { "FTP", "ftp", 1, NETWORK, NULL, urlSetup, urlinstGetMappedFile, urlGetPackageSet, urlGetComponentSet, NULL, NULL }, { "HTTP", "http", 1, NETWORK, NULL, urlSetup, urlinstGetMappedFile, urlGetPackageSet, urlGetComponentSet, NULL, NULL }, #if 0 /* disabled for now */ #ifdef __i386__ { "SMB image", "smb", 0, NETWORK, NULL, smbSetup, imageGetFile, smbGetPackageSet, smbGetComponentSet, NULL, NULL }, #endif #endif } ; static int numMethods = sizeof(methods) / sizeof(struct installMethod); 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 inline int fileInBase(char * name) { if (!strcmp(name, "hdlist") || !strcmp(name, "rpmconvert")) return 1; if (!strncmp(name, "install", 7) && !strcmp(name + 8, ".tr")) return 1; return 0; } static int imageGetFile(struct installMethod * method, char * name, char ** realName) { static char buf[300]; if (fileInBase(name)) strcpy(buf, "/tmp/rhimage/RedHat/base/"); else strcpy(buf, "/tmp/rhimage/RedHat/RPMS/"); strcat(buf, name); *realName = buf; return 0; } static void getConfig(char *first, char **firstData, ...) { char *env, **data, *ptr; va_list ap; ptr = getenv(first); *firstData = ptr ? strdup(ptr) : ptr; va_start(ap, firstData); while ((env = va_arg(ap, char *))) { data = va_arg(ap, char **); ptr = getenv(env); *data = ptr ? strdup(getenv(env)) : ptr; } } static int hdSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl) { struct hdinfo * hdi; hdi = malloc(sizeof(*hdi)); getConfig("DEVICE", &hdi->device, "TYPE", &hdi->type, "DIR", &hdi->dir, NULL); method->data = hdi; return INST_OKAY; } static int hdGetPackageSet(struct installMethod * method, struct pkgSet * ps) { struct hdinfo * hdi = method->data; int rc; umount("/tmp/hdimage"); if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0)) return INST_ERROR; rc = psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps); umount("/tmp/hdimage"); return rc; } static int hdGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { struct hdinfo * hdi = method->data; int rc; if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0)) return INST_ERROR; rc = psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs); umount("/tmp/hdimage"); return rc; } static int hdPrepareMedia(struct installMethod * method, struct fstab * fstab) { struct hdinfo * hdi = method->data; int i; char * buf; for (i = 0; i < fstab->numEntries; i++) { logMessage("looking: %s ?= %s", fstab->entries[i].device, hdi->device); if (fstab->entries[i].isMounted && !strcmp(fstab->entries[i].device, hdi->device)) break; } if (i < fstab->numEntries) { logMessage("device %s is already mounted -- using symlink", fstab->entries[i].device); buf = alloca(strlen(fstab->entries[i].mntpoint) + 10); sprintf(buf, "/mnt/%s", fstab->entries[i].mntpoint); rmdir("/tmp/hdimage"); if (symlink(buf, "/tmp/hdimage")) { logMessage("failed to create symlink %s: %s\n", buf, strerror(errno)); newtWinMessage(_("Error"), _("Ok"), _("Failed to create symlink for package source.")); return INST_ERROR; } } else { logMessage("mounting device which contains packages"); umount("/tmp/hdimage"); if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0)) return INST_ERROR; } return 0; } static int imageGetPackageSet(struct installMethod * method, struct pkgSet * ps) { return psFromHeaderListFile("/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 netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl) { logMessage("making symlink from /tmp/rhimage to image"); unlink("/tmp/image"); symlink("rhimage", "/tmp/image"); return 0; } static int urlSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl) { struct iurlinfo ui; enum { URL_SETUP_NET, URL_SETUP_HOST1, URL_SETUP_HOST2, URL_SETUP_CHECK, URL_SETUP_DONE } step = URL_SETUP_NET; int rc; FD_t fd; char doMore; char buf[256]; urlprotocol protocol=URL_METHOD_FTP; if (!strncmp(method->abbrev, "ftp", 3)) protocol = URL_METHOD_FTP; if (!strncmp(method->abbrev, "http", 4)) protocol = URL_METHOD_HTTP; memset(&ui, 0, sizeof(ui)); if (method->data) memcpy(&ui, method->data, sizeof(ui)); else memset(&ui, 0, sizeof(ui)); while (step != URL_SETUP_DONE) { switch (step) { case URL_SETUP_NET: getConfig("URLPREFIX", &ui.urlprefix, "HOST", &ui.address, "PREFIX", &ui.prefix, "LOGIN", &ui.login, "PASSWORD", &ui.password, "PROXY", &ui.proxy, "PROXYPORT", &ui.proxyPort, NULL); if (protocol == URL_METHOD_FTP) { if (ui.proxy) addMacro(NULL, "_ftpproxy", NULL, ui.proxy, RMIL_RPMRC); if (ui.proxyPort) addMacro(NULL, "_ftpproxyport", NULL, ui.proxyPort, RMIL_RPMRC); } else { if (ui.proxy) addMacro(NULL, "_ftpproxy", NULL, ui.proxy, RMIL_RPMRC); if (ui.proxyPort) addMacro(NULL, "_ftpproxyport", NULL, ui.proxyPort, RMIL_RPMRC); } if (ui.urlprefix != NULL) step = URL_SETUP_CHECK; else step = URL_SETUP_HOST1; break; case URL_SETUP_HOST1: rc = urlMainSetupPanel(&ui, protocol, &doMore); if (rc == INST_ERROR) return rc; else if (rc) step = URL_SETUP_NET; else if (doMore == ' ') step = URL_SETUP_CHECK; else step = URL_SETUP_HOST2; break; case URL_SETUP_HOST2: rc = urlSecondarySetupPanel(&ui, protocol); if (rc == INST_ERROR) return rc; else if (rc) step = URL_SETUP_HOST1; else step = URL_SETUP_CHECK; break; case URL_SETUP_CHECK: fd = urlinstStartTransfer(&ui, "base/hdlist"); if (fd == NULL || fdFileno(fd) < 0) { snprintf(buf, sizeof(buf), "%s/RedHat/base/hdlist", ui.urlprefix); newtPopWindow(); newtWinMessage(_("Error"), _("Ok"), "Error transferring %s:\n%s", buf, urlStrerror(buf)); step = URL_SETUP_HOST1; ufdClose(fd); break; } if (psFromHeaderListDesc(fd, &ui.ps, 1)) { step = URL_SETUP_HOST1; ufdClose(fd); break; } urlinstFinishTransfer(fd); if (urlinstGetFile(&ui, "base/comps", "/tmp/comps")) { step = URL_SETUP_HOST1; break; } step = URL_SETUP_DONE; break; case URL_SETUP_DONE: break; } } if (method->data) free(method->data); method->data = malloc(sizeof(ui)); memcpy(method->data, &ui, sizeof(ui)); return 0; } static int urlGetPackageSet(struct installMethod * method, struct pkgSet * ps) { struct iurlinfo * ui = method->data; *ps = ui->ps; return 0; } static int urlGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { return psReadComponentsFile("/tmp/comps", ps, cs); } extern int isPackage; static int urlinstGetMappedFile(struct installMethod * method, char * name, char ** realName) { static char sbuf[300]; char * buf; int rc; struct iurlinfo * ui = method->data; if (access("/mnt/var/tmp", X_OK)) strcpy(sbuf, "/tmp/"); else strcpy(sbuf, "/mnt/var/tmp/"); strcat(sbuf, name); *realName = sbuf; buf = alloca(strlen(name) + 30); if (fileInBase(name)) strcpy(buf, "base/"); else strcpy(buf, "RPMS/"); strcat(buf, name); rc = urlinstGetFile(ui, buf, *realName); if (!rc) return 0; while (rc) { rc = newtWinChoice(_("ftp"), _("Yes"), _("No"), _("I'm having trouble getting %s. Would you " "like to retry?"), name); if (rc == 2) return INST_ERROR; rc = urlinstGetFile(ui, buf, *realName); } return 0; } #if 0 /* disabled for now */ #ifdef __i386__ static int smbSetup(struct installMethod * method, struct partitionTable table, struct netInfo * netc, struct intfInfo * intf, struct driversLoaded ** dl) { char * host = NULL, * dir = NULL, * acct = NULL, * pass = NULL; char * buf; static int moduleLoaded = 0; enum { SMB_STEP_NET, SMB_STEP_INFO, SMB_STEP_MOUNT, SMB_STEP_DONE } step = SMB_STEP_NET; int rc; while (step != SMB_STEP_DONE) { switch (step) { case SMB_STEP_NET: getConfig("HOST", &host, "DIR", &dir, "ACCT", &acct, "PASS", &pass, NULL); step = SMB_STEP_MOUNT; break; case SMB_STEP_INFO: rc = smbGetSetup(&host, &dir, &acct, &pass); if (rc == INST_CANCEL) step = SMB_STEP_NET; else if (rc == INST_ERROR) return INST_ERROR; else step = SMB_STEP_MOUNT; break; case SMB_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 (!moduleLoaded) { rc = loadModule("smbfs", DRIVER_FS, DRIVER_MINOR_NONE, dl); if (rc) return rc; moduleLoaded = 1; } rc = doPwMount(buf, "/tmp/rhimage", "smb", 1, 0, acct, pass); free(buf); } if (rc) { step = SMB_STEP_INFO; newtWinMessage("Error", "Ok", "I could not mount that directory from the server"); } else { if (access("/tmp/rhimage/RedHat", R_OK)) { step = SMB_STEP_INFO; newtWinMessage(_("Error"), _("Ok"), _("That directory does not seem " "to contain a Red Hat installation tree.")); umount("/tmp/rhimage"); } else step = SMB_STEP_DONE; } break; case SMB_STEP_DONE: break; } } free(host); free(dir); return 0; } static int smbGetPackageSet(struct installMethod * method, struct pkgSet * ps) { return psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps); } static int smbGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs); } #endif #endif /* disabled */