diff options
Diffstat (limited to 'mdk-stage1')
-rw-r--r-- | mdk-stage1/.cvsignore | 1 | ||||
-rw-r--r-- | mdk-stage1/Makefile | 4 | ||||
-rw-r--r-- | mdk-stage1/frontend.h | 2 | ||||
-rw-r--r-- | mdk-stage1/newt-frontend.c | 4 | ||||
-rw-r--r-- | mdk-stage1/rescue-gui.c | 206 | ||||
-rw-r--r-- | mdk-stage1/stdio-frontend.c | 4 |
6 files changed, 221 insertions, 0 deletions
diff --git a/mdk-stage1/.cvsignore b/mdk-stage1/.cvsignore index 36f56f6b5..af2397e4b 100644 --- a/mdk-stage1/.cvsignore +++ b/mdk-stage1/.cvsignore @@ -9,3 +9,4 @@ debug.log mkinitrd_helper.tar.bz2 hack_* stage1-usbnet +rescue-gui diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 3b1482724..1e4b25653 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -236,6 +236,10 @@ tar-mkinitrd_helper: clean tar cfj mkinitrd_helper.tar.bz2 mkinitrd_helper-subdir --exclude CVS rm -rf mkinitrd_helper-subdir +rescue-gui: rescue-gui.o frontend-common.o $(FRONTEND_LINK) $(STAGE1_LIBC) + $(CC) $(LDFLAGS_STAGE1) -o $@ $^ + $(STRIPCMD) $@ + .depend: $(CPP) $(CFLAGS) -M $(ALLSRC) > .depend diff --git a/mdk-stage1/frontend.h b/mdk-stage1/frontend.h index 167291798..9c2609281 100644 --- a/mdk-stage1/frontend.h +++ b/mdk-stage1/frontend.h @@ -41,6 +41,8 @@ enum return_type ask_from_list(char *msg, char ** elems, char ** choice); enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_comments, char ** choice); enum return_type ask_from_entries(char *msg, char ** questions, char *** answers, int entry_size, void (*callback_func)(char ** strings)); +void suspend_to_console(void); +void resume_from_suspend(void); void verror_message(char *msg, va_list ap); void vinfo_message(char *msg, va_list ap); diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c index e0bc7c5ce..15221c91f 100644 --- a/mdk-stage1/newt-frontend.c +++ b/mdk-stage1/newt-frontend.c @@ -390,3 +390,7 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers return RETURN_OK; } + + +void suspend_to_console(void) { newtSuspend(); } +void resume_from_suspend(void) { newtResume(); } diff --git a/mdk-stage1/rescue-gui.c b/mdk-stage1/rescue-gui.c new file mode 100644 index 000000000..bed0b403c --- /dev/null +++ b/mdk-stage1/rescue-gui.c @@ -0,0 +1,206 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2001 MandrakeSoft + * + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#define _USE_BSD +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <sys/mount.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/unistd.h> +#include <sys/select.h> + +#include "config-stage1.h" +#include "frontend.h" +#include "tools.h" + +char * env[] = { + "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sbin:/mnt/usr/sbin:/mnt/bin:/mnt/usr/bin", + "LD_LIBRARY_PATH=/lib:/usr/lib:/mnt/lib:/mnt/usr/lib:/usr/X11R6/lib:/mnt/usr/X11R6/lib", + "HOME=/", + "TERM=linux", + "TERMINFO=/etc/terminfo", + NULL +}; + +void pause(void) { unsigned char t; fflush(stdout); read(0, &t, 1); } + + +/* ------ UUURGH this is duplicated from `init.c', don't edit here........ */ +static inline _syscall3(int, reboot, int, magic, int, magic2, int, flag); +#define LOOP_CLR_FD 0x4C01 +void del_loop(char *device) +{ + int fd; + if ((fd = open(device, O_RDONLY, 0)) < 0) { + printf("del_loop open failed\n"); + return; + } + + if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { + printf("del_loop ioctl failed"); + return; + } + + close(fd); +} +struct filesystem { char * dev; char * name; char * fs; int mounted; }; +void unmount_filesystems(void) +{ + int fd, size; + char buf[65535]; /* this should be big enough */ + char *p; + struct filesystem fs[500]; + int numfs = 0; + int i, nb; + + printf("unmounting filesystems...\n"); + + fd = open("/proc/mounts", O_RDONLY, 0); + if (fd < 1) { + printf("ERROR: failed to open /proc/mounts"); + sleep(2); + return; + } + + size = read(fd, buf, sizeof(buf) - 1); + buf[size] = '\0'; + + close(fd); + + p = buf; + while (*p) { + fs[numfs].mounted = 1; + fs[numfs].dev = p; + while (*p != ' ') p++; + *p++ = '\0'; + fs[numfs].name = p; + while (*p != ' ') p++; + *p++ = '\0'; + fs[numfs].fs = p; + while (*p != ' ') p++; + *p++ = '\0'; + while (*p != '\n') p++; + p++; + if (strcmp(fs[numfs].name, "/") != 0) numfs++; /* skip if root, no need to take initrd root in account */ + } + + /* Pixel's ultra-optimized sorting algorithm: + multiple passes trying to umount everything until nothing moves + anymore (a.k.a holy shotgun method) */ + do { + nb = 0; + for (i = 0; i < numfs; i++) { + /*printf("trying with %s\n", fs[i].name);*/ + if (fs[i].mounted && umount(fs[i].name) == 0) { + if (strncmp(fs[i].dev + sizeof("/dev/") - 1, "loop", + sizeof("loop") - 1) == 0) + del_loop(fs[i].dev); + + printf("\t%s\n", fs[i].name); + fs[i].mounted = 0; + nb++; + } + } + } while (nb); + + for (i = nb = 0; i < numfs; i++) + if (fs[i].mounted) { + printf("\t%s umount failed\n", fs[i].name); + if (strcmp(fs[i].fs, "ext2") == 0) nb++; /* don't count not-ext2 umount failed */ + } + + if (nb) { + printf("failed to umount some filesystems\n"); + while (1); + } +} +/* ------ UUURGH -- end */ + + +int main(int argc, char **argv) +{ + enum return_type results; + + char install_bootloader[] = "Re-install Boot Loader"; + char mount_parts[] = "Mount your partitions under /mnt"; + char go_to_console[] = "Go to console"; + char reboot_[] = "Reboot"; + + char * actions[] = { install_bootloader, mount_parts, go_to_console, reboot_, NULL }; + char * choice; + + init_frontend("Welcome to " DISTRIB_NAME " Rescue (" VERSION ") " __DATE__ " " __TIME__); + + do { + int pid; + char * binary = NULL; + + choice = ""; + results = ask_from_list("Please choose the desired action.", actions, &choice); + + if (ptr_begins_static_str(choice, install_bootloader)) { + binary = "/usr/bin/install_bootloader"; + } + if (ptr_begins_static_str(choice, mount_parts)) { + binary = "/usr/bin/guessmounts"; + } + if (ptr_begins_static_str(choice, reboot_)) { + finish_frontend(); + unmount_filesystems(); + printf("rebooting system\n"); + sleep(2); + reboot(0xfee1dead, 672274793, 0x01234567); + } + + if (binary) { + int wait_status; + suspend_to_console(); + if (!(pid = fork())) { + + char * child_argv[2]; + child_argv[0] = binary; + child_argv[1] = NULL; + + execve(child_argv[0], child_argv, env); + printf("Can't execute binary (%s)\n<press Enter>\n", binary); + pause(); + + return 33; + } + while (wait4(-1, &wait_status, 0, NULL) != pid) {}; + printf("<press Enter to return to Rescue GUI>"); + pause(); + resume_from_suspend(); + if (!WIFEXITED(wait_status) || WEXITSTATUS(wait_status) != 0) { + error_message("Program exited abnormally (return code %d).", WEXITSTATUS(wait_status)); + if (WIFSIGNALED(wait_status)) + error_message("(received signal %d)", WTERMSIG(wait_status)); + } + } + + } while (results == RETURN_OK && !ptr_begins_static_str(choice, go_to_console)); + + finish_frontend(); + printf("Bye.\n"); + + return 0; +} diff --git a/mdk-stage1/stdio-frontend.c b/mdk-stage1/stdio-frontend.c index 0eda5d76c..83e8fd76d 100644 --- a/mdk-stage1/stdio-frontend.c +++ b/mdk-stage1/stdio-frontend.c @@ -360,3 +360,7 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers return RETURN_OK; } } + + +void suspend_to_console(void) {} +void resume_from_suspend(void) {} |