diff options
Diffstat (limited to 'loader2/loader.c')
-rw-r--r-- | loader2/loader.c | 137 |
1 files changed, 106 insertions, 31 deletions
diff --git a/loader2/loader.c b/loader2/loader.c index d4d4dc1f0..a44c99119 100644 --- a/loader2/loader.c +++ b/loader2/loader.c @@ -37,6 +37,7 @@ #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/wait.h> #include <linux/fb.h> @@ -365,36 +366,52 @@ static void writeVNCPasswordFile(char *pfile, char *password) { fclose(f); } -/* read information that's passed as environmental variables */ -static void readEnvVars(int flags, struct loaderData_s ** ld) { - struct loaderData_s * loaderData = *ld; - char * env; +/* read information from /tmp/netinfo (written by linuxrc) */ +static void readNetInfo(int flags, struct loaderData_s ** ld) { + struct loaderData_s * loaderData = *ld; + FILE *f; + char *end; + char buf[100], *vname, *vparm; - env = getenv("IPADDR"); - if (env && *env) { - loaderData->ip = strdup(env); - loaderData->ipinfo_set = 1; + f = fopen("/tmp/netinfo", "r"); + if (!f) { + return; } - env = getenv("NETMASK"); - if (env && *env) { - loaderData->netmask = strdup(env); - } - env = getenv("GATEWAY"); - if (env && *env) { - loaderData->gateway = strdup(env); - } - env = getenv("DNS"); - if (env && *env) { - loaderData->dns = strdup(env); - } - env = getenv("MTU"); - if (env && *env) { - loaderData->mtu = atoi(env); - } - env = getenv("REMIP"); - if (env && *env) { - loaderData->ptpaddr = strdup(env); + vname = (char *)malloc(sizeof(char)*15); + vparm = (char *)malloc(sizeof(char)*85); + + while(fgets(buf, 100, f)) { + if ((vname = strtok(buf, "="))) { + vparm = strtok(NULL, "="); + while (isspace(*vparm)) + vparm++; + end = strchr(vparm, '\0'); + while (isspace(*end)) + end--; + end++; + *end = '\0'; + if (strstr(vname, "IPADDR")) { + loaderData->ip = strdup(vparm); + loaderData->ipinfo_set = 1; + } + if (strstr(vname, "NETMASK")) { + loaderData->netmask = strdup(vparm); + } + if (strstr(vname, "GATEWAY")) { + loaderData->gateway = strdup(vparm); + } + if (strstr(vname, "DNS")) { + loaderData->dns = strdup(vparm); + } + if (strstr(vname, "MTU")) { + loaderData->mtu = atoi(vparm); + } + if (strstr(vname, "REMIP")) { + loaderData->ptpaddr = strdup(vparm); + } + } } + fclose(f); } /* parses /proc/cmdline for any arguments which are important to us. @@ -528,7 +545,7 @@ static int parseCmdLineFlags(int flags, struct loaderData_s * loaderData, } } - readEnvVars(flags, &loaderData); + readNetInfo(flags, &loaderData); /* NULL terminates the array of extra args */ extraArgs[numExtraArgs] = NULL; @@ -912,6 +929,19 @@ static void migrate_runtime_directory(char * dirname) { } +static int hasGraphicalOverride(char *extraArgs[]) { + int i; + + if (getenv("DISPLAY")) + return 1; + + for (i = 0; extraArgs[i] != NULL; i++) { + if (!strncasecmp(extraArgs[i], "--vnc", 5)) + return 1; + } + return 0; +} + int main(int argc, char ** argv) { int flags = 0; struct stat sb; @@ -958,6 +988,14 @@ int main(int argc, char ** argv) { if (!strcmp(argv[0] + strlen(argv[0]) - 5, "rmmod")) return combined_insmod_main(argc, argv); + if (!testing && !access("/var/run/loader.run", R_OK)) { + printf(_("loader has already been run. Starting shell.")); + execl("/bin/sh", "-/bin/sh", NULL); + exit(0); + } + i = open("/var/run/loader.run", O_CREAT | O_TRUNC | O_RDWR, 0600); + close(i); + /* The fstat checks disallows serial console if we're running through a pty. This is handy for Japanese. */ fstat(0, &sb); @@ -999,7 +1037,7 @@ int main(int argc, char ** argv) { extraArgs[0] = NULL; flags = parseCmdLineFlags(flags, &loaderData, cmdLine, extraArgs); - if (FL_SERIAL(flags) && !getenv("DISPLAY")) + if (FL_SERIAL(flags) && !hasGraphicalOverride(extraArgs)) flags |= LOADER_FLAGS_TEXT; setupRamfs(); @@ -1173,6 +1211,11 @@ int main(int argc, char ** argv) { else *argptr++ = "/usr/bin/anaconda"; + /* make sure /tmp/updates exists so that magic in anaconda to */ + /* symlink rhpl/ will work */ + if (access("/tmp/updates", F_OK)) + mkdirChain("/tmp/updates"); + logMessage("Running anaconda script %s", *(argptr-1)); *argptr++ = "-m"; @@ -1265,10 +1308,42 @@ int main(int argc, char ** argv) { closeLog(); if (!FL_TESTING(flags)) { + int pid, status, rc; + char *buf = sdupprintf(_("Running anaconda, the %s system installer - please wait...\n"), getProductName()); printf("%s", buf); - execv(anacondaArgs[0], anacondaArgs); - perror("exec"); + + if (!(pid = fork())) { + execv(anacondaArgs[0], anacondaArgs); + fprintf(stderr, "exec of anaconda failed: %s", strerror(errno)); + exit(1); + } + + waitpid(pid, &status, 0); + + if (!WIFEXITED(status) || WEXITSTATUS(status)) + rc = 1; + else + rc = 0; + +#if defined(__s390__) || defined(__s390x__) + /* FIXME: we have to send a signal to linuxrc on s390 so that shutdown + * can happen. this is ugly */ + FILE * f; + f = fopen("/var/run/init.pid", "r"); + if (!f) { + logMessage("can't find init.pid, guessing that init is pid 1"); + pid = 1; + } else { + char * buf = malloc(256); + fgets(buf, 256, f); + pid = atoi(buf); + } + kill(pid, SIGUSR1); + return rc; +#else + return rc; +#endif } #if 0 else { |