#include #include #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 "scsi.h" #include "windows.h" struct ftpinfo { char * address; char * login; char * password; char * prefix; char * proxy; int sock; struct pkgSet ps; }; struct hdinfo { char * device; char * type; char * dir; }; 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 ftpinstStartTransfer(struct ftpinfo * fi, char * filename); static int ftpinstFinishTransfer(struct ftpinfo * fi); 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 hdSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * 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 ftpSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int ftpGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int ftpGetComponentSet(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 int tapeSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int tapeGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int tapeGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); static int tapeGetMappedFile(struct installMethod * method, char * name, char ** realName, int isPreskel); #ifdef __i386__ static int smbSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl); static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr, char ** pwptr); static int smbGetPackageSet(struct installMethod * method, struct pkgSet * ps); static int smbGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs); #endif static struct installMethod methods[] = { { "Local CDROM", "cdrom", 0, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL, NULL }, { "NFS image", "nfs", 0, NULL, singleimageSetSymlinks, imageGetFile, imageGetPackageSet, imageGetComponentSet, NULL, NULL }, { "hard drive", "hd", 0, NULL, hdSetup, imageGetFile, hdGetPackageSet, hdGetComponentSet, hdPrepareMedia, NULL }, { "FTP", "ftp", 1, NULL, ftpSetup, ftpinstGetMappedFile, ftpGetPackageSet, ftpGetComponentSet, NULL, NULL }, #ifdef __i386__ { "SMB image", "smb", 0, NULL, smbSetup, imageGetFile, smbGetPackageSet, smbGetComponentSet, NULL, NULL }, #endif { "SCSI Tape", "tape", 1, NULL, tapeSetup, tapeGetMappedFile, tapeGetPackageSet, tapeGetComponentSet, NULL }, } ; 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 int imageGetFile(struct installMethod * method, char * name, char ** realName, int isPreskel) { static char buf[300]; if (!strcmp(name, "hdlist") || !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 hdSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { newtComponent okay, cancel, form, text, listbox, label, answer, dirEntry; int i, j; char buf[80]; struct partition * part = NULL; char * type; char * dir; char * dest; char * defaultDevice; char * defaultDir; int done = 0; struct hdinfo * hdi; if (method->data) { hdi = method->data; defaultDir = strdup(hdi->dir); defaultDevice = hdi->device; } else { defaultDir = strdup("/"); defaultDevice = ""; } while (!done) { newtCenteredWindow(64, 17, "Select Partition"); text = newtTextbox(1, 1, 62, 4, NEWT_TEXTBOX_WRAP); newtTextboxSetText(text, "What partition and directory on that " "partition hold the RedHat/RPMS and " "RedHat/base directories?"); okay = newtButton(15, 13, "Ok"); cancel = newtButton(38, 13, "Cancel"); form = newtForm(NULL, NULL, 0); listbox = newtListbox(7, 5, 5, NEWT_LISTBOX_RETURNEXIT); label = newtLabel(5, 4, " Device Begin End Size (k)"); for (i = 0, j = 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]); if (!strcmp(table.parts[i].device, defaultDevice)) { newtListboxSetCurrent(listbox, j); } j++; } } newtFormAddComponent(form, newtLabel(1, 11, "Directory holding Red Hat:")); dirEntry = newtEntry(28, 11, defaultDir, 28, &dir, NEWT_ENTRY_SCROLL); newtFormAddComponents(form, text, label, listbox, dirEntry, okay, cancel, NULL); answer = newtRunForm(form); if (answer != cancel) { part = newtListboxGetCurrent(listbox); } dir = strdup(dir); free(defaultDir); defaultDir = dir; defaultDevice = part->device; 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: continue; } if (doMount(part->device, "/tmp/hdimage", type, 1, 0)) continue; unlink("/tmp/rhimage"); /* the physical device is mounted on /tmp/hdimage, but all access are through /tmp/rhimage which points to the RedHat directory in /tmp/hdimage */ dest = alloca(strlen(dir) + 20); sprintf(dest, "/tmp/hdimage/%s", dir); if (symlink(dest, "/tmp/rhimage")) { newtWinMessage("Error", "Ok", "Failed to create /tmp/rhimage " "symlink: %s", strerror(errno)); umount("/tmp/hdimage"); continue; } if (access("/tmp/rhimage/RedHat/base/hdlist", R_OK)) { newtWinMessage("Error", "Ok", "Device %s does not appear to contain " "a Red Hat installation tree.", part->device); umount("/tmp/hdimage"); continue; } if (method->data) { hdi = method->data; free(hdi->dir); } hdi = malloc(sizeof(*hdi)); hdi->device = part->device; hdi->type = type; hdi->dir = strdup(dir); method->data = hdi; done = 1; umount("/tmp/hdimage"); } return 0; } static int hdGetPackageSet(struct installMethod * method, struct pkgSet * ps) { struct hdinfo * hdi = method->data; int rc; 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++) { 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"); 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 netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { logMessage("making symlink from /tmp/rhimage to image"); symlink("rhimage", "/tmp/image"); return 0; } /* returns a socket file descriptor, a ftpFinishTransfer() must occur after this call */ static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename) { char * buf; newtComponent form; int fd; logMessage("ftping %s to a fd", filename); newtCenteredWindow(60, 3, "Retrieving"); 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(); strcpy(buf, fi->prefix); strcat(buf, "/RedHat/"); strcat(buf, filename); fd = ftpGetFileDesc(fi->sock, buf); return fd; } static int ftpinstFinishTransfer(struct ftpinfo * fi) { newtPopWindow(); return ftpGetFileDone(fi->sock); } static int ftpinstGetFile(struct ftpinfo * fi, char * filename, char * dest) { char * buf; newtComponent form; int fd, rc; logMessage("ftping %s as %s", filename, dest); newtCenteredWindow(60, 3, "Retrieving"); 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) { newtWinMessage("Error", "Ok", "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) { newtWinMessage("ftp", "Ok", "I cannot get file %s: %s\n", buf, ftpStrerror(rc)); return INST_ERROR; } return 0; } static int ftpMainSetupPanel(struct ftpinfo * fi, char * doSecondarySetup) { newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text, cb; char * site, * dir; if (fi->address) { site = fi->address; dir = fi->prefix; } else { site = ""; dir = ""; } if (fi->login || fi->password || fi->login) *doSecondarySetup = 'X'; else *doSecondarySetup = ' '; newtCenteredWindow(50, 17, "FTP Setup"); form = newtForm(NULL, NULL, 0); okay = newtButton(10, 13, "Ok"); cancel = newtButton(30, 13, "Cancel"); text = newtTextbox(1, 1, 47, 8, 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 architecure\n"); newtFormAddComponent(form, newtLabel(3, 8, "FTP site name :")); newtFormAddComponent(form, newtLabel(3, 9, "Red Hat directory:")); siteEntry = newtEntry(22, 8, site, 24, &site, NEWT_ENTRY_SCROLL); dirEntry = newtEntry(22, 9, dir, 24, &dir, NEWT_ENTRY_SCROLL); cb = newtCheckbox(3, 11, "Use non-anonymous ftp or a proxy server", *doSecondarySetup, NULL, doSecondarySetup); newtFormAddComponents(form, text, siteEntry, dirEntry, cb, okay, cancel, NULL); answer = newtRunForm(form); if (answer == cancel) { newtFormDestroy(form); newtPopWindow(); return INST_CANCEL; } if (fi->address) free(fi->address); fi->address = strdup(site); if (fi->prefix) free(fi->prefix); fi->prefix = strdup(dir); newtFormDestroy(form); newtPopWindow(); return 0; } static int ftpSecondarySetupPanel(struct ftpinfo * fi) { newtComponent form, okay, cancel, answer, text, accountEntry; newtComponent passwordEntry, proxyEntry; char * account, * password, * proxy; newtCenteredWindow(50, 15, "Further FTP Setup"); form = newtForm(NULL, NULL, 0); okay = newtButton(10, 11, "Ok"); cancel = newtButton(30, 11, "Cancel"); text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP); newtTextboxSetText(text, "If you are using non anonymous ftp, enter the account " "name and password you wish to use below. If you are " "using an FTP proxy enter the name of the FTP proxy server " "to use."); newtFormAddComponent(form, newtLabel(3, 6, "Account name :")); newtFormAddComponent(form, newtLabel(3, 7, "Password :")); newtFormAddComponent(form, newtLabel(3, 9, "FTP Proxy :")); accountEntry = newtEntry(18, 6, fi->login, 24, &account, NEWT_ENTRY_SCROLL); passwordEntry = newtEntry(18, 7, NULL, 24, &password, NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN); proxyEntry = newtEntry(18, 9, fi->proxy, 24, &proxy, NEWT_ENTRY_SCROLL); newtFormAddComponents(form, text, accountEntry, passwordEntry, proxyEntry, okay, cancel, NULL); answer = newtRunForm(form); if (answer == cancel) { newtFormDestroy(form); newtPopWindow(); return INST_CANCEL; } if (fi->login) free(fi->login); if (strlen(account)) fi->login = strdup(account); else fi->login = NULL; if (fi->password) free(fi->password); if (strlen(password)) fi->password = strdup(password); else fi->password = NULL; if (fi->proxy) free(fi->proxy); if (strlen(proxy)) fi->proxy = strdup(proxy); else fi->proxy = NULL; 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_FTP1, FTP_SETUP_FTP2, FTP_SETUP_CHECK, FTP_SETUP_DONE } step = FTP_SETUP_NET; int rc, fd; char doMore; memset(&fi, 0, sizeof(fi)); 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_FTP1; break; case FTP_SETUP_FTP1: rc = ftpMainSetupPanel(&fi, &doMore); if (rc == INST_ERROR) return rc; else if (rc) step = FTP_SETUP_NET; else if (doMore == ' ') step = FTP_SETUP_CHECK; else step = FTP_SETUP_FTP2; break; case FTP_SETUP_FTP2: rc = ftpSecondarySetupPanel(&fi); if (rc == INST_ERROR) return rc; else if (rc) step = FTP_SETUP_FTP1; else step = FTP_SETUP_CHECK; break; case FTP_SETUP_CHECK: if ((fi.sock = ftpOpen(fi.address, fi.login, fi.password ? fi.password : "rhinstall@", fi.proxy, -1)) < 0) { newtWinMessage("ftp", "Ok", "I cannot log into machine: %s\n", ftpStrerror(fi.sock)); step = FTP_SETUP_FTP1; break; } fd = ftpinstStartTransfer(&fi, "base/hdlist"); if (fd < 0) { newtPopWindow(); ftpClose(fi.sock); step = FTP_SETUP_FTP1; break; } if (psFromHeaderListDesc(fd, &fi.ps, 1)) { ftpClose(fi.sock); step = FTP_SETUP_FTP1; break; } ftpinstFinishTransfer(&fi); if (ftpinstGetFile(&fi, "base/comps", "/tmp/comps")) { ftpClose(fi.sock); step = FTP_SETUP_FTP1; 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 ftpGetPackageSet(struct installMethod * method, struct pkgSet * ps) { struct ftpinfo * fi = method->data; *ps = fi->ps; return 0; } static int ftpGetComponentSet(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, "hdlist") || !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 ? fi->password : "rhinstall@", fi->proxy, -1)) < 0) { newtWinMessage("ftp", "Ok", "I cannot log into machine: %s\n", ftpStrerror(fi->sock)); free(fi); return INST_ERROR; } return ftpinstGetFile(fi, buf, *realName); } int tapeOp(int fd, int cmd, int count, int reportErr) { struct mtop mtcmd; mtcmd.mt_op = cmd; mtcmd.mt_count = count; if (ioctl(fd, MTIOCTOP, &mtcmd)) { if (reportErr) newtWinMessage("Tape Error", "Ok", "tape ioctl %d failed: %s", cmd, strerror(errno)); return 1; } return 0; } static int tapeSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * intf, struct driversLoaded ** dl) { int rc; int fd; int catalogAlloced; struct tapeinfo * info; char magic[5]; int foundit = 0; char catalogBuf[16384]; char * chptr, * start, * next; int offset = 0; /* eventually we should support devices other then /dev/nst0 */ if ((rc = setupSCSIInterfaces(1, dl))) return rc; if ((rc = devMakeInode("nst0", "/tmp/nst0"))) return rc; if ((fd = open("/tmp/nst0", O_RDONLY)) < 0) { devRemoveInode("/tmp/nst0"); if (errno == ENODEV) { newtWinMessage("Error", "Ok", "I couldn't find any SCSI tape drives."); } else { errorWindow("Error opening device nst0: %s"); } return INST_ERROR; } winStatus(45, 3, "Tape", "Looking for Red Hat tape image..."); /* now, let's see if we can find the file on the tape */ if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) { if (!strcmp(magic, "1234\n")) { logMessage("found magic on first try"); foundit = 1; } } else if (rc < 0) { newtWinMessage("Error", "Ok", "Error reading from tape: %s", strerror(errno)); } if (!foundit) { logMessage("seeking to next file"); if (tapeOp(fd, MTFSF, 1, 0)) { logMessage("failed to find beginning of next file: %s", strerror(errno)); } else { if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) { if (!strcmp(magic, "1234\n")) { logMessage("found magic on second try"); foundit = 1; offset = 1; } } } } if (!foundit) { errorWindow("I can't find the Red Hat tape installation image" "on that tape."); close(fd); newtPopWindow(); return INST_ERROR; } if ((rc = read(fd, catalogBuf, sizeof(catalogBuf) - 1)) < 0) { errorWindow("Error reading file catalog from tape: %s"); newtPopWindow(); close(fd); return INST_ERROR; } newtPopWindow(); info = malloc(sizeof(*info)); info->fd = fd; info->offset = offset; info->curr = -1; method->data = info; /* read in the catalog */ catalogAlloced = 20; info->catalog = malloc(sizeof(*info->catalog) * catalogAlloced); info->catalogEntries = 0; start = catalogBuf; while (strncmp(start, "--done--", 8)) { chptr = strchr(start, '\n'); next = chptr + 1; *chptr = '\0'; while (*chptr != ' ') chptr--; *chptr = '\0'; chptr++; if (info->catalogEntries == catalogAlloced) { catalogAlloced += 20; info->catalog = realloc(info->catalog, sizeof(*info->catalog) * catalogAlloced); } info->catalog[info->catalogEntries].filename = strdup(start); info->catalog[info->catalogEntries].size = strtoul(chptr, NULL, 10); info->catalogEntries++; start = next; } return 0; } static int tapeGetPackageSet(struct installMethod * method, struct pkgSet * ps) { struct tapeinfo * info = method->data; if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR; info->curr++; return psFromHeaderListDesc(info->fd, ps, 1); } static int tapeCopyFile(struct tapeinfo * info, char * tapename, char * out) { int outfd; char buf[4096]; int i; int total, amount; int done = 0; /* let's figure out where we need to go */ for (i = 0; i < info->catalogEntries; i++) { if (!strcmp(tapename, info->catalog[i].filename)) break; } if (i < 0) { newtWinMessage("Error", "Ok", "I can't find file %s on the tape", tapename); return INST_ERROR; } if (i < info->curr) { newtWinMessage("Error", "Ok", "The tape is not positioned properly"); return INST_ERROR; } else { logMessage("skipping %d files on the tape to get to %s", i - info->curr, tapename); while (i > info->curr) { if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR; logMessage("skipped file"); info->curr++; } } if ((outfd = open(out, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) { newtWinMessage("Error", "Ok", "failed to create %s: %s", out, strerror(errno)); return INST_ERROR; } total = 0; while (!done) { amount = read(info->fd, buf, sizeof(buf)); if (amount < 0) break; if (((total + amount) > info->catalog[i].size)) { done = 1; amount = info->catalog[i].size - total; } if (write(outfd, buf, amount) != amount) { newtWinMessage("Error", "Ok", "failed to write to %s: %s", out, strerror(errno)); close(outfd); return INST_ERROR; } total += amount; } if (i < 0) { newtWinMessage("Error", "Ok", "failed to read from tape: %s", out, strerror(errno)); close(outfd); return INST_ERROR; } close(outfd); return 0; } static int tapeGetComponentSet(struct installMethod * method, struct pkgSet * ps, struct componentSet * cs) { struct tapeinfo * info = method->data; int rc; if ((rc = tapeCopyFile(info, "comps", "/tmp/comps"))) return rc; return psReadComponentsFile("/tmp/comps", ps, cs); } static int tapeGetMappedFile(struct installMethod * method, char * name, char ** realName, int isPreskel) { static char sbuf[300]; int rc; struct tapeinfo * info = method->data; if (isPreskel) strcpy(sbuf, "/mnt/"); else strcpy(sbuf, "/mnt/var/tmp/"); strcat(sbuf, name); *realName = sbuf; return (rc = tapeCopyFile(info, name, sbuf)); } #ifdef __i386__ static int smbSetup(struct installMethod * method, struct partitionTable table, struct netConfig * netc, struct netInterface * 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: rc = bringUpNetworking(intf, netc, dl); if (rc) return rc; step = SMB_STEP_INFO; 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 smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr, char ** pwptr) { newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text; newtComponent acctEntry, passEntry; char * site, * dir, * acct, * pass; if (*hostptr) { site = *hostptr; dir = *dirptr; acct = *acctptr; pass = *pwptr; } else { site = ""; dir = ""; acct = ""; pass = ""; } newtCenteredWindow(50, 16, "SMB Setup"); form = newtForm(NULL, NULL, 0); okay = newtButton(10, 12, "Ok"); cancel = newtButton(30, 12, "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 SMB server\n" " o the volume to share which contains\n" " Red Hat Linux for your architecture"); newtFormAddComponent(form, newtLabel(3, 7, "SMB server name :")); newtFormAddComponent(form, newtLabel(3, 8, "Share volume :")); newtFormAddComponent(form, newtLabel(3, 9, "Account name :")); newtFormAddComponent(form, newtLabel(3, 10, "Password :")); siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL); dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL); acctEntry = newtEntry(22, 9, "guest", 24, &acct, NEWT_ENTRY_SCROLL); passEntry = newtEntry(22, 10, pass, 24, &pass, NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN); newtFormAddComponents(form, text, siteEntry, dirEntry, acctEntry, passEntry, okay, cancel, NULL); answer = newtRunForm(form); if (answer == cancel) { newtFormDestroy(form); newtPopWindow(); return INST_CANCEL; } *hostptr = strdup(site); *dirptr = strdup(dir); *acctptr = strdup(acct); *pwptr = strdup(pass); newtFormDestroy(form); newtPopWindow(); 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