diff options
Diffstat (limited to 'mdk-stage1/init.c')
-rw-r--r-- | mdk-stage1/init.c | 92 |
1 files changed, 86 insertions, 6 deletions
diff --git a/mdk-stage1/init.c b/mdk-stage1/init.c index 3f912c2ac..6d571a62a 100644 --- a/mdk-stage1/init.c +++ b/mdk-stage1/init.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <unistd.h> #include <stdio.h> +#include <dirent.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> @@ -378,7 +379,86 @@ int in_reboot(void) return 0; } -int exit_value_proceed = 66; +int recursive_remove(char *file); +int recursive_remove(char *file) +{ + struct stat sb; + + if (lstat(file, &sb) != 0) { + printf("failed to stat %s: %d\n", file, errno); + return -1; + } + + /* only descend into subdirectories if device is same as dir */ + if (S_ISDIR(sb.st_mode)) { + char * strBuf = alloca(strlen(file) + 1024); + DIR * dir; + struct dirent * d; + + if (!(dir = opendir(file))) { + printf("error opening %s: %d\n", file, errno); + return -1; + } + while ((d = readdir(dir))) { + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + strcpy(strBuf, file); + strcat(strBuf, "/"); + strcat(strBuf, d->d_name); + + if (recursive_remove(strBuf) != 0) { + closedir(dir); + return -1; + } + } + closedir(dir); + + if (rmdir(file)) { + printf("failed to rmdir %s: %d\n", file, errno); + return -1; + } + } else { + if (unlink(file) != 0) { + printf("failed to remove %s: %d\n", file, errno); + return -1; + } + } + return 0; +} + + +int create_initial_fs_symlinks(char* symlinks) +{ + FILE *f; + char buf[5000]; + + if (!(f = fopen(symlinks, "rb"))) { + printf("Error opening symlink definitions file '%s'\n", symlinks); + return -1; + } + while (fgets(buf, sizeof(buf), f)) { + char oldpath[500], newpath[500]; + struct stat sb; + + buf[strlen(buf)-1] = '\0'; // trim \n + if (sscanf(buf, "%s %s", oldpath, newpath) != 2) { + sprintf(oldpath, "%s%s", STAGE2_LOCATION, buf); + sprintf(newpath, "%s", buf); + } + if (lstat(newpath, &sb) == 0) + recursive_remove(newpath); + printf("Creating symlink %s -> %s\n", oldpath, newpath); + if (symlink(oldpath, newpath)) { + printf("Error creating symlink\n"); + return -1; + } + } + fclose(f); + return 0; +} + + int exit_value_restart = 0x35; int main(int argc, char **argv) @@ -454,12 +534,12 @@ int main(int argc, char **argv) if (!testing) doklog(); - /* Go into normal init mode - keep going, and then do a orderly shutdown - when: + if (create_initial_fs_symlinks(STAGE2_LOCATION "/usr/share/symlinks") != 0) + fatal_error("Fatal error finishing initialization (could not create symlinks)."); + + if (mount(STAGE2_LOCATION "/usr", "/usr", "none", MS_BIND|MS_RDONLY, NULL)) + fatal_error("Unable to bind mount /usr filesystem from rescue or installer stage2"); - 1) install exits - 2) we receive a SIGHUP - */ do { if (counter == 1) { |