summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/Makefile2
-rw-r--r--mdk-stage1/cdrom.c3
-rw-r--r--mdk-stage1/dns.c154
-rw-r--r--mdk-stage1/dns.h30
-rw-r--r--mdk-stage1/modules.c8
-rw-r--r--mdk-stage1/mount.c29
-rw-r--r--mdk-stage1/mount.h4
-rw-r--r--mdk-stage1/mount_rpcgen.h208
-rw-r--r--mdk-stage1/network.c62
-rw-r--r--mdk-stage1/nfsmount.c292
-rw-r--r--mdk-stage1/nfsmount.h328
-rw-r--r--mdk-stage1/probing.c24
-rw-r--r--mdk-stage1/stage1.c3
-rw-r--r--mdk-stage1/stdio-frontend.c16
-rw-r--r--mdk-stage1/tools.c19
-rw-r--r--mdk-stage1/tools.h1
16 files changed, 1135 insertions, 48 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile
index 5cefa06fe..5df003dbd 100644
--- a/mdk-stage1/Makefile
+++ b/mdk-stage1/Makefile
@@ -67,7 +67,7 @@ STAGE1_NETWORK_LIBS = /usr/lib/libresolv.a
STAGE1SRC = stage1.c log.c tools.c modules.c probing.c mount.c
CDROMSRC = cdrom.c
DISKSRC = disk.c
-NETWORKSRC = network.c dns.c
+NETWORKSRC = network.c dns.c nfsmount.c
ALLSRC = $(INITSRC) $(STAGE1SRC) $(CDROMSRC) $(DISKSRC) $(NETWORKSRC)
diff --git a/mdk-stage1/cdrom.c b/mdk-stage1/cdrom.c
index 901d4ac5c..ba985f563 100644
--- a/mdk-stage1/cdrom.c
+++ b/mdk-stage1/cdrom.c
@@ -63,7 +63,8 @@ static enum return_type try_with_device(char *dev_name)
if (IS_SPECIAL_STAGE2 || ramdisk_possible())
load_ramdisk(); /* we don't care about return code, we'll do it live if we failed */
- if (IS_RESCUE) umount("/tmp/image"); /* TOCHECK */
+ if (IS_RESCUE)
+ umount("/tmp/image"); /* TOCHECK */
method_name = strdup("cdrom");
return RETURN_OK;
diff --git a/mdk-stage1/dns.c b/mdk-stage1/dns.c
new file mode 100644
index 000000000..ca750536a
--- /dev/null
+++ b/mdk-stage1/dns.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <alloca.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "log.h"
+
+#include "dns.h"
+
+/* This is dumb, but glibc doesn't like to do hostname lookups w/o libc.so */
+
+union dns_response {
+ HEADER hdr;
+ u_char buf[PACKETSZ];
+} ;
+
+static int do_query(char * query, int queryType, char ** domainName, struct in_addr * ipNum)
+{
+ int len, ancount, type;
+ u_char * data, * end;
+ char name[MAXDNAME];
+ union dns_response response;
+
+#ifdef __sparc__
+ /* from jj: */
+ /* We have to wait till ethernet negotiation is done */
+ _res.retry = 3;
+#else
+ _res.retry = 2;
+#endif
+
+
+ len = res_search(query, C_IN, queryType, (void *) &response, sizeof(response));
+ if (len <= 0)
+ return -1;
+
+ if (ntohs(response.hdr.rcode) != NOERROR)
+ return -1;
+
+ ancount = ntohs(response.hdr.ancount);
+ if (ancount < 1)
+ return -1;
+
+ data = response.buf + sizeof(HEADER);
+ end = response.buf + len;
+
+ /* skip the question */
+ data += dn_skipname(data, end) + QFIXEDSZ;
+
+ /* parse the answer(s) */
+ while (--ancount >= 0 && data < end) {
+
+ /* skip the domain name portion of the RR record */
+ data += dn_skipname(data, end);
+
+ /* get RR information */
+ GETSHORT(type, data);
+ data += INT16SZ; /* skipp class */
+ data += INT32SZ; /* skipp TTL */
+ GETSHORT(len, data);
+
+ if (type == T_PTR) {
+ /* we got a pointer */
+ len = dn_expand(response.buf, end, data, name, sizeof(name));
+ if (len <= 0) return -1;
+ if (queryType == T_PTR && domainName) {
+ /* we wanted a pointer */
+ *domainName = malloc(strlen(name) + 1);
+ strcpy(*domainName, name);
+ return 0;
+ }
+ } else if (type == T_A) {
+ /* we got an address */
+ if (queryType == T_A && ipNum) {
+ /* we wanted an address */
+ memcpy(ipNum, data, sizeof(*ipNum));
+ return 0;
+ }
+ }
+
+ /* move ahead to next RR */
+ data += len;
+ }
+
+ return -1;
+}
+
+char * mygethostbyaddr(char * ipnum) {
+ int rc;
+ char * result;
+ char * strbuf;
+ char * chptr;
+ char * splits[4];
+ int i;
+
+ _res.retry = 1;
+
+ strbuf = alloca(strlen(ipnum) + 1);
+ strcpy(strbuf, ipnum);
+
+ ipnum = alloca(strlen(strbuf) + 20);
+
+ for (i = 0; i < 4; i++) {
+ chptr = strbuf;
+ while (*chptr && *chptr != '.')
+ chptr++;
+ *chptr = '\0';
+
+ if (chptr - strbuf > 3) return NULL;
+ splits[i] = strbuf;
+ strbuf = chptr + 1;
+ }
+
+ sprintf(ipnum, "%s.%s.%s.%s.in-addr.arpa", splits[3], splits[2], splits[1], splits[0]);
+
+ rc = do_query(ipnum, T_PTR, &result, NULL);
+
+ if (rc)
+ return NULL;
+ else
+ return result;
+}
+
+int mygethostbyname(char * name, struct in_addr * addr) {
+ int rc = do_query(name, T_A, NULL, addr);
+ if (!rc)
+ log_message("%s is-at %s", name, inet_ntoa(*addr));
+ return rc;
+}
diff --git a/mdk-stage1/dns.h b/mdk-stage1/dns.h
new file mode 100644
index 000000000..97af9c08a
--- /dev/null
+++ b/mdk-stage1/dns.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 H_DNS
+#define H_DNS
+
+#include <netinet/in.h>
+
+int mygethostbyname(char * name, struct in_addr * addr);
+char * mygethostbyaddr(char * ipnum);
+
+#endif
diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c
index 1b3e91d84..b3376520d 100644
--- a/mdk-stage1/modules.c
+++ b/mdk-stage1/modules.c
@@ -146,19 +146,17 @@ int load_modules_dependencies(void)
while (start && *start) {
ptr = strchr(start, ' ');
if (ptr) *ptr = '\0';
- tmp_deps[i] = strdup(start);
+ tmp_deps[i++] = strdup(start);
if (ptr)
start = ptr + 1;
else
start = NULL;
- i++;
while (start && *start && *start == ' ')
start++;
}
- tmp_deps[i] = NULL;
+ 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));
+ modules_deps[line].deps = memdup(tmp_deps, sizeof(char *) * i);
line++;
start = end + 1;
diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c
index 15533e716..ade92adf5 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)
@@ -106,11 +107,12 @@ int my_mount(char *dev, char *location, char *fs)
int rc;
#ifndef DISABLE_MEDIAS
- rc = ensure_dev_exists(dev);
-
- if (rc != 0) {
- log_message("could not create required device file");
- return -1;
+ if (strcmp(fs, "nfs")) {
+ rc = ensure_dev_exists(dev);
+ if (rc != 0) {
+ log_message("could not create required device file");
+ return -1;
+ }
}
#endif
@@ -147,6 +149,23 @@ int my_mount(char *dev, char *location, char *fs)
}
#endif
+#ifndef DISABLE_NETWORK
+ if (!strcmp(fs, "nfs")) {
+ int flags = 0;
+
+ my_insmod("nfs");
+ flags |= MS_RDONLY;
+
+ log_message("preparing nfsmount for %s", dev);
+
+ rc = nfsmount_prepare(dev, &flags, &opts);
+ if (rc != 0) {
+ log_perror(dev);
+ return rc;
+ }
+ }
+#endif
+
rc = mount(dev, location, fs, flags, opts);
if (rc != 0)
diff --git a/mdk-stage1/mount.h b/mdk-stage1/mount.h
index 6ab4da559..b679e5c30 100644
--- a/mdk-stage1/mount.h
+++ b/mdk-stage1/mount.h
@@ -22,6 +22,10 @@
#ifndef _MOUNT_H_
#define _MOUNT_H_
+#ifndef DISABLE_NETWORK
+#include "nfsmount.h"
+#endif
+
int my_mount(char *dev, char *location, char *fs);
#endif
diff --git a/mdk-stage1/mount_rpcgen.h b/mdk-stage1/mount_rpcgen.h
new file mode 100644
index 000000000..d70ccaf9d
--- /dev/null
+++ b/mdk-stage1/mount_rpcgen.h
@@ -0,0 +1,208 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _MOUNT_H_RPCGEN
+#define _MOUNT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE 32
+
+typedef char fhandle[FHSIZE];
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhandle(XDR *, fhandle);
+#elif __STDC__
+extern bool_t xdr_fhandle(XDR *, fhandle);
+#else /* Old Style C */
+bool_t xdr_fhandle();
+#endif /* Old Style C */
+
+
+struct fhstatus {
+ u_int fhs_status;
+ union {
+ fhandle fhs_fhandle;
+ } fhstatus_u;
+};
+typedef struct fhstatus fhstatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
+#elif __STDC__
+extern bool_t xdr_fhstatus(XDR *, fhstatus*);
+#else /* Old Style C */
+bool_t xdr_fhstatus();
+#endif /* Old Style C */
+
+
+typedef char *dirpath;
+#ifdef __cplusplus
+extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
+#elif __STDC__
+extern bool_t xdr_dirpath(XDR *, dirpath*);
+#else /* Old Style C */
+bool_t xdr_dirpath();
+#endif /* Old Style C */
+
+
+typedef char *name;
+#ifdef __cplusplus
+extern "C" bool_t xdr_name(XDR *, name*);
+#elif __STDC__
+extern bool_t xdr_name(XDR *, name*);
+#else /* Old Style C */
+bool_t xdr_name();
+#endif /* Old Style C */
+
+
+typedef struct mountbody *mountlist;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
+#elif __STDC__
+extern bool_t xdr_mountlist(XDR *, mountlist*);
+#else /* Old Style C */
+bool_t xdr_mountlist();
+#endif /* Old Style C */
+
+
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
+#elif __STDC__
+extern bool_t xdr_mountbody(XDR *, mountbody*);
+#else /* Old Style C */
+bool_t xdr_mountbody();
+#endif /* Old Style C */
+
+
+typedef struct groupnode *groups;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groups(XDR *, groups*);
+#elif __STDC__
+extern bool_t xdr_groups(XDR *, groups*);
+#else /* Old Style C */
+bool_t xdr_groups();
+#endif /* Old Style C */
+
+
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+typedef struct groupnode groupnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
+#elif __STDC__
+extern bool_t xdr_groupnode(XDR *, groupnode*);
+#else /* Old Style C */
+bool_t xdr_groupnode();
+#endif /* Old Style C */
+
+
+typedef struct exportnode *exports;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exports(XDR *, exports*);
+#elif __STDC__
+extern bool_t xdr_exports(XDR *, exports*);
+#else /* Old Style C */
+bool_t xdr_exports();
+#endif /* Old Style C */
+
+
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+typedef struct exportnode exportnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
+#elif __STDC__
+extern bool_t xdr_exportnode(XDR *, exportnode*);
+#else /* Old Style C */
+bool_t xdr_exportnode();
+#endif /* Old Style C */
+
+
+#define MOUNTPROG ((u_long)100005)
+#define MOUNTVERS ((u_long)1)
+
+#ifdef __cplusplus
+#define MOUNTPROC_NULL ((u_long)0)
+extern "C" void * mountproc_null_1(void *, CLIENT *);
+extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT ((u_long)1)
+extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP ((u_long)2)
+extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
+extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT ((u_long)3)
+extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern "C" void * mountproc_umntall_1(void *, CLIENT *);
+extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern "C" exports * mountproc_export_1(void *, CLIENT *);
+extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
+extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+
+#elif __STDC__
+#define MOUNTPROC_NULL ((u_long)0)
+extern void * mountproc_null_1(void *, CLIENT *);
+extern void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT ((u_long)1)
+extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP ((u_long)2)
+extern mountlist * mountproc_dump_1(void *, CLIENT *);
+extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT ((u_long)3)
+extern void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern void * mountproc_umntall_1(void *, CLIENT *);
+extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern exports * mountproc_export_1(void *, CLIENT *);
+extern exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern exports * mountproc_exportall_1(void *, CLIENT *);
+extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+
+#else /* Old Style C */
+#define MOUNTPROC_NULL ((u_long)0)
+extern void * mountproc_null_1();
+extern void * mountproc_null_1_svc();
+#define MOUNTPROC_MNT ((u_long)1)
+extern fhstatus * mountproc_mnt_1();
+extern fhstatus * mountproc_mnt_1_svc();
+#define MOUNTPROC_DUMP ((u_long)2)
+extern mountlist * mountproc_dump_1();
+extern mountlist * mountproc_dump_1_svc();
+#define MOUNTPROC_UMNT ((u_long)3)
+extern void * mountproc_umnt_1();
+extern void * mountproc_umnt_1_svc();
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern void * mountproc_umntall_1();
+extern void * mountproc_umntall_1_svc();
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern exports * mountproc_export_1();
+extern exports * mountproc_export_1_svc();
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern exports * mountproc_exportall_1();
+extern exports * mountproc_exportall_1_svc();
+#endif /* Old Style C */
+
+#endif /* !_MOUNT_H_RPCGEN */
diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c
index 31042b1f6..dbce28113 100644
--- a/mdk-stage1/network.c
+++ b/mdk-stage1/network.c
@@ -28,6 +28,7 @@
#include <net/route.h>
#include <resolv.h>
#include <sys/ioctl.h>
+#include <sys/mount.h>
#include <stdio.h>
#include "stage1.h"
@@ -36,6 +37,7 @@
#include "probing.h"
#include "log.h"
#include "dns.h"
+#include "mount.h"
#include "network.h"
@@ -342,8 +344,6 @@ 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);
@@ -371,7 +371,7 @@ static enum return_type configure_network(struct interface_info * intf)
}
else {
hostname = strdup(name);
- domain = strchr(strdup(name), '.');
+ domain = strchr(strdup(name), '.') + 1;
}
return RETURN_OK;
@@ -399,6 +399,7 @@ static enum return_type bringup_networking(struct interface_info * intf)
break;
case BRINGUP_CONF:
+ write_resolvconf();
results = configure_network(intf);
if (results != RETURN_OK)
step = BRINGUP_NET;
@@ -499,14 +500,61 @@ static enum return_type intf_select_and_up(void)
}
while (results == RETURN_BACK);
- return RETURN_ERROR;
+ return RETURN_OK;
}
+
+
enum return_type nfs_prepare(void)
{
+ char * questions[] = { "NFS server name", "Linux-Mandrake directory", NULL };
+ char ** answers;
+ char * nfsmount_location;
enum return_type results = intf_select_and_up();
- return results;
+ if (results != RETURN_OK)
+ return results;
+
+ do {
+ results = ask_from_entries("Please enter the name or IP address of your NFS server, "
+ "and the directory containing the Linux-Mandrake installation.",
+ questions, &answers, 40);
+ if (results != RETURN_OK)
+ return nfs_prepare();
+
+ nfsmount_location = malloc(strlen(answers[0]) + strlen(answers[1]) + 2);
+ strcpy(nfsmount_location, answers[0]);
+ strcat(nfsmount_location, ":");
+ strcat(nfsmount_location, answers[1]);
+
+ if (my_mount(nfsmount_location, "/tmp/image", "nfs") == -1) {
+ error_message("I can't mount the directory from the NFS server.");
+ results = RETURN_BACK;
+ continue;
+ }
+
+ if (access("/tmp/image/Mandrake/mdkinst", R_OK)) {
+ error_message("That NFS volume does not seem to contain the Linux-Mandrake Installation.");
+ umount("/tmp/image");
+ results = RETURN_BACK;
+ }
+ }
+ while (results == RETURN_BACK);
+
+ log_message("found the Linux-Mandrake Installation, good news!");
+
+ if (IS_SPECIAL_STAGE2) {
+ if (load_ramdisk() != RETURN_OK) {
+ error_message("Could not load program into memory");
+ return nfs_prepare();
+ }
+ }
+
+ if (IS_RESCUE)
+ umount("/tmp/image"); /* TOCHECK */
+
+ method_name = strdup("nfs");
+ return RETURN_OK;
}
@@ -514,12 +562,12 @@ enum return_type ftp_prepare(void)
{
enum return_type results = intf_select_and_up();
- return results;
+ return RETURN_ERROR | results;
}
enum return_type http_prepare(void)
{
enum return_type results = intf_select_and_up();
- return results;
+ return RETURN_ERROR | results;
}
diff --git a/mdk-stage1/nfsmount.c b/mdk-stage1/nfsmount.c
new file mode 100644
index 000000000..6cc692273
--- /dev/null
+++ b/mdk-stage1/nfsmount.c
@@ -0,0 +1,292 @@
+/*
+ * 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.
+ *
+ */
+
+/* this is based on work from redhat, made it lighter (gc)
+ */
+
+
+/* MODIFIED for Red Hat Linux installer
+ * msw@redhat.com
+ * o always mounts without lockd
+ * o uses our own host resolution
+ */
+
+/*
+ * nfsmount.c -- Linux NFS mount
+ * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Wed Feb 8 12:51:48 1995, biro@yggdrasil.com (Ross Biro): allow all port
+ * numbers to be specified on the command line.
+ *
+ * Fri, 8 Mar 1996 18:01:39, Swen Thuemmler <swen@uni-paderborn.de>:
+ * Omit the call to connect() for Linux version 1.3.11 or later.
+ *
+ * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
+ * Implemented the "bg", "fg" and "retry" mount options for NFS.
+ */
+
+/*
+ * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/mount.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <linux/nfs.h>
+#include <linux/nfs_mount.h> //#include "mount_constants.h"
+
+
+#include "dns.h"
+#include "log.h"
+
+#include "nfsmount.h"
+
+
+bool_t
+xdr_fhandle(XDR *xdrs, fhandle objp)
+{
+ if (!xdr_opaque(xdrs, objp, FHSIZE)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_fhstatus(XDR *xdrs, fhstatus *objp)
+{
+
+ if (!xdr_u_int(xdrs, &objp->fhs_status)) {
+ return (FALSE);
+ }
+ switch (objp->fhs_status) {
+ case 0:
+ if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
+ return (FALSE);
+ }
+ break;
+ default:
+ break;
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_dirpath(XDR *xdrs, dirpath *objp)
+{
+
+ if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static int nfs_mount_version = 3; /* kernel >= 2.1.32 */ /* *********** TODO for kernel 2.4, nfs-mount version 4 */
+
+
+int nfsmount_prepare(const char *spec, int *flags, char **mount_opts)
+{
+ char hostdir[1024];
+ CLIENT *mclient;
+ char *hostname, *dirname;
+ fhandle root_fhandle;
+ struct timeval total_timeout;
+ enum clnt_stat clnt_stat;
+ static struct nfs_mount_data data;
+ struct sockaddr_in server_addr;
+ struct sockaddr_in mount_server_addr;
+ int msock, fsock;
+ struct timeval retry_timeout;
+ struct fhstatus status;
+ char *s;
+ int port;
+
+ msock = fsock = -1;
+ mclient = NULL;
+
+ strncpy(hostdir, spec, sizeof(hostdir));
+ if ((s = (strchr(hostdir, ':')))) {
+ hostname = hostdir;
+ dirname = s + 1;
+ *s = '\0';
+ } else {
+ log_message("nfsmount: format not host:dir");
+ goto fail;
+ }
+
+ server_addr.sin_family = AF_INET;
+
+ /* first, try as IP address */
+ if (!inet_aton(hostname, &server_addr.sin_addr)) {
+ /* failure, try as machine name */
+ if (mygethostbyname(hostname, &server_addr.sin_addr)) {
+ log_message("nfsmount: can't get address for %s", hostname);
+ goto fail;
+ } else
+ server_addr.sin_family = AF_INET;
+ }
+
+ memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
+
+
+
+ /* Set default options.
+ * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
+ * let the kernel decide.
+ * timeo is filled in after we know whether it'll be TCP or UDP. */
+ memset(&data, 0, sizeof(data));
+ data.retrans = 3;
+ data.acregmin = 3;
+ data.acregmax = 60;
+ data.acdirmin = 30;
+ data.acdirmax = 60;
+#if NFS_MOUNT_VERSION >= 2
+ data.namlen = NAME_MAX;
+#endif
+
+#if NFS_MOUNT_VERSION >= 3
+ if (nfs_mount_version >= 3)
+ data.flags |= NFS_MOUNT_NONLM; /* HACK HACK msw */
+#endif
+
+ /* Adjust options if none specified */
+ if (!data.timeo)
+ data.timeo = 7; /* udp */
+
+
+ data.version = nfs_mount_version;
+ *mount_opts = (char *) &data;
+
+ if (*flags & MS_REMOUNT)
+ return 0;
+
+
+ retry_timeout.tv_sec = 3;
+ retry_timeout.tv_usec = 0;
+ total_timeout.tv_sec = 20;
+ total_timeout.tv_usec = 0;
+
+
+ /* contact the mount daemon via TCP */
+ mount_server_addr.sin_port = htons(0);
+ msock = RPC_ANYSOCK;
+ mclient = clnttcp_create(&mount_server_addr, MOUNTPROG, MOUNTVERS, &msock, 0, 0);
+
+ /* if this fails, contact the mount daemon via UDP */
+ if (!mclient) {
+ mount_server_addr.sin_port = htons(0);
+ msock = RPC_ANYSOCK;
+ mclient = clntudp_create(&mount_server_addr, MOUNTPROG, MOUNTVERS, retry_timeout, &msock);
+ }
+ if (mclient) {
+ /* try to mount hostname:dirname */
+ mclient->cl_auth = authunix_create_default();
+ clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
+ (xdrproc_t) xdr_dirpath, (caddr_t) &dirname,
+ (xdrproc_t) xdr_fhstatus, (caddr_t) &status,
+ total_timeout);
+ if (clnt_stat != RPC_SUCCESS) {
+ if (errno != ECONNREFUSED) {
+ clnt_perror(mclient, "mount");
+ goto fail; /* don't retry */
+ }
+ clnt_perror(mclient, "mount");
+ auth_destroy(mclient->cl_auth);
+ clnt_destroy(mclient);
+ mclient = 0;
+ close(msock);
+ }
+ } else
+ goto fail;
+
+ if (status.fhs_status != 0) {
+ log_message("nfsmount prepare failed, reason given by server: %d", status.fhs_status);
+ goto fail;
+ }
+
+ memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle, sizeof (root_fhandle));
+
+ /* create nfs socket for kernel */
+
+ fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fsock < 0) {
+ perror("nfs socket");
+ goto fail;
+ }
+ if (bindresvport(fsock, 0) < 0) {
+ perror("nfs bindresvport");
+ goto fail;
+ }
+ server_addr.sin_port = PMAPPORT;
+ port = pmap_getport(&server_addr, NFS_PROGRAM, NFS_VERSION, IPPROTO_UDP);
+ if (port == 0)
+ port = NFS_PORT;
+#ifdef NFS_MOUNT_DEBUG
+ else
+ log_message("used portmapper to find NFS port\n");
+ log_message("using port %d for nfs deamon\n", port);
+#endif
+ server_addr.sin_port = htons(port);
+
+ /* prepare data structure for kernel */
+
+ data.fd = fsock;
+ memcpy((char *) &data.root, (char *) &root_fhandle, sizeof (root_fhandle));
+ memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
+ strncpy(data.hostname, hostname, sizeof(data.hostname));
+
+ /* clean up */
+
+ auth_destroy(mclient->cl_auth);
+ clnt_destroy(mclient);
+ close(msock);
+ return 0;
+
+ /* abort */
+
+ fail:
+ if (msock != -1) {
+ if (mclient) {
+ auth_destroy(mclient->cl_auth);
+ clnt_destroy(mclient);
+ }
+ close(msock);
+ }
+ if (fsock != -1)
+ close(fsock);
+
+ return -1;
+}
+
diff --git a/mdk-stage1/nfsmount.h b/mdk-stage1/nfsmount.h
new file mode 100644
index 000000000..12ffa69a6
--- /dev/null
+++ b/mdk-stage1/nfsmount.h
@@ -0,0 +1,328 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NFSMOUNT_H_RPCGEN
+#define _NFSMOUNT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+int nfsmount_prepare(const char *spec, int *flags, char **mount_opts);
+
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
+ */
+
+/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
+#ifndef _rpcsvc_mount_h
+#define _rpcsvc_mount_h
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE 32
+
+typedef char fhandle[FHSIZE];
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhandle(XDR *, fhandle);
+#elif __STDC__
+extern bool_t xdr_fhandle(XDR *, fhandle);
+#else /* Old Style C */
+bool_t xdr_fhandle();
+#endif /* Old Style C */
+
+
+struct fhstatus {
+ u_int fhs_status;
+ union {
+ fhandle fhs_fhandle;
+ } fhstatus_u;
+};
+typedef struct fhstatus fhstatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
+#elif __STDC__
+extern bool_t xdr_fhstatus(XDR *, fhstatus*);
+#else /* Old Style C */
+bool_t xdr_fhstatus();
+#endif /* Old Style C */
+
+
+typedef char *dirpath;
+#ifdef __cplusplus
+extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
+#elif __STDC__
+extern bool_t xdr_dirpath(XDR *, dirpath*);
+#else /* Old Style C */
+bool_t xdr_dirpath();
+#endif /* Old Style C */
+
+
+typedef char *name;
+#ifdef __cplusplus
+extern "C" bool_t xdr_name(XDR *, name*);
+#elif __STDC__
+extern bool_t xdr_name(XDR *, name*);
+#else /* Old Style C */
+bool_t xdr_name();
+#endif /* Old Style C */
+
+
+typedef struct mountbody *mountlist;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
+#elif __STDC__
+extern bool_t xdr_mountlist(XDR *, mountlist*);
+#else /* Old Style C */
+bool_t xdr_mountlist();
+#endif /* Old Style C */
+
+
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
+#elif __STDC__
+extern bool_t xdr_mountbody(XDR *, mountbody*);
+#else /* Old Style C */
+bool_t xdr_mountbody();
+#endif /* Old Style C */
+
+
+typedef struct groupnode *groups;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groups(XDR *, groups*);
+#elif __STDC__
+extern bool_t xdr_groups(XDR *, groups*);
+#else /* Old Style C */
+bool_t xdr_groups();
+#endif /* Old Style C */
+
+
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+typedef struct groupnode groupnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
+#elif __STDC__
+extern bool_t xdr_groupnode(XDR *, groupnode*);
+#else /* Old Style C */
+bool_t xdr_groupnode();
+#endif /* Old Style C */
+
+
+typedef struct exportnode *exports;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exports(XDR *, exports*);
+#elif __STDC__
+extern bool_t xdr_exports(XDR *, exports*);
+#else /* Old Style C */
+bool_t xdr_exports();
+#endif /* Old Style C */
+
+
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+typedef struct exportnode exportnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
+#elif __STDC__
+extern bool_t xdr_exportnode(XDR *, exportnode*);
+#else /* Old Style C */
+bool_t xdr_exportnode();
+#endif /* Old Style C */
+
+
+struct ppathcnf {
+ int pc_link_max;
+ short pc_max_canon;
+ short pc_max_input;
+ short pc_name_max;
+ short pc_path_max;
+ short pc_pipe_buf;
+ u_char pc_vdisable;
+ char pc_xxx;
+ short pc_mask[2];
+};
+typedef struct ppathcnf ppathcnf;
+#ifdef __cplusplus
+extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
+#elif __STDC__
+extern bool_t xdr_ppathcnf(XDR *, ppathcnf*);
+#else /* Old Style C */
+bool_t xdr_ppathcnf();
+#endif /* Old Style C */
+
+#endif /*!_rpcsvc_mount_h*/
+
+#define MOUNTPROG ((u_long)100005)
+#define MOUNTVERS ((u_long)1)
+
+#ifdef __cplusplus
+#define MOUNTPROC_NULL ((u_long)0)
+extern "C" void * mountproc_null_1(void *, CLIENT *);
+extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT ((u_long)1)
+extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP ((u_long)2)
+extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
+extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT ((u_long)3)
+extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern "C" void * mountproc_umntall_1(void *, CLIENT *);
+extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern "C" exports * mountproc_export_1(void *, CLIENT *);
+extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
+extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+
+#elif __STDC__
+#define MOUNTPROC_NULL ((u_long)0)
+extern void * mountproc_null_1(void *, CLIENT *);
+extern void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT ((u_long)1)
+extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP ((u_long)2)
+extern mountlist * mountproc_dump_1(void *, CLIENT *);
+extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT ((u_long)3)
+extern void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern void * mountproc_umntall_1(void *, CLIENT *);
+extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern exports * mountproc_export_1(void *, CLIENT *);
+extern exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern exports * mountproc_exportall_1(void *, CLIENT *);
+extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+
+#else /* Old Style C */
+#define MOUNTPROC_NULL ((u_long)0)
+extern void * mountproc_null_1();
+extern void * mountproc_null_1_svc();
+#define MOUNTPROC_MNT ((u_long)1)
+extern fhstatus * mountproc_mnt_1();
+extern fhstatus * mountproc_mnt_1_svc();
+#define MOUNTPROC_DUMP ((u_long)2)
+extern mountlist * mountproc_dump_1();
+extern mountlist * mountproc_dump_1_svc();
+#define MOUNTPROC_UMNT ((u_long)3)
+extern void * mountproc_umnt_1();
+extern void * mountproc_umnt_1_svc();
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern void * mountproc_umntall_1();
+extern void * mountproc_umntall_1_svc();
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern exports * mountproc_export_1();
+extern exports * mountproc_export_1_svc();
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern exports * mountproc_exportall_1();
+extern exports * mountproc_exportall_1_svc();
+#endif /* Old Style C */
+#define MOUNTVERS_POSIX ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" void * mountproc_null_2(void *, CLIENT *);
+extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
+extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
+extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
+extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
+extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
+extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
+extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
+extern "C" void * mountproc_umntall_2(void *, CLIENT *);
+extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
+extern "C" exports * mountproc_export_2(void *, CLIENT *);
+extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
+extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
+extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
+#define MOUNTPROC_PATHCONF ((u_long)7)
+extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
+extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+
+#elif __STDC__
+extern void * mountproc_null_2(void *, CLIENT *);
+extern void * mountproc_null_2_svc(void *, struct svc_req *);
+extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
+extern fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
+extern mountlist * mountproc_dump_2(void *, CLIENT *);
+extern mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
+extern void * mountproc_umnt_2(dirpath *, CLIENT *);
+extern void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
+extern void * mountproc_umntall_2(void *, CLIENT *);
+extern void * mountproc_umntall_2_svc(void *, struct svc_req *);
+extern exports * mountproc_export_2(void *, CLIENT *);
+extern exports * mountproc_export_2_svc(void *, struct svc_req *);
+extern exports * mountproc_exportall_2(void *, CLIENT *);
+extern exports * mountproc_exportall_2_svc(void *, struct svc_req *);
+#define MOUNTPROC_PATHCONF ((u_long)7)
+extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
+extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+
+#else /* Old Style C */
+extern void * mountproc_null_2();
+extern void * mountproc_null_2_svc();
+extern fhstatus * mountproc_mnt_2();
+extern fhstatus * mountproc_mnt_2_svc();
+extern mountlist * mountproc_dump_2();
+extern mountlist * mountproc_dump_2_svc();
+extern void * mountproc_umnt_2();
+extern void * mountproc_umnt_2_svc();
+extern void * mountproc_umntall_2();
+extern void * mountproc_umntall_2_svc();
+extern exports * mountproc_export_2();
+extern exports * mountproc_export_2_svc();
+extern exports * mountproc_exportall_2();
+extern exports * mountproc_exportall_2_svc();
+#define MOUNTPROC_PATHCONF ((u_long)7)
+extern ppathcnf * mountproc_pathconf_2();
+extern ppathcnf * mountproc_pathconf_2_svc();
+#endif /* Old Style C */
+
+#endif /* !_NFSMOUNT_H_RPCGEN */
diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c
index cb03876f4..83257ae39 100644
--- a/mdk-stage1/probing.c
+++ b/mdk-stage1/probing.c
@@ -22,7 +22,7 @@
/*
* This contains stuff related to probing:
- * (1) PCI devices
+ * (1) any (actually SCSI and NET only) devices (autoprobe for PCI)
* (2) IDE media
* (3) SCSI media
* (4) ETH devices
@@ -54,7 +54,7 @@ void probe_that_type(enum driver_type type)
if (IS_EXPERT)
ask_insmod(type);
else {
- /* probe for PCI devices */
+ /* ---- PCI probe */
char * mytype;
FILE * f;
int len = 0;
@@ -144,8 +144,8 @@ static void find_media(void)
log_message("looking for ide media");
count = 0;
- strcpy(b, "/proc/ide/hda");
- for (; b[12] <= 'm'; b[12]++) {
+ strcpy(b, "/proc/ide/hd");
+ for (b[12] = 'a'; b[12] <= 'h'; b[12]++) {
int i;
/* first, test if file exists (will tell if attached medium exists) */
@@ -332,8 +332,7 @@ static void find_media(void)
tmp[count].name = NULL;
count++;
- medias = (struct media_info *) malloc(sizeof(struct media_info) * count);
- memcpy(medias, tmp, sizeof(struct media_info) * count);
+ medias = memdup(tmp, sizeof(struct media_info) * count);
}
@@ -360,11 +359,8 @@ void get_medias(enum media_type media, char *** names, char *** models)
tmp_names[count] = NULL;
tmp_models[count++] = NULL;
- *names = (char **) malloc(sizeof(char *) * count);
- memcpy(*names, tmp_names, sizeof(char *) * count);
-
- *models = (char **) malloc(sizeof(char *) * count);
- memcpy(*models, tmp_models, sizeof(char *) * count);
+ *names = memdup(tmp_names, sizeof(char *) * count);
+ *models = memdup(tmp_models, sizeof(char *) * count);
}
#endif /* DISABLE_MEDIAS */
@@ -401,7 +397,6 @@ char ** get_net_devices(void)
};
char ** ptr = devices;
char * tmp[50];
- char ** results;
int i = 0;
static int already_probed = 0;
@@ -418,9 +413,6 @@ char ** get_net_devices(void)
}
tmp[i++] = NULL;
- results = (char **) malloc(sizeof(char *) * i);
- memcpy(results, tmp, sizeof(char *) * i);
-
- return results;
+ return memdup(tmp, sizeof(char *) * i);
}
#endif /* DISABLE_NETWORK */
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c
index db75719e8..4f72ab9d1 100644
--- a/mdk-stage1/stage1.c
+++ b/mdk-stage1/stage1.c
@@ -3,6 +3,9 @@
*
* Copyright 2000 MandrakeSoft
*
+ * View the homepage: http://us.mandrakesoft.com/~gc/html/stage1.html
+ *
+ *
* This software may be freely redistributed under the terms of the GNU
* public license.
*
diff --git a/mdk-stage1/stdio-frontend.c b/mdk-stage1/stdio-frontend.c
index 6d1a64afd..ae7a57af1 100644
--- a/mdk-stage1/stdio-frontend.c
+++ b/mdk-stage1/stdio-frontend.c
@@ -61,9 +61,15 @@ static int get_int_response(void)
static char * get_string_response(void)
{
+ /* I won't use a scanf/%s since I also want the null string to be accepted */
char s[50];
+ int i = 0;
fflush(stdout);
- scanf(" %50s", s);
+ read(0, &(s[i++]), 1);
+ fcntl(0, F_SETFL, O_NONBLOCK);
+ while (read(0, &(s[i++]), 1) > 0 && i < sizeof(s));
+ fcntl(0, F_SETFL, 0);
+ s[i-2] = '\0';
return strdup(s);
}
@@ -216,10 +222,10 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers
{
int j, i = 0;
- printf("> %s (`-' for void answer)\n", msg);
+ printf("> %s\n", msg);
while (questions && *questions) {
- printf("(%d) %s\n", i, *questions);
+ printf("(%c) %s\n", i + 'a', *questions);
i++;
questions++;
}
@@ -229,10 +235,8 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers
while (1) {
int r;
for (j = 0 ; j < i ; j++) {
- printf("(%d) ? ", j);
+ printf("(%c) ? ", j + 'a');
(*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();
diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c
index 2fae6acea..9420ed1dd 100644
--- a/mdk-stage1/tools.c
+++ b/mdk-stage1/tools.c
@@ -70,8 +70,7 @@ void process_cmdline(void)
i++;
continue;
}
- name = (char *) malloc(i-j + 1);
- memcpy(name, &buf[j], i-j);
+ name = memdup(&buf[j], i-j + 1);
name[i-j] = 0;
if (buf[i] == '=') {
@@ -79,8 +78,7 @@ void process_cmdline(void)
i++;
while (buf[i] != ' ' && buf[i] != 0)
i++;
- value = (char *) malloc(i-k + 1);
- memcpy(value, &buf[k], i-k);
+ value = memdup(&buf[k], i-k + 1);
value[i-k] = 0;
}
@@ -104,8 +102,7 @@ void process_cmdline(void)
tmp_params[p++].name = NULL;
- params = (struct cmdline_elem *) malloc(sizeof(struct cmdline_elem) * p);
- memcpy(params, tmp_params, sizeof(struct cmdline_elem) * p);
+ params = memdup(tmp_params, sizeof(struct cmdline_elem) * p);
log_message("\tgot %d args", p);
}
@@ -231,7 +228,7 @@ enum return_type load_ramdisk(void)
}
stat(img_name, &statr);
- init_progression("Loading Installation program into memory...", statr.st_size);
+ init_progression("Loading program into memory...", statr.st_size);
while (!gzeof(st2)) {
int actually = gzread(st2, buffer, sizeof(buffer));
@@ -264,3 +261,11 @@ enum return_type load_ramdisk(void)
return RETURN_OK;
}
+
+/* pixel's */
+void * memdup(void *src, size_t size)
+{
+ void * r = malloc(size);
+ memcpy(r, src, size);
+ return r;
+}
diff --git a/mdk-stage1/tools.h b/mdk-stage1/tools.h
index e975970c2..a21615891 100644
--- a/mdk-stage1/tools.h
+++ b/mdk-stage1/tools.h
@@ -29,6 +29,7 @@ void set_param(int i);
int total_memory(void);
int ramdisk_possible(void);
enum return_type load_ramdisk(void);
+void * memdup(void *src, size_t size);
#endif