aboutsummaryrefslogtreecommitdiff
path: root/nfs/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'nfs/mount.c')
-rw-r--r--nfs/mount.c195
1 files changed, 129 insertions, 66 deletions
diff --git a/nfs/mount.c b/nfs/mount.c
index 59363073..6120f87a 100644
--- a/nfs/mount.c
+++ b/nfs/mount.c
@@ -1,5 +1,5 @@
-/*
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/*
+ Copyright (C) 1995,96,97,98,2001,02 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -18,22 +18,28 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-#include "nfs.h"
-
-#include <rpcsvc/mount.h>
+#define malloc a_byte_for_every_bozotic_sun_lossage_and_youd_need_a_lotta_ram
+#include <rpc/types.h>
+#undef TRUE /* Get rid of sun defs. */
+#undef FALSE
+#undef malloc
#include <rpc/pmap_prot.h>
#include <errno.h>
+#include <error.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
+#include "nfs.h"
+#include "mount.h"
+
/* Service name for portmapper */
char *pmap_service_name = "sunrpc";
/* Fallback port number for portmapper */
-short pmap_service_number = PMAPPORT;
+short pmap_service_number = PMAPPORT;
/* RPC program for mount server. */
int mount_program = MOUNTPROG;
@@ -59,11 +65,17 @@ short nfs_port = NFS_PORT;
/* True iff NFS_PORT should be used even if portmapper present. */
int nfs_port_override = 0;
+/* Host name and port number we actually decided to use. */
+const char *mounted_hostname;
+uint16_t mounted_nfs_port; /* host order */
+
+int protocol_version = 2;
+
/* Set up an RPC for procedure PROCNUM for talking to the portmapper.
Allocate storage with malloc and point *BUF at it; caller must free
this when done. Return the address where the args for the
procedure should be placed. */
-int *
+static int *
pmap_initialize_rpc (int procnum, void **buf)
{
return initialize_rpc (PMAPPROG, PMAPVERS, procnum, 0, buf, 0, 0, -1);
@@ -73,29 +85,38 @@ pmap_initialize_rpc (int procnum, void **buf)
server. Allocate storage with malloc and point *BUF at it; caller
must free this when done. Return the address where the args for
the procedure should be placed. */
-int *
+static int *
mount_initialize_rpc (int procnum, void **buf)
{
return initialize_rpc (MOUNTPROG, MOUNTVERS, procnum, 0, buf, 0, 0, -1);
}
/* Using the mount protocol, lookup NAME at host HOST.
- Return a node for it or null for an error. */
+ Return a node for it or null for an error. If an
+ error occurs, a message is automatically sent to stderr. */
struct node *
mount_root (char *name, char *host)
{
struct sockaddr_in addr;
struct hostent *h;
- struct servent *s;
int *p;
void *rpcbuf;
int port;
+ error_t err;
struct node *np;
short pmapport;
/* Lookup the portmapper port number */
if (pmap_service_name)
{
+ struct servent *s;
+
+ /* XXX This will always fail! pmap_service_name will always be "sunrpc"
+ What should pmap_service_name really be? By definition the second
+ argument is either "tcp" or "udp" Thus, is this backwards
+ (as service_name suggests)? If so, should it read:
+ s = getservbyname (pmap_service_name, "udp");
+ or is there something I am missing here? */
s = getservbyname ("sunrpc", pmap_service_name);
if (s)
pmapport = s->s_port;
@@ -112,103 +133,145 @@ mount_root (char *name, char *host)
herror (host);
return 0;
}
-
+
addr.sin_family = h->h_addrtype;
- bcopy (h->h_addr_list[0], &addr.sin_addr, h->h_length);
+ memcpy (&addr.sin_addr, h->h_addr_list[0], h->h_length);
addr.sin_port = pmapport;
-
- connect (main_udp_socket,
- (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
- if (!mount_port_override)
+ if (mount_port_override)
+ addr.sin_port = htons (mount_port);
+ else
{
/* Formulate and send a PMAPPROC_GETPORT request
to lookup the mount program on the server. */
+ if (connect (main_udp_socket, (struct sockaddr *)&addr,
+ sizeof (struct sockaddr_in)) == -1)
+ {
+ error (0, errno, "server mount program");
+ return 0;
+ }
+
p = pmap_initialize_rpc (PMAPPROC_GETPORT, &rpcbuf);
- *p++ = htonl (MOUNTPROG);
- *p++ = htonl (MOUNTVERS);
- *p++ = htonl (IPPROTO_UDP);
- *p++ = htonl (0);
- errno = conduct_rpc (&rpcbuf, &p);
- if (!errno)
+ if (! p)
{
- port = ntohl (*p++);
+ error (0, errno, "creating rpc packet");
+ return 0;
+ }
+
+ *(p++) = htonl (MOUNTPROG);
+ *(p++) = htonl (MOUNTVERS);
+ *(p++) = htonl (IPPROTO_UDP);
+ *(p++) = htonl (0);
+ err = conduct_rpc (&rpcbuf, &p);
+ if (!err)
+ {
+ port = ntohl (*p);
+ p++;
addr.sin_port = htons (port);
}
else if (mount_port)
addr.sin_port = htons (mount_port);
else
{
- free (rpcbuf);
- perror ("portmap of mount");
- return 0;
+ error (0, err, "portmap of mount");
+ goto error_with_rpcbuf;
}
free (rpcbuf);
}
- else
- addr.sin_port = htons (mount_port);
-
- /* Now talking to the mount program, fetch the file handle
+ /* Now, talking to the mount program, fetch a file handle
for the root. */
- connect (main_udp_socket,
- (struct sockaddr *) &addr, sizeof (struct sockaddr_in));
+ if (connect (main_udp_socket, (struct sockaddr *) &addr,
+ sizeof (struct sockaddr_in)) == -1)
+ {
+ error (0, errno, "connect");
+ goto error_with_rpcbuf;
+ }
+
p = mount_initialize_rpc (MOUNTPROC_MNT, &rpcbuf);
+ if (! p)
+ {
+ error (0, errno, "rpc");
+ goto error_with_rpcbuf;
+ }
+
p = xdr_encode_string (p, name);
- errno = conduct_rpc (&rpcbuf, &p);
- if (errno)
+ err = conduct_rpc (&rpcbuf, &p);
+ if (err)
{
- free (rpcbuf);
- perror (name);
- return 0;
+ error (0, err, "%s", name);
+ goto error_with_rpcbuf;
}
/* XXX Protocol spec says this should be a "unix error code"; we'll
- pretend that an NFS error code is what's meant, the numbers match
+ pretend that an NFS error code is what's meant; the numbers match
anyhow. */
- errno = nfs_error_trans (htonl (*p++));
- if (errno)
+ err = nfs_error_trans (htonl (*p));
+ p++;
+ if (err)
{
- free (rpcbuf);
- perror (name);
- return 0;
+ error (0, err, "%s", name);
+ goto error_with_rpcbuf;
}
-
+
/* Create the node for root */
- np = lookup_fhandle (p);
- p += NFS_FHSIZE / sizeof (int);
+ xdr_decode_fhandle (p, &np);
free (rpcbuf);
mutex_unlock (&np->lock);
- if (!nfs_port_override)
+ if (nfs_port_override)
+ port = nfs_port;
+ else
{
- /* Now send another PMAPPROC_GETPORT request to lookup the nfs server. */
+ /* Send another PMAPPROC_GETPORT request to lookup the nfs server. */
addr.sin_port = pmapport;
- connect (main_udp_socket,
- (struct sockaddr *) &addr, sizeof (struct sockaddr_in));
+ if (connect (main_udp_socket, (struct sockaddr *) &addr,
+ sizeof (struct sockaddr_in)) == -1)
+ {
+ error (0, errno, "connect");
+ return 0;
+ }
+
p = pmap_initialize_rpc (PMAPPROC_GETPORT, &rpcbuf);
- *p++ = htonl (NFS_PROGRAM);
- *p++ = htonl (NFS_VERSION);
- *p++ = htonl (IPPROTO_UDP);
- *p++ = htonl (0);
- errno = conduct_rpc (&rpcbuf, &p);
- if (!errno)
- port = ntohl (*p++);
+ if (! p)
+ {
+ error (0, errno, "rpc");
+ goto error_with_rpcbuf;
+ }
+ *(p++) = htonl (NFS_PROGRAM);
+ *(p++) = htonl (NFS_VERSION);
+ *(p++) = htonl (IPPROTO_UDP);
+ *(p++) = htonl (0);
+ err = conduct_rpc (&rpcbuf, &p);
+ if (!err)
+ {
+ port = ntohl (*p);
+ p++;
+ }
else if (nfs_port)
port = nfs_port;
else
{
- free (rpcbuf);
- perror ("pmap of nfs server");
- return 0;
+ error (0, err, "portmap of nfs server");
+ goto error_with_rpcbuf;
}
free (rpcbuf);
}
- else
- port = nfs_port;
-
+
addr.sin_port = htons (port);
- connect (main_udp_socket,
- (struct sockaddr *) &addr, sizeof (struct sockaddr_in));
-
+ if (connect (main_udp_socket, (struct sockaddr *) &addr,
+ sizeof (struct sockaddr_in)) == -1)
+ {
+ error (0, errno, "connect");
+ return 0;
+ }
+
+ mounted_hostname = host;
+ mounted_nfs_port = port;
+
return np;
+
+error_with_rpcbuf:
+ free (rpcbuf);
+
+ return 0;
}