diff options
author | Erik Troan <ewt@redhat.com> | 1999-08-25 18:31:41 +0000 |
---|---|---|
committer | Erik Troan <ewt@redhat.com> | 1999-08-25 18:31:41 +0000 |
commit | a6724e3ec33ea192194d951566b3b65acef36446 (patch) | |
tree | 911d3bf98eb525e2c32caab60426161008d7204e /loader | |
parent | 23bbde543a970005930a7ea558e1e80992dc8e28 (diff) | |
download | anaconda-a6724e3ec33ea192194d951566b3b65acef36446.tar.gz anaconda-a6724e3ec33ea192194d951566b3b65acef36446.tar.xz anaconda-a6724e3ec33ea192194d951566b3b65acef36446.zip |
first attempt at kickstart
Diffstat (limited to 'loader')
-rw-r--r-- | loader/Makefile | 2 | ||||
-rw-r--r-- | loader/kickstart.c | 166 | ||||
-rw-r--r-- | loader/kickstart.h | 15 | ||||
-rw-r--r-- | loader/loader.c | 298 | ||||
-rw-r--r-- | loader/loader.h | 12 | ||||
-rw-r--r-- | loader/net.c | 121 | ||||
-rw-r--r-- | loader/net.h | 2 |
7 files changed, 556 insertions, 60 deletions
diff --git a/loader/Makefile b/loader/Makefile index 28bd16ec4..71fd66f59 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,6 +1,6 @@ DESTDIR = ../../trees/initrd -OBJS = log.o windows.o modules.o devices.o net.o cdrom.o urls.o +OBJS = log.o windows.o modules.o devices.o net.o cdrom.o urls.o kickstart.o LOADEROBJS = loader.o loader-pcmcia.o pcmcia.o popen.o SOURCES = $(subst .o,.c,$(OBJS) $(LOADEROBJS)) BINS = loader loader-pcmcia init diff --git a/loader/kickstart.c b/loader/kickstart.c new file mode 100644 index 000000000..1caaf9a2a --- /dev/null +++ b/loader/kickstart.c @@ -0,0 +1,166 @@ +#include <alloca.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <string.h> +#include <newt.h> +#include <popt.h> +#include <unistd.h> + +#include "lang.h" +#include "loader.h" +#include "kickstart.h" + +struct ksCommandNames { + int code; + char * name; +} ; + +struct ksCommand { + int code, argc; + char ** argv; +}; + +struct ksCommandNames ksTable[] = { + { KS_CMD_NFS, "nfs" }, + { KS_CMD_CDROM, "cdrom" }, + { KS_CMD_HD, "harddrive" }, + { KS_CMD_URL, "url" }, + { KS_CMD_NETWORK, "network" }, + { KS_CMD_DEVICE, "device" }, + { KS_CMD_NONE, NULL } +}; + +struct ksCommand * commands = NULL; +int numCommands = 0; + +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; + + if ((fd = open(cmdFile, O_RDONLY)) < 0) { + newtWinMessage(_("Kickstart Error"), _("Ok"), + _("Error opening: kickstart file %s: %s"), cmdFile, + strerror(errno)); + return LOADER_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 LOADER_ERROR; + } + + close(fd); + + buf[sb.st_size] = '\0'; + + commands = malloc(sizeof(*commands) * commandsAlloced); + + start = buf; + while (*start && !inPackages) { + 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, "%packages")) { + inPackages = 1; + } 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) { + 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; +} diff --git a/loader/kickstart.h b/loader/kickstart.h new file mode 100644 index 000000000..134e4b805 --- /dev/null +++ b/loader/kickstart.h @@ -0,0 +1,15 @@ +#ifndef H_KICKSTART + +#define KS_CMD_NONE 0 +#define KS_CMD_NFS 1 +#define KS_CMD_CDROM 2 +#define KS_CMD_HD 3 +#define KS_CMD_URL 4 +#define KS_CMD_NETWORK 5 +#define KS_CMD_DEVICE 6 + +int ksReadCommands(char * cmdFile); +int ksGetCommand(int cmd, char ** last, int * argc, char *** argv); +int ksHasCommand(int cmd); + +#endif diff --git a/loader/loader.c b/loader/loader.c index 4c205af94..f442a3005 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -44,6 +44,7 @@ #include "cdrom.h" #include "devices.h" +#include "kickstart.h" #include "lang.h" #include "loader.h" #include "log.h" @@ -53,6 +54,11 @@ #include "urls.h" #include "windows.h" +int probe_main(int argc, char ** argv); +int rmmod_main(int argc, char ** argv); +int cardmgr_main(int argc, char ** argv); +int ourInsmodCommand(int argc, char ** argv); + struct knownDevices devices; struct installMethod { @@ -435,7 +441,6 @@ static int loadStage2Ramdisk(int fd, off_t size, int flags) { if (devMakeInode("ram3", "/tmp/ram3")) return 1; if (doPwMount("/tmp/ram3", "/mnt/runtime", "ext2", 0, 0, NULL, NULL)) { -logMessage("mount error %s", strerror(errno)); newtWinMessage(_("Error"), _("Ok"), "Error mounting ramdisk. This shouldn't " "happen, and I'm rebooting your system now."); @@ -447,6 +452,44 @@ logMessage("mount error %s", strerror(errno)); return 0; } +static char * setupHardDrive(char * device, char * type, char * dir, + int flags) { + int fd; + char * path; + int rc; + char * url; + + logMessage("mounting device %s as %s", device, type); + + if (!FL_TESTING(flags)) { + /* +5 skips over /dev/ */ + if (devMakeInode(device, "/tmp/hddev")) + logMessage("devMakeInode failed!"); + + if (doPwMount("/tmp/hddev", "/tmp/hdimage", type, 1, 0, NULL, NULL)) + return NULL; + + path = alloca(50 + (dir ? strlen(dir) : 2)); + sprintf(path, "/tmp/hdimage/%s/RedHat/base/stage2.img", + dir ? dir : ""); + if ((fd = open(path, O_RDONLY)) < 0) { + logMessage("cannot open %s", path); + umount("/tmp/hdimage"); + free(path); + return NULL; + } + + rc = loadStage2Ramdisk(fd, 0, flags); + close(fd); + if (rc) return NULL; + } + + url = malloc(50 + strlen(dir ? dir : "")); + sprintf(url, "hd://%s/%s", device + 5, dir ? dir : "."); + + return url; +} + static char * mountHardDrive(struct installMethod * method, char * location, struct knownDevices * kd, moduleInfoSet modInfo, moduleList modLoaded, @@ -466,7 +509,6 @@ static char * mountHardDrive(struct installMethod * method, char * dir = NULL; char * tmpDir; char * type; - char * path; char * url = NULL; int numPartitions; @@ -594,40 +636,13 @@ static char * mountHardDrive(struct installMethod * method, default: continue; } - if (!FL_TESTING(flags)) { - logMessage("mounting device %s as %s", part->name, type); - - /* +5 skips over /dev/ */ - if (devMakeInode(part->name + 5, "/tmp/hddev")) - logMessage("devMakeInode failed!"); - - if (doPwMount("/tmp/hddev", "/tmp/hdimage", type, 1, 0, NULL, NULL)) - continue; - - logMessage("opening stage2"); - - path = malloc(50 + (dir ? strlen(dir) : 2)); - sprintf(path, "/tmp/hdimage/%s/RedHat/base/stage2.img", - dir ? dir : ""); - if ((fd = open(path, O_RDONLY)) < 0) { - logMessage("cannot open %s", path); - newtWinMessage(_("Error"), _("Ok"), - _("Device %s does not appear to contain " - "a Red Hat installation tree."), part->name); - umount("/tmp/hdimage"); - free(path); - continue; - } - - free(path); - - rc = loadStage2Ramdisk(fd, 0, flags); - close(fd); - if (rc) continue; - - url = malloc(50 + strlen(dir ? dir : "")); - sprintf(url, "hd://%s/%s", part->name + 5, dir ? dir : "."); - if (dir) free(dir); + url = setupHardDrive(part->name + 5, type, dir, flags); + if (dir) free(dir); + if (url) { + newtWinMessage(_("Error"), _("Ok"), + _("Device %s does not appear to contain " + "a Red Hat installation tree."), part->name); + continue; } done = 1; @@ -896,6 +911,8 @@ static char * mountUrlImage(struct installMethod * method, url = malloc(strlen(ui.urlprefix) + 2); strcpy(url, ui.urlprefix); + writeNetInfo("/tmp/netinfo", &netDev); + return url; } @@ -988,6 +1005,149 @@ static char * doMountImage(char * location, struct knownDevices * kd, return url; } +static char * setupKickstart(char * location, struct knownDevices * kd, + moduleInfoSet modInfo, + moduleList modLoaded, + moduleDeps modDeps, int flags) { + static struct networkDeviceConfig netDev; + char * host = NULL, * dir = NULL, * partname = NULL; + char * url = NULL, * proxy = NULL, * proxyport = NULL; + char ** ksArgv; + char * fullPath; + char * device; + int ksArgc; + int ksType; + int i, rc, fd, partNum; + enum deviceClass ksDeviceType; + struct poptOption * table; + poptContext optCon; + struct partitionTable partTable; + struct poptOption ksNfsOptions[] = { + { "server", '\0', POPT_ARG_STRING, &host, 0 }, + { "dir", '\0', POPT_ARG_STRING, &dir, 0 }, + { 0, 0, 0, 0, 0 } + }; + struct poptOption ksHDOptions[] = { + { "dir", '\0', POPT_ARG_STRING, &dir, 0 }, + { "partition", '\0', POPT_ARG_STRING, &partname, 0 }, + { 0, 0, 0, 0, 0 } + }; + struct poptOption ksUrlOptions[] = { + { "url", '\0', POPT_ARG_STRING, &url, 0 }, + { "proxy", '\0', POPT_ARG_STRING, &proxy, 0 }, + { "proxyport", '\0', POPT_ARG_STRING, &proxyport, 0 }, + { 0, 0, 0, 0, 0 } + }; + + /* XXX kickstartDevices(modInfo, modLoaded, modDeps); */ + + if (ksHasCommand(KS_CMD_NFS)) { + ksDeviceType = DEVICE_NET; + ksType = KS_CMD_NFS; + table = ksNfsOptions; + } else if (ksHasCommand(KS_CMD_CDROM)) { + ksDeviceType = DEVICE_CDROM; + ksType = KS_CMD_CDROM; + table = NULL; + } else if (ksHasCommand(KS_CMD_HD)) { + ksDeviceType = DEVICE_DISK; + ksType = KS_CMD_HD; + table = ksHDOptions; + } else if (ksHasCommand(KS_CMD_URL)) { + ksDeviceType = DEVICE_NET; + ksType = KS_CMD_URL; + table = ksUrlOptions; + } else { + logMessage("no install method specified for kickstart"); + return NULL; + } + + for (i = 0; i < kd->numKnown; i++) + if (kd->known[i].class == ksType) break; + + if (i == kd->numKnown) { + logMessage("no appropriate device for kickstart method is available"); + return NULL; + } + + device = kd->known[i].name; + + if (table) { + ksGetCommand(ksType, NULL, &ksArgc, &ksArgv); + + optCon = poptGetContext(NULL, ksArgc, ksArgv, table, 0); + + if ((rc = poptGetNextOpt(optCon)) < -1) { + logMessage("bad argument to kickstart method command %s: %s", + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(rc)); + return NULL; + } + } + + if (ksType == KS_CMD_NFS || ksType == KS_CMD_URL) { + if (kickstartNetwork(device, &netDev, flags)) return NULL; + writeNetInfo("/tmp/netinfo", &netDev); + } + + if (ksType == KS_CMD_NFS) { + mlLoadModule("nfs", modLoaded, modDeps, NULL, flags); + fullPath = alloca(strlen(host) + strlen(dir) + 2); + sprintf(fullPath, "%s:%s", host, dir); + + logMessage("mounting nfs path %s", fullPath); + + if (doPwMount(fullPath, "/mnt/source", "nfs", 1, 0, NULL, NULL)) + return NULL; + + symlink("/mnt/source/RedHat/instimage", "/mnt/runtime"); + + return "dir://mnt/source/."; + } else if (ksType == KS_CMD_CDROM) { + return setupCdrom(NULL, location, kd, modInfo, modLoaded, modDeps, + flags, 1); + } else if (ksType == KS_CMD_HD) { + for (i = 0; i < kd->numKnown; i++) { + if (kd->known[i].class != DEVICE_DISK) continue; + if (!strncmp(kd->known[i].name, partname, strlen(partname) - 1)) + break; + } + if (i == kd->numKnown) { + logMessage("unknown partition %s", partname); + return NULL; + } + + devMakeInode(kd->known[i].name, "/tmp/hddevice"); + if ((fd = open("/tmp/hddevice", O_RDONLY)) < 0) { + logMessage("failed to open device %s", kd->known[i].name); + return NULL; + } + + if ((rc = balkanReadTable(fd, &partTable))) { + logMessage("failed to read partition partTable for " + "device %s: %d", kd->known[i].name, rc); + return NULL; + } + + partNum = atoi(partname + 3); + if (partTable.maxNumPartitions < partNum || + partTable.parts[partNum].type == -1) { + logMessage("partition %d on device %s does not exist"); + return NULL; + } + + /* XXX this shouldn't be hard coded to ext2 */ + return setupHardDrive(partname, + partTable.parts[partNum].type == BALKAN_PART_EXT2 ? + "ext2" : "vfat", + dir, flags); + } else if (ksType == KS_CMD_URL) { + abort(); + } + + return NULL; +} + static int parseCmdLineFlags(int flags, char * cmdLine) { int fd; char buf[500]; @@ -1015,11 +1175,55 @@ static int parseCmdLineFlags(int flags, char * cmdLine) { flags |= LOADER_FLAGS_TEXT; else if (!strcasecmp(argv[i], "rescue")) flags |= LOADER_FLAGS_RESCUE; + else if (!strcasecmp(argv[i], "ks=floppy")) + flags |= LOADER_FLAGS_RESCUE; } return flags; } +int kickstartFromFloppy(char * location) { + int infd = -1, outfd = -1; + char buf[4096]; + int i; + + /*loadFilesystem("vfat", "vfat", &dl);*/ + if (devMakeInode("fd0", "/tmp/fd0")) + return 1; + + if (doPwMount("/tmp/fd0", "/tmp/ks", "vfat", 1, 0, NULL, NULL)) { + logMessage("failed to mount floppy: %s", strerror(errno)); + return 1; + } + + if (access("/tmp/ks/ks.cfg", R_OK)) { + newtWinMessage(_("Error"), _("Ok"), + _("Cannot find ks.cfg on boot floppy.")); + return 1; + } + + + outfd = open(location, O_CREAT | O_RDWR, 0666); + infd = open("/tmp/ks/ks.cfg", O_RDONLY); + + while ((i = read(infd, buf, sizeof(buf))) > 0) { + if (write(outfd, buf, i) != i) break; + } + + close(infd); + close(outfd); + + umount("/tmp/ks"); + unlink("/tmp/fd0"); + + if (ksReadCommands("location")) { + logMessage("error reading kickstart commands"); + return 1; + } + + return 0; +} + int main(int argc, char ** argv) { char ** argptr; char * anacondaArgs[30]; @@ -1034,11 +1238,11 @@ int main(int argc, char ** argv) { int testing = 0; struct knownDevices kd; moduleInfoSet modInfo; + char * ksFile = NULL; struct poptOption optionTable[] = { - { "cmdline", '\0', POPT_ARG_STRING, &cmdLine, 0, - "override /proc/cmdline contents" }, - { "probe", '\0', POPT_ARG_NONE, &probeOnly, 0, - "display a list of probed pci devices" }, + { "cmdline", '\0', POPT_ARG_STRING, &cmdLine, 0 }, + { "ksfile", '\0', POPT_ARG_STRING, &ksFile, 0 }, + { "probe", '\0', POPT_ARG_NONE, &probeOnly, 0 }, { "test", '\0', POPT_ARG_NONE, &testing, 0 }, { 0, 0, 0, 0, 0 } }; @@ -1076,6 +1280,12 @@ int main(int argc, char ** argv) { flags = parseCmdLineFlags(flags, cmdLine); + if (FL_KSFLOPPY(flags)) { + kickstartFromFloppy("/tmp/ks.cfg"); + } else if (FL_KICKSTART(flags)) { + /* XXX we need to get our ks file from the network */ + } + arg = FL_TESTING(flags) ? "./module-info" : "/modules/module-info"; modInfo = isysNewModuleInfoSet(); if (isysReadModuleInfo(arg, modInfo)) { @@ -1106,7 +1316,13 @@ int main(int argc, char ** argv) { pciProbe(modInfo, modLoaded, modDeps, probeOnly, &kd, flags); if (probeOnly) exit(0); - url = doMountImage("/mnt/source", &kd, modInfo, modLoaded, modDeps, flags); + if (ksFile) { + ksReadCommands(ksFile); + url = setupKickstart("/mnt/source", &kd, modInfo, modLoaded, modDeps, + flags); + } else + url = doMountImage("/mnt/source", &kd, modInfo, modLoaded, modDeps, + flags); if (!FL_TESTING(flags)) { diff --git a/loader/loader.h b/loader/loader.h index b2ca30ab1..788d5f656 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -6,9 +6,13 @@ #define LOADER_FLAGS_EXPERT (1 << 1) #define LOADER_FLAGS_TEXT (1 << 2) #define LOADER_FLAGS_RESCUE (1 << 3) +#define LOADER_FLAGS_KICKSTART (1 << 4) +#define LOADER_FLAGS_KSFLOPPY (1 << 5) -#define FL_TESTING(a) ((a) & LOADER_FLAGS_TESTING) -#define FL_EXPERT(a) ((a) & LOADER_FLAGS_EXPERT) -#define FL_TEXT(a) ((a) & LOADER_FLAGS_TEXT) -#define FL_RESCUE(a) ((a) & LOADER_FLAGS_RESCUE) +#define FL_TESTING(a) ((a) & LOADER_FLAGS_TESTING) +#define FL_EXPERT(a) ((a) & LOADER_FLAGS_EXPERT) +#define FL_TEXT(a) ((a) & LOADER_FLAGS_TEXT) +#define FL_RESCUE(a) ((a) & LOADER_FLAGS_RESCUE) +#define FL_KICKSTART(a) ((a) & LOADER_FLAGS_KICKSTART) +#define FL_KSFLOPPY(a) ((a) & LOADER_FLAGS_KSFLOPPY) diff --git a/loader/net.c b/loader/net.c index 5da64bef1..e8da203f5 100644 --- a/loader/net.c +++ b/loader/net.c @@ -1,5 +1,6 @@ #include <arpa/inet.h> #include <errno.h> +#include <popt.h> #include <resolv.h> #include <net/if.h> #include <newt.h> @@ -9,6 +10,7 @@ #include "isys/dns.h" #include "pump/pump.h" +#include "kickstart.h" #include "lang.h" #include "loader.h" #include "log.h" @@ -98,6 +100,22 @@ int nfsGetSetup(char ** hostptr, char ** dirptr) { return 0; } +static void fillInIpInfo(struct networkDeviceConfig * cfg) { + if (!(cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST)) { + *((int32 *) &cfg->dev.broadcast) = (*((int32 *) &cfg->dev.ip) & + *((int32 *) &cfg->dev.netmask)) | + ~(*((int32 *) &cfg->dev.netmask)); + cfg->dev.set |= PUMP_INTFINFO_HAS_BROADCAST; + } + + if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK)) { + *((int32 *) &cfg->dev.network) = + *((int32 *) &cfg->dev.ip) & + *((int32 *) &cfg->dev.netmask); + cfg->dev.set |= PUMP_INTFINFO_HAS_NETWORK; + } +} + static void dhcpBoxCallback(newtComponent co, void * ptr) { struct intfconfig_s * c = ptr; @@ -233,7 +251,6 @@ int readNetConfig(char * device, struct networkDeviceConfig * cfg, int flags) { _("Sending request for IP information..."), 0); chptr = pumpDhcpRun(device, 0, 0, NULL, &newCfg.dev, NULL); - logMessage("pump told us: %s", chptr); newtPopWindow(); } else { chptr = NULL; @@ -243,6 +260,7 @@ int readNetConfig(char * device, struct networkDeviceConfig * cfg, int flags) { i = 2; cfg->isDynamic = 1; } else { + logMessage("pump told us: %s", chptr); i = 0; } } @@ -250,19 +268,7 @@ int readNetConfig(char * device, struct networkDeviceConfig * cfg, int flags) { cfg->dev = newCfg.dev; - if (!(cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST)) { - *((int32 *) &cfg->dev.broadcast) = (*((int32 *) &cfg->dev.ip) & - *((int32 *) &cfg->dev.netmask)) | - ~(*((int32 *) &cfg->dev.netmask)); - cfg->dev.set |= PUMP_INTFINFO_HAS_BROADCAST; - } - - if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK)) { - *((int32 *) &cfg->dev.network) = - *((int32 *) &cfg->dev.ip) & - *((int32 *) &cfg->dev.netmask); - cfg->dev.set |= PUMP_INTFINFO_HAS_NETWORK; - } + fillInIpInfo(cfg); if (!(cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)) { if (*c.gw && inet_aton(c.gw, &addr)) { @@ -385,3 +391,90 @@ int findHostAndDomain(struct networkDeviceConfig * dev, int flags) { return 0; } + +int kickstartNetwork(char * device, struct networkDeviceConfig * netDev, + int flags) { + char ** ksArgv; + int ksArgc; + int netSet, rc; + char * bootProto = NULL; + char * arg, * chptr; + poptContext optCon; + struct in_addr * parseAddress; + struct poptOption ksOptions[] = { + { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0 }, + { "gateway", '\0', POPT_ARG_STRING, NULL, 'g' }, + { "ip", '\0', POPT_ARG_STRING, NULL, 'i' }, + { "nameserver", '\0', POPT_ARG_STRING, NULL, 'n' }, + { "netmask", '\0', POPT_ARG_STRING, NULL, 'm' }, + { 0, 0, 0, 0, 0 } + }; + + if (ksGetCommand(KS_CMD_NETWORK, NULL, &ksArgc, &ksArgv)) { + /* This is for compatibility with RH 5.0 */ + ksArgv = alloca(sizeof(*ksArgv) * 1); + ksArgv[0] = "network"; + ksArgc = 1; + } + + optCon = poptGetContext(NULL, ksArgc, ksArgv, ksOptions, 0); + while ((rc = poptGetNextOpt(optCon)) >= 0) { + parseAddress = NULL; + netSet = 0; + + arg = poptGetOptArg(optCon); + + switch (rc) { + case 'g': + parseAddress = &netDev->dev.gateway; + netSet = PUMP_NETINFO_HAS_GATEWAY; + break; + + case 'i': + parseAddress = &netDev->dev.ip; + netSet = PUMP_INTFINFO_HAS_IP; + break; + + case 'n': + parseAddress = &netDev->dev.dnsServers[netDev->dev.numDns++]; + netSet = PUMP_NETINFO_HAS_DNS; + break; + + case 'm': + parseAddress = &netDev->dev.netmask; + netSet = PUMP_INTFINFO_HAS_NETMASK; + break; + } + + if (!inet_aton(arg, parseAddress)) { + logMessage("bad ip number in network command: %s", arg); + return -1; + } + + netDev->dev.set |= netSet; + } + + if (rc < -1) { + newtWinMessage(_("kickstart"), _("Ok"), + _("bad argument to kickstart network command %s: %s"), + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(rc)); + } else { + poptFreeContext(optCon); + } + + if (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")) { + chptr = pumpDhcpRun(device, 0, 0, NULL, &netDev->dev, NULL); + if (chptr) { + logMessage("pump told us: %s", chptr); + return -1; + } + } + + fillInIpInfo(netDev); + configureNetwork(netDev); + findHostAndDomain(netDev, flags); + writeResolvConf(netDev); + + return 0; +} diff --git a/loader/net.h b/loader/net.h index e89eed90e..10031a532 100644 --- a/loader/net.h +++ b/loader/net.h @@ -15,5 +15,7 @@ int nfsGetSetup(char ** hostptr, char ** dirptr); int writeNetInfo(const char * fn, struct networkDeviceConfig * dev); int findHostAndDomain(struct networkDeviceConfig * dev, int flags); int writeResolvConf(struct networkDeviceConfig * net); +int kickstartNetwork(char * device, struct networkDeviceConfig * netDev, + int flags); #endif |