#include #include #include #include #include #include #include #include #include #include #include #include "install.h" #include "intl.h" #include "kickstart.h" #include "log.h" struct ksCommandNames { int code; char * name; } ; struct ksCommand { int code, argc; char ** argv; }; struct ksCommandNames ksTable[] = { { KS_CMD_NFS, "nfs" }, { KS_CMD_INSTALL, "install" }, { KS_CMD_UPGRADE, "upgrade" }, { KS_CMD_ROOTPW, "rootpw" }, #if defined(__i386__) { KS_CMD_LILO, "lilo" }, #else if defined(__sparc__) { KS_CMD_LILO, "silo" }, #endif { KS_CMD_PART, "part" }, { KS_CMD_CLEARPART, "clearpart" }, { KS_CMD_ZEROMBR, "zerombr" }, { KS_CMD_XCONFIG, "xconfig" }, { KS_CMD_KEYBOARD, "keyboard" }, { KS_CMD_MOUSE, "mouse" }, { KS_CMD_TIMEZONE, "timezone" }, { KS_CMD_CDROM, "cdrom" }, { KS_CMD_DEVICE, "device" }, { KS_CMD_LANG, "lang" }, { KS_CMD_NETWORK, "network" }, { KS_CMD_AUTH, "auth" }, #if defined(__sparc__) { KS_CMD_KBDTYPE, "kbdtype" }, #endif { KS_CMD_URL, "url" }, { KS_CMD_HD, "harddrive" }, { KS_CMD_PCMCIA, "pcmcia" }, { KS_CMD_REBOOT, "reboot" }, { KS_CMD_NOPROBE, "noprobe" }, { KS_CMD_SKIPX, "skipx" }, { KS_CMD_NONE, NULL } }; struct ksCommand * commands = NULL; int numCommands = 0; struct ksPackage * packages = NULL; int numPackages = 0; char * post = NULL; int ksReadCommands(char * cmdFile) { int fd; char * buf; struct stat sb; char * start, * end, * chptr; char oldch; int line = 0; char ** argv; int argc; int inPackages = 0; struct ksCommandNames * cmd; int commandsAlloced = 5; int packagesAlloced = 5; if ((fd = open(cmdFile, O_RDONLY)) < 0) { newtWinMessage(_("Kickstart Error"), _("Ok"), _("Error opening: kickstart file %s: %s"), cmdFile, strerror(errno)); return INST_ERROR; } fstat(fd, &sb); buf = alloca(sb.st_size + 1); if (read(fd, buf, sb.st_size) != sb.st_size) { newtWinMessage(_("Kickstart Error"), _("Ok"), _("Error reading contents of kickstart file %s: %s"), cmdFile, strerror(errno)); close(fd); return INST_ERROR; } close(fd); buf[sb.st_size] = '\0'; commands = malloc(sizeof(*commands) * commandsAlloced); packages = malloc(sizeof(*packages) * packagesAlloced); start = buf; while (*start) { line++; if (!(end = strchr(start, '\n'))) end = start + strlen(start); oldch = *end; *end = '\0'; while (*start && isspace(*start)) start++; chptr = end - 1; while (chptr > start && isspace(*chptr)) chptr--; if (isspace(*chptr)) *chptr = '\0'; else *(chptr + 1) = '\0'; if (!*start || *start == '#') { /* no nothing */ } else if (!strcmp(start, "%post")) { if (oldch) start = end + 1; else start = end; if (*start) { post = strdup(start); } break; } else if (!strcmp(start, "%packages")) { inPackages = 1; } else if (inPackages) { if (numPackages == packagesAlloced) { packagesAlloced += 5; packages = realloc(packages, sizeof(*packages) * packagesAlloced); } if (*start == '@') { packages[numPackages].isComponent = 1; start++; while (*start && isspace(*start)) start++; if (*start) packages[numPackages++].name = strdup(start); } else { packages[numPackages].isComponent = 0; packages[numPackages++].name = strdup(start); } } else { if (poptParseArgvString(start, &argc, &argv) || !argc) { newtWinMessage(_("Kickstart Error"), _("Ok"), _("Error on line %d of kickstart file %s."), argv[0], line, cmdFile); } else { for (cmd = ksTable; cmd->name; cmd++) if (!strcmp(cmd->name, argv[0])) break; if (!cmd->name) { newtWinMessage(_("Kickstart Error"), _("Ok"), _("Unknown command %s on line %d of " "kickstart file %s."), argv[0], line, cmdFile); } else { if (numCommands == commandsAlloced) { commandsAlloced += 5; commands = realloc(commands, sizeof(*commands) * commandsAlloced); } commands[numCommands].code = cmd->code; commands[numCommands].argc = argc; commands[numCommands].argv = argv; numCommands++; } } } if (oldch) start = end + 1; else start = end; } return 0; } int ksHasCommand(int cmd) { int i = 0; while (i < numCommands) { if (commands[i].code == cmd) return 1; i++; } return 0; } int ksGetCommand(int cmd, char ** last, int * argc, char *** argv) { int i = 0; if (last) { for (i = 0; i < numCommands; i++) { if (commands[i].argv == last) break; } i++; } while (i < numCommands) { if (commands[i].code == cmd) { if (argv) *argv = commands[i].argv; if (argc) *argc = commands[i].argc; return 0; } i++; } return 1; } void ksGetPackageList(struct ksPackage ** list, int * count) { *list = packages; *count = numPackages; } int ksRunPost(void) { pid_t child; int fd; if (!post) return 0; logMessage("running kickstart post-install script"); if ((fd = open("/mnt/tmp/ks.script", O_CREAT | O_RDWR, 0755)) < 0) { newtWinMessage(_("Error"), _("Ok"), _("Failed to create " "/mnt/tmp/ks.script: %s"), strerror(errno)); return INST_ERROR; } write(fd, "#!/bin/sh\n", 10); if (write(fd, post, strlen(post)) != strlen(post)) { newtWinMessage(_("Error"), _("Ok"), _("Failed to write ks post script: %s"), strerror(errno)); close(fd); unlink("/mnt/tmp/ks.script"); return INST_ERROR; } close(fd); if (!(child = fork())) { chdir("/mnt"); chroot("/mnt"); execl("/tmp/ks.script", "/tmp/ks.script", NULL); logMessage("exec failed: %s\n", strerror(errno)); exit(1); } waitpid(child, NULL, 0); unlink("/mnt/tmp/ks.script"); return 0; }