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

  1. #include <ctype.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 "install.h"
  14. #include "log.h"
  15. #include "methods.h"
  16. #include "net.h"
  17. #include "windows.h"
  18.  
  19. /* This was split into two pieces to keep the initial install program small */
  20.  
  21. static int nfsPrepare(struct installMethod * method);
  22. static int cdromPrepare(struct installMethod * method);
  23. int floppyRoot(struct installMethod * method);
  24. static int nfsGetSetup(char ** hostptr, char ** dirptr);
  25. static int totalMemory(void);            /* in K */
  26.  
  27. static struct installMethod methods[] = {
  28.     { "Local CDROM",         "cdrom", 0, cdromPrepare, NULL, NULL,
  29.         NULL, NULL, NULL },
  30.     { "NFS image",         "nfs", 0, nfsPrepare, NULL, NULL,
  31.         NULL, NULL, NULL },
  32.     { "hard drive",        "hd", 0, floppyRoot, NULL, NULL,
  33.         NULL, NULL, NULL },
  34.     { "FTP",             "ftp", 0, floppyRoot, NULL, NULL,
  35.         NULL, NULL, NULL },
  36. } ;
  37. static int numMethods = sizeof(methods) / sizeof(struct installMethod);
  38.  
  39. #define LOAD_BLOCK_COUNT 16
  40. static int loadRamdisk(char * todev, char * fromdev, int blocks,
  41.             char * label) {
  42.     newtComponent form, scale;
  43.     char * topath, * frompath;
  44.     char buf[LOAD_BLOCK_COUNT * 1024];
  45.     int rc = 0;
  46.     int i;
  47.     int to, from;
  48.  
  49.     if (blocks % LOAD_BLOCK_COUNT) {
  50.     logMessage("internal error: blocks in loadRamdisk() must be "
  51.         "divisible by %d!!", LOAD_BLOCK_COUNT);
  52.     return 1;
  53.     }
  54.  
  55.     topath = alloca(strlen(todev) + 8);
  56.     sprintf(topath, "/tmp/%s", todev);
  57.  
  58.     frompath = alloca(strlen(fromdev) + 8);
  59.     sprintf(frompath, "/tmp/%s", fromdev);
  60.  
  61.     if (devMakeInode(todev, topath)) return 1;
  62.     if (devMakeInode(fromdev, frompath)) {
  63.     unlink(topath);
  64.     return 1;
  65.     }
  66.  
  67.     to = open(topath, O_WRONLY);
  68.     if (to < 0) {
  69.     logMessage("failed to open %s: %s", topath, strerror(errno));
  70.     unlink(topath);
  71.     unlink(frompath);
  72.     return 1;
  73.     }
  74.  
  75.     from = open(frompath, O_RDONLY);
  76.     if (from < 0) {
  77.     logMessage("failed to open %s: %s", frompath, strerror(errno));
  78.     unlink(topath);
  79.     unlink(frompath);
  80.     return 1;
  81.     }
  82.  
  83.     unlink(frompath);
  84.     unlink(topath);
  85.  
  86.     logMessage("copying %d blocks from %s to %s", blocks, fromdev, todev);
  87.  
  88.     newtOpenWindow(10, 10, 60, 5, "Loading");
  89.     
  90.     form = newtForm(NULL, NULL, 0);
  91.     
  92.     newtFormAddComponent(form, newtLabel(1, 1, label));
  93.     scale = newtScale(1, 3, 58, blocks / LOAD_BLOCK_COUNT);
  94.     newtFormAddComponent(form, scale);
  95.     newtDrawForm(form);
  96.     newtRefresh();
  97.  
  98.     for (i = 0; i < (blocks / LOAD_BLOCK_COUNT) && !rc; i++) {
  99.     newtScaleSet(scale, i);
  100.     newtRefresh();
  101.  
  102.     if (read(from, buf, sizeof(buf)) != sizeof(buf)) {
  103.         logMessage("error reading from device: %s", strerror(errno));
  104.         rc = 1;
  105.     } else {
  106.         if (write(to, buf, sizeof(buf)) != sizeof(buf)) {
  107.         logMessage("error writing to device: %s", strerror(errno));
  108.         rc = 1;
  109.         }
  110.     }
  111.     }
  112.  
  113.     newtPopWindow();
  114.     newtFormDestroy(form);
  115.     
  116.     close(from);
  117.     close(to);
  118.  
  119.     return rc;
  120. }
  121.  
  122. static int totalMemory(void) {
  123.     int fd;
  124.     int bytesRead;
  125.     char buf[4096];
  126.     char * chptr, * start;
  127.     int total = 0;
  128.  
  129.     fd = open("/proc/meminfo", O_RDONLY);
  130.     if (fd < 0) {
  131.     logMessage("failed to open /proc/meminfo: %s", strerror(errno));
  132.     return 0;
  133.     }
  134.  
  135.     bytesRead = read(fd, buf, sizeof(buf) - 1);
  136.     if (bytesRead < 0) {
  137.     logMessage("failed to read from /proc/meminfo: %s", strerror(errno));
  138.     close(fd);
  139.     return 0;
  140.     }
  141.  
  142.     close(fd);
  143.     buf[bytesRead] = '\0';
  144.  
  145.     chptr = buf;
  146.     while (*chptr && !total) {
  147.     if (*chptr != '\n' || strncmp(chptr + 1, "MemTotal:", 9)) {
  148.         chptr++;
  149.         continue;
  150.     }
  151.  
  152.     start = ++chptr ;
  153.     while (*chptr && *chptr != '\n') chptr++;
  154.  
  155.     *chptr = '\0';
  156.  
  157.     logMessage("found total memory tag: \"%s\"", start);
  158.     
  159.     while (!isdigit(*start) && *start) start++;
  160.     if (!*start) {
  161.         logMessage("no number appears after MemTotal tag");
  162.         return 0;
  163.     }
  164.  
  165.     chptr = start;
  166.     while (*chptr && isdigit(*chptr)) {
  167.         total = (total * 10) + (*chptr - '0');
  168.         chptr++;
  169.     }
  170.     }
  171.  
  172.     logMessage("%d kB are available", total);
  173.  
  174.     return total;
  175. }
  176.  
  177. static int installMethodWindow(struct installMethod ** method) {
  178.     newtComponent form, listbox, okay, text;
  179.     struct installMethod * newMethod;
  180.     int i;
  181.  
  182.     newtOpenWindow(21, 4, 38, 15, "Installation Method");
  183.  
  184.     form = newtForm(NULL, NULL, 0);
  185.  
  186.     text = newtTextbox(3, 1, 32, 2, NEWT_TEXTBOX_WRAP);
  187.     newtTextboxSetText(text, "What type of media contains the packages "
  188.             "to be installed?");
  189.  
  190.     listbox = newtListbox(12, 4, 0, NEWT_LISTBOX_RETURNEXIT);
  191.  
  192.     for (i = 0; i < numMethods; i++) {
  193.     newtListboxAddEntry(listbox, methods[i].name, methods + i);
  194.     }
  195.  
  196.     okay = newtButton(14, 11, "Ok");
  197.  
  198.     newtFormAddComponents(form, text, listbox, okay, NULL);
  199.  
  200.     newtRunForm(form);
  201.  
  202.     newMethod = newtListboxGetCurrent(listbox);
  203.  
  204.     newtFormDestroy(form);
  205.     newtPopWindow();
  206.  
  207.     *method = newMethod;
  208.  
  209.     return 0;
  210. }
  211.  
  212. int chooseInstallMethod(struct installMethod ** method) {
  213.     int rc;
  214.     do {
  215.     rc = installMethodWindow(method);
  216.     if (rc) return rc;
  217.  
  218.     if ((*method)->prepareImage) {
  219.         rc = (*method)->prepareImage((*method));
  220.         if (rc == INST_ERROR) return rc;
  221.     }
  222.     } while (rc);
  223.  
  224.     return 0;
  225. }
  226.  
  227. static int nfsGetSetup(char ** hostptr, char ** dirptr) {
  228.     newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text;
  229.     char * site, * dir;
  230.  
  231.     if (*hostptr) {
  232.     site = *hostptr;
  233.     dir = *dirptr;
  234.     } else {
  235.     site = "";
  236.     dir = "";
  237.     }
  238.  
  239.     newtOpenWindow(15, 4, 50, 14, "NFS Setup");
  240.  
  241.     form = newtForm(NULL, NULL, 0);
  242.     okay = newtButton(10, 10, "Ok");
  243.     cancel = newtButton(30, 10, "Cancel");
  244.  
  245.     text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP);
  246.     newtTextboxSetText(text,
  247.     "Please enter the following information:\n"
  248.     "\n"
  249.     "    o the name or IP number of your NFS server\n"
  250.     "    o the directory on that server containing\n"
  251.     "      Red Hat Linux for your architecture");
  252.  
  253.     newtFormAddComponent(form, newtLabel(3, 7, "NFS server name  :"));
  254.     newtFormAddComponent(form, newtLabel(3, 8, "Red Hat directory:"));
  255.  
  256.     siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL);
  257.     dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL);
  258.  
  259.     newtFormAddComponents(form, text, siteEntry, dirEntry, okay, cancel, NULL);
  260.  
  261.     answer = newtRunForm(form);
  262.     if (answer == cancel) {
  263.     newtFormDestroy(form);
  264.     newtPopWindow();
  265.     
  266.     return INST_CANCEL;
  267.     }
  268.  
  269.     *hostptr = strdup(site);
  270.     *dirptr = strdup(dir);
  271.  
  272.     newtFormDestroy(form);
  273.     newtPopWindow();
  274.  
  275.     return 0;
  276. }
  277.  
  278. static int cdromPrepare(struct installMethod * method) {
  279.     char * cddev;
  280.     struct driversLoaded * dl = NULL;
  281.     int rc;
  282.  
  283.     messageWindow("Note", "Insert your Red Hat CD into your CD drive now");
  284.  
  285.     while (1) {
  286.     rc = setupCDdevice(&cddev, &dl);
  287.     if (rc) return rc;
  288.  
  289.     rc = doMount(cddev, "/tmp/rhimage", "iso9660", 1, 0);
  290.     if (rc) {
  291.         removeCDmodule(&dl);
  292.         messageWindow("Error", 
  293.             "I could not mount a CD on device /dev/%s", cddev);
  294.         continue;
  295.     }
  296.  
  297.     if (access("/tmp/rhimage/RedHat", R_OK)) {
  298.         umount("/tmp/rhimage");
  299.         removeCDmodule(&dl);
  300.         messageWindow("Error", "That CDROM device does not seem "
  301.               "to contain a Red Hat CDROM.");
  302.         continue;
  303.     }
  304.  
  305.     break;
  306.     }
  307.  
  308.     if (access("/usr/bin/runinstall2", R_OK)) {
  309.     symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
  310.     symlink("/tmp/rhimage/RedHat/instimage/etc", "/etc");
  311.     symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
  312.     }
  313.  
  314.     writeModuleConf("/tmp", dl);
  315.  
  316.     return 0;
  317. }
  318.  
  319. static int nfsPrepare(struct installMethod * method) {
  320.     struct netInterface intf;
  321.     struct netConfig netc;
  322.     struct driversLoaded * dl = NULL;
  323.     char * host = NULL, * dir = NULL;
  324.     char * buf;
  325.     enum { NFS_STEP_NET, NFS_STEP_INFO, NFS_STEP_MOUNT, NFS_STEP_DONE }
  326.         step = NFS_STEP_NET;
  327.     int rc;
  328.  
  329.     memset(&intf, 0, sizeof(intf));
  330.     memset(&netc, 0, sizeof(netc));
  331.  
  332.     while (step != NFS_STEP_DONE) {
  333.     switch (step) {
  334.       case NFS_STEP_NET:
  335.         rc = bringUpNetworking(&intf, &netc, &dl);
  336.         if (rc) return rc;
  337.         step = NFS_STEP_INFO;
  338.         break;
  339.  
  340.       case NFS_STEP_INFO:
  341.         rc = nfsGetSetup(&host, &dir);
  342.         if (rc == INST_CANCEL)
  343.         step = NFS_STEP_NET;
  344.         else if (rc == INST_ERROR)
  345.         return INST_ERROR;
  346.         else
  347.         step = NFS_STEP_MOUNT;
  348.         break;
  349.  
  350.       case NFS_STEP_MOUNT:
  351.         if (!strlen(host) || !strlen(dir))
  352.         rc = INST_ERROR;
  353.         else {
  354.         buf = malloc(strlen(host) + strlen(dir) + 10);
  355.         strcpy(buf, host);
  356.         strcat(buf, ":");
  357.         strcat(buf, dir);
  358.         rc = doMount(buf, "/tmp/rhimage", "nfs", 1, 0);
  359.         free(buf);
  360.         }
  361.  
  362.         if (rc) {
  363.         step = NFS_STEP_INFO;
  364.         messageWindow("Error", 
  365.             "I could not mount that directory from the server");
  366.         } else {
  367.             if (access("/tmp/rhimage/RedHat", R_OK)) {
  368.             step = NFS_STEP_INFO;
  369.             messageWindow("Error", "That directory does not seem "
  370.                   "to contain a Red Hat installation tree.");
  371.             umount("/tmp/rhimage");
  372.         } else
  373.             step = NFS_STEP_DONE;
  374.         }
  375.  
  376.         break;
  377.  
  378.       case NFS_STEP_DONE:
  379.         break;
  380.     }
  381.     }
  382.  
  383.     free(host);
  384.     free(dir);
  385.  
  386.     writeNetInterfaceConfig("/tmp", &intf);
  387.     writeNetConfig("/tmp", &netc, &intf, 1);
  388.     writeModuleConf("/tmp", dl);
  389.  
  390.     if (access("/usr/bin/runinstall2", R_OK)) {
  391.     symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
  392.     symlink("/tmp/rhimage/RedHat/instimage/etc", "/etc");
  393.     symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
  394.     }
  395.  
  396.     return 0;
  397. }
  398.  
  399. int floppyRoot(struct installMethod * method) { 
  400.     newtComponent form, text, okay, cancel, answer;
  401.     static int isMounted = 0;
  402.  
  403.     if (isMounted) return 0;
  404.  
  405.     if (access("/usr/bin/runinstall2", R_OK)) {
  406.     newtOpenWindow(20, 4, 40, 15, "Second Floppy");
  407.  
  408.     text = newtTextbox(1, 1, 38, 5, NEWT_TEXTBOX_WRAP);
  409.     newtTextboxSetText(text, 
  410.         "This install method requires a second disk. Please remove "
  411.         "the boot disk currently in your drive and replace it with "
  412.         "the Red Hat Supplementary Install disk.");
  413.  
  414.     okay = newtButton(6, 10, "Ok");
  415.     cancel = newtButton(24, 10, "Cancel");
  416.  
  417.     form = newtForm(NULL, NULL, 0);
  418.     newtFormAddComponents(form, text, okay, cancel, NULL);
  419.       
  420.     answer = newtRunForm(form);
  421.  
  422.     newtFormDestroy(form);
  423.     newtPopWindow();
  424.  
  425.     if (answer == cancel) return INST_CANCEL;
  426.  
  427.     if (testing) return 0;
  428.  
  429.     while (doMount("fd0", "/tmp/image", "ext2", 1, 0) ||
  430.            access("/tmp/image/usr/bin/runinstall2", R_OK)) {
  431.         /* in case the mount succeeded */
  432.         umount("/tmp/image");
  433.  
  434.         newtOpenWindow(20, 4, 40, 15, "Second Floppy");
  435.         text = newtTextbox(1, 1, 38, 5, NEWT_TEXTBOX_WRAP);
  436.  
  437.         newtTextboxSetText(text, 
  438.         "I failed to mount the floppy. Please insert the "
  439.         "Red Hat Supplementary Install disk, or choose "
  440.         "Cancel to pick a different installation process.");
  441.  
  442.         okay = newtButton(6, 10, "Ok");
  443.         cancel = newtButton(24, 10, "Cancel");
  444.  
  445.         form = newtForm(NULL, NULL, 0);
  446.         newtFormAddComponents(form, text, okay, cancel);
  447.       
  448.         answer = newtRunForm(form);
  449.         
  450.         newtFormDestroy(form);
  451.         newtPopWindow();
  452.  
  453.         if (answer == cancel) return INST_CANCEL;
  454.     }
  455.  
  456.     if (totalMemory() > 6000) {
  457.         umount("/tmp/image");
  458.         loadRamdisk("ram2", "fd0", 1440, "Loading supplemental disk...");
  459.         if (doMount("ram2", "/tmp/image", "ext2", 1, 0)) {
  460.         errorWindow("Error mounting ramdisk. This shouldn't "
  461.                 "happen, and I'm rebooting your system now.");
  462.         exit(1);
  463.         }
  464.     }
  465.  
  466.  
  467.     symlink("/tmp/image/lib", "/lib");
  468.     symlink("/tmp/image/etc", "/etc");
  469.     symlink("/tmp/image/usr/bin", "/usr/bin");
  470.     }
  471.  
  472.     isMounted = 1;
  473.  
  474.     return 0;
  475. }
  476.  
  477.