summaryrefslogtreecommitdiffstats
path: root/mdk-stage1
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1')
-rw-r--r--mdk-stage1/Makefile82
-rw-r--r--mdk-stage1/config-stage1.h33
-rw-r--r--mdk-stage1/frontend.h1
-rw-r--r--mdk-stage1/mount.c6
-rw-r--r--mdk-stage1/network.c451
-rw-r--r--mdk-stage1/network.h28
-rw-r--r--mdk-stage1/newt-frontend.c32
-rw-r--r--mdk-stage1/pci-resource/Makefile6
-rwxr-xr-xmdk-stage1/pci-resource/update-pci-ids.pl7
-rw-r--r--mdk-stage1/probing.c39
-rw-r--r--mdk-stage1/probing.h2
-rw-r--r--mdk-stage1/stage1-data/stage1-with-sash.tar.bz2bin345069 -> 345037 bytes
-rw-r--r--mdk-stage1/stage1.c37
-rw-r--r--mdk-stage1/stdio-frontend.c48
-rw-r--r--mdk-stage1/tools.c2
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
index 082976ffa..71fd37d25 100644
--- a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2
+++ b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2
Binary files differ
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)