home *** CD-ROM | disk | FTP | other *** search
- #include <alloca.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <newt.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/mount.h>
- #include <unistd.h>
-
- #include "hd.h"
- #include "fs.h"
- #include "ftp.h"
- #include "install.h"
- #include "log.h"
- #include "methods.h"
- #include "net.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;
- };
-
- /* 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 hdGetPackageSet(struct installMethod * method,
- struct pkgSet * ps);
- static int hdPrepareMedia(struct installMethod * method,
- struct fstab * fstab);
- 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 fileGetPackageSet(struct installMethod * method,
- struct pkgSet * ps);
- static int fileGetComponentSet(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 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,
- fileGetPackageSet, fileGetComponentSet, NULL, 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, "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 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) {
- newtOpenWindow(10, 4, 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")) {
- messageWindow("Error", "Failed to create /tmp/rhimage "
- "symlink: %s", strerror(errno));
- umount("/tmp/hdimage");
- continue;
- }
-
- if (access("/tmp/rhimage/RedHat/base/hdlist", R_OK)) {
- messageWindow("Error", "Device %s does not appear to contain "
- "a Red Hat insallation 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 (!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));
- messageWindow("Error", "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);
-
- newtOpenWindow(10, 10, 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);
-
- newtOpenWindow(10, 10, 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) {
- 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 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 = ' ';
-
- newtOpenWindow(17, 3, 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;
-
- newtOpenWindow(17, 4, 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) {
- messageWindow("ftp", "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)) {
- 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 fileGetPackageSet(struct installMethod * method,
- struct pkgSet * ps) {
- struct ftpinfo * fi = method->data;
-
- *ps = fi->ps;
- return 0;
- }
-
- 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 ? fi->password : "rhinstall@",
- fi->proxy, -1))
- < 0) {
- messageWindow("ftp", "I cannot log into machine: %s\n",
- ftpStrerror(fi->sock));
- free(fi);
- return INST_ERROR;
- }
-
- return ftpinstGetFile(fi, buf, *realName);
- }
-