home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / MISC / SRC / INSTALL / LATEMETH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-23  |  17.5 KB  |  679 lines

  1. #include <alloca.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <newt.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/mount.h>
  9. #include <unistd.h>
  10.  
  11. #include "hd.h"
  12. #include "fs.h"
  13. #include "ftp.h"
  14. #include "install.h"
  15. #include "log.h"
  16. #include "methods.h"
  17. #include "net.h"
  18. #include "windows.h"
  19.  
  20. struct ftpinfo {
  21.     char * address;
  22.     char * login;
  23.     char * password;
  24.     char * prefix;
  25.     char * proxy;
  26.     int sock;
  27.     struct pkgSet ps;
  28. };
  29.  
  30. struct hdinfo {
  31.     char * device;
  32.     char * type;
  33.     char * dir;
  34. };
  35.  
  36. /* This was split into two pieces to keep the initial install program small */
  37.  
  38. static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename);
  39. static int ftpinstFinishTransfer(struct ftpinfo * fi);
  40. static int ftpinstGetMappedFile(struct installMethod * method, char * name, 
  41.                         char ** realName, int isPreskel);
  42. static int imageGetFile(struct installMethod * method, char * name, 
  43.             char ** realName, int isPreskel);
  44. static int singleimageSetSymlinks(struct installMethod * method, 
  45.                             struct partitionTable table,
  46.                             struct netConfig * netc, 
  47.                   struct netInterface * intf,
  48.                   struct driversLoaded ** dl);
  49. static int hdSetup(struct installMethod * method, struct partitionTable table,
  50.                struct netConfig * netc, struct netInterface * intf,
  51.                struct driversLoaded ** dl);
  52. static int hdGetPackageSet(struct installMethod * method,
  53.                  struct pkgSet * ps);
  54. static int hdPrepareMedia(struct installMethod * method,
  55.                 struct fstab * fstab);
  56. static int hdGetComponentSet(struct installMethod * method,
  57.                    struct pkgSet * ps,
  58.                    struct componentSet * cs);
  59. static int ftpSetup(struct installMethod * method, struct partitionTable table,
  60.                 struct netConfig * netc, struct netInterface * intf,
  61.                 struct driversLoaded ** dl);
  62. static int fileGetPackageSet(struct installMethod * method,
  63.                  struct pkgSet * ps);
  64. static int fileGetComponentSet(struct installMethod * method,
  65.                    struct pkgSet * ps,
  66.                    struct componentSet * cs);
  67. static int imageGetPackageSet(struct installMethod * method,
  68.                   struct pkgSet * ps);
  69. static int imageGetComponentSet(struct installMethod * method,
  70.                  struct pkgSet * ps,
  71.                  struct componentSet * cs);
  72.  
  73. static struct installMethod methods[] = {
  74.     { "Local CDROM",         "cdrom", 0, NULL, singleimageSetSymlinks, 
  75.         imageGetFile, 
  76.         imageGetPackageSet, imageGetComponentSet, NULL, NULL },
  77.     { "NFS image",         "nfs", 0, NULL, singleimageSetSymlinks, 
  78.         imageGetFile, 
  79.         imageGetPackageSet, imageGetComponentSet, NULL, NULL },
  80.     { "hard drive",        "hd",  0, NULL, hdSetup, imageGetFile,
  81.         hdGetPackageSet, hdGetComponentSet, hdPrepareMedia, NULL },
  82.     { "FTP",            "ftp", 1, NULL, ftpSetup, ftpinstGetMappedFile,
  83.         fileGetPackageSet, fileGetComponentSet, NULL, NULL },
  84. } ;
  85. static int numMethods = sizeof(methods) / sizeof(struct installMethod);
  86.  
  87. struct installMethod * findInstallMethod(char * argptr) {
  88.     int i;
  89.  
  90.     for (i = 0; i < numMethods; i++) 
  91.     if (!strcmp(argptr, methods[i].abbrev)) return (methods + i);
  92.  
  93.     return NULL;
  94. }
  95.  
  96. static int imageGetFile(struct installMethod * method, char * name, 
  97.             char ** realName, int isPreskel) {
  98.     static char buf[300];
  99.  
  100.     if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") ||
  101.     !strcmp(name, "rpmconvert"))
  102.     strcpy(buf, "/tmp/rhimage/RedHat/base/");
  103.     else
  104.     strcpy(buf, "/tmp/rhimage/RedHat/RPMS/");
  105.  
  106.     strcat(buf, name);
  107.     *realName = buf;
  108.  
  109.     return 0;
  110. }
  111.  
  112. static int hdSetup(struct installMethod * method, struct partitionTable table,
  113.                struct netConfig * netc, struct netInterface * intf,
  114.                struct driversLoaded ** dl) {
  115.     newtComponent okay, cancel, form, text, listbox, label, answer, dirEntry;
  116.     int i, j;
  117.     char buf[80];
  118.     struct partition * part = NULL;
  119.     char * type;
  120.     char * dir;
  121.     char * dest;
  122.     char * defaultDevice;
  123.     char * defaultDir;
  124.     int done = 0;
  125.     struct hdinfo * hdi;
  126.  
  127.     if (method->data) {
  128.     hdi = method->data;
  129.     defaultDir = strdup(hdi->dir);
  130.     defaultDevice = hdi->device;
  131.     } else {
  132.     defaultDir = strdup("/");
  133.     defaultDevice = "";
  134.     }
  135.  
  136.     while (!done) {
  137.     newtOpenWindow(10, 4, 64, 17, "Select Partition");
  138.     text = newtTextbox(1, 1, 62, 4, NEWT_TEXTBOX_WRAP);
  139.     newtTextboxSetText(text, "What partition and directory on that "
  140.                 "partition hold the RedHat/RPMS and "
  141.                 "RedHat/base directories?");
  142.     okay = newtButton(15, 13, "Ok");
  143.     cancel = newtButton(38, 13, "Cancel");
  144.  
  145.     form = newtForm(NULL, NULL, 0);
  146.  
  147.     listbox = newtListbox(7, 5, 5, NEWT_LISTBOX_RETURNEXIT);
  148.  
  149.     label = 
  150.         newtLabel(5, 4, "  Device          Begin        End   Size (k)");
  151.  
  152.     for (i = 0, j = 0; i < table.count; i++) {
  153.         if (table.parts[i].type == PART_EXT2 ||
  154.         table.parts[i].type == PART_DOS) {
  155.         sprintf(buf, "/dev/%-5s  %9d  %9d  %9d", table.parts[i].device, 
  156.             table.parts[i].begin, table.parts[i].end, 
  157.             table.parts[i].size);
  158.         newtListboxAddEntry(listbox, buf, &table.parts[i]);
  159.     
  160.         if (!strcmp(table.parts[i].device, defaultDevice)) {
  161.             newtListboxSetCurrent(listbox, j);
  162.         }
  163.  
  164.         j++;
  165.         }
  166.     }
  167.  
  168.     newtFormAddComponent(form, 
  169.                 newtLabel(1, 11, "Directory holding Red Hat:"));
  170.     dirEntry = newtEntry(28, 11, defaultDir, 28, &dir, NEWT_ENTRY_SCROLL);
  171.  
  172.     newtFormAddComponents(form, text, label, listbox, dirEntry,
  173.                 okay, cancel, NULL);
  174.     answer = newtRunForm(form);
  175.                 
  176.     if (answer != cancel) {
  177.         part = newtListboxGetCurrent(listbox);
  178.     }
  179.  
  180.     dir = strdup(dir);
  181.     free(defaultDir);
  182.     defaultDir = dir;
  183.     defaultDevice = part->device;
  184.  
  185.     newtFormDestroy(form);
  186.     newtPopWindow();
  187.  
  188.     if (answer == cancel) return INST_CANCEL;
  189.  
  190.     switch (part->type) {
  191.       case PART_EXT2:    type = "ext2";         break;
  192.       case PART_DOS:    type = "msdos";     break;
  193.       default:    continue;
  194.     }
  195.  
  196.     if (doMount(part->device, "/tmp/hdimage", type, 1, 0))
  197.         continue;
  198.  
  199.     unlink("/tmp/rhimage");
  200.     
  201.     /* the physical device is mounted on /tmp/hdimage, but all
  202.        access are through /tmp/rhimage which points to the RedHat
  203.        directory in /tmp/hdimage */
  204.  
  205.     dest = alloca(strlen(dir) + 20);
  206.     sprintf(dest, "/tmp/hdimage/%s", dir);
  207.  
  208.     if (symlink(dest, "/tmp/rhimage")) {
  209.         messageWindow("Error", "Failed to create /tmp/rhimage "
  210.                 "symlink: %s", strerror(errno));
  211.         umount("/tmp/hdimage");
  212.         continue;
  213.     } 
  214.  
  215.     if (access("/tmp/rhimage/RedHat/base/hdlist", R_OK)) {
  216.         messageWindow("Error", "Device %s does not appear to contain "
  217.             "a Red Hat insallation tree.", part->device);
  218.         umount("/tmp/hdimage");
  219.         continue;
  220.     } 
  221.  
  222.     if (method->data) {
  223.         hdi = method->data;
  224.         free(hdi->dir);
  225.     }
  226.     
  227.     hdi = malloc(sizeof(*hdi));
  228.     hdi->device = part->device;
  229.     hdi->type = type;
  230.     hdi->dir = strdup(dir);
  231.     method->data = hdi;
  232.  
  233.     done = 1; 
  234.  
  235.     umount("/tmp/hdimage");
  236.     }
  237.  
  238.     return 0;
  239. }
  240.  
  241. static int hdGetPackageSet(struct installMethod * method,
  242.                  struct pkgSet * ps) {
  243.     struct hdinfo * hdi = method->data;
  244.     int rc;
  245.  
  246.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  247.     return INST_ERROR;
  248.  
  249.     rc = psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps);
  250.     
  251.     umount("/tmp/hdimage");
  252.  
  253.     return rc;
  254. }
  255.  
  256. static int hdGetComponentSet(struct installMethod * method,
  257.                    struct pkgSet * ps,
  258.                    struct componentSet * cs) {
  259.     struct hdinfo * hdi = method->data;
  260.     int rc;
  261.  
  262.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  263.     return INST_ERROR;
  264.  
  265.     rc = psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
  266.     
  267.     umount("/tmp/hdimage");
  268.  
  269.     return rc;
  270. }
  271.  
  272. static int hdPrepareMedia(struct installMethod * method,
  273.                 struct fstab * fstab) {
  274.     struct hdinfo * hdi = method->data;
  275.     int i;
  276.     char * buf;
  277.  
  278.     for (i = 0; i < fstab->numEntries; i++) {
  279.     if (!strcmp(fstab->entries[i].device, hdi->device)) break;
  280.     }
  281.  
  282.     if (i < fstab->numEntries) {
  283.     logMessage("device %s is already mounted -- using symlink",
  284.             fstab->entries[i].device);
  285.     buf = alloca(strlen(fstab->entries[i].mntpoint) + 10);
  286.  
  287.     sprintf(buf, "/mnt/%s", fstab->entries[i].mntpoint);
  288.     
  289.     rmdir("/tmp/hdimage");
  290.     if (symlink(buf, "/tmp/hdimage")) {
  291.         logMessage("failed to create symlink %s: %s\n", 
  292.             buf, strerror(errno));
  293.         messageWindow("Error", "Failed to create symlink for package "
  294.             "source.");
  295.         return INST_ERROR;
  296.     }
  297.     } else {
  298.     logMessage("mounting device which contains packages");
  299.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  300.         return INST_ERROR;
  301.     }
  302.  
  303.     return 0;
  304. }
  305.  
  306. static int imageGetPackageSet(struct installMethod * method,
  307.                   struct pkgSet * ps) {
  308.     return psFromHeaderListFile("/tmp/rhimage/RedHat/base/hdlist", ps);
  309. }
  310.  
  311. static int imageGetComponentSet(struct installMethod * method,
  312.                     struct pkgSet * ps,
  313.                     struct componentSet * cs) {
  314.     return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
  315. }
  316.  
  317. static int singleimageSetSymlinks(struct installMethod * method, 
  318.                             struct partitionTable table,
  319.                             struct netConfig * netc, 
  320.                   struct netInterface * intf,
  321.                   struct driversLoaded ** dl) {
  322.     logMessage("making symlink from /tmp/rhimage to image");
  323.     symlink("rhimage", "/tmp/image");
  324.     return 0;
  325. }
  326.  
  327. /* returns a socket file descriptor, a ftpFinishTransfer() must occur after 
  328.    this call */
  329. static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename) {
  330.     char * buf;
  331.     newtComponent form;
  332.     int fd;
  333.  
  334.     logMessage("ftping %s to a fd", filename);
  335.  
  336.     newtOpenWindow(10, 10, 60, 3, "Retrieving");
  337.  
  338.     buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
  339.     sprintf(buf, "Retrieving %s...", filename);
  340.     form = newtForm(NULL, NULL, 0);
  341.     newtFormAddComponent(form, newtLabel(1, 1, buf));
  342.  
  343.     newtDrawForm(form);
  344.     newtRefresh();
  345.  
  346.     strcpy(buf, fi->prefix);
  347.     strcat(buf, "/RedHat/");
  348.     strcat(buf, filename);
  349.     fd = ftpGetFileDesc(fi->sock, buf);
  350.  
  351.     return fd;
  352. }
  353.  
  354. static int ftpinstFinishTransfer(struct ftpinfo * fi) {
  355.     newtPopWindow();
  356.  
  357.     return ftpGetFileDone(fi->sock);
  358. }
  359.  
  360. static int ftpinstGetFile(struct ftpinfo * fi, char * filename, char * dest) {
  361.     char * buf;
  362.     newtComponent form;
  363.     int fd, rc;
  364.  
  365.     logMessage("ftping %s as %s", filename, dest);
  366.  
  367.     newtOpenWindow(10, 10, 60, 3, "Retrieving");
  368.  
  369.     buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
  370.     sprintf(buf, "Retrieving %s...", filename);
  371.     form = newtForm(NULL, NULL, 0);
  372.     newtFormAddComponent(form, newtLabel(1, 1, buf));
  373.  
  374.     newtDrawForm(form);
  375.     newtRefresh();
  376.  
  377.     fd = open(dest, O_WRONLY | O_CREAT, 0644);
  378.     if (fd < 0) {
  379.     messageWindow("Error", "open of %s failed: %s\n", dest, 
  380.             strerror(errno));
  381.     return INST_ERROR;
  382.     }
  383.  
  384.     strcpy(buf, fi->prefix);
  385.     strcat(buf, "/RedHat/");
  386.     strcat(buf, filename);
  387.     rc = ftpGetFile(fi->sock, buf, fd);
  388.  
  389.     close(fd);
  390.  
  391.     newtFormDestroy(form);
  392.     newtPopWindow();
  393.  
  394.     if (rc) {
  395.     messageWindow("ftp", "I cannot get file %s: %s\n", buf,
  396.             ftpStrerror(rc));
  397.     return INST_ERROR;
  398.     }
  399.  
  400.     return 0;
  401. }
  402.  
  403. static int ftpMainSetupPanel(struct ftpinfo * fi, char * doSecondarySetup) {
  404.     newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text, cb;
  405.     char * site, * dir;
  406.  
  407.     if (fi->address) {
  408.     site = fi->address;
  409.     dir = fi->prefix;
  410.     } else {
  411.     site = "";
  412.     dir = "";
  413.     }
  414.  
  415.     if (fi->login || fi->password || fi->login)
  416.     *doSecondarySetup = 'X';
  417.     else
  418.     *doSecondarySetup = ' ';
  419.  
  420.     newtOpenWindow(17, 3, 50, 17, "FTP Setup");
  421.  
  422.     form = newtForm(NULL, NULL, 0);
  423.     okay = newtButton(10, 13, "Ok");
  424.     cancel = newtButton(30, 13, "Cancel");
  425.  
  426.     text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
  427.     newtTextboxSetText(text,
  428.     "Please enter the following information:\n"
  429.     "\n"
  430.     "    o the name or IP number of your FTP server\n"
  431.     "    o the directory on that server containing\n"
  432.     "      Red Hat Linux for your architecure\n");
  433.  
  434.     newtFormAddComponent(form, newtLabel(3, 8, "FTP site name    :"));
  435.     newtFormAddComponent(form, newtLabel(3, 9, "Red Hat directory:"));
  436.  
  437.     siteEntry = newtEntry(22, 8, site, 24, &site, NEWT_ENTRY_SCROLL);
  438.     dirEntry = newtEntry(22, 9, dir, 24, &dir, NEWT_ENTRY_SCROLL);
  439.  
  440.     cb = newtCheckbox(3, 11, "Use non-anonymous ftp or a proxy server",
  441.             *doSecondarySetup, NULL, doSecondarySetup);
  442.  
  443.     newtFormAddComponents(form, text, siteEntry, dirEntry, cb, okay, cancel, 
  444.               NULL);
  445.  
  446.     answer = newtRunForm(form);
  447.     if (answer == cancel) {
  448.     newtFormDestroy(form);
  449.     newtPopWindow();
  450.     
  451.     return INST_CANCEL;
  452.     }
  453.  
  454.     if (fi->address) free(fi->address);
  455.     fi->address = strdup(site);
  456.  
  457.     if (fi->prefix) free(fi->prefix);
  458.     fi->prefix = strdup(dir);
  459.  
  460.     newtFormDestroy(form);
  461.     newtPopWindow();
  462.  
  463.     return 0;
  464. }
  465.  
  466. static int ftpSecondarySetupPanel(struct ftpinfo * fi) {
  467.     newtComponent form, okay, cancel, answer, text, accountEntry;
  468.     newtComponent passwordEntry, proxyEntry;
  469.     char * account, * password, * proxy;
  470.  
  471.     newtOpenWindow(17, 4, 50, 15, "Further FTP Setup");
  472.  
  473.     form = newtForm(NULL, NULL, 0);
  474.     okay = newtButton(10, 11, "Ok");
  475.     cancel = newtButton(30, 11, "Cancel");
  476.  
  477.     text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
  478.     newtTextboxSetText(text,
  479.     "If you are using non anonymous ftp, enter the account "
  480.     "name and password you wish to use below. If you are "
  481.     "using an FTP proxy enter the name of the FTP proxy server "
  482.     "to use.");
  483.  
  484.     newtFormAddComponent(form, newtLabel(3, 6, "Account name :"));
  485.     newtFormAddComponent(form, newtLabel(3, 7, "Password     :"));
  486.  
  487.     newtFormAddComponent(form, newtLabel(3, 9, "FTP Proxy    :"));
  488.  
  489.     accountEntry = newtEntry(18, 6, fi->login, 24, &account, NEWT_ENTRY_SCROLL);
  490.     passwordEntry = newtEntry(18, 7, NULL, 24, &password, 
  491.                 NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN);
  492.     proxyEntry = newtEntry(18, 9, fi->proxy, 24, &proxy, NEWT_ENTRY_SCROLL);
  493.  
  494.     newtFormAddComponents(form, text, accountEntry, passwordEntry, proxyEntry, 
  495.               okay, cancel, NULL);
  496.  
  497.     answer = newtRunForm(form);
  498.     if (answer == cancel) {
  499.     newtFormDestroy(form);
  500.     newtPopWindow();
  501.     
  502.     return INST_CANCEL;
  503.     }
  504.  
  505.     if (fi->login) free(fi->login);
  506.     if (strlen(account))
  507.     fi->login = strdup(account);
  508.     else
  509.     fi->login = NULL;
  510.  
  511.     if (fi->password) free(fi->password);
  512.     if (strlen(password))
  513.     fi->password = strdup(password);
  514.     else
  515.     fi->password = NULL;
  516.  
  517.     if (fi->proxy) free(fi->proxy);
  518.     if (strlen(proxy))
  519.     fi->proxy = strdup(proxy);
  520.     else
  521.     fi->proxy = NULL;
  522.  
  523.     newtFormDestroy(form);
  524.     newtPopWindow();
  525.  
  526.     return 0;
  527. }
  528.  
  529. static int ftpSetup(struct installMethod * method, struct partitionTable table,
  530.                 struct netConfig * netc, struct netInterface * intf,
  531.                 struct driversLoaded ** dl) {
  532.     struct ftpinfo fi;
  533.     enum { FTP_SETUP_NET, FTP_SETUP_FTP1, FTP_SETUP_FTP2, FTP_SETUP_CHECK, 
  534.         FTP_SETUP_DONE } step = FTP_SETUP_NET;
  535.     int rc, fd;
  536.     char doMore;
  537.  
  538.     memset(&fi, 0, sizeof(fi));
  539.  
  540.     if (method->data)
  541.     memcpy(&fi, method->data, sizeof(fi));
  542.     else
  543.     memset(&fi, 0, sizeof(fi));
  544.  
  545.     while (step != FTP_SETUP_DONE) {
  546.     switch (step) {
  547.  
  548.       case FTP_SETUP_NET:
  549.         rc = bringUpNetworking(intf, netc, dl);
  550.         if (rc) return rc;
  551.         step = FTP_SETUP_FTP1;
  552.         break;
  553.  
  554.       case FTP_SETUP_FTP1:
  555.         rc = ftpMainSetupPanel(&fi, &doMore);
  556.         if (rc == INST_ERROR) 
  557.         return rc;
  558.         else if (rc)
  559.         step = FTP_SETUP_NET;
  560.         else if (doMore == ' ')
  561.         step = FTP_SETUP_CHECK;
  562.         else 
  563.         step = FTP_SETUP_FTP2;
  564.         break;
  565.  
  566.       case FTP_SETUP_FTP2:
  567.         rc = ftpSecondarySetupPanel(&fi);
  568.         if (rc == INST_ERROR) 
  569.         return rc;
  570.         else if (rc)
  571.         step = FTP_SETUP_FTP1;
  572.         else
  573.         step = FTP_SETUP_CHECK;
  574.         break;
  575.  
  576.       case FTP_SETUP_CHECK:
  577.         if ((fi.sock = ftpOpen(fi.address, fi.login, 
  578.                    fi.password ? fi.password : "rhinstall@", 
  579.                    fi.proxy, -1)) < 0) {
  580.         messageWindow("ftp", "I cannot log into machine: %s\n",
  581.                 ftpStrerror(fi.sock));
  582.         step = FTP_SETUP_FTP1;
  583.         break;
  584.         }
  585.  
  586.         
  587.         fd = ftpinstStartTransfer(&fi, "base/hdlist");
  588.         if (fd < 0) {
  589.         newtPopWindow();
  590.         ftpClose(fi.sock);
  591.         step = FTP_SETUP_FTP1;
  592.         break;
  593.         }
  594.  
  595.         if (psFromHeaderListDesc(fd, &fi.ps)) {
  596.         ftpClose(fi.sock);
  597.         step = FTP_SETUP_FTP1;
  598.         break;
  599.         }
  600.  
  601.         ftpinstFinishTransfer(&fi);
  602.  
  603.         if (ftpinstGetFile(&fi, "base/comps", "/tmp/comps")) {
  604.         ftpClose(fi.sock);
  605.         step = FTP_SETUP_FTP1;
  606.         break;
  607.         }
  608.         
  609.         step = FTP_SETUP_DONE;
  610.         break;
  611.  
  612.       case FTP_SETUP_DONE:
  613.         break;
  614.     }
  615.     }
  616.  
  617.     if (method->data) free(method->data);
  618.     method->data = malloc(sizeof(fi));
  619.     memcpy(method->data, &fi, sizeof(fi));
  620.  
  621.     return 0;
  622. }
  623.  
  624. static int fileGetPackageSet(struct installMethod * method,
  625.                  struct pkgSet * ps) {
  626.     struct ftpinfo * fi = method->data;
  627.  
  628.     *ps = fi->ps;
  629.     return 0;
  630. }
  631.  
  632. static int fileGetComponentSet(struct installMethod * method,
  633.                    struct pkgSet * ps,
  634.                    struct componentSet * cs) {
  635.     return psReadComponentsFile("/tmp/comps", ps, cs);
  636. }
  637.  
  638. static int ftpinstGetMappedFile(struct installMethod * method, char * name, 
  639.                         char ** realName, int isPreskel) {
  640.     static char sbuf[300];
  641.     char * buf;
  642.     int rc;
  643.     struct ftpinfo * fi = method->data;
  644.  
  645.     if (isPreskel)
  646.     strcpy(sbuf, "/mnt/");
  647.     else
  648.     strcpy(sbuf, "/mnt/var/tmp/");
  649.  
  650.     strcat(sbuf, name);
  651.     *realName = sbuf;
  652.  
  653.     buf = alloca(strlen(name) + 30);
  654.     if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") ||
  655.     !strcmp(name, "rpmconvert"))
  656.     strcpy(buf, "base/");
  657.     else
  658.     strcpy(buf, "RPMS/");
  659.     strcat(buf, name);
  660.  
  661.     rc = ftpinstGetFile(fi, buf, *realName);
  662.     if (!rc) return 0;
  663.  
  664.     /* Try again, and relogin */
  665.     ftpClose(fi->sock);
  666.  
  667.     if ((fi->sock = ftpOpen(fi->address, fi->login, 
  668.                 fi->password ? fi->password : "rhinstall@", 
  669.                 fi->proxy, -1)) 
  670.         < 0) {
  671.     messageWindow("ftp", "I cannot log into machine: %s\n",
  672.             ftpStrerror(fi->sock));
  673.     free(fi);
  674.     return INST_ERROR;
  675.     }
  676.  
  677.     return ftpinstGetFile(fi, buf, *realName);
  678. }
  679.