diff options
Diffstat (limited to 'mdk-stage1')
-rw-r--r-- | mdk-stage1/Makefile | 82 | ||||
-rw-r--r-- | mdk-stage1/config-stage1.h | 33 | ||||
-rw-r--r-- | mdk-stage1/frontend.h | 1 | ||||
-rw-r--r-- | mdk-stage1/mount.c | 6 | ||||
-rw-r--r-- | mdk-stage1/network.c | 451 | ||||
-rw-r--r-- | mdk-stage1/network.h | 28 | ||||
-rw-r--r-- | mdk-stage1/newt-frontend.c | 32 | ||||
-rw-r--r-- | mdk-stage1/pci-resource/Makefile | 6 | ||||
-rwxr-xr-x | mdk-stage1/pci-resource/update-pci-ids.pl | 7 | ||||
-rw-r--r-- | mdk-stage1/probing.c | 39 | ||||
-rw-r--r-- | mdk-stage1/probing.h | 2 | ||||
-rw-r--r-- | mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 | bin | 345069 -> 345037 bytes | |||
-rw-r--r-- | mdk-stage1/stage1.c | 37 | ||||
-rw-r--r-- | mdk-stage1/stdio-frontend.c | 48 | ||||
-rw-r--r-- | mdk-stage1/tools.c | 2 |
15 files changed, 725 insertions, 49 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 1bf95ada9..5cefa06fe 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -19,14 +19,13 @@ # #***************************************************************************** -VERSION = 7.2cooker +VERSION = 8.0b ARCH := $(patsubst i%86,i386,$(shell uname -m)) ARCH := $(patsubst sparc%,sparc,$(ARCH)) - #- We can leave "-g" forever since stripping will remove everything CFLAGS = -Os -Wall -Werror -fomit-frame-pointer INCLUDES = -I. DEFS = -D_GNU_SOURCE=1 -DVERSION=\"$(VERSION)\" @@ -57,15 +56,43 @@ FRONTEND_OBJS = $(subst .c,.o,$($(F)_FRONTEND_SRC)) FRONTEND_LIBS = $($(F)_FRONTEND_LIBS) - #- stage1 itself (minus stage1.c) -STAGE1SRC = log.c tools.c modules.c probing.c cdrom.c disk.c network.c mount.c +STAGE1_OWN_LIBS = insmod-busybox/libinsmod.a mar/libmar.a -STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC)) $(FRONTEND_OBJS) insmod-busybox/libinsmod.a mar/libmar.a $(FRONTEND_LIBS) /usr/lib/libz.a +STAGE1_OTHER_LIBS = /usr/lib/libz.a +STAGE1_NETWORK_LIBS = /usr/lib/libresolv.a + + + #- stage1 itself +STAGE1SRC = stage1.c log.c tools.c modules.c probing.c mount.c +CDROMSRC = cdrom.c +DISKSRC = disk.c +NETWORKSRC = network.c dns.c + +ALLSRC = $(INITSRC) $(STAGE1SRC) $(CDROMSRC) $(DISKSRC) $(NETWORKSRC) + + +STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC) $(CDROMSRC) $(DISKSRC) $(NETWORKSRC)) + +STAGE1OBJS_UTILS = $(FRONTEND_OBJS) $(STAGE1_OWN_LIBS) $(FRONTEND_LIBS) $(STAGE1_OTHER_LIBS) + + +STAGE1OBJS-CDROM = $(subst .c,-CDROM.o,$(STAGE1SRC) $(CDROMSRC)) + +CDROM_DEFS = -DDISABLE_DISK -DDISABLE_NETWORK + + +STAGE1OBJS-DISK = $(subst .c,-DISK.o,$(STAGE1SRC) $(DISKSRC)) + +DISK_DEFS = -DDISABLE_CDROM -DDISABLE_NETWORK + + +STAGE1OBJS-NETWORK = $(subst .c,-NETWORK.o,$(STAGE1SRC) $(NETWORKSRC)) + +NETWORK_DEFS = -DDISABLE_CDROM -DDISABLE_DISK -ALLSRC = $(INITSRC) $(STAGE1SRC) stage1.c ifeq (i386, $(ARCH)) @@ -81,7 +108,7 @@ LDFLAGS_STAGE1 = -static endif -BINS = init stage1-network +BINS = init stage1-full # stage1-cdrom stage1-network #ifeq (i386, $(ARCH)) @@ -115,29 +142,50 @@ init: $(INITOBJS) $(CC) $(LDFLAGS_INIT) -o $@ $(INITOBJS) strip -s $@ -stage1-network: stage1-network.o $(STAGE1OBJS) $(NETOBJS) - $(CC) $(LDFLAGS_STAGE1) -o $@ $^ +stage1-cdrom: dirs $(STAGE1OBJS-CDROM) $(STAGE1OBJS_UTILS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS-CDROM) $(STAGE1OBJS_UTILS) + strip -s $@ + +stage1-network: dirs $(STAGE1OBJS-NETWORK) $(STAGE1OBJS_UTILS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS-NETWORK) $(STAGE1OBJS_UTILS) $(STAGE1_NETWORK_LIBS) + strip -s $@ + +stage1-disk: dirs $(STAGE1OBJS-DISK) $(STAGE1OBJS_UTILS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS-DISK) $(STAGE1OBJS_UTILS) + strip -s $@ + +stage1-pcmcia: dirs $(STAGE1OBJS-PCMIA) $(STAGE1OBJS_UTILS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS-PCMIA) $(STAGE1OBJS_UTILS) strip -s $@ -stage1-network-diet: $(STAGE1OBJS) stage1-network.o $(NETOBJS) - gcc -nostdlib -o $@ ../../../tmp/dietlibc/start.o $^ ../../../tmp/dietlibc/dietlibc.a +stage1-full: dirs $(STAGE1OBJS) $(STAGE1OBJS_UTILS) + $(CC) $(LDFLAGS_STAGE1) -o $@ $(STAGE1OBJS) $(STAGE1OBJS_UTILS) $(STAGE1_NETWORK_LIBS) strip -s $@ -test: stage1-network.o $(STAGE1OBJS) $(NETOBJS) - $(CC) -o st1 $^ + +#stage1-network-diet: $(STAGE1OBJS) stage1-network.o $(NETOBJS) +# gcc -nostdlib -o $@ ../../../tmp/dietlibc/start.o $^ ../../../tmp/dietlibc/dietlibc.a +# strip -s $@ + + +$(STAGE1OBJS-CDROM): %-CDROM.o: %.c + $(COMPILE) $(CDROM_DEFS) -c $< -o $@ + +$(STAGE1OBJS-DISK): %-DISK.o: %.c + $(COMPILE) $(DISK_DEFS) -c $< -o $@ + +$(STAGE1OBJS-NETWORK): %-NETWORK.o: %.c + $(COMPILE) $(NETWORK_DEFS) -c $< -o $@ .c.o: $(COMPILE) -c $< -stage1-network.o: stage1.c - $(COMPILE) -c $< -o $@ - clean: @for n in $(DIRS); do \ (cd $$n; make clean) \ done - rm -f *.o .depend *.rdz *.img $(BINS) st1 + rm -f *.o .depend *.rdz *.img $(BINS) deps: $(CPP) $(CFLAGS) -DHAVE_CONFIG_H -M $(ALLSRC) > .depend diff --git a/mdk-stage1/config-stage1.h b/mdk-stage1/config-stage1.h new file mode 100644 index 000000000..d54b80ff1 --- /dev/null +++ b/mdk-stage1/config-stage1.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 _CONFIG_STAGE1_H_ +#define _CONFIG_STAGE1_H_ + +/* If we have more than that amount of memory, we assume we can load the second stage as a ramdisk */ +#define MEM_LIMIT_RAMDISK 52 * 1024 + +/* user-definable (in Makefile): DISABLE_NETWORK, DISABLE_DISK, DISABLE_CDROM, DISABLE_PCMCIA */ + + +/* some factorizing for disabling more features */ + +#ifdef DISABLE_DISK +#ifdef DISABLE_CDROM +#define DISABLE_MEDIAS +#endif +#endif + + +#endif diff --git a/mdk-stage1/frontend.h b/mdk-stage1/frontend.h index 9b2bc9f39..9d001bdcf 100644 --- a/mdk-stage1/frontend.h +++ b/mdk-stage1/frontend.h @@ -36,5 +36,6 @@ void end_progression(void); enum return_type ask_yes_no(char *msg); 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); #endif diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c index 6de11b480..15533e716 100644 --- a/mdk-stage1/mount.c +++ b/mdk-stage1/mount.c @@ -31,6 +31,7 @@ #include "mount.h" +#ifndef DISABLE_MEDIAS /* WARNING: this won't work if the argument is not /dev/ based */ static int ensure_dev_exists(char *dev) { @@ -93,6 +94,7 @@ static int ensure_dev_exists(char *dev) return 0; } +#endif /* DISABLE_MEDIAS */ /* mounts, creating the device if needed+possible */ @@ -103,12 +105,14 @@ int my_mount(char *dev, char *location, char *fs) struct stat buf; int rc; +#ifndef DISABLE_MEDIAS rc = ensure_dev_exists(dev); if (rc != 0) { log_message("could not create required device file"); return -1; } +#endif log_message("mounting %s on %s as type %s", dev, location, fs); @@ -131,6 +135,7 @@ int my_mount(char *dev, char *location, char *fs) flags = MS_MGC_VAL; +#ifndef DISABLE_MEDIAS if (!strcmp(fs, "vfat")) { my_insmod("vfat"); opts = "check=relaxed"; @@ -140,6 +145,7 @@ int my_mount(char *dev, char *location, char *fs) my_insmod("isofs"); flags |= MS_RDONLY; } +#endif rc = mount(dev, location, fs, flags, opts); diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c index de0e0070e..31042b1f6 100644 --- a/mdk-stage1/network.c +++ b/mdk-stage1/network.c @@ -21,15 +21,416 @@ #include <stdlib.h> #include <unistd.h> +#include <string.h> +#include <sys/socket.h> +#include <net/if.h> +#include <arpa/inet.h> +#include <net/route.h> +#include <resolv.h> +#include <sys/ioctl.h> +#include <stdio.h> + #include "stage1.h" #include "frontend.h" #include "modules.h" #include "probing.h" #include "log.h" +#include "dns.h" #include "network.h" +static void error_message_net(void) /* reduce code size */ +{ + error_message("Could not configure network"); +} + + +static int configure_net_device(struct interface_info * intf) +{ + struct ifreq req; + struct rtentry route; + int s; + struct sockaddr_in addr; + struct in_addr ia; + char ip[20], nm[20], nw[20], bc[20]; + + addr.sin_family = AF_INET; + addr.sin_port = 0; + + memcpy(&ia, &intf->ip, sizeof(intf->ip)); + strcpy(ip, inet_ntoa(ia)); + + memcpy(&ia, &intf->netmask, sizeof(intf->netmask)); + strcpy(nm, inet_ntoa(ia)); + + memcpy(&ia, &intf->broadcast, sizeof(intf->broadcast)); + strcpy(bc, inet_ntoa(ia)); + + memcpy(&ia, &intf->network, sizeof(intf->network)); + strcpy(nw, inet_ntoa(ia)); + + log_message("configuring device %s ip: %s nm: %s nw: %s bc: %s", intf->device, ip, nm, nw, bc); + + if (IS_TESTING) + return 0; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + log_perror("socket"); + error_message_net(); + return 1; + } + + strcpy(req.ifr_name, intf->device); + + if (intf->is_up == 1) { + log_message("interface already up, downing"); + + req.ifr_flags = 0; + if (ioctl(s, SIOCSIFFLAGS, &req)) { + close(s); + log_perror("SIOCSIFFLAGS (downing)"); + error_message_net(); + return 1; + } + } + + /* sets IP address */ + addr.sin_port = 0; + memcpy(&addr.sin_addr, &intf->ip, sizeof(intf->ip)); + memcpy(&req.ifr_addr, &addr, sizeof(addr)); + if (ioctl(s, SIOCSIFADDR, &req)) { + close(s); + log_perror("SIOCSIFADDR"); + error_message_net(); + return 1; + } + + /* sets broadcast */ + memcpy(&addr.sin_addr, &intf->broadcast, sizeof(intf->broadcast)); + memcpy(&req.ifr_broadaddr, &addr, sizeof(addr)); + if (ioctl(s, SIOCSIFBRDADDR, &req)) { + close(s); + log_perror("SIOCSIFBRDADDR"); + error_message_net(); + return 1; + } + + /* sets netmask */ + memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask)); + memcpy(&req.ifr_netmask, &addr, sizeof(addr)); + if (ioctl(s, SIOCSIFNETMASK, &req)) { + close(s); + log_perror("SIOCSIFNETMASK"); + error_message_net(); + return 1; + } + + if (intf->is_ptp) + req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_POINTOPOINT | IFF_NOARP; + else + req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST; + + /* brings up networking! */ + if (ioctl(s, SIOCSIFFLAGS, &req)) { + close(s); + log_perror("SIOCSIFFLAGS (upping)"); + error_message_net(); + return 1; + } + + memset(&route, 0, sizeof(route)); + route.rt_dev = intf->device; + route.rt_flags = RTF_UP; + + memcpy(&addr.sin_addr, &intf->network, sizeof(intf->network)); + memcpy(&route.rt_dst, &addr, sizeof(addr)); + + memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask)); + memcpy(&route.rt_genmask, &addr, sizeof(addr)); + + /* adds route */ + if (ioctl(s, SIOCADDRT, &route)) { + close(s); + log_perror("SIOCADDRT"); + error_message_net(); + return 1; + } + + close(s); + + intf->is_up = 1; + + return 0; +} + +/* host network informations */ +static char * hostname = NULL; +static char * domain = NULL; +static struct in_addr gateway = { 0 }; +static struct in_addr dns_server = { 0 }; + +static int add_default_route(void) +{ + int s; + struct rtentry route; + struct sockaddr_in addr; + + if (IS_TESTING) + return 0; + + if (gateway.s_addr == 0) { + log_message("no gateway provided, can't add default route"); + return 0; + } + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + close(s); + log_perror("socket"); + error_message_net(); + return 1; + } + + memset(&route, 0, sizeof(route)); + + addr.sin_family = AF_INET; + addr.sin_port = 0; + addr.sin_addr = gateway; + memcpy(&route.rt_gateway, &addr, sizeof(addr)); + + addr.sin_addr.s_addr = INADDR_ANY; + memcpy(&route.rt_dst, &addr, sizeof(addr)); + memcpy(&route.rt_genmask, &addr, sizeof(addr)); + + route.rt_flags = RTF_UP | RTF_GATEWAY; + route.rt_metric = 0; + + if (ioctl(s, SIOCADDRT, &route)) { + close(s); + log_perror("SIOCADDRT"); + error_message_net(); + return 1; + } + + close(s); + + return 0; +} + + +static int write_resolvconf(void) { + char * filename = "/etc/resolv.conf"; + FILE * f; + + if (IS_TESTING) + return 1; + + if (dns_server.s_addr == 0) { + log_message("resolvconf needs a dns server"); + return -1; + } + + f = fopen(filename, "w"); + if (!f) { + log_perror(filename); + return -1; + } + + if (domain) + fprintf(f, "search %s\n", domain); /* we can live without the domain search (user will have to enter fully-qualified names) */ + fprintf(f, "nameserver %s\n", inet_ntoa(dns_server)); + + fclose(f); + res_init(); /* reinit the resolver so DNS changes take affect */ + + return 0; +} + + +static void guess_netmask(struct interface_info * intf, struct in_addr * addr) +{ + unsigned long int tmp = ntohl(intf->ip.s_addr); + if (((tmp & 0xFF000000) >> 24) <= 127) + inet_aton("255.0.0.0", addr); + else if (((tmp & 0xFF000000) >> 24) <= 191) + inet_aton("255.255.0.0", addr); + else + inet_aton("255.255.255.0", addr); + log_message("netmask guess: %s", inet_ntoa(*addr)); +} + + +static enum return_type setup_network_interface(struct interface_info * intf) +{ + enum return_type results; + char * bootprotos[] = { "Static", "DHCP", NULL }; + char * choice; + + results = ask_from_list("Please choose the desired IP attribution.", bootprotos, &choice); + if (results != RETURN_OK) + return results; + + if (!strcmp(choice, "Static")) { + char * questions[] = { "IP of this machine", "IP of Domain Name Server", "IP of default gateway", NULL }; + char ** answers; + struct in_addr addr; + + results = ask_from_entries("Please enter the network information.", questions, &answers, 16); + if (results != RETURN_OK) + return setup_network_interface(intf); + + if (!inet_aton(answers[0], &addr)) { + error_message("Invalid IP address"); + return setup_network_interface(intf); + } + memcpy(&intf->ip, &addr, sizeof(addr)); + + if (!inet_aton(answers[1], &dns_server)) { + log_message("invalid DNS"); + dns_server.s_addr = 0; /* keep an understandable state */ + } + + if (!inet_aton(answers[2], &gateway)) { + log_message("invalid gateway"); + gateway.s_addr = 0; /* keep an understandable state */ + } + + if (IS_EXPERT) { + char * questions_expert[] = { "Netmask", NULL }; + char ** answers_expert; + results = ask_from_entries("Please enter additional network information.", questions_expert, &answers_expert, 16); + if (results != RETURN_OK) + return results; + + if (!inet_aton(answers_expert[0], &addr)) { + error_message("Invalid netmask"); + return setup_network_interface(intf); + } + } + else + guess_netmask(intf, &addr); + memcpy(&intf->netmask, &addr, sizeof(addr)); + + *((uint32_t *) &intf->broadcast) = (*((uint32_t *) &intf->ip) & + *((uint32_t *) &intf->netmask)) | ~(*((uint32_t *) &intf->netmask)); + + inet_aton("255.255.255.255", &addr); + if (!memcmp(&addr, &intf->netmask, sizeof(addr))) { + log_message("netmask is 255.255.255.255 -> point to point device"); + intf->network = gateway; + intf->is_ptp = 1; + } else { + *((uint32_t *) &intf->network) = *((uint32_t *) &intf->ip) & *((uint32_t *) &intf->netmask); + intf->is_ptp = 0; + } + intf->boot_proto = BOOTPROTO_STATIC; + } else { + error_message("DHCP not implemented yet"); + intf->boot_proto = BOOTPROTO_DHCP; + } + + if (configure_net_device(intf)) + return RETURN_ERROR; + return add_default_route(); +} + + +static enum return_type configure_network(struct interface_info * intf) +{ + char ips[50]; + char * name; + + write_resolvconf(); + + wait_message("Trying to guess hostname and domain..."); + strcpy(ips, inet_ntoa(intf->ip)); + name = mygethostbyaddr(ips); + remove_wait_message(); + + if (!name) { + enum return_type results; + char * questions[] = { "Host name", "Domain name", NULL }; + char ** answers; + char * boulet; + + log_message("reverse name lookup on self failed"); + + results = ask_from_entries("I could not guess hostname and domain name; please fill in this information. " + "Valid answers are for example: `mybox' for hostname and `mynetwork.com' for domain name, " + "for a machine called `mybox.mynetwork.com' on the Internet.", + questions, &answers, 32); + if (results != RETURN_OK) + return results; + + hostname = answers[0]; + if ((boulet = strchr(hostname, '.')) != NULL) + boulet[0] = '\0'; + domain = answers[1]; + } + else { + hostname = strdup(name); + domain = strchr(strdup(name), '.'); + } + + return RETURN_OK; +} + + +static enum return_type bringup_networking(struct interface_info * intf) +{ + static struct interface_info loopback; + enum { BRINGUP_NET, BRINGUP_CONF, BRINGUP_DONE } step = BRINGUP_NET; + + my_insmod("af_packet"); + +// if (intf->is_up == 1) +// log_message("interface already up (with IP %s)", inet_ntoa(intf->ip)); + + while (step != BRINGUP_DONE) { + enum return_type results = RETURN_ERROR; + switch (step) { + case BRINGUP_NET: + results = setup_network_interface(intf); + if (results != RETURN_OK) + return results; + step = BRINGUP_CONF; + break; + + case BRINGUP_CONF: + results = configure_network(intf); + if (results != RETURN_OK) + step = BRINGUP_NET; + else + step = BRINGUP_DONE; + break; + + case BRINGUP_DONE: + break; + } + } + + write_resolvconf(); /* maybe we have now domain to write also */ + + if (loopback.is_up == 0) { + int rc; + strcpy(loopback.device, "lo"); + loopback.is_ptp = 0; + loopback.is_up = 0; + loopback.ip.s_addr = htonl(0x7f000001); + loopback.netmask.s_addr = htonl(0xff000000); + loopback.broadcast.s_addr = htonl(0x7fffffff); + loopback.network.s_addr = htonl(0x7f000000); + rc = configure_net_device(&loopback); + if (rc) + return RETURN_ERROR; + } + + return RETURN_OK; +} + + static char * interface_select(void) { char ** interfaces, ** ptr; @@ -64,23 +465,61 @@ static char * interface_select(void) return choice; } -enum return_type nfs_prepare(void) + + +/* -=-=-- */ + + +static enum return_type intf_select_and_up(void) { - char * iface = interface_select(); + static struct interface_info intf[20]; + static int num_interfaces = 0; + enum return_type results; - if (iface == NULL) - return RETURN_BACK; + do { + struct interface_info * sel_intf = NULL; + int i; + char * iface = interface_select(); + + if (iface == NULL) + return RETURN_BACK; + + for (i = 0; i < num_interfaces ; i++) + if (!strcmp(intf[i].device, iface)) + sel_intf = &(intf[i]); + + if (sel_intf == NULL) { + sel_intf = &(intf[num_interfaces]); + strcpy(sel_intf->device, iface); + sel_intf->is_up = 0; + num_interfaces++; + } + results = bringup_networking(sel_intf); + } + while (results == RETURN_BACK); return RETURN_ERROR; } +enum return_type nfs_prepare(void) +{ + enum return_type results = intf_select_and_up(); + + return results; +} + + enum return_type ftp_prepare(void) { - return RETURN_ERROR; + enum return_type results = intf_select_and_up(); + + return results; } enum return_type http_prepare(void) { - return RETURN_ERROR; + enum return_type results = intf_select_and_up(); + + return results; } diff --git a/mdk-stage1/network.h b/mdk-stage1/network.h index bc7e19104..9f59cb29e 100644 --- a/mdk-stage1/network.h +++ b/mdk-stage1/network.h @@ -22,9 +22,37 @@ #ifndef _NETWORK_H_ #define _NETWORK_H_ +#include <netinet/in.h> +#include <netinet/ip.h> +#include <arpa/inet.h> + + enum return_type nfs_prepare(void); enum return_type ftp_prepare(void); enum return_type http_prepare(void); +enum boot_proto_type { BOOTPROTO_STATIC, BOOTPROTO_DHCP }; + +/* all of these in_addr things are in network byte order! */ +struct interface_info { + char device[10]; + int is_ptp, is_up; + int set, manually_set; + struct in_addr ip, netmask, broadcast, network; + struct in_addr boot_server; + char * boot_file; + enum boot_proto_type boot_proto; +}; + +struct net_info { + int set, manually_set; + char * hostname, * domain; /* dynamically allocated */ + struct in_addr gateway; + struct in_addr dns_server; + int numDns; +}; + + + #endif diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c index f5bfae047..4f62f87f0 100644 --- a/mdk-stage1/newt-frontend.c +++ b/mdk-stage1/newt-frontend.c @@ -202,3 +202,35 @@ enum return_type ask_yes_no(char *msg) return RETURN_BACK; else return RETURN_ERROR; } + +enum return_type ask_from_entries(char *msg, char ** questions, char *** answers, int entry_size) +{ + struct newtWinEntry entries[50]; + int j, i = 0; + int rc; + + while (questions && *questions) { + entries[i].text = *questions; + entries[i].flags = NEWT_FLAG_SCROLL; + i++; + questions++; + } + entries[i].text = NULL; + entries[i].value = NULL; + + *answers = (char **) malloc(sizeof(char *) * i); + + for (j = 0 ; j < i ; j++) { + entries[j].value = &((*answers)[j]); + *(entries[j].value) = NULL; + } + + rc = newtWinEntries("Please fill entries...", msg, 52, 5, 5, entry_size, entries, "Ok", "Cancel", NULL); + + if (rc == 3) + return RETURN_BACK; + if (rc != 1) + return RETURN_ERROR; + + return RETURN_OK; +} diff --git a/mdk-stage1/pci-resource/Makefile b/mdk-stage1/pci-resource/Makefile index ed16b6f67..84d335c91 100644 --- a/mdk-stage1/pci-resource/Makefile +++ b/mdk-stage1/pci-resource/Makefile @@ -13,12 +13,12 @@ # 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 - # #***************************************************************************** -pci-ids.h: ../../perl-install/pci_probing/pcitable +all: pci-ids.h + +pci-ids.h: ../../perl-install/pci_probing/pcitable update-pci-ids.pl make -C ../../perl-install/pci_probing perl update-pci-ids.pl > $@ diff --git a/mdk-stage1/pci-resource/update-pci-ids.pl b/mdk-stage1/pci-resource/update-pci-ids.pl index 4aaa04b70..396621faa 100755 --- a/mdk-stage1/pci-resource/update-pci-ids.pl +++ b/mdk-stage1/pci-resource/update-pci-ids.pl @@ -19,6 +19,9 @@ struct pci_module_map { my %t = (scsi => 'scsi', eth => 'net'); foreach (keys %t) { + print "#ifndef DISABLE_NETWORK\n" if ($_ eq 'eth'); + print "#ifndef DISABLE_MEDIAS\n" if ($_ eq 'scsi'); + print " struct pci_module_map ${_}_pci_ids[] = { "; @@ -36,6 +39,8 @@ struct pci_module_map ${_}_pci_ids[] = { print " }; int ${_}_num_ids=sizeof(${_}_pci_ids)/sizeof(struct pci_module_map); -" +"; + + print "#endif\n"; } diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index 6d70137e2..cb03876f4 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -36,10 +36,11 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <sys/types.h> #include <sys/socket.h> #include <net/if.h> #include <sys/ioctl.h> +#include "stage1.h" + #include "log.h" #include "frontend.h" #include "modules.h" @@ -48,17 +49,17 @@ #include "probing.h" -void pci_probing(enum driver_type type) +void probe_that_type(enum driver_type type) { if (IS_EXPERT) ask_insmod(type); else { - /* do it automatically */ + /* probe for PCI devices */ char * mytype; FILE * f; - int len; - char buf[100]; - struct pci_module_map * pcidb; + int len = 0; + char buf[200]; + struct pci_module_map * pcidb = NULL; if (type == SCSI_ADAPTERS) mytype = "SCSI"; @@ -76,12 +77,16 @@ void pci_probing(enum driver_type type) switch (type) { case SCSI_ADAPTERS: +#ifndef DISABLE_MEDIAS pcidb = scsi_pci_ids; len = scsi_num_ids; +#endif break; case NETWORK_DEVICES: +#ifndef DISABLE_NETWORK pcidb = eth_pci_ids; len = eth_num_ids; +#endif break; default: return; @@ -90,23 +95,28 @@ void pci_probing(enum driver_type type) while (1) { int i, garb, vendor, device; - if (!fgets(buf,100,f)) break; + if (!fgets(buf, sizeof(buf), f)) break; sscanf(buf, "%x %04x%04x", &garb, &vendor, &device); for (i = 0; i < len; i++) { if (pcidb[i].vendor == vendor && pcidb[i].device == device) { log_message("PCI: found suggestion for %s (%s)", pcidb[i].name, pcidb[i].module); +#ifndef DISABLE_MEDIAS if (type == SCSI_ADAPTERS) { /* insmod takes time, let's use the wait message */ wait_message("Installing %s driver for %s", mytype, pcidb[i].name); my_insmod(pcidb[i].module); remove_wait_message(); - } else if (type == NETWORK_DEVICES) { + } +#endif +#ifndef DISABLE_NETWORK + if (type == NETWORK_DEVICES) { /* insmod is quick, let's use the info message */ info_message("Found %s driver for %s", mytype, pcidb[i].name); my_insmod(pcidb[i].module); } +#endif } } } @@ -114,6 +124,7 @@ void pci_probing(enum driver_type type) } +#ifndef DISABLE_MEDIAS static struct media_info * medias = NULL; static void find_media(void) @@ -125,7 +136,7 @@ static void find_media(void) int fd; if (!medias) - pci_probing(SCSI_ADAPTERS); + probe_that_type(SCSI_ADAPTERS); else free(medias); /* that does not free the strings, by the way */ @@ -196,7 +207,6 @@ static void find_media(void) } - /* ----------------------------------------------- */ log_message("looking for scsi media"); @@ -318,7 +328,6 @@ static void find_media(void) end_scsi: } - /* ----------------------------------------------- */ tmp[count].name = NULL; count++; @@ -357,8 +366,10 @@ void get_medias(enum media_type media, char *** names, char *** models) *models = (char **) malloc(sizeof(char *) * count); memcpy(*models, tmp_models, sizeof(char *) * count); } +#endif /* DISABLE_MEDIAS */ +#ifndef DISABLE_NETWORK int net_device_available(char * device) { struct ifreq req; int s; @@ -392,8 +403,11 @@ char ** get_net_devices(void) char * tmp[50]; char ** results; int i = 0; + static int already_probed = 0; - pci_probing(NETWORK_DEVICES); + if (!already_probed) + probe_that_type(NETWORK_DEVICES); + already_probed = 1; while (ptr && *ptr) { if (net_device_available(*ptr)) { @@ -409,3 +423,4 @@ char ** get_net_devices(void) return results; } +#endif /* DISABLE_NETWORK */ diff --git a/mdk-stage1/probing.h b/mdk-stage1/probing.h index 42ea2f986..98b5a75f1 100644 --- a/mdk-stage1/probing.h +++ b/mdk-stage1/probing.h @@ -38,7 +38,7 @@ enum media_query_type { QUERY_NAME, QUERY_MODEL }; enum driver_type { SCSI_ADAPTERS, NETWORK_DEVICES }; -void pci_probing(enum driver_type type); +void probe_that_type(enum driver_type type); void get_medias(enum media_type media, char *** names, char *** models); char ** get_net_devices(void); diff --git a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 Binary files differindex 082976ffa..71fd37d25 100644 --- a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 +++ b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index b99435c59..db75719e8 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -39,9 +39,18 @@ #include "frontend.h" #include "modules.h" #include "tools.h" + +#ifndef DISABLE_CDROM #include "cdrom.h" +#endif + +#ifndef DISABLE_NETWORK #include "network.h" +#endif + +#ifndef DISABLE_DISK #include "disk.h" +#endif /* globals */ @@ -98,11 +107,17 @@ void spawn_shell(void) enum return_type method_select_and_prepare(void) { +#ifndef DISABLE_DISK char * disk_install = "Hard disk"; +#endif +#ifndef DISABLE_CDROM char * cdrom_install = "CDROM drive"; +#endif +#ifndef DISABLE_NETWORK char * network_nfs_install = "NFS server"; char * network_ftp_install = "FTP server"; char * network_http_install = "HTTP server"; +#endif enum return_type results; char * choice; char * means[10]; @@ -127,16 +142,28 @@ enum return_type method_select_and_prepare(void) if (results != RETURN_OK) return results; + results = RETURN_ERROR; + +#ifndef DISABLE_CDROM if (!strcmp(choice, cdrom_install)) results = cdrom_prepare(); - else if (!strcmp(choice, disk_install)) +#endif + +#ifndef DISABLE_DISK + if (!strcmp(choice, disk_install)) results = disk_prepare(); - else if (!strcmp(choice, network_nfs_install)) +#endif + +#ifndef DISABLE_NETWORK + if (!strcmp(choice, network_nfs_install)) results = nfs_prepare(); - else if (!strcmp(choice, network_ftp_install)) + + if (!strcmp(choice, network_ftp_install)) results = ftp_prepare(); - else if (!strcmp(choice, network_http_install)) + + if (!strcmp(choice, network_http_install)) results = http_prepare(); +#endif if (results != RETURN_OK) method_select_and_prepare(); @@ -162,6 +189,7 @@ int main(int argc, char **argv) fatal_error("could not open and parse modules dependencies"); init_frontend(); +#ifndef DISABLE_CDROM if (IS_CDROM) { /* try as automatic as possible with cdrom bootdisk */ ret = cdrom_prepare(); @@ -169,6 +197,7 @@ int main(int argc, char **argv) ret = method_select_and_prepare(); } else +#endif ret = method_select_and_prepare(); finish_frontend(); diff --git a/mdk-stage1/stdio-frontend.c b/mdk-stage1/stdio-frontend.c index 095c269a0..6d1a64afd 100644 --- a/mdk-stage1/stdio-frontend.c +++ b/mdk-stage1/stdio-frontend.c @@ -59,12 +59,20 @@ static int get_int_response(void) return i; } +static char * get_string_response(void) +{ + char s[50]; + fflush(stdout); + scanf(" %50s", s); + return strdup(s); +} + static void blocking_msg(char *type, char *fmt, va_list args) { printf(type); vprintf(fmt, args); get_any_response(); - printf("\n"); +// printf("\n"); } void error_message(char *msg, ...) @@ -80,7 +88,7 @@ void info_message(char *msg, ...) va_list args; va_start(args, msg); va_end(args); - blocking_msg("> Info! ", msg, args); + blocking_msg("> Notice: ", msg, args); } void wait_message(char *msg, ...) @@ -108,7 +116,7 @@ void init_progression(char *msg, int size) size_progress = size; actually_drawn = 0; printf("%s\n[", msg); - for (i=0; i<40; i++) + for (i=0; i<60; i++) printf("."); printf("]\033[G["); /* only works on ANSI-compatibles */ fflush(stdout); @@ -116,7 +124,7 @@ void init_progression(char *msg, int size) void update_progression(int current_size) { - while ((int)((current_size*40)/size_progress) > actually_drawn) { + while ((int)((current_size*60)/size_progress) > actually_drawn) { printf("*"); actually_drawn++; } @@ -202,3 +210,35 @@ enum return_type ask_yes_no(char *msg) return RETURN_BACK; else return RETURN_ERROR; } + + +enum return_type ask_from_entries(char *msg, char ** questions, char *** answers, int entry_size) +{ + int j, i = 0; + + printf("> %s (`-' for void answer)\n", msg); + + while (questions && *questions) { + printf("(%d) %s\n", i, *questions); + i++; + questions++; + } + + *answers = (char **) malloc(sizeof(char *) * i); + + while (1) { + int r; + for (j = 0 ; j < i ; j++) { + printf("(%d) ? ", j); + (*answers)[j] = get_string_response(); + if (!strcmp((*answers)[j], "-")) + (*answers)[j] = strdup(""); + } + printf("(0) Cancel (1) Accept (2) Re-enter answers\n? "); + r = get_int_response(); + if (r == 0) + return RETURN_BACK; + if (r == 1) + return RETURN_OK; + } +} diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index c1e934ab0..2fae6acea 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -250,7 +250,7 @@ enum return_type load_ramdisk(void) end_progression(); - gzclose(st2); + gzclose(st2); /* opened by gzdopen, but also closes the associated fd */ close(ram_fd); if (IS_RESCUE) |