home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / kickstart.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-23  |  5.6 KB  |  267 lines

  1. #include <alloca.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6. #include <sys/wait.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <newt.h>
  10. #include <popt.h>
  11. #include <unistd.h>
  12.  
  13. #include "install.h"
  14. #include "intl.h"
  15. #include "kickstart.h"
  16. #include "log.h"
  17.  
  18. struct ksCommandNames {
  19.     int code;
  20.     char * name;
  21. } ;
  22.  
  23. struct ksCommand {
  24.     int code, argc;
  25.     char ** argv;
  26. };
  27.  
  28. struct ksCommandNames ksTable[] = {
  29.     { KS_CMD_NFS, "nfs" },
  30.     { KS_CMD_INSTALL, "install" },
  31.     { KS_CMD_UPGRADE, "upgrade" },
  32.     { KS_CMD_ROOTPW, "rootpw" },
  33. #if defined(__i386__)
  34.     { KS_CMD_LILO, "lilo" },
  35. #else if defined(__sparc__)
  36.     { KS_CMD_LILO, "silo" },
  37. #endif
  38.     { KS_CMD_PART, "part" },
  39.     { KS_CMD_CLEARPART, "clearpart" },
  40.     { KS_CMD_ZEROMBR, "zerombr" },
  41.     { KS_CMD_XCONFIG, "xconfig" },
  42.     { KS_CMD_KEYBOARD, "keyboard" },
  43.     { KS_CMD_MOUSE, "mouse" },
  44.     { KS_CMD_TIMEZONE, "timezone" },
  45.     { KS_CMD_CDROM, "cdrom" },
  46.     { KS_CMD_DEVICE, "device" },
  47.     { KS_CMD_LANG, "lang" },
  48.     { KS_CMD_NETWORK, "network" },
  49.     { KS_CMD_NONE, NULL }
  50. };
  51.  
  52. struct ksCommand * commands = NULL;
  53. int numCommands = 0;
  54. struct ksPackage * packages = NULL;
  55. int numPackages = 0;
  56. char * post = NULL;
  57.  
  58. int ksReadCommands(char * cmdFile) {
  59.     int fd;
  60.     char * buf;
  61.     struct stat sb;
  62.     char * start, * end, * chptr;
  63.     char oldch;
  64.     int line = 0;
  65.     char ** argv; 
  66.     int argc;
  67.     int inPackages = 0;
  68.     struct ksCommandNames * cmd;
  69.     int commandsAlloced = 5;
  70.     int packagesAlloced = 5;
  71.  
  72.     if ((fd = open(cmdFile, O_RDONLY)) < 0) {
  73.     newtWinMessage(_("Kickstart Error"), _("Ok"), 
  74.             _("Error opening: kickstart file %s: %s"), cmdFile, 
  75.             strerror(errno));
  76.     return INST_ERROR;
  77.     }
  78.  
  79.     fstat(fd, &sb);
  80.  
  81.     buf = alloca(sb.st_size + 1);
  82.     if (read(fd, buf, sb.st_size) != sb.st_size) {
  83.     newtWinMessage(_("Kickstart Error"), _("Ok"), 
  84.             _("Error reading contents of kickstart file %s: %s"),
  85.             cmdFile, strerror(errno));
  86.     close(fd);
  87.     return INST_ERROR;
  88.     }
  89.  
  90.     close(fd);
  91.  
  92.     buf[sb.st_size] = '\0';
  93.  
  94.     commands = malloc(sizeof(*commands) * commandsAlloced);
  95.     packages = malloc(sizeof(*packages) * packagesAlloced);
  96.  
  97.     start = buf;
  98.     while (*start) {
  99.     line++;
  100.  
  101.     if (!(end = strchr(start, '\n')))
  102.         end = start + strlen(start);
  103.  
  104.     oldch = *end;
  105.     *end = '\0';
  106.  
  107.     while (*start && isspace(*start)) start++;
  108.  
  109.     chptr = end - 1;
  110.     while (chptr > start && isspace(*chptr)) chptr--;
  111.  
  112.     if (isspace(*chptr)) 
  113.         *chptr = '\0';
  114.     else
  115.         *(chptr + 1) = '\0';
  116.  
  117.     if (!*start || *start == '#') {
  118.         /* no nothing */
  119.     } else if (!strcmp(start, "%post")) {
  120.         if (oldch)
  121.         start = end + 1;
  122.         else
  123.         start = end;
  124.  
  125.         if (*start) {
  126.         post = strdup(start);
  127.         }
  128.         break;
  129.         
  130.     } else if (!strcmp(start, "%packages")) {
  131.         inPackages = 1;
  132.     } else if (inPackages) {
  133.         if (numPackages == packagesAlloced) {
  134.         packagesAlloced += 5;
  135.         packages = realloc(packages,
  136.                    sizeof(*packages) * packagesAlloced);
  137.         }
  138.  
  139.         if (*start == '@') {
  140.         packages[numPackages].isComponent = 1;
  141.         start++;
  142.         while (*start && isspace(*start)) start++;
  143.         if (*start)
  144.             packages[numPackages++].name = strdup(start);
  145.         } else {
  146.         packages[numPackages].isComponent = 0;
  147.         packages[numPackages++].name = strdup(start);
  148.         }
  149.     } else {
  150.         if (poptParseArgvString(start, &argc, &argv) || !argc) {
  151.         newtWinMessage(_("Kickstart Error"), _("Ok"), 
  152.                    _("Error on line %d of kickstart file %s."),
  153.                 argv[0], line, cmdFile);
  154.         } else {
  155.         for (cmd = ksTable; cmd->name; cmd++)
  156.             if (!strcmp(cmd->name, argv[0])) break;
  157.  
  158.         if (!cmd->name) {
  159.             newtWinMessage(_("Kickstart Error"), _("Ok"), 
  160.                    _("Unknown command %s on line %d of "
  161.                      "kickstart file %s."), argv[0], line, 
  162.                    cmdFile);
  163.         } else {
  164.             if (numCommands == commandsAlloced) {
  165.             commandsAlloced += 5;
  166.             commands = realloc(commands,
  167.                        sizeof(*commands) * commandsAlloced);
  168.             }
  169.  
  170.             commands[numCommands].code = cmd->code;
  171.             commands[numCommands].argc = argc;
  172.             commands[numCommands].argv = argv;
  173.             numCommands++;
  174.         }
  175.         }
  176.     }
  177.  
  178.     if (oldch)
  179.         start = end + 1;
  180.     else
  181.         start = end;
  182.     }
  183.  
  184.     return 0;
  185. }
  186.  
  187. int ksHasCommand(int cmd) {
  188.     int i = 0;
  189.  
  190.     while (i < numCommands) {
  191.     if (commands[i].code == cmd) return 1;
  192.     i++;
  193.     }
  194.  
  195.     return 0;
  196. }
  197.  
  198. int ksGetCommand(int cmd, char ** last, int * argc, char *** argv) {
  199.     int i = 0;
  200.  
  201.     if (last) {
  202.     for (i = 0; i < numCommands; i++) {
  203.         if (commands[i].argv == last) break;
  204.     }
  205.  
  206.     i++;
  207.     }
  208.  
  209.     while (i < numCommands) {
  210.     if (commands[i].code == cmd) {
  211.         if (argv) *argv = commands[i].argv;
  212.         if (argc) *argc = commands[i].argc;
  213.         return 0;
  214.     }
  215.     i++;
  216.     }
  217.  
  218.     return 1;
  219. }
  220.  
  221. void ksGetPackageList(struct ksPackage ** list, int * count) {
  222.     *list = packages;
  223.     *count = numPackages;
  224. }
  225.  
  226. int ksRunPost(void) {
  227.     pid_t child;
  228.     int fd;
  229.  
  230.     if (!post) return 0;
  231.  
  232.     logMessage("running kickstart post-install script");
  233.  
  234.     if ((fd = open("/mnt/tmp/ks.script", O_CREAT | O_RDWR, 0755)) < 0) {
  235.     newtWinMessage(_("Error"), _("Ok"), _("Failed to create "
  236.                 "/mnt/tmp/ks.script: %s"), strerror(errno));
  237.     return INST_ERROR;
  238.     }
  239.  
  240.     write(fd, "#!/bin/sh\n", 10);
  241.  
  242.     if (write(fd, post, strlen(post)) != strlen(post)) {
  243.     newtWinMessage(_("Error"), _("Ok"), 
  244.                _("Failed to write ks post script: %s"),
  245.                strerror(errno));
  246.     close(fd);
  247.     unlink("/mnt/tmp/ks.script");
  248.     return INST_ERROR;
  249.     }
  250.  
  251.     close(fd);
  252.     
  253.     if (!(child = fork())) {
  254.     chdir("/mnt");
  255.     chroot("/mnt");
  256.     execl("/tmp/ks.script", "/tmp/ks.script", NULL);
  257.     logMessage("exec failed: %s\n", strerror(errno));
  258.     exit(1);
  259.     }
  260.  
  261.     waitpid(child, NULL, 0);
  262.  
  263.     unlink("/mnt/tmp/ks.script");
  264.  
  265.     return 0;
  266. }
  267.