#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_DEVICE, "device" },
{ KS_CMD_HD, "harddrive" },
{ KS_CMD_TEXT, "text" },
{ KS_CMD_URL, "url" },
{ KS_CMD_NETWORK, "network" },
{ KS_CMD_DEVICE, "device" },
{ KS_CMD_XDISPLAY, "xdisplay" },
{ KS_CMD_DRIVERDISK, "driverdisk" },
{ 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;
}