diff options
author | Guillaume Cottenceau <gc@mandriva.com> | 2000-12-07 23:16:19 +0000 |
---|---|---|
committer | Guillaume Cottenceau <gc@mandriva.com> | 2000-12-07 23:16:19 +0000 |
commit | 0c0b00ab8086c07600680d41e2f8feefe0f8f150 (patch) | |
tree | 0da2100a6944b5efed0aa02d950d98a071bec0cc | |
parent | 71d6a65fa155d25fc325d6a9b83a746f5845922e (diff) | |
download | drakx-0c0b00ab8086c07600680d41e2f8feefe0f8f150.tar drakx-0c0b00ab8086c07600680d41e2f8feefe0f8f150.tar.gz drakx-0c0b00ab8086c07600680d41e2f8feefe0f8f150.tar.bz2 drakx-0c0b00ab8086c07600680d41e2f8feefe0f8f150.tar.xz drakx-0c0b00ab8086c07600680d41e2f8feefe0f8f150.zip |
first draft can detect your cdrom drives
soon will launch the stage2
-rw-r--r-- | mdk-stage1/Makefile | 23 | ||||
-rw-r--r-- | mdk-stage1/cdrom.c | 93 | ||||
-rw-r--r-- | mdk-stage1/cdrom.h | 29 | ||||
-rw-r--r-- | mdk-stage1/disk.c | 91 | ||||
-rw-r--r-- | mdk-stage1/disk.h | 27 | ||||
-rw-r--r-- | mdk-stage1/frontend.h | 34 | ||||
-rw-r--r-- | mdk-stage1/init.c | 198 | ||||
-rw-r--r-- | mdk-stage1/log.c | 48 | ||||
-rw-r--r-- | mdk-stage1/log.h | 8 | ||||
-rw-r--r-- | mdk-stage1/mar/Makefile | 13 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-extract-only.c | 43 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-extract-only.h | 6 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-frontend.c | 18 | ||||
-rw-r--r-- | mdk-stage1/mar/mar.h | 3 | ||||
-rw-r--r-- | mdk-stage1/minilibc.c | 16 | ||||
-rw-r--r-- | mdk-stage1/minilibc.h | 4 | ||||
-rw-r--r-- | mdk-stage1/modules.c | 203 | ||||
-rw-r--r-- | mdk-stage1/modules.h | 33 | ||||
-rw-r--r-- | mdk-stage1/network.c | 46 | ||||
-rw-r--r-- | mdk-stage1/network.h | 30 | ||||
-rw-r--r-- | mdk-stage1/newt-frontend.c | 149 | ||||
-rw-r--r-- | mdk-stage1/probing.c | 301 | ||||
-rw-r--r-- | mdk-stage1/probing.h | 44 | ||||
-rw-r--r-- | mdk-stage1/stage1.c | 180 | ||||
-rw-r--r-- | mdk-stage1/stage1.h | 61 | ||||
-rw-r--r-- | mdk-stage1/tools.c | 71 | ||||
-rw-r--r-- | mdk-stage1/tools.h | 30 |
27 files changed, 1575 insertions, 227 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index a1b2fc68f..beefda163 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -29,7 +29,7 @@ ARCH := $(patsubst sparc%,sparc,$(ARCH)) #- We can leave "-g" forever since stripping will remove everything CFLAGS = -Os -g -Wall -Werror -fomit-frame-pointer INCLUDES = -I. -DEFS = -D_GNU_SOURCE=1 -DVERSION=\"$(VERSION)\" -DUSE_LOGDEV -DSPAWN_SHELL +DEFS = -D_GNU_SOURCE=1 -DVERSION=\"$(VERSION)\" COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CFLAGS) @@ -41,12 +41,12 @@ INITOBJS = $(subst .c,.o,$(INITSRC)) #- stage1 itself (minus stage1.c) -STAGE1SRC = log.c #cdrom.c devices.c +STAGE1SRC = log.c tools.c modules.c probing.c newt-frontend.c cdrom.c disk.c network.c -STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC)) +STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC)) insmod-busybox/libinsmod.a mar/libmar.a /usr/lib/libnewt.a /usr/lib/libslang.a /usr/lib/libz.a -ALLSRC = $(INITSRC) $(STAGE1SRC) +ALLSRC = $(INITSRC) $(STAGE1SRC) stage1.c ifeq (i386, $(ARCH)) @@ -81,13 +81,12 @@ BINS = init stage1-network #BINS += stage1-all #endif -DIRS = mar +DIRS = mar insmod-busybox all: dirs $(BINS) dirs: - @echo -e "*** BUILDING in all directories\n" @for n in . $(DIRS); do \ [ "$$n" = "." ] || make -C $$n ;\ done @@ -95,20 +94,24 @@ dirs: init: $(INITOBJS) $(CC) $(LDFLAGS_INIT) -o $@ $(INITOBJS) + strip -s $@ -stage1-network: $(STAGE1OBJS) stage1-network.o $(NETOBJS) - $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS) stage1-network.o $(NETOBJS) +stage1-network: stage1-network.o $(STAGE1OBJS) $(NETOBJS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $^ + strip -s $@ +stage1-network-diet: $(STAGE1OBJS) stage1-network.o $(NETOBJS) + gcc -nostdlib -o $@ ../../../tmp/dietlibc/start.o $^ ../../../tmp/dietlibc/dietlibc.a + strip -s $@ .c.o: $(COMPILE) -c $< stage1-network.o: stage1.c - $(COMPILE) -DNETWORK_INSTALL -o $@ -c $< + $(COMPILE) -c $< -o $@ clean: - @echo -e "*** CLEANING in all directories\n" @for n in $(DIRS); do \ (cd $$n; make clean) \ done diff --git a/mdk-stage1/cdrom.c b/mdk-stage1/cdrom.c new file mode 100644 index 000000000..e794dc9f5 --- /dev/null +++ b/mdk-stage1/cdrom.c @@ -0,0 +1,93 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include "stage1.h" +#include "frontend.h" +#include "modules.h" +#include "probing.h" +#include "log.h" + +#include "cdrom.h" + +static enum return_type try_with_device(char *dev_name) +{ + log_message("with dev %s", dev_name); + + error_message("Should be trying with sucking device."); + + return RETURN_OK; +} + +enum return_type cdrom_prepare(void) +{ + char ** medias, ** ptr, ** medias_models; + char * choice; + int i, count = 0; + enum return_type results; + + my_insmod("ide-cd"); + my_insmod("sr_mod"); + my_insmod("isofs"); + + medias = get_medias(CDROM, QUERY_NAME); + + ptr = medias; + while (ptr && *ptr) { + log_message("found CDROM %s", *ptr); + count++; + ptr++; + } + + if (count == 0) { + error_message("No CDROM device found."); + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return cdrom_prepare(); + } + + if (count == 1) { + results = try_with_device(*medias); + if (results == RETURN_OK) + return RETURN_OK; + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return cdrom_prepare(); + } + + medias_models = get_medias(CDROM, QUERY_MODEL); + + results = ask_from_list_comments("Please choose the CDROM drive to use for the installation.", medias, medias_models, &choice); + + if (results != RETURN_OK) + return results; + + results = try_with_device(choice); + if (results == RETURN_OK) + return RETURN_OK; + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return cdrom_prepare(); +} diff --git a/mdk-stage1/cdrom.h b/mdk-stage1/cdrom.h new file mode 100644 index 000000000..639487eed --- /dev/null +++ b/mdk-stage1/cdrom.h @@ -0,0 +1,29 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _CDROM_H_ +#define _CDROM_H_ + +#include "stage1.h" + +enum return_type cdrom_prepare(void); + +#endif diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c new file mode 100644 index 000000000..e64782471 --- /dev/null +++ b/mdk-stage1/disk.c @@ -0,0 +1,91 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include "stage1.h" +#include "frontend.h" +#include "modules.h" +#include "probing.h" +#include "log.h" + +#include "disk.h" + +static enum return_type try_with_device(char *dev_name) +{ + + return RETURN_OK; +} + +enum return_type disk_prepare(void) +{ + char ** medias, ** ptr, ** medias_models; + char * choice; + int i, count = 0; + enum return_type results; + + my_insmod("sd_mod"); + my_insmod("vfat"); + my_insmod("reiserfs"); + + medias = get_medias(DISK, QUERY_NAME); + + /* TODO partition check */ + ptr = medias; + while (ptr && *ptr) { + log_message("found DISK %s", *ptr); + count++; + ptr++; + } + + if (count == 0) { + error_message("No DISK drive found."); + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return disk_prepare(); + } + + if (count == 1) { + results = try_with_device(*medias); + if (results == RETURN_OK) + return RETURN_OK; + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return disk_prepare(); + } + + medias_models = get_medias(DISK, QUERY_MODEL); + + results = ask_from_list_comments("Please choose the DISK drive to use for the installation.", medias, medias_models, &choice); + + if (results != RETURN_OK) + return results; + + results = try_with_device(choice); + if (results == RETURN_OK) + return RETURN_OK; + i = ask_scsi_insmod(); + if (i == RETURN_BACK) + return RETURN_BACK; + return disk_prepare(); +} diff --git a/mdk-stage1/disk.h b/mdk-stage1/disk.h new file mode 100644 index 000000000..54213cf68 --- /dev/null +++ b/mdk-stage1/disk.h @@ -0,0 +1,27 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _DISK_H_ +#define _DISK_H_ + +enum return_type disk_prepare(void); + +#endif diff --git a/mdk-stage1/frontend.h b/mdk-stage1/frontend.h new file mode 100644 index 000000000..27b858a51 --- /dev/null +++ b/mdk-stage1/frontend.h @@ -0,0 +1,34 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Each different frontend must implement all functions defined here + */ + + +#ifndef _FRONTEND_H_ +#define _FRONTEND_H_ + +#include "stage1.h" + +void init_frontend(void); +void finish_frontend(void); +void error_message(char *msg); +void wait_message(char *msg, ...); +void remove_wait_message(void); + +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); + +#endif diff --git a/mdk-stage1/init.c b/mdk-stage1/init.c index 7a0363c3f..3783bc8c7 100644 --- a/mdk-stage1/init.c +++ b/mdk-stage1/init.c @@ -34,12 +34,12 @@ #define ENV_DEBUG 4 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=/", - "TERMINFO=/etc/linux-terminfo", - NULL + "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 }; @@ -73,7 +73,11 @@ void print_warning(char *msg) } -void doklog(char * fn) +/* fork to: + * (1) watch /proc/kmsg and copy the stuff to /dev/tty4 + * (2) listens to /dev/log and copy also this stuff (log from programs) + */ +void doklog() { fd_set readset, unixs; int in, out, i; @@ -86,28 +90,24 @@ void doklog(char * fn) /* open kernel message logger */ in = open("/proc/kmsg", O_RDONLY,0); - if (in < 0) - { + if (in < 0) { print_error("could not open /proc/kmsg"); return; } - - out = open(fn, O_WRONLY, 0); + + out = open("/dev/tty4", O_WRONLY, 0); if (out < 0) print_warning("couldn't open tty for syslog -- still using /tmp/syslog\n"); - + log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644); - if (log < 0) - { + if (log < 0) { print_error("error opening /tmp/syslog"); sleep(5); return; } - /* if we get this far, we should be in good shape */ - if (fork()) - { + if (fork()) { /* parent */ close(in); close(out); @@ -116,7 +116,7 @@ void doklog(char * fn) return; } - printf("logging process forked.\n"); + printf("kernel logging process forked.\n"); close(0); close(1); @@ -124,39 +124,38 @@ void doklog(char * fn) dup2(1, log); -#if defined(USE_LOGDEV) /* now open the syslog socket */ sockaddr.sun_family = AF_UNIX; - strcpy(sockaddr.sun_path, "/dev/log"); + strncpy(sockaddr.sun_path, "/dev/log", UNIX_PATH_MAX); sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - { + if (sock < 0) { printf("error creating socket: %d\n", errno); sleep(5); } - printf("got socket\n"); - if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) + - strlen(sockaddr.sun_path))) - { - printf("bind error: %d\n", errno); + print_str(log, "] got socket\n"); + if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) + strlen(sockaddr.sun_path))) { + print_str(log, "] bind error: "); + print_int(log, errno); + print_str(log, "\n"); sleep(5); } - printf("bound socket\n"); + print_str(log, "] bound socket\n"); chmod("/dev/log", 0666); - if (listen(sock, 5)) - { - printf("listen error: %d\n", errno); + if (listen(sock, 5)) { + print_str(log, "] listen error: "); + print_int(log, errno); + print_str(log, "\n"); sleep(5); } -#endif + /* disable on-console syslog output */ syslog(8, NULL, 1); + print_str(log, "] kernel/system logger ok\n"); FD_ZERO(&unixs); - while (1) - { + while (1) { memcpy(&readset, &unixs, sizeof(unixs)); if (sock >= 0) FD_SET(sock, &readset); @@ -164,59 +163,53 @@ void doklog(char * fn) i = select(20, &readset, NULL, NULL, NULL); if (i <= 0) continue; - - if (FD_ISSET(in, &readset)) - { + + /* has /proc/kmsg things to tell us? */ + if (FD_ISSET(in, &readset)) { i = read(in, buf, sizeof(buf)); - if (i > 0) - { + if (i > 0) { if (out >= 0) write(out, buf, i); write(log, buf, i); } } - - for (readfd = 0; readfd < 20; ++readfd) - { - if (FD_ISSET(readfd, &readset) && FD_ISSET(readfd, &unixs)) - { + + /* examine some fd's in the hope to find some syslog outputs from programs */ + for (readfd = 0; readfd < 20; ++readfd) { + if (FD_ISSET(readfd, &readset) && FD_ISSET(readfd, &unixs)) { + print_str(log, "] one fd moves: "); + print_int(log, readfd); + print_str(log, "\n"); i = read(readfd, buf, sizeof(buf)); - if (i > 0) - { - if (out >= 0) - { + if (i > 0) { + if (out >= 0) { write(out, buf, i); - write(out, "\n", 1); + write(out, "\n", 1); } - + write(log, buf, i); write(log, "\n", 1); + } else if (i == 0) { + /* socket closed */ + close(readfd); + FD_CLR(readfd, &unixs); } - else - if (i == 0) - { - /* socket closed */ - close(readfd); - FD_CLR(readfd, &unixs); - } } } - if (sock >= 0 && FD_ISSET(sock, &readset)) - { + /* the socket has moved, new stuff to do */ + if (sock >= 0 && FD_ISSET(sock, &readset)) { + print_str(log, "] syslog socket moved\n"); s = sizeof(sockaddr); readfd = accept(sock, (struct sockaddr *) &sockaddr, &s); - if (readfd < 0) - { - char * msg_error = "error in accept\n"; + if (readfd < 0) { + char * msg_error = "] error in accept\n"; if (out >= 0) write(out, msg_error, strlen(msg_error)); write(log, msg_error, strlen(msg_error)); close(sock); sock = -1; } else - { FD_SET(readfd, &unixs); - } } } } @@ -225,14 +218,12 @@ void doklog(char * fn) void del_loop(char *device) { int fd; - if ((fd = open(device, O_RDONLY, 0)) < 0) - { + if ((fd = open(device, O_RDONLY, 0)) < 0) { printf("del_loop open failed\n"); return; } - if (ioctl(fd, LOOP_CLR_FD, 0) < 0) - { + if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { printf("del_loop ioctl failed"); return; } @@ -248,6 +239,7 @@ struct filesystem int mounted; }; +/* attempt to unmount all filesystems in /proc/mounts */ void unmount_filesystems(void) { int fd, size; @@ -260,8 +252,7 @@ void unmount_filesystems(void) printf("unmounting filesystems...\n"); fd = open("/proc/mounts", O_RDONLY, 0); - if (fd < 1) - { + if (fd < 1) { print_error("failed to open /proc/mounts"); sleep(2); return; @@ -273,8 +264,7 @@ void unmount_filesystems(void) close(fd); p = buf; - while (*p) - { + while (*p) { fs[numfs].mounted = 1; fs[numfs].dev = p; while (*p != ' ') p++; @@ -293,14 +283,11 @@ void unmount_filesystems(void) /* Pixel's ultra-optimized sorting algorithm: multiple passes trying to umount everything until nothing moves anymore (a.k.a holy shotgun method) */ - do - { + do { nb = 0; - for (i = 0; i < numfs; i++) - { + for (i = 0; i < numfs; i++) { /*printf("trying with %s\n", fs[i].name);*/ - if (fs[i].mounted && umount(fs[i].name) == 0) - { + 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); @@ -311,16 +298,14 @@ void unmount_filesystems(void) } } } while (nb); - + for (i = nb = 0; i < numfs; i++) - if (fs[i].mounted) - { + 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) - { + if (nb) { printf("failed to umount some filesystems\n"); while (1); } @@ -338,8 +323,7 @@ void disable_swap(void) printf("disabling swap...\n"); fd = open("/proc/swaps", O_RDONLY, 0); - if (fd < 0) - { + if (fd < 0) { print_warning("failed to open /proc/swaps"); return; } @@ -347,16 +331,14 @@ void disable_swap(void) /* read all data at once */ i = read(fd, buf, sizeof(buf) - 1); close(fd); - if (i < 0) - { + if (i < 0) { print_warning("failed to read /proc/swaps"); return; } buf[i] = '\0'; start = buf; - while (*start) - { + while (*start) { /* move to next line */ while (*start != '\n' && *start) start++; if (!*start) return; @@ -394,8 +376,7 @@ int main(int argc, char **argv) /* getpid() != 1 should work, by linuxrc tends to get a larger pid */ testing = (getpid() > 50); - if (!testing) - { + if (!testing) { /* turn off screen blanking */ printf("\033[9;0]"); printf("\033[8]"); @@ -408,8 +389,7 @@ int main(int argc, char **argv) printf("VERSION: %s\n", VERSION); - if (!testing) - { + if (!testing) { printf("mounting /proc filesystem... "); if (mount("/proc", "/proc", "proc", 0, NULL)) fatal_error("Unable to mount proc filesystem"); @@ -422,8 +402,7 @@ int main(int argc, char **argv) signal(SIGTSTP, SIG_IGN); - if (!testing) - { + if (!testing) { fd = open("/dev/tty1", O_RDWR, 0); if (fd < 0) /* try with devfs */ @@ -444,8 +423,7 @@ int main(int argc, char **argv) if (ioctl(0, TIOCSCTTY, NULL)) print_error("could not set new controlling tty"); - if (!testing) - { + if (!testing) { char * my_hostname = "localhost.localdomain"; sethostname(my_hostname, strlen(my_hostname)); /* the default domainname (as of 2.0.35) is "(none)", which confuses @@ -454,19 +432,19 @@ int main(int argc, char **argv) } if (!testing) - doklog("/dev/tty4"); + doklog(); /* Go into normal init mode - keep going, and then do a orderly shutdown when: - 1) /bin/install exits + 1) install exits 2) we receive a SIGHUP */ - + + printf("Remember what Warly said: drink white part of an egg each morning builds a man!\n"); printf("running stage1...\n"); - if (!(installpid = fork())) - { + if (!(installpid = fork())) { /* child */ char * child_argv[2]; child_argv[0] = "/sbin/stage1"; @@ -478,20 +456,16 @@ int main(int argc, char **argv) exit(0); } - while (!end_stage2) - { + while (!end_stage2) { childpid = wait4(-1, &wait_status, 0, NULL); if (childpid == installpid) end_stage2 = 1; } - if (!WIFEXITED(wait_status) || WEXITSTATUS(wait_status)) - { + if (!WIFEXITED(wait_status) || WEXITSTATUS(wait_status)) { printf("install exited abnormally :-( "); if (WIFSIGNALED(wait_status)) - { printf("-- received signal %d", WTERMSIG(wait_status)); - } printf("\n"); abnormal_termination = 1; } @@ -516,15 +490,13 @@ int main(int argc, char **argv) disable_swap(); unmount_filesystems(); - if (!abnormal_termination) - { + if (!abnormal_termination) { printf("rebooting system\n"); sleep(2); + printf("**temp** should be rebooting\n"); while(1); reboot(0xfee1dead, 672274793, 0x1234567); - } - else - { + } else { printf("you may safely reboot your system\n"); while (1); } diff --git a/mdk-stage1/log.c b/mdk-stage1/log.c index 27e77bf02..7536d0a08 100644 --- a/mdk-stage1/log.c +++ b/mdk-stage1/log.c @@ -19,26 +19,29 @@ * */ - +#include <stdlib.h> +#include <unistd.h> #include <fcntl.h> #include <stdarg.h> #include <stdio.h> -#include <stdlib.h> -#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> #include "log.h" static FILE * logfile = NULL; - -void do_log_message(const char * s, va_list args) +void vlog_message_nobs(const char * s, va_list args) { - if (!logfile) return; - fprintf(logfile, "* "); vfprintf(logfile, s, args); +} + +void vlog_message(const char * s, va_list args) +{ + vlog_message_nobs(s, args); fprintf(logfile, "\n"); - fflush(logfile); } @@ -46,25 +49,34 @@ void do_log_message(const char * s, va_list args) void log_message(const char * s, ...) { va_list args; - + + if (!logfile) { + fprintf(stderr, "Log is not open!\n"); + return; + } + va_start(args, s); - do_log_message(s, args); + vlog_message(s, args); va_end(args); return; } +void log_perror(char *msg) +{ + log_message("%s %s", strerror(errno), msg); +} + void open_log(int testing) { - if (!testing) - { - logfile = fopen("/dev/tty3", "w"); - if (!logfile) - logfile = fopen("/tmp/install.log", "a"); - } - else - logfile = fopen("debug.log", "w"); + if (!testing) { + logfile = fopen("/dev/tty3", "w"); + if (!logfile) + logfile = fopen("/tmp/install.log", "a"); + } + else + logfile = fopen("debug.log", "w"); } void close_log(void) diff --git a/mdk-stage1/log.h b/mdk-stage1/log.h index 61daa41be..9be73e83c 100644 --- a/mdk-stage1/log.h +++ b/mdk-stage1/log.h @@ -23,12 +23,12 @@ #ifndef _LOG_H_ #define _LOG_H_ -#include <stdio.h> - -extern FILE * log; -extern int logfd; +#include <stdarg.h> void log_message(const char * s, ...); +void vlog_message(const char * s, va_list args); +void vlog_message_nobs(const char * s, va_list args); +void log_perror(char *msg); void open_log(int useLocal); void close_log(void); diff --git a/mdk-stage1/mar/Makefile b/mdk-stage1/mar/Makefile index c35f50f02..e7f6977ce 100644 --- a/mdk-stage1/mar/Makefile +++ b/mdk-stage1/mar/Makefile @@ -18,7 +18,7 @@ #***************************************************************************** -all: mar +all: libmar.a mar clean: rm -f *.o mar @@ -26,11 +26,18 @@ clean: FLAGS = -Wall -Werror -Os -fomit-frame-pointer -c -mar: mar-frontend.o mar-extract-only.o - gcc -o mar mar-frontend.o mar-extract-only.o -lz +mar: mar-frontend.o mar-extract-only-standalone.o + gcc -o mar mar-frontend.o mar-extract-only-standalone.o -lz + +libmar.a: mar-extract-only.o + ar -cru $@ $^ + ranlib $@ mar-frontend.o: mar-frontend.c mar.h mar-extract-only.h gcc $(FLAGS) mar-frontend.c mar-extract-only.o: mar-extract-only.c mar-extract-only.h mar.h gcc $(FLAGS) mar-extract-only.c + +mar-extract-only-standalone.o: mar-extract-only.c mar-extract-only.h mar.h + gcc $(FLAGS) -o $@ -D_STANDALONE_ mar-extract-only.c diff --git a/mdk-stage1/mar/mar-extract-only.c b/mdk-stage1/mar/mar-extract-only.c index 3627e84bb..b1079880e 100644 --- a/mdk-stage1/mar/mar-extract-only.c +++ b/mdk-stage1/mar/mar-extract-only.c @@ -26,15 +26,34 @@ #include "mar.h" - +#ifdef _STANDALONE_ void gzerr(gzFile f) /* decrease code size */ { fprintf(stderr, gzerror(f, &gz_errnum)); } +void +log_perror(char *msg) +{ + perror(msg); +} +void +log_message(char *msg) +{ + fprintf(stderr, msg); +} +#else /* _STANDALONE_ */ +#include "../log.h" +void +gzerr(gzFile f) /* decrease code size */ +{ + log_message(gzerror(f, &gz_errnum)); +} +#endif /* _STANDALONE_ */ + int -calc_integrity(struct mar_stream *s) +mar_calc_integrity(struct mar_stream *s) { char buf[4096]; int current_crc = 0; @@ -51,20 +70,18 @@ calc_integrity(struct mar_stream *s) gzerr(s->mar_gzfile); return -1; } - DEBUG_MAR(printf("D: mar::calc_integrity more-bytes-to-handle-for-crc %d\n", bytes);); while (bytes > 0) { bytes--; current_crc += buf[bytes]; } } - DEBUG_MAR(printf("D: mar::calc_integrity computed-crc %d\n", current_crc);); return current_crc; } int -extract_file(struct mar_stream *s, char *filename, char *dest_dir) +mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir) { struct mar_element * elem = s->first_element; while (elem) @@ -80,13 +97,13 @@ extract_file(struct mar_stream *s, char *filename, char *dest_dir) fd = creat(dest_file, 00660); if (fd == -1) { - perror(dest_file); + log_perror(dest_file); return -1; } buf = (char *) alloca(elem->file_length); if (!buf) { - perror(dest_file); + log_perror(dest_file); return -1; } if (gzseek(s->mar_gzfile, elem->data_offset, SEEK_SET) != elem->data_offset) @@ -101,7 +118,7 @@ extract_file(struct mar_stream *s, char *filename, char *dest_dir) } if (write(fd, buf, elem->file_length) != elem->file_length) { - perror(dest_file); + log_perror(dest_file); return -1; } close(fd); /* do not check return value for code size */ @@ -114,7 +131,7 @@ extract_file(struct mar_stream *s, char *filename, char *dest_dir) int -open_marfile(char *filename, struct mar_stream *s) +mar_open_file(char *filename, struct mar_stream *s) { int end_filetable = 0; struct mar_element * previous_element = NULL; @@ -123,7 +140,7 @@ open_marfile(char *filename, struct mar_stream *s) s->mar_gzfile = gzopen(filename, "rb"); if (!s->mar_gzfile) { - perror(filename); + log_perror(filename); return -1; } @@ -134,11 +151,10 @@ open_marfile(char *filename, struct mar_stream *s) return -1; } - DEBUG_MAR(printf("D: mar::open_marfile crc-in-marfile %d\n", s->crc32);); /* verify integrity */ - if (s->crc32 != calc_integrity(s)) + if (s->crc32 != mar_calc_integrity(s)) { - fprintf(stderr, "E: mar::open_marfile CRC check failed\n"); + log_message("E: mar::open_marfile CRC check failed"); return -1; } else @@ -167,7 +183,6 @@ open_marfile(char *filename, struct mar_stream *s) { struct mar_element * e = (struct mar_element *) malloc(sizeof(struct mar_element)); e->filename = strdup(buf); - DEBUG_MAR(printf("D: mar::open_marfile processing-file %s\n", e->filename);); /* read file_length */ if (gzread(s->mar_gzfile, &(e->file_length), sizeof(int)) != sizeof(int)) { diff --git a/mdk-stage1/mar/mar-extract-only.h b/mdk-stage1/mar/mar-extract-only.h index f5db6c183..e8a88e96e 100644 --- a/mdk-stage1/mar/mar-extract-only.h +++ b/mdk-stage1/mar/mar-extract-only.h @@ -28,8 +28,8 @@ #include "mar.h" -int open_marfile(char *filename, struct mar_stream *s); -int extract_file(struct mar_stream *s, char *filename, char *dest_dir); -int calc_integrity(struct mar_stream *s); +int mar_open_file(char *filename, struct mar_stream *s); +int mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir); +int mar_calc_integrity(struct mar_stream *s); #endif diff --git a/mdk-stage1/mar/mar-frontend.c b/mdk-stage1/mar/mar-frontend.c index 55550d8a1..79a83a1c3 100644 --- a/mdk-stage1/mar/mar-frontend.c +++ b/mdk-stage1/mar/mar-frontend.c @@ -28,7 +28,7 @@ #include "mar-extract-only.h" void -list_files(struct mar_stream *s) +mar_list_files(struct mar_stream *s) { struct mar_element * elem = s->first_element; printf("%-20s%8s\n", "FILENAME", "LENGTH"); @@ -58,7 +58,7 @@ file_size(char *filename) /* ``files'' is a NULL-terminated array of char* */ int -create_marfile(char *dest_file, char **files) +mar_create_file(char *dest_file, char **files) { int filenum = 0; int current_offset_filetable; @@ -179,27 +179,23 @@ main(int argc, char **argv) if (strcmp(argv[1], "-l") == 0) { struct mar_stream s; - if (open_marfile(argv[2], &s) != 0) + if (mar_open_file(argv[2], &s) != 0) { fprintf(stderr, "E: open-marfile-failed\n"); exit(-1); } - list_files(&s); - if (s.crc32 == calc_integrity(&s)) - printf("CRC OK\n"); - else - printf("CRC FAILED!\n"); + mar_list_files(&s); exit(0); } if ((strcmp(argv[1], "-x") == 0) && argc >= 4) { struct mar_stream s; int i = 3; - if (open_marfile(argv[2], &s) != 0) + if (mar_open_file(argv[2], &s) != 0) exit(-1); while (i < argc) { - int res = extract_file(&s, argv[i], "./"); + int res = mar_extract_file(&s, argv[i], "./"); if (res == 1) fprintf(stderr, "W: file-not-found-in-archive %s\n", argv[i]); if (res == -1) @@ -220,7 +216,7 @@ main(int argc, char **argv) files[argc-3] = NULL; { int results; - results = create_marfile(argv[2], files); + results = mar_create_file(argv[2], files); if (results != 0) fprintf(stderr, "E: create-marfile-failed\n"); exit(results); diff --git a/mdk-stage1/mar/mar.h b/mdk-stage1/mar/mar.h index bd731770b..e9633ab92 100644 --- a/mdk-stage1/mar/mar.h +++ b/mdk-stage1/mar/mar.h @@ -27,7 +27,6 @@ #ifndef MAR_H #define MAR_H -#if 1 #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -36,8 +35,6 @@ #include <fcntl.h> #include <errno.h> #include <unistd.h> -#endif -//#include <minilibc.h> #include <zlib.h> diff --git a/mdk-stage1/minilibc.c b/mdk-stage1/minilibc.c index e7c374105..c98d87e24 100644 --- a/mdk-stage1/minilibc.c +++ b/mdk-stage1/minilibc.c @@ -188,7 +188,7 @@ char * strchr(char * str, int ch) return NULL; } -void print_int(int i) +void print_int(int fd, int i) { char buf[10]; char * chptr = buf + 9; @@ -207,12 +207,12 @@ void print_int(int i) i = i / 10; } - write(1, chptr + 1, j); + write(fd, chptr + 1, j); } -void print_str(char * string) +void print_str(int fd, char * string) { - write(1, string, strlen(string)); + write(fd, string, strlen(string)); } /* Minimum printf which handles only characters, %d's and %s's */ @@ -235,18 +235,18 @@ void printf(char * fmt, ...) if (*chptr == '%') { *chptr++ = '\0'; - print_str(start); + print_str(1, start); switch (*chptr++) { case 's': strarg = va_arg(args, char *); - print_str(strarg); + print_str(1, strarg); break; case 'd': numarg = va_arg(args, int); - print_int(numarg); + print_int(1, numarg); break; } @@ -254,7 +254,7 @@ void printf(char * fmt, ...) } else { - print_str(start); + print_str(1, start); start = NULL; } } diff --git a/mdk-stage1/minilibc.h b/mdk-stage1/minilibc.h index 824ac5d6e..e6743a854 100644 --- a/mdk-stage1/minilibc.h +++ b/mdk-stage1/minilibc.h @@ -136,7 +136,7 @@ int strncmp(const char * a, const char * b, int len); char * strchr(char * str, int ch); char * strncpy(char * dst, const char * src, int len); -void print_str(char * string); -void print_int(int i); +void print_str(int fd, char * string); +void print_int(int fd, int i); /* Minimum printf which handles only characters, %d's and %s's */ void printf(char * fmt, ...); diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c new file mode 100644 index 000000000..cdf50d9eb --- /dev/null +++ b/mdk-stage1/modules.c @@ -0,0 +1,203 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * (1) calculate dependencies + * (2) unarchive relevant modules + * (3) insmod them + */ + +#include <stdlib.h> +#include <unistd.h> +#include "insmod-busybox/insmod.h" +#include "stage1.h" +#include "log.h" +#include "mar/mar-extract-only.h" +#include "frontend.h" + +#include "modules.h" + +static struct module_deps_elem * modules_deps = NULL; + + +/* unarchive and insmod given module + * WARNING: module must not contain the trailing ".o" + */ +int insmod_archived_file(char * mod_name) +{ + char * archive_name = "/modules/modules.mar"; + char module_name[50]; + char final_name[50] = "/tmp/"; + static struct mar_stream s = { 0, NULL, NULL }; + int i; + + /* don't consume too much memory */ + if (s.first_element == NULL) { + if (mar_open_file(archive_name, &s) != 0) { + log_message("open marfile failed"); + return -1; + } + } + + strncpy(module_name, mod_name, sizeof(module_name)); + strncat(module_name, ".o", sizeof(module_name)); + i = mar_extract_file(&s, module_name, "/tmp/"); + if (i == 1) { + log_message("file-not-found-in-archive %s", module_name); + return -1; + } + if (i != 0) + return -1; + + strncat(final_name, mod_name, sizeof(final_name)); + strncat(final_name, ".o", sizeof(final_name)); + + return insmod_call(final_name); +} + + + +int load_modules_dependencies(void) +{ + char * deps_file = "/modules/modules.dep"; + char * buf, * ptr, * start, * end; + struct stat s; + int fd, line, i; + + log_message("loading modules dependencies"); + + if (IS_TESTING) + return 0; + + fd = open(deps_file, O_RDONLY); + if (fd == -1) { + log_perror(deps_file); + return -1; + } + + fstat(fd, &s); + buf = alloca(s.st_size + 1); + if (read(fd, buf, s.st_size) != s.st_size) { + log_perror(deps_file); + return -1; + } + buf[s.st_size] = '\0'; + close(fd); + + ptr = buf; + line = 0; + while (ptr) { + line++; + ptr = strchr(ptr + 1, '\n'); + } + + modules_deps = malloc(sizeof(*modules_deps) * (line+1)); + + start = buf; + line = 0; + while (start < (buf+s.st_size) && *start) { + char * tmp_deps[50]; + + end = strchr(start, '\n'); + *end = '\0'; + + ptr = strchr(start, ':'); + if (!ptr) { + start = end + 1; + continue; + } + *ptr = '\0'; + ptr++; + + while (*ptr && (*ptr == ' ')) ptr++; + if (!*ptr) { + start = end + 1; + continue; + } + + /* sort of a good line */ + modules_deps[line].name = strdup(start); + + start = ptr; + i = 0; + while (start && *start) { + ptr = strchr(start, ' '); + if (ptr) *ptr = '\0'; + tmp_deps[i] = strdup(start); + if (ptr) + start = ptr + 1; + else + start = NULL; + i++; + while (start && *start && *start == ' ') + start++; + } + tmp_deps[i] = NULL; + + modules_deps[line].deps = (char **) malloc(sizeof(char *) * (i+1)); + memcpy(modules_deps[line].deps, tmp_deps, sizeof(char *) * (i+1)); + + line++; + start = end + 1; + } + modules_deps[line].name = NULL; + + return 0; +} + + +int insmod_with_deps(char * mod_name) +{ + struct module_deps_elem * dep; + + dep = modules_deps; + while (dep && dep->name && strcmp(dep->name, mod_name)) dep++; + + if (dep && dep->name && dep->deps) { + char ** one_dep; + one_dep = dep->deps; + while (*one_dep) { + /* here, we can fail but we don't care, if the error is + * important, the desired module will fail also */ + insmod_with_deps(*one_dep); + one_dep++; + } + } + + log_message("needs %s", mod_name); + return insmod_archived_file(mod_name); +} + + +int my_insmod(char * mod_name) +{ + int i; + log_message("have to insmod %s", mod_name); + + if (IS_TESTING) + return 0; + + i = insmod_with_deps(mod_name); + if (i == 0) + log_message("\tsucceeded %s.", mod_name); + return i; + +} + + +enum return_type ask_scsi_insmod(void) +{ + error_message("Try to load a SCSI module"); + return RETURN_OK; +} diff --git a/mdk-stage1/modules.h b/mdk-stage1/modules.h new file mode 100644 index 000000000..cf7eadebe --- /dev/null +++ b/mdk-stage1/modules.h @@ -0,0 +1,33 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +#ifndef _MODULES_H_ +#define _MODULES_H_ + +#include "stage1.h" + +int load_modules_dependencies(void); +int my_insmod(char * mod_name); + +enum return_type ask_scsi_insmod(void); + + +struct module_deps_elem { + char * name; + char ** deps; +}; + + + +#endif diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c new file mode 100644 index 000000000..e6d0c6c4e --- /dev/null +++ b/mdk-stage1/network.c @@ -0,0 +1,46 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include "stage1.h" +#include "frontend.h" +#include "modules.h" +#include "probing.h" +#include "log.h" + +#include "network.h" + + +enum return_type nfs_prepare(void) +{ + return RETURN_ERROR; +} + +enum return_type ftp_prepare(void) +{ + return RETURN_ERROR; +} + +enum return_type http_prepare(void) +{ + return RETURN_ERROR; +} diff --git a/mdk-stage1/network.h b/mdk-stage1/network.h new file mode 100644 index 000000000..bc7e19104 --- /dev/null +++ b/mdk-stage1/network.h @@ -0,0 +1,30 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _NETWORK_H_ +#define _NETWORK_H_ + +enum return_type nfs_prepare(void); +enum return_type ftp_prepare(void); +enum return_type http_prepare(void); + + +#endif diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c new file mode 100644 index 000000000..2c7e5434b --- /dev/null +++ b/mdk-stage1/newt-frontend.c @@ -0,0 +1,149 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + + +/* + * Each different frontend must implement all functions defined in frontend.h + */ + + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include "stage1.h" +#include "log.h" +#include "newt.h" + +#include "frontend.h" + + +void init_frontend(void) +{ + newtInit(); + newtCls(); + + newtDrawRootText(0, 0, "Welcome to Linux-Mandrake (" VERSION ") " __DATE__ " " __TIME__); + + newtPushHelpLine(" <Tab>/<Alt-Tab> between elements, <Space>/<Enter> selects"); +} + + +void finish_frontend(void) +{ + newtFinished(); +} + + +void error_message(char *msg) +{ + newtWinMessage("Error", "Ok", msg); +} + +void wait_message(char *msg, ...) +{ + int width = 36; + int height = 3; + char * title = "Please wait..."; + newtComponent t, f; + char * buf = NULL; + int size = 0; + int i = 0; + va_list args; + + va_start(args, msg); + + do { + size += 1000; + if (buf) free(buf); + buf = malloc(size); + i = vsnprintf(buf, size, msg, args); + } while (i == size); + + va_end(args); + + newtCenteredWindow(width, height, title); + + t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP); + newtTextboxSetText(t, buf); + f = newtForm(NULL, NULL, 0); + + free(buf); + + newtFormAddComponent(f, t); + + newtDrawForm(f); + newtRefresh(); + newtFormDestroy(f); +} + +void remove_wait_message(void) +{ + newtPopWindow(); +} + + +enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_comments, char ** choice) +{ + char * items[50]; + int answer = 0, rc; + char ** sav_elems = elems; + int i; + + i = 0; + while (elems && *elems) { + items[i] = malloc(sizeof(char) * (strlen(*elems) + strlen(*elems_comments) + 3)); + strcpy(items[i], *elems); + strcat(items[i], " ("); + strcat(items[i], *elems_comments); + strcat(items[i], ")"); + i++; + elems++; + elems_comments++; + } + items[i] = NULL; + + rc = newtWinMenu("Please choose...", msg, 52, 5, 5, 7, items, &answer, "Ok", "Cancel", NULL); + + if (rc == 2) + return RETURN_BACK; + + *choice = strdup(sav_elems[answer]); + + return RETURN_OK; +} + + +enum return_type ask_from_list(char *msg, char ** elems, char ** choice) +{ + int answer = 0, rc; + + rc = newtWinMenu("Please choose...", msg, 52, 5, 5, 7, elems, &answer, "Ok", "Cancel", NULL); + + if (rc == 2) + return RETURN_BACK; + + *choice = strdup(elems[answer]); + + return RETURN_OK; +} + diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c new file mode 100644 index 000000000..29ffdcd7c --- /dev/null +++ b/mdk-stage1/probing.c @@ -0,0 +1,301 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + + +/* + * This contains stuff related to probing: + * (1) PCI devices + * (2) IDE media + * (3) SCSI media + */ + + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "log.h" +#include "frontend.h" +#include "modules.h" + +#include "probing.h" + + +static void pci_probing(enum driver_type type) +{ + if (IS_EXPERT) { + error_message("You should be asked if you have some SCSI."); + } else { + wait_message("Installing SCSI module..."); + my_insmod("advansys"); + remove_wait_message(); + } +} + + +static struct media_info * medias = NULL; + +static void find_media(void) +{ + char b[50]; + char buf[500]; + struct media_info tmp[50]; + int count; + int fd; + + if (medias) + return; + + /* ----------------------------------------------- */ + log_message("looking for ide media"); + + count = 0; + strcpy(b, "/proc/ide/hda"); + for (; b[12] <= 'm'; b[12]++) { + int i; + + /* first, test if file exists (will tell if attached medium exists) */ + b[13] = '\0'; + if (access(b, R_OK)) + continue; + + tmp[count].name = strdup("hda"); + tmp[count].name[2] = b[12]; + + /* media type */ + strcpy(b + 13, "/media"); + fd = open(b, O_RDONLY); + if (fd == -1) { + log_message("failed to open %s for reading", b); + continue; + } + + i = read(fd, buf, sizeof(buf)); + if (i == -1) { + log_message("failed to read %s", b); + continue; + } + buf[i] = '\0'; + close(fd); + + if (!strncmp(buf, "disk", strlen("disk"))) + tmp[count].type = DISK; + else if (!strncmp(buf, "cdrom", strlen("cdrom"))) + tmp[count].type = CDROM; + else if (!strncmp(buf, "tape", strlen("tape"))) + tmp[count].type = TAPE; + else if (!strncmp(buf, "floppy", strlen("floppy"))) + tmp[count].type = FLOPPY; + else + tmp[count].type = UNKNOWN_MEDIA; + + /* media model */ + strcpy(b + 13, "/model"); + fd = open(b, O_RDONLY); + if (fd == -1) { + log_message("failed to open %s for reading", b); + continue; + } + + i = read(fd, buf, sizeof(buf)); + if (i <= 0) { + log_message("failed to read %s", b); + tmp[count].model = strdup("(none)"); + } + else { + buf[i-1] = '\0'; /* eat the \n */ + tmp[count].model = strdup(buf); + } + + tmp[count].bus = IDE; + count++; + } + + log_message("found %d IDE media", count); + + + /* ----------------------------------------------- */ + log_message("looking for scsi media"); + + pci_probing(SCSI_ADAPTERS); + + fd = open("/proc/scsi/scsi", O_RDONLY); + if (fd != -1) { + enum { SCSI_TOP, SCSI_HOST, SCSI_VENDOR, SCSI_TYPE } state = SCSI_TOP; + char * start, * chptr, * next, * end; + + int i = read(fd, &buf, sizeof(buf)); + if (i < 1) { + close(fd); + goto end_scsi; + } + close(fd); + buf[i] = '\0'; + + if (!strncmp(buf, "Attached devices: none", strlen("Attached devices: none"))) + goto end_scsi; + + start = buf; + while (*start) { + char tmp_model[50]; + char tmp_name[10]; + char scsi_disk_count = 'a'; + char scsi_cdrom_count = '0'; + char scsi_tape_count = '0'; + + chptr = start; + while (*chptr != '\n') chptr++; + *chptr = '\0'; + next = chptr + 1; + + switch (state) { + case SCSI_TOP: + if (strncmp(start, "Attached devices: ", strlen("Attached devices: "))) + goto end_scsi; + state = SCSI_HOST; + break; + + case SCSI_HOST: + if (strncmp(start, "Host: ", strlen("Host: "))) + goto end_scsi; + state = SCSI_VENDOR; + break; + + case SCSI_VENDOR: + if (strncmp(start, " Vendor: ", strlen(" Vendor: "))) + goto end_scsi; + + /* (1) Grab Vendor info */ + start += 10; + end = chptr = strstr(start, "Model:"); + if (!chptr) + goto end_scsi; + + chptr--; + while (*chptr == ' ') + chptr--; + if (*chptr == ':') { + chptr++; + *(chptr + 1) = '\0'; + strcpy(tmp_model,"(unknown)"); + } else { + *(chptr + 1) = '\0'; + strcpy(tmp_model, start); + } + + /* (2) Grab Model info */ + start = end; + start += 7; + + chptr = strstr(start, "Rev:"); + if (!chptr) + goto end_scsi; + + chptr--; + while (*chptr == ' ') chptr--; + *(chptr + 1) = '\0'; + + strcat(tmp_model, ", "); + strcat(tmp_model, start); + + tmp[count].model = strdup(tmp_model); + + state = SCSI_TYPE; + + break; + + case SCSI_TYPE: + if (strncmp(" Type:", start, 7)) + goto end_scsi; + *tmp_name = '\0'; + + if (strstr(start, "Direct-Access")) { + sprintf(tmp_name, "sd%c", scsi_disk_count++); + tmp[count].type = DISK; + } else if (strstr(start, "Sequential-Access")) { + sprintf(tmp_name, "st%c", scsi_tape_count++); + tmp[count].type = TAPE; + } else if (strstr(start, "CD-ROM")) { + sprintf(tmp_name, "scd%c", scsi_cdrom_count++); + tmp[count].type = CDROM; + } + + if (*tmp_name) { + tmp[count].name = strdup(tmp_name); + tmp[count].bus = SCSI; + count++; + } + + state = SCSI_HOST; + } + + start = next; + } + + end_scsi: + } + + log_message("adding SCSI totals %d media", count); + + + /* ----------------------------------------------- */ + tmp[count].name = NULL; + count++; + + medias = (struct media_info *) malloc(sizeof(struct media_info) * count); + memcpy(medias, tmp, sizeof(struct media_info) * count); +} + + +/* Finds by media */ +char ** get_medias(enum media_type media, enum media_query_type qtype) +{ + struct media_info * m; + char * tmp[50]; + char ** answer; + int count; + + find_media(); + + m = medias; + + count = 0; + while (m && m->name) { + if (m->type == media) { + if (qtype == QUERY_NAME) + tmp[count] = m->name; + else + tmp[count] = m->model; + count++; + } + m++; + } + tmp[count] = NULL; + count++; + + answer = (char **) malloc(sizeof(char *) * count); + memcpy(answer, tmp, sizeof(char *) * count); + + return answer; +} diff --git a/mdk-stage1/probing.h b/mdk-stage1/probing.h new file mode 100644 index 000000000..ee221f01b --- /dev/null +++ b/mdk-stage1/probing.h @@ -0,0 +1,44 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _PROBING_H_ +#define _PROBING_H_ + +enum media_type { DISK, FLOPPY, CDROM, TAPE, UNKNOWN_MEDIA }; + +enum bus_type { IDE, SCSI }; + +struct media_info { + char * name; + char * model; + enum media_type type; + enum bus_type bus; +}; + +enum media_query_type { QUERY_NAME, QUERY_MODEL }; + +enum driver_type { SCSI_ADAPTERS, NETWORK_DEVICES }; + + +char ** get_medias(enum media_type media, enum media_query_type qtype); + + +#endif diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 16b848a9c..16d896f3b 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -19,6 +19,7 @@ * */ +#include <sys/mount.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -29,11 +30,24 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#include <ctype.h> + +#include "stage1.h" #include "log.h" +#include "probing.h" +#include "frontend.h" +#include "modules.h" + +#include "cdrom.h" +#include "network.h" +#include "disk.h" + +/* globals */ -int testing; +int stage1_mode = 0; +struct cmdline_elem params[500]; void fatal_error(char *msg) @@ -42,26 +56,63 @@ void fatal_error(char *msg) while (1); } + void process_cmdline(void) { - char buf[512]; - int fd; - int size; - - - log_message("opening /proc/cmdline... "); - - if ((fd = open("/proc/cmdline", O_RDONLY, 0)) < 0) fatal_error("could not open /proc/cmdline"); + char buf[512]; + int fd, size, i, p; + + log_message("opening /proc/cmdline... "); + + if ((fd = open("/proc/cmdline", O_RDONLY, 0)) == -1) + fatal_error("could not open /proc/cmdline"); + + size = read(fd, buf, sizeof(buf)); + buf[size-1] = 0; + close(fd); + + log_message("\t%s", buf); + + i = 0; p = 0; + while (buf[i] != 0) { + char *name, *value = NULL; + int j = i; + while (buf[i] != ' ' && buf[i] != '=' && buf[i] != 0) + i++; + if (i == j) { + i++; + continue; + } + name = (char *) malloc(i-j + 1); + memcpy(name, &buf[j], i-j); + name[i-j] = 0; + + if (buf[i] == '=') { + int k = i+1; + i++; + while (buf[i] != ' ' && buf[i] != 0) + i++; + value = (char *) malloc(i-k + 1); + memcpy(value, &buf[k], i-k); + value[i-k] = 0; + } - size = read(fd, buf, sizeof(buf) - 1); - buf[size] = '\0'; - close(fd); + params[p].name = name; + params[p].value = value; + p++; + i++; + if (!strcmp(name, "expert")) stage1_mode |= MODE_EXPERT; + if (!strcmp(name, "text")) stage1_mode |= MODE_TEXT; + if (!strcmp(name, "rescue")) stage1_mode |= MODE_RESCUE; + if (!strcmp(name, "pcmcia")) stage1_mode |= MODE_PCMCIA; + if (!strcmp(name, "cdrom")) stage1_mode |= MODE_CDROM; + } + params[p].name = NULL; - log_message("\t%s", buf); + log_message("\tgot %d args", p); } -#ifdef SPAWN_SHELL /* spawns a shell on console #2 */ void spawn_shell(void) { @@ -69,23 +120,20 @@ void spawn_shell(void) int fd; char * shell_name = "/sbin/sash"; - if (!testing) - { + log_message("spawning a shell.."); + + if (!IS_TESTING) { fd = open("/dev/tty2", O_RDWR); - if (fd < 0) - { + if (fd == -1) { log_message("cannot open /dev/tty2 -- no shell will be provided"); return; } - else - if (access(shell_name, X_OK)) - { - log_message("cannot open shell - /usr/bin/sh doesn't exist"); - return; - } + else if (access(shell_name, X_OK)) { + log_message("cannot open shell - %s doesn't exist", shell_name); + return; + } - if (!(pid = fork())) - { + if (!(pid = fork())) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); @@ -94,36 +142,92 @@ void spawn_shell(void) setsid(); if (ioctl(0, TIOCSCTTY, NULL)) perror("could not set new controlling tty"); - + execl(shell_name, shell_name, NULL); log_message("execl of %s failed: %s", shell_name, strerror(errno)); } close(fd); } - else - log_message("I should be spawning a shell"); } + +enum return_type method_select_and_prepare(void) +{ + char * disk_install = "Hard disk"; + char * cdrom_install = "CDROM drive"; + char * network_nfs_install = "NFS server"; + char * network_ftp_install = "FTP server"; + char * network_http_install = "HTTP server"; + enum return_type results; + char * choice; + char * means[10]; + int i; + + i = 0; +#ifndef DISABLE_NETWORK + means[i] = network_nfs_install; i++; + means[i] = network_ftp_install; i++; + means[i] = network_http_install; i++; +#endif +#ifndef DISABLE_DISK + means[i] = disk_install; i++; +#endif +#ifndef DISABLE_CDROM + means[i] = cdrom_install; i++; #endif + means[i] = NULL; + results = ask_from_list("Please choose the mean of installation.", means, &choice); + + if (results != RETURN_OK) + return results; + + if (!strcmp(choice, cdrom_install)) + return cdrom_prepare(); + else if (!strcmp(choice, disk_install)) + return disk_prepare(); + else if (!strcmp(choice, network_nfs_install)) + return nfs_prepare(); + else if (!strcmp(choice, network_ftp_install)) + return ftp_prepare(); + else if (!strcmp(choice, network_http_install)) + return http_prepare(); + + return RETURN_ERROR; +} -int -main(int argc, char **argv) + +int main(int argc, char **argv) { - /* getpid() != 1 should work, by linuxrc tends to get a larger pid */ - testing = (getpid() > 50); + enum return_type ret; + + if (getpid() > 50) + stage1_mode |= MODE_TESTING; - open_log(testing); + open_log(IS_TESTING); log_message("welcome to the Linux-Mandrake install (stage1, version " VERSION " built " __DATE__ " " __TIME__")"); process_cmdline(); spawn_shell(); + if (load_modules_dependencies()) + fatal_error("could not open and parse modules dependencies"); - - printf("Temporary end of stage1 binary -- entering an infinite loop\n"); - log_message("Temporary end of stage1 binary -- entering an infinite loop"); - while(1); + init_frontend(); + + if (IS_CDROM) + ret = cdrom_prepare(); + else + ret = method_select_and_prepare(); + + while (ret == RETURN_BACK) + ret = method_select_and_prepare(); + + finish_frontend(); + close_log(); + + if (ret == RETURN_ERROR) + fatal_error("could not select an installation method"); return 0; } diff --git a/mdk-stage1/stage1.h b/mdk-stage1/stage1.h new file mode 100644 index 000000000..108fe14aa --- /dev/null +++ b/mdk-stage1/stage1.h @@ -0,0 +1,61 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _STAGE1_H_ +#define _STAGE1_H_ + + +/* Some global stuff */ + +struct cmdline_elem +{ + char * name; + char * value; +}; + +extern struct cmdline_elem params[500]; + + +enum return_type { RETURN_OK, RETURN_BACK, RETURN_ERROR }; + +extern int stage1_mode; + +#define MODE_TESTING (1 << 0) +#define MODE_EXPERT (1 << 1) +#define MODE_TEXT (1 << 2) +#define MODE_RESCUE (1 << 3) +#define MODE_KICKSTART (1 << 4) +#define MODE_PCMCIA (1 << 5) +#define MODE_CDROM (1 << 6) + +#define IS_TESTING ((stage1_mode) & MODE_TESTING) +#define IS_EXPERT ((stage1_mode) & MODE_EXPERT) +#define IS_TEXT ((stage1_mode) & MODE_TEXT) +#define IS_RESCUE ((stage1_mode) & MODE_RESCUE) +#define IS_KICKSTART ((stage1_mode) & MODE_KICKSTART) +#define IS_PCMCIA ((stage1_mode) & MODE_PCMCIA) +#define IS_CDROM ((stage1_mode) & MODE_CDROM) + + +void fatal_error(char *msg); + + +#endif diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c new file mode 100644 index 000000000..e07fcd347 --- /dev/null +++ b/mdk-stage1/tools.c @@ -0,0 +1,71 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <ctype.h> +#include "stage1.h" +#include "log.h" + +#include "tools.h" + +int total_memory(void) +{ + int fd; + int i; + char buf[4096]; + char * memtotal_tag = "MemTotal:"; + int memtotal = 0; + + fd = open("/proc/meminfo", O_RDONLY); + if (fd == -1) + fatal_error("could not open /proc/meminfo"); + + i = read(fd, buf, sizeof(buf)); + if (i < 0) + fatal_error("could not read /proc/meminfo"); + + close(fd); + buf[i] = 0; + + i = 0; + while (buf[i] != 0 && strncmp(&buf[i], memtotal_tag, strlen(memtotal_tag))) + i++; + + while (buf[i] != 0 && buf[i] != '\n' && !isdigit(buf[i])) + i++; + + if (buf[i] == 0 || buf[i] == '\n') + fatal_error("could not read MemTotal"); + + while (buf[i] != 0 && isdigit(buf[i])) { + memtotal = (memtotal * 10) + (buf[i] - '0'); + i++; + } + + log_message("%s %d kB", memtotal_tag, memtotal); + + return memtotal; +} diff --git a/mdk-stage1/tools.h b/mdk-stage1/tools.h new file mode 100644 index 000000000..21d09ec86 --- /dev/null +++ b/mdk-stage1/tools.h @@ -0,0 +1,30 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 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. + * + */ + +/* + * Portions from Erik Troan (ewt@redhat.com) + * + * Copyright 1996 Red Hat Software + * + */ + +#ifndef _TOOLS_H_ +#define _TOOLS_H_ + + +/* returns value of MemTotal tag from /proc/meminfo */ +int total_memory(void); + + +#endif |