diff options
author | Guillaume Cottenceau <gc@mandriva.com> | 2000-12-16 22:03:06 +0000 |
---|---|---|
committer | Guillaume Cottenceau <gc@mandriva.com> | 2000-12-16 22:03:06 +0000 |
commit | 2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915 (patch) | |
tree | 9e3e67b830f02fb32f528f391bb72a1deddade6c | |
parent | c930e6cc7e11b72ab1786f209dffb49a11bea8f7 (diff) | |
download | drakx-2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915.tar drakx-2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915.tar.gz drakx-2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915.tar.bz2 drakx-2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915.tar.xz drakx-2766c6bb69ced7c4f33ec9d8bda56ba5b66e2915.zip |
- network/nfs works
-rw-r--r-- | mdk-stage1/Makefile | 2 | ||||
-rw-r--r-- | mdk-stage1/cdrom.c | 3 | ||||
-rw-r--r-- | mdk-stage1/dns.c | 154 | ||||
-rw-r--r-- | mdk-stage1/dns.h | 30 | ||||
-rw-r--r-- | mdk-stage1/modules.c | 8 | ||||
-rw-r--r-- | mdk-stage1/mount.c | 29 | ||||
-rw-r--r-- | mdk-stage1/mount.h | 4 | ||||
-rw-r--r-- | mdk-stage1/mount_rpcgen.h | 208 | ||||
-rw-r--r-- | mdk-stage1/network.c | 62 | ||||
-rw-r--r-- | mdk-stage1/nfsmount.c | 292 | ||||
-rw-r--r-- | mdk-stage1/nfsmount.h | 328 | ||||
-rw-r--r-- | mdk-stage1/probing.c | 24 | ||||
-rw-r--r-- | mdk-stage1/stage1.c | 3 | ||||
-rw-r--r-- | mdk-stage1/stdio-frontend.c | 16 | ||||
-rw-r--r-- | mdk-stage1/tools.c | 19 | ||||
-rw-r--r-- | mdk-stage1/tools.h | 1 |
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 |