home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / install / .#install.c.1.44 < prev    next >
Text File  |  1997-10-01  |  10KB  |  457 lines

  1. /*
  2.  * install.c
  3.  * 
  4.  * This is the first half of the install. It does just enough to get the
  5.  * second half going. It, and everything it needs, has to fit on one floppy
  6.  * along with a kernel and modules. Needless to say, it's a bit tight.
  7.  *
  8.  * Erik Troan (ewt@redhat.com)
  9.  *
  10.  * Copyright 1997 Red Hat Software 
  11.  *
  12.  * This software may be freely redistributed under the terms of the GNU
  13.  * public license.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21. #include <alloca.h>
  22. #include <dirent.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25. #include <netinet/in.h>        /* for ntohl */
  26. #include <stdarg.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <sys/stat.h>
  31. #include <sys/sysmacros.h>
  32. #include <sys/wait.h>
  33. #include <unistd.h>
  34. #include <zlib.h>
  35.  
  36. #include "devices.h"
  37. #include "fs.h"
  38. #include "install.h"
  39. #include "kbd.h"
  40. #include "kickstart.h"
  41. #include "log.h"
  42. #include "methods.h"
  43. #include "mono.h"
  44. #include "net.h"
  45. #include "newt.h"
  46. #include "perror.h"
  47. #include "run.h"
  48. #include "windows.h"
  49. #include "pcmcia-probing/pcmcia-probe.h"
  50.  
  51. int testing = 0;
  52. int expert = 0;
  53. int kickstart = 0;
  54. int debug = 1;
  55.  
  56. /* librpm.a provides this */
  57. int cpioInstallArchive(gzFile stream, void * mappings,
  58.                int numMappings, void * cb, void * cbData,
  59.                char ** failedFile);
  60.  
  61. char * welcomeText =
  62.     "Welcome to Red Hat Linux!\n"
  63.     "\n"
  64.     "This installation process is outlined in detail in the Official Red "
  65.     "Hat Linux User's Guide available from Red Hat Software. If you have "
  66.     "access to this manual, you should read the installation section before "
  67.     "continuing.\n\n"
  68.     "If you have purchased Official Red Hat Linux, be sure to register your "
  69.     "purchase through our web site, http://www.redhat.com."
  70.     ;
  71.  
  72. void welcome(void) {
  73.     if (!testing && !kickstart)
  74.     newtWinMessage("Red Hat Linux", "Ok", welcomeText);
  75. }
  76.  
  77. void mountFloppy() {
  78.     if (!testing) {
  79.     logMessage("mounting ext2 fs on floppy");
  80.     doMount("fd0", "/tmp/bootdisk", "ext2", 1, 0);
  81.     logMessage("floppy filesystem mounted on /tmp/bootdisk");
  82.     }
  83. }
  84.  
  85. #if 0
  86. void showmtab(void) {
  87.     char buf[5000];
  88.     int fd, i;
  89.  
  90.     fd = open("/proc/mounts", O_RDONLY);
  91.     if (fd < 0) {
  92.     newtWinMessage("Error", "Ok", perrorstr("open /proc/mounts"));
  93.     return;
  94.     }
  95.  
  96.     i = read(fd, buf, sizeof(buf) - 1);
  97.     if (i < 1) {
  98.     close(fd);
  99.     newtWinMessage("Error", "Ok", perrorstr("read /proc/mounts"));
  100.     return;
  101.     }
  102.     close(fd);
  103.  
  104.     buf[i] = '\0';
  105.  
  106.     newtWinMessage("/proc/mounts", "Ok", buf);
  107. }
  108. #endif
  109.  
  110. int expandPcmciaArchive() {
  111.     gzFile stream;
  112.     char * failedFile;
  113.     int rc;
  114.  
  115.     stream = gzopen("/tmp/image/pcmcia.cgz", "r");
  116.  
  117.     if (!stream) {
  118.     logMessage("gzopen failed to read pcmcia.cgz: %s", strerror(errno));
  119.     return INST_ERROR;
  120.     }
  121.  
  122.     rc = cpioInstallArchive(stream, NULL, 0, NULL, NULL, &failedFile);
  123.     if (rc) {
  124.     logMessage("cpio expansion failed on file %s, error %d\n",
  125.            failedFile, rc);
  126.     gzclose(stream);
  127.     return INST_ERROR;
  128.     }
  129.  
  130.     gzclose(stream);
  131.  
  132.     return 0;
  133. }
  134.  
  135. #ifdef __i386__
  136. int setupPCMCIA(char ** arg) {
  137.     int rc;
  138.     struct driversLoaded * dl = NULL;
  139.     int status;
  140.     char * probeOutput;
  141.     static char pcic[20];
  142.  
  143.     /* just probe and if pcmcia controller exists we load support
  144.        automatically */
  145.     probeOutput = pcmciaProbeController();
  146.     if (probeOutput == NULL)
  147.     return 0;
  148.  
  149.     rc = loadFloppyRoot(NULL,
  150.         "PCMCIA support requires a second disk. Please remove "
  151.         "the boot disk currently in your drive and replace it with "
  152.         "the Red Hat Supplementary Install disk.");
  153.     if (rc) return rc;
  154.  
  155.     if (testing) {
  156.     sleep(2);
  157.     return 0;
  158.     }
  159.  
  160.     winStatus(35, 3, "PCMCIA", "Loading PCMCIA support...");
  161.  
  162.     chdir("/modules");
  163.     unlink("53c7,8xx.o.gz");
  164.     unlink("3c59x.o.gz");
  165.     unlink("cdrom.o.gz");
  166.     unlink("aztcd.o.gz");
  167.     unlink("cdu31a.o.gz");
  168.     unlink("cm206.o.gz");
  169.     unlink("de4x5.o.gz");
  170.     unlink("sbpcd.o.gz");
  171.     unlink("sjcd.o.gz");
  172.     unlink("sonycd535.o.gz");
  173.     unlink("optcd.o.gz");
  174.     unlink("gscd.o.gz");
  175.     unlink("aic7xxx.o.gz");
  176.     unlink("eata_dma.o.gz");
  177.     unlink("eata_pio.o.gz");
  178.     unlink("pas_16.o.gz");
  179.     unlink("ultrastor.o.gz");
  180.     unlink("u14-34f.o.gz");
  181.  
  182.     chdir("/");
  183.  
  184.     expandPcmciaArchive();
  185.  
  186.     newtPopWindow();
  187.  
  188.     logMessage("pcmcia probe returned: %s", probeOutput);
  189.  
  190.     if (strstr(probeOutput, "TCIC")) {
  191.     strcpy(pcic, "tcic");
  192.     } else
  193.     strcpy(pcic, "i82365");
  194.     logMessage("pcmcia pcic type: %s", pcic);
  195.  
  196.     winStatus(40, 3, "PCMCIA", "Starting PCMCIA services...");
  197.  
  198.     loadModule("pcmcia_core", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
  199.     loadModule(pcic, DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
  200.     loadModule("ds", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
  201.  
  202.     *arg = pcic;
  203.  
  204.     if (!fork()) {
  205.     if (!fork()) {
  206.         execl("/sbin/cardmgr", "/sbin/cardmgr", NULL);
  207.         exit(-1);
  208.     }
  209.     exit(-1);
  210.     }
  211.  
  212.     wait(&status);
  213.  
  214.     /* if cardmgr a chance to get going */
  215.     sleep(5);
  216.  
  217.     newtPopWindow();
  218.  
  219.     return 0;
  220. }
  221. #endif
  222.  
  223. void doSuspend(void) {
  224.     pid_t pid;
  225.     int status;
  226.  
  227.     if (testing) {
  228.     newtFinished();
  229.     exit(1);
  230.     } else if (access("/bin/sh", X_OK)) {
  231.     return;
  232.     }
  233.  
  234.     newtSuspend();
  235.     if (!(pid = fork())) {
  236.     printf("\n\nType <exit> to return to the install program.\n\n");
  237.     execl("/bin/sh", "-/bin/sh", NULL);
  238.     perror("error execing /bin/sh");
  239.     sleep(5);
  240.     exit(1);
  241.     }
  242.     waitpid(pid, &status, 0);
  243.     newtResume();
  244. }
  245.  
  246. void main(int argc, char ** argv) {
  247.     char ** argptr;
  248.     struct installMethod * method;
  249.     int rc;
  250.     char * pcmciaArg = NULL;
  251.     int isRescue = 0;
  252.     int isSerial;
  253.     int force = 0;
  254.     struct stat sb;
  255.     char * childArgs[20];
  256.     struct netInterface intf;
  257.     struct netConfig netc;
  258.     struct driversLoaded * dl = NULL;
  259.     char * ksPath;
  260.     char * file, * ksFile = NULL;
  261.     char * server;
  262.  
  263.     memset(&intf, 0, sizeof(intf));
  264.     memset(&netc, 0, sizeof(netc));
  265.  
  266.     argptr = argv + 1;
  267.     while (*argptr) {
  268.     if (!strcmp(*argptr, "--test")) {
  269.         testing = 1;
  270.     } else if (!strcmp(*argptr, "--force")) {
  271.         force = 1;
  272.     } else if (!strcmp(*argptr, "--rescue")) {
  273.         isRescue = 1;
  274.     } else if (!strcmp(*argptr, "--kickstart") || 
  275.            !strcmp(*argptr, "--ks")) {
  276.         kickstart = 1;
  277.     } else if (!strcmp(*argptr, "--expert")) {
  278.         expert = 1;
  279.     }
  280.  
  281.     argptr++;
  282.     }
  283.  
  284.     if (!testing && !force && (getpid() > 50)) {
  285.     fprintf(stderr, "you're running me on a live system! that's ");
  286.     fprintf(stderr, "incredibly stupid.\n");
  287.     exit(1);
  288.     }
  289.  
  290.     openLog();
  291.  
  292.     /* see if we're on a serial console -- if so, don't setup a keymap */
  293.     if (fstat(0, &sb)) {
  294.     logMessage("error stat'ing stdin: %s", strerror(errno));
  295.     return;
  296.     }
  297.  
  298.     if (!S_ISCHR(sb.st_mode)) {
  299.     logMessage("stdin isn't a character device!!! ack!");
  300.     return;
  301.     }
  302.  
  303.     isSerial = (major(sb.st_rdev) == 4 && minor(sb.st_dev) >= 64) ||
  304.                (major(sb.st_rdev) == 5 && minor(sb.st_dev) >= 64);
  305.  
  306.     if (!isRescue) 
  307.     logMessage("welcome to the Red Hat install "
  308.            "(first stage, version " VERSION " built " __DATE__ " "
  309.            __TIME__")");
  310.  
  311.     if (!kickstart)
  312.     setenv("NEWT_MONO", "1", 1);
  313.  
  314.     newtInit();
  315.     newtCls();
  316.  
  317.     newtSetSuspendCallback(doSuspend);
  318.  
  319.     newtDrawRootText(0, 0, "Welcome to Red Hat Linux");
  320.  
  321.     setColorState();
  322.  
  323.     newtFinished();
  324.  
  325.     newtInit();
  326.     newtCls();
  327.     newtDrawRootText(0, 0, "Welcome to Red Hat Linux");
  328.  
  329.     if (!isRescue)
  330.     welcome();
  331.  
  332.     newtPushHelpLine(NULL);
  333.  
  334.     #ifndef __sparc__
  335.     /* kickstart installs do this later */
  336.     if (!isSerial && !kickstart) setupKeyboard();
  337.     #endif
  338.  
  339.     #ifdef __i386__
  340.     /* this blocks on kickstart installs, but there is nothing to
  341.        be done about it */
  342.     do {
  343.         rc = setupPCMCIA(&pcmciaArg);
  344.     } while (rc);
  345.     #endif
  346.  
  347.     if (isRescue) {
  348.     do {
  349.         rc = floppyRoot(NULL, &netc, &intf, &dl);
  350.     } while (rc);
  351.     } else if (kickstart) {
  352.     if ((bringUpNetworking(&intf, &netc, &dl))) {
  353.         kickstart = 0;
  354.     } else if (!(server = getenv("BOOTP_SERVER"))) {
  355.         newtWinMessage("Kickstart Error", "Ok", "No kickstart "
  356.                "configuration file server can be found.");
  357.         kickstart = 0;
  358.     } else {
  359.         if (!(file = getenv("BOOTP_BOOTFILE")) || !strlen(file))
  360.         file = "/kickstartdir/";
  361.  
  362.         ksPath = alloca(strlen(server) + strlen(file) + 
  363.                 strlen(netc.hostname) + 50);
  364.         strcpy(ksPath, server);
  365.         strcat(ksPath, ":");
  366.         strcat(ksPath, file);
  367.  
  368.         if (ksPath[strlen(ksPath) - 1] == '/') {
  369.         ksPath[strlen(ksPath) - 1] = '\0';
  370.         file = alloca(30);
  371.         sprintf(file, "%02X%02X%02X%02X.kickstart",
  372.             (ntohl(intf.ip) & 0xFF000000) >> 24,
  373.             (ntohl(intf.ip) & 0x00FF0000) >> 16,
  374.             (ntohl(intf.ip) & 0x0000FF00) >> 8,
  375.             (ntohl(intf.ip) & 0x000000FF) >> 0);
  376.         } else {
  377.         file = strrchr(ksPath, '/');
  378.         if (!file) {
  379.             file = ksPath;
  380.             ksPath = "/";
  381.         } else {
  382.             *file++ = '\0';
  383.         }
  384.         }
  385.  
  386.         logMessage("ks server: %s file: %s", ksPath, file);
  387.  
  388.         loadFilesystem("nfs", &dl);
  389.  
  390.         if ((rc = doMount(ksPath, "/tmp/ks", "nfs", 1, 0))) {
  391.         newtWinMessage("Error", "Ok", 
  392.             "I could not mount the kickstart path %s.\n",
  393.             ksPath);
  394.         kickstart = 0;
  395.         } else {
  396.         ksFile = alloca(strlen(file) + 20);
  397.         sprintf(ksFile, "/tmp/ks/%s", file);
  398.  
  399.         if (ksReadCommands(ksFile)) 
  400.             kickstart = 0;
  401.         else
  402.             kickstart = 1;
  403.         }
  404.     }
  405.     }
  406.  
  407.     if (!isRescue)
  408.     while ((rc = chooseInstallMethod(&method, &netc, &intf, &dl)));
  409.  
  410.     if (intf.isConfigured) {
  411.     writeNetInterfaceConfig("/tmp", &intf);
  412.     writeNetConfig("/tmp", &netc, &intf, 1);
  413.     }
  414.     if (dl) writeModuleConf("/tmp", dl, 0);
  415.  
  416.     newtFinished();
  417.  
  418.     closeLog();
  419.  
  420.     if (testing) exit(0);
  421.  
  422.     argptr = childArgs;
  423.     *argptr++ = "/usr/bin/runinstall2";
  424.     if (isRescue)
  425.     *argptr++ = "--rescue";
  426.     else {
  427.     *argptr++ = "--method";
  428.     *argptr++ = method->abbrev;
  429.     }
  430.  
  431.     if (expert)
  432.     *argptr++ = "--expert";
  433.  
  434.     if (pcmciaArg) {
  435.     *argptr++ = "--pcmcia";
  436.     *argptr++ = pcmciaArg;
  437.     }
  438.  
  439.     if (kickstart) {
  440.     *argptr++ = "--ks";
  441.     *argptr++ = ksFile;
  442.     }
  443.  
  444.     *argptr++ = NULL;
  445.  
  446.     execv(childArgs[0], childArgs);
  447.  
  448.     rc = errno;
  449.     openLog();
  450.     logMessage("error in exec of second stage loader :-(");
  451.     logMessage("\terror:%s", strerror(rc));
  452.  
  453.     while (1) ;
  454.  
  455.     exit(0);
  456. }
  457.