summaryrefslogtreecommitdiff
path: root/nfsd
diff options
context:
space:
mode:
authorThomas Bushnell <thomas@gnu.org>1996-08-07 19:03:53 +0000
committerThomas Bushnell <thomas@gnu.org>1996-08-07 19:03:53 +0000
commit19d0f00234b0884a31c8bd4b806c6d512baae9be (patch)
treeb1fbd27e19126286009ba2486e1fc49886b8d8d7 /nfsd
parentfeecb48f23f7e3cff12f14a579a56b8b8143b275 (diff)
*** empty log message ***
Diffstat (limited to 'nfsd')
-rw-r--r--nfsd/ChangeLog73
-rw-r--r--nfsd/cache.c93
-rw-r--r--nfsd/fsys.c42
-rw-r--r--nfsd/loop.c293
-rw-r--r--nfsd/main.c37
-rw-r--r--nfsd/nfsd.h10
-rw-r--r--nfsd/ops.c164
-rw-r--r--nfsd/proctables.c57
-rw-r--r--nfsd/xdr.c21
9 files changed, 456 insertions, 334 deletions
diff --git a/nfsd/ChangeLog b/nfsd/ChangeLog
new file mode 100644
index 00000000..977a77de
--- /dev/null
+++ b/nfsd/ChangeLog
@@ -0,0 +1,73 @@
+Wed Aug 7 11:39:31 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * ops.c (op_null, op_getattr, op_setattr, op_lookup, op_readlink,
+ count_read_buffersize, op_read, op_write, op_create, op_remove,
+ op_rename, op_link, op_symlink, op_mkdir, op_rmdir,
+ count_readdir_buffersize, op_statfs, op_mnt, op_getport): Add new
+ parm `version'.
+ * loop.c (server_loop): Supply VERSION to PROC->alloc_reply and
+ PROC->func.
+ * nfsd.h (struct procedure): Add new parm to `func' and
+ `alloc_reply' members to specify protocol version.
+
+ * ops.c (mounttable): Use op_null for MOUNTPROC_UMNT and
+ MOUNTPROC_UMNTALL.
+
+ * ops.c (op_create): Ignore most of setattr structure given.
+ (op_mkdir): Likewise.
+ (complete_setattr): Clean up and be less active when possible.
+
+ * ops.c (op_readdir): Correctly end list of directory entries.
+
+ * nfsd.h (authserver): New variable.
+n * main.c: Include <hurd.h>.
+ (main): Initialize AUTHSERVER.
+ * cache.c: Include <hurd/io.h> and <hurd/auth.h>.
+ (create_cached_handle): Reauthenticate port before calling
+ file_getfh.
+
+ * fsys.c (init_filesystems): When setting NFSYS, it needs to be at
+ least as big as INDEX + 1, and install the control port into the
+ correct slot.
+ (init_filesystems): When allocating or reallocating FSYSTABLE,
+ make sure the new entries are zeroed.
+ (enter_filesystem): Likewise.
+
+Tue Aug 6 13:18:40 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * cache.c (create_cached_handle): Always call fsys_getfile when
+ creating a new cached handle instead of relying upon the passed in
+ port.
+
+ * xdr.c (hurd_mode_to_nfs_mode): Specify octal number in octal
+ notation.
+ (encode_fattr): Bother filling in all the fields.
+
+ * loop.c (server_loop): Don't attempt to call cache_handle_rele if
+ C is null.
+
+ * cache.c (fh_hash): Mod-ulize HASH before returning it.
+
+ * cache.c (process_cred): Arrange to skip VERF field for
+ non-AUTH_UNIX creds too.
+
+ * loop.c (server_loop): Don't call skip_cred for the VERF here;
+ process_cred does it for us.
+ * xdr.c (skip_cred): Delete function.
+ * nfsd.h (skip_cred): Delete decl.
+
+ * cache.c (process_cred): After processing gid list, set P after
+ it. Start gid processing loop at 0.
+
+ * main.c (main): Detach one thread for pmap_udp_socket,
+ and NTHREADS threads for main_udp_socket.
+ * loop.c (server_loop): New parm `fd'; don't do select.
+ Ignore errors that we get from recvfrom instead of processing the
+ last message again.
+
+ * nfsd.h (server_loop): New parm.
+
+ * main.c (main): Stringify LOCALSTATEDIR; but for now just pound
+ in /var. Call asprintf correctly.
+
+
diff --git a/nfsd/cache.c b/nfsd/cache.c
index 745a7c8e..8b1ee134 100644
--- a/nfsd/cache.c
+++ b/nfsd/cache.c
@@ -23,6 +23,8 @@
#include <hurd/fsys.h>
#include <assert.h>
#include <string.h>
+#include <hurd/io.h>
+#include <hurd/auth.h>
#include "nfsd.h"
@@ -136,35 +138,40 @@ process_cred (int *p, struct idspec **credp)
{
int size = ntohl (*p++);
*credp = idspec_lookup (0, 0, 0, 0);
- return p + INTSIZE (size);
+ p += INTSIZE (size);
+ }
+ else
+ {
+ p++; /* skip size */
+ p++; /* skip seconds */
+ len = ntohl (*p++);
+ p += INTSIZE (len); /* skip hostname */
+
+ uid = p++; /* remember loc of uid */
+ *uid = ntohl (*uid);
+
+ firstgid = *p++; /* remember first gid */
+ gids = p; /* here's where the array will start */
+ ngids = ntohl (*p++);
+
+ /* Now swap the first gid to be the first element of the array */
+ *gids = firstgid;
+ ngids++; /* and count it */
+
+ /* And byteswap the gids */
+ for (i = 0; i < ngids; i++)
+ gids[i] = ntohl (gids[i]);
+
+ p += ngids - 1;
+
+ *credp = idspec_lookup (1, ngids, uid, gids);
}
-
- p++; /* skip size */
- p++; /* skip seconds */
- len = ntohl (*p++);
- p += INTSIZE (len); /* skip hostname */
-
- uid = p++; /* remember loc of uid */
- *uid = ntohl (*uid);
-
- firstgid = *p++; /* remember first gid */
- gids = p; /* here's where the array will start */
- ngids = ntohl (*p++);
-
- /* Now swap the first gid to be the first element of the array */
- *gids = firstgid;
- ngids++; /* and count it */
-
- /* And byteswap the gids */
- for (i = 1; i < ngids; i++)
- gids[i] = ntohl (gids[i]);
/* Next is the verf field; skip it entirely */
p++; /* skip id */
len = htonl (*p++);
p += INTSIZE (len);
- *credp = idspec_lookup (1, ngids, uid, gids);
return p;
}
@@ -239,7 +246,7 @@ fh_hash (char *fhandle, struct idspec *i)
for (n = 0; n < NFS_FHSIZE; n++)
hash += fhandle[n];
hash += (int) i >> 6;
- return hash;
+ return hash % FHHASH_TABLE_SIZE;
}
int *
@@ -342,7 +349,7 @@ scan_fhs ()
}
struct cache_handle *
-create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
+create_cached_handle (int fs, struct cache_handle *credc, file_t userport)
{
char fhandle[NFS_FHSIZE];
error_t err;
@@ -350,20 +357,35 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
int hash;
char *bp = fhandle + sizeof (int);
size_t handlelen = NFS_FHSIZE - sizeof (int);
+ mach_port_t newport, ref;
+ /* Authenticate USERPORT so that we can call file_getfh on it. */
+ ref = mach_reply_port ();
+ if (io_reauthenticate (userport, ref, MACH_MSG_TYPE_MAKE_SEND)
+ || auth_user_authenticate (authserver, ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newport))
+ {
+ /* Reauthentication has failed, but maybe the filesystem will let
+ us call file_getfh anyway. */
+ newport = userport;
+ }
+ else
+ mach_port_deallocate (mach_task_self (), userport);
+ mach_port_destroy (mach_task_self (), ref);
+
+ /* Fetch the file handle */
*(int *)fhandle = fs;
err = file_getfh (newport, &bp, &handlelen);
+ mach_port_deallocate (mach_task_self (), newport);
if (err || handlelen != NFS_FHSIZE - sizeof (int))
- {
- mach_port_deallocate (mach_task_self (), newport);
- return 0;
- }
+ return 0;
if (bp != fhandle + sizeof (int))
{
bcopy (bp, fhandle + sizeof (int), NFS_FHSIZE - sizeof (int));
vm_deallocate (mach_task_self (), (vm_address_t) bp, handlelen);
}
+ /* Cache it */
hash = fh_hash (fhandle, credc->ids);
mutex_lock (&fhhashlock);
for (c = fhhashtable[hash]; c; c = c->next)
@@ -374,9 +396,22 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
nfreefh--;
c->references++;
mutex_unlock (&fhhashlock);
- mach_port_deallocate (mach_task_self (), newport);
return c;
}
+
+ /* Always call fsys_getfile so that we don't depend on the
+ particular open modes of the port passed in. */
+
+ err = fsys_getfile (lookup_filesystem (fs),
+ credc->ids->uids, credc->ids->nuids,
+ credc->ids->gids, credc->ids->ngids,
+ fhandle + sizeof (int), NFS_FHSIZE - sizeof (int),
+ &newport);
+ if (err)
+ {
+ mutex_unlock (&fhhashlock);
+ return 0;
+ }
/* Create it anew */
c = malloc (sizeof (struct cache_handle));
diff --git a/nfsd/fsys.c b/nfsd/fsys.c
index d3c50220..97137455 100644
--- a/nfsd/fsys.c
+++ b/nfsd/fsys.c
@@ -49,10 +49,16 @@ init_filesystems (void)
int line;
file_t root;
static FILE *index_file;
+ int i;
fsystable = (struct fsys_spec *) malloc ((fsystablesize = 10)
* sizeof (struct fsys_spec));
-
+ for (i = 0; i < fsystablesize; i++)
+ {
+ fsystable[i].fsys = MACH_PORT_NULL;
+ fsystable[i].name = 0;
+ }
+
if (!index_file_name)
return;
@@ -91,14 +97,22 @@ init_filesystems (void)
}
if (index >= fsystablesize)
- fsystable = (struct fsys_spec *) realloc (fsystable,
- (fsystablesize = index * 2)
- * sizeof (struct fsys_spec));
- if (index > nfsys)
- nfsys = index;
+ {
+ fsystable = (struct fsys_spec *)
+ realloc (fsystable, index * 2 * sizeof (struct fsys_spec));
+ for (i = fsystablesize; i < index * 2; i++)
+ {
+ fsystable[i].fsys = MACH_PORT_NULL;
+ fsystable[i].name = 0;
+ }
+ fsystablesize = index * 2;
+ }
+
+ if (index + 1 > nfsys)
+ nfsys = index + 1;
fsystable[index].name = name;
- file_getcontrol (root, &fsystable[nfsys].fsys);
+ file_getcontrol (root, &fsystable[index].fsys);
mach_port_deallocate (mach_task_self (), root);
}
}
@@ -176,9 +190,17 @@ enter_filesystem (char *name, file_t root)
return i;
if (nfsys == fsystablesize)
- fsystable = (struct fsys_spec *) realloc (fsystable,
- (fsystablesize *= 2)
- * sizeof (struct fsys_spec));
+ {
+ fsystable = (struct fsys_spec *) realloc (fsystable,
+ (fsystablesize * 2)
+ * sizeof (struct fsys_spec));
+ for (i = fsystablesize; i < fsystablesize * 2; i++)
+ {
+ fsystable[i].fsys = MACH_PORT_NULL;
+ fsystable[i].name = 0;
+ }
+ fsystablesize *= 2;
+ }
fsystable[nfsys].name = malloc (strlen (name) + 1);
strcpy (fsystable[nfsys].name, name);
diff --git a/nfsd/loop.c b/nfsd/loop.c
index 3520e1da..c7053234 100644
--- a/nfsd/loop.c
+++ b/nfsd/loop.c
@@ -36,7 +36,7 @@
#undef malloc
void
-server_loop ()
+server_loop (int fd)
{
char buf[MAXIOSIZE];
int xid;
@@ -53,181 +53,162 @@ server_loop ()
struct cache_handle *c, fakec;
error_t err;
size_t addrlen;
- fd_set readfds;
- int maxfd;
- int i;
int *errloc;
-
+ int cc;
+
bzero (&fakec, sizeof (struct cache_handle));
- if (main_udp_socket > pmap_udp_socket)
- maxfd = main_udp_socket;
- else
- maxfd = pmap_udp_socket;
-
for (;;)
{
- FD_ZERO (&readfds);
- FD_SET (main_udp_socket, &readfds);
- FD_SET (pmap_udp_socket, &readfds);
- select (maxfd, &readfds, 0, 0, 0);
-
- for (i = main_udp_socket;
- i != -1;
- i = (i == main_udp_socket ? pmap_udp_socket : -1))
- {
- if (!FD_ISSET (i, &readfds))
- continue;
-
- p = (int *) buf;
- proc = 0;
- addrlen = sizeof (struct sockaddr_in);
- recvfrom (i, buf, MAXIOSIZE, 0, &sender, &addrlen);
- xid = *p++;
-
- /* Ignore things that aren't proper RPCs. */
- if (ntohl (*p++) != CALL)
- continue;
-
- cr = check_cached_replies (xid, &sender);
- if (cr->data)
- /* This transacation has already completed */
- goto repost_reply;
+ p = (int *) buf;
+ proc = 0;
+ addrlen = sizeof (struct sockaddr_in);
+ cc = recvfrom (fd, buf, MAXIOSIZE, 0, &sender, &addrlen);
+ if (cc == -1)
+ continue; /* ignore errors */
+ xid = *p++;
- r = (int *) rbuf = malloc (MAXIOSIZE);
-
- if (ntohl (*p++) != RPC_MSG_VERSION)
- {
- /* Reject RPC */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_DENIED);
- *r++ = htonl (RPC_MISMATCH);
- *r++ = htonl (RPC_MSG_VERSION);
- *r++ = htonl (RPC_MSG_VERSION);
- goto send_reply;
- }
+ /* Ignore things that aren't proper RPCs. */
+ if (ntohl (*p++) != CALL)
+ continue;
- program = ntohl (*p++);
- switch (program)
- {
- case MOUNTPROG:
- version = MOUNTVERS;
- table = &mounttable;
- break;
-
- case NFS_PROGRAM:
- version = NFS_VERSION;
- table = &nfstable;
- break;
+ cr = check_cached_replies (xid, &sender);
+ if (cr->data)
+ /* This transacation has already completed */
+ goto repost_reply;
+
+ r = (int *) rbuf = malloc (MAXIOSIZE);
+
+ if (ntohl (*p++) != RPC_MSG_VERSION)
+ {
+ /* Reject RPC */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_DENIED);
+ *r++ = htonl (RPC_MISMATCH);
+ *r++ = htonl (RPC_MSG_VERSION);
+ *r++ = htonl (RPC_MSG_VERSION);
+ goto send_reply;
+ }
+
+ program = ntohl (*p++);
+ switch (program)
+ {
+ case MOUNTPROG:
+ version = MOUNTVERS;
+ table = &mounttable;
+ break;
- case PMAPPROG:
- version = PMAPVERS;
- table = &pmaptable;
- break;
+ case NFS_PROGRAM:
+ version = NFS_VERSION;
+ table = &nfstable;
+ break;
- default:
- /* Program unavailable */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROG_UNAVAIL);
- goto send_reply;
- }
+ case PMAPPROG:
+ version = PMAPVERS;
+ table = &pmaptable;
+ break;
- if (ntohl (*p++) != version)
- {
- /* Program mismatch */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROG_MISMATCH);
- *r++ = htonl (version);
- *r++ = htonl (version);
- goto send_reply;
- }
+ default:
+ /* Program unavailable */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (PROG_UNAVAIL);
+ goto send_reply;
+ }
- procedure = htonl (*p++);
- if (procedure < table->min
- || procedure > table->max
- || table->procs[procedure - table->min].func == 0)
- {
- /* Procedure unavailable */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROC_UNAVAIL);
- *r++ = htonl (table->min);
- *r++ = htonl (table->max);
- goto send_reply;
- }
- proc = &table->procs[procedure - table->min];
-
- p = process_cred (p, &cred); /* auth */
- p = skip_cred (p); /* verf */
+ if (ntohl (*p++) != version)
+ {
+ /* Program mismatch */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (PROG_MISMATCH);
+ *r++ = htonl (version);
+ *r++ = htonl (version);
+ goto send_reply;
+ }
- if (proc->need_handle)
- p = lookup_cache_handle (p, &c, cred);
- else
- {
- fakec.ids = cred;
- c = &fakec;
- }
-
- if (proc->alloc_reply)
- {
- size_t amt;
- amt = (*proc->alloc_reply) (p) + 256;
- if (amt > MAXIOSIZE)
- {
- free (rbuf);
- r = (int *) rbuf = malloc (amt);
- }
- }
-
- /* Fill in beginning of reply */
+ procedure = htonl (*p++);
+ if (procedure < table->min
+ || procedure > table->max
+ || table->procs[procedure - table->min].func == 0)
+ {
+ /* Procedure unavailable */
*r++ = xid;
*r++ = htonl (REPLY);
*r++ = htonl (MSG_ACCEPTED);
*r++ = htonl (AUTH_NULL);
*r++ = htonl (0);
- *r++ = htonl (SUCCESS);
- if (proc->process_error)
- {
- /* Assume success for now and patch it later if necessary */
- errloc = r;
- *r++ = htonl (0);
- }
-
- if (c)
- err = (*proc->func) (c, p, &r);
- else
- err = ESTALE;
+ *r++ = htonl (PROC_UNAVAIL);
+ *r++ = htonl (table->min);
+ *r++ = htonl (table->max);
+ goto send_reply;
+ }
+ proc = &table->procs[procedure - table->min];
+
+ p = process_cred (p, &cred);
+
+ if (proc->need_handle)
+ p = lookup_cache_handle (p, &c, cred);
+ else
+ {
+ fakec.ids = cred;
+ c = &fakec;
+ }
- if (proc->process_error && err)
+ if (proc->alloc_reply)
+ {
+ size_t amt;
+ amt = (*proc->alloc_reply) (p, version) + 256;
+ if (amt > MAXIOSIZE)
{
- r = errloc;
- *r++ = htonl (nfs_error_trans (err));
+ free (rbuf);
+ r = (int *) rbuf = malloc (amt);
}
-
- cred_rele (cred);
- if (c != &fakec)
- cache_handle_rele (c);
-
- send_reply:
- cr->data = rbuf;
- cr->len = (char *)r - rbuf;
-
- repost_reply:
- sendto (i, cr->data, cr->len, 0,
- (struct sockaddr *)&sender, addrlen);
- release_cached_reply (cr);
}
+
+ /* Fill in beginning of reply */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (SUCCESS);
+ if (proc->process_error)
+ {
+ /* Assume success for now and patch it later if necessary */
+ errloc = r;
+ *r++ = htonl (0);
+ }
+
+ if (c)
+ err = (*proc->func) (c, p, &r, version);
+ else
+ err = ESTALE;
+
+ if (proc->process_error && err)
+ {
+ r = errloc;
+ *r++ = htonl (nfs_error_trans (err));
+ }
+
+ cred_rele (cred);
+ if (c && c != &fakec)
+ cache_handle_rele (c);
+
+ send_reply:
+ cr->data = rbuf;
+ cr->len = (char *)r - rbuf;
+
+ repost_reply:
+ sendto (fd, cr->data, cr->len, 0,
+ (struct sockaddr *)&sender, addrlen);
+ release_cached_reply (cr);
}
}
diff --git a/nfsd/main.c b/nfsd/main.c
index 69099361..4dcd816f 100644
--- a/nfsd/main.c
+++ b/nfsd/main.c
@@ -23,16 +23,24 @@
#include <unistd.h>
#include <rpc/pmap_prot.h>
#include <maptime.h>
+#include <hurd.h>
int main_udp_socket, pmap_udp_socket;
struct sockaddr_in main_address, pmap_address;
char *index_file_name;
+#ifdef makefiles_not_broken
+#define STATEDIR # LOCALSTATEDIR
+#else
+#define STATEDIR "/var"
+#endif
+
int
main (int argc, char **argv)
{
int nthreads;
-
+ int fail;
+
if (argc > 2)
{
fprintf (stderr, "%s [num-threads]\n", argv[0]);
@@ -45,8 +53,9 @@ main (int argc, char **argv)
if (!nthreads)
nthreads = 4;
- index_file_name = asprintf ("%s/state/misc/nfsd.index", LOCALSTATEDIR);
+ asprintf (&index_file_name, "%s/state/misc/nfsd.index", STATEDIR);
+ authserver = getauth ();
maptime_map (0, 0, &mapped_time);
main_address.sin_family = AF_INET;
@@ -58,15 +67,29 @@ main (int argc, char **argv)
main_udp_socket = socket (PF_INET, SOCK_DGRAM, 0);
pmap_udp_socket = socket (PF_INET, SOCK_DGRAM, 0);
- bind (main_udp_socket, (struct sockaddr *)&main_address,
- sizeof (struct sockaddr_in));
- bind (pmap_udp_socket, (struct sockaddr *)&pmap_address,
- sizeof (struct sockaddr_in));
+ fail = bind (main_udp_socket, (struct sockaddr *)&main_address,
+ sizeof (struct sockaddr_in));
+ if (fail)
+ {
+ perror ("Binding NFS socket");
+ exit (1);
+ }
+ fail = bind (pmap_udp_socket, (struct sockaddr *)&pmap_address,
+ sizeof (struct sockaddr_in));
+ if (fail)
+ {
+ perror ("Binding PMAP socket");
+ exit (1);
+ }
init_filesystems ();
+ cthread_detach (cthread_fork ((cthread_fn_t) server_loop,
+ pmap_udp_socket));
+
while (nthreads--)
- cthread_detach (cthread_fork ((cthread_fn_t) server_loop, 0));
+ cthread_detach (cthread_fork ((cthread_fn_t) server_loop,
+ main_udp_socket));
for (;;)
{
diff --git a/nfsd/nfsd.h b/nfsd/nfsd.h
index 7b6f530d..0ea93703 100644
--- a/nfsd/nfsd.h
+++ b/nfsd/nfsd.h
@@ -67,8 +67,8 @@ struct cached_reply
struct procedure
{
- error_t (*func) (struct cache_handle *, int *, int **);
- size_t (*alloc_reply) (int *);
+ error_t (*func) (struct cache_handle *, int *, int **, int);
+ size_t (*alloc_reply) (int *, int);
int need_handle;
int process_error;
};
@@ -92,6 +92,9 @@ extern struct sockaddr_in main_address, pmap_address;
/* Name of the file on disk containing the filesystem index table */
extern char *index_file_name;
+/* Our auth server */
+auth_t authserver;
+
/* cache.c */
int *process_cred (int *, struct idspec **);
@@ -107,13 +110,12 @@ void release_cached_reply (struct cached_reply *cr);
void scan_replies (void);
/* loop.c */
-void server_loop (void);
+void server_loop (int);
/* ops.c */
extern struct proctable nfstable, mounttable, pmaptable;
/* xdr.c */
-int *skip_cred (int *);
int nfs_error_trans (error_t);
int *encode_fattr (int *, struct stat *);
int *decode_name (int *, char **);
diff --git a/nfsd/ops.c b/nfsd/ops.c
index 93c8373c..cbcfb409 100644
--- a/nfsd/ops.c
+++ b/nfsd/ops.c
@@ -32,7 +32,8 @@
static error_t
op_null (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
return 0;
}
@@ -40,7 +41,8 @@ op_null (struct cache_handle *c,
static error_t
op_getattr (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
struct stat st;
error_t err;
@@ -67,17 +69,14 @@ complete_setattr (mach_port_t port,
uid = ntohl (*p++);
gid = ntohl (*p++);
- if ((uid != -1 && uid != st.st_uid)
- || (gid != -1 && gid != st.st_gid))
- {
- if (uid == -1)
- uid = st.st_uid;
- if (gid == -1)
- gid = st.st_gid;
- err = file_chown (port, uid, gid);
- if (err)
- return err;
- }
+ if (uid == -1)
+ uid = st.st_uid;
+ if (gid == -1)
+ gid = st.st_gid;
+ if (uid != st.st_uid || gid != st.st_gid)
+ err = file_chown (port, uid, gid);
+ if (err)
+ return err;
size = ntohl (*p++);
if (size != -1 && size != st.st_size)
@@ -89,33 +88,35 @@ complete_setattr (mach_port_t port,
atime.microseconds = ntohl (*p++);
mtime.seconds = ntohl (*p++);
mtime.microseconds = ntohl (*p++);
+
if (atime.seconds != -1 && atime.microseconds == -1)
atime.microseconds = 0;
if (mtime.seconds != -1 && mtime.microseconds == -1)
mtime.microseconds = 0;
- if (atime.seconds != -1 || mtime.seconds != -1
- || atime.microseconds != -1 || mtime.microseconds != -1)
- {
- if (atime.seconds == -1)
- atime.seconds = st.st_atime;
- if (atime.microseconds == -1)
- atime.microseconds = st.st_atime_usec;
- if (mtime.seconds == -1)
- mtime.seconds = st.st_mtime;
- if (mtime.microseconds == -1)
- mtime.microseconds = st.st_mtime_usec;
- err = file_utimes (port, atime, mtime);
- if (err)
- return err;
- }
-
- return 0;
+
+ if (atime.seconds == -1)
+ atime.seconds = st.st_atime;
+ if (atime.microseconds == -1)
+ atime.microseconds = st.st_atime_usec;
+ if (mtime.seconds == -1)
+ mtime.seconds = st.st_mtime;
+ if (mtime.microseconds == -1)
+ mtime.microseconds = st.st_mtime_usec;
+
+ if (atime.seconds != st.st_atime
+ || atime.microseconds != st.st_atime_usec
+ || mtime.seconds != st.st_mtime
+ || mtime.microseconds != st.st_mtime_usec)
+ err = file_utimes (port, atime, mtime);
+
+ return err;
}
static error_t
op_setattr (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
error_t err = 0;
mode_t mode;
@@ -132,7 +133,8 @@ op_setattr (struct cache_handle *c,
static error_t
op_lookup (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
error_t err;
char *name;
@@ -171,7 +173,8 @@ op_lookup (struct cache_handle *c,
static error_t
op_readlink (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
char buf[2048], *transp = buf;
mach_msg_type_number_t len = sizeof (buf);
@@ -193,7 +196,7 @@ op_readlink (struct cache_handle *c,
}
static size_t
-count_read_buffersize (int *p)
+count_read_buffersize (int *p, int version)
{
return ntohl (*++p); /* skip OFFSET, return COUNT */
}
@@ -201,7 +204,8 @@ count_read_buffersize (int *p)
static error_t
op_read (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
off_t offset;
size_t count;
@@ -229,7 +233,8 @@ op_read (struct cache_handle *c,
static error_t
op_write (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
off_t offset;
size_t count;
@@ -268,7 +273,8 @@ op_write (struct cache_handle *c,
static error_t
op_create (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
error_t err;
char *name;
@@ -278,6 +284,8 @@ op_create (struct cache_handle *c,
struct cache_handle *newc;
struct stat st;
mode_t mode;
+ int statchanged = 0;
+ off_t size;
p = decode_name (p, &name);
mode = ntohl (*p++);
@@ -292,12 +300,33 @@ op_create (struct cache_handle *c,
if (err)
return err;
- err = complete_setattr (newport, p);
if (!err)
err = io_stat (newport, &st);
+ if (err)
+ goto errout;
+
+ /* NetBSD ignores most of the setattr fields given; that's good enough
+ for me too. */
+
+ p++, p++; /* skip uid and gid */
+
+ size = ntohl (*p++);
+ if (size != -1 && size != st.st_size)
+ {
+ err = file_set_size (newport, size);
+ statchanged = 1;
+ }
+ if (err)
+ goto errout;
+
+ /* ignore times */
+
+ if (statchanged)
+ err = io_stat (newport, &st);
if (err)
{
+ errout:
dir_unlink (c->port, name);
free (name);
return err;
@@ -316,7 +345,8 @@ op_create (struct cache_handle *c,
static error_t
op_remove (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
error_t err;
char *name;
@@ -332,7 +362,8 @@ op_remove (struct cache_handle *c,
static error_t
op_rename (struct cache_handle *fromc,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
struct cache_handle *toc;
char *fromname, *toname;
@@ -354,7 +385,8 @@ op_rename (struct cache_handle *fromc,
static error_t
op_link (struct cache_handle *filec,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
struct cache_handle *dirc;
char *name;
@@ -375,7 +407,8 @@ op_link (struct cache_handle *filec,
static error_t
op_symlink (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
char *name, *target;
error_t err;
@@ -416,7 +449,8 @@ op_symlink (struct cache_handle *c,
static error_t
op_mkdir (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
char *name;
mode_t mode;
@@ -448,7 +482,8 @@ op_mkdir (struct cache_handle *c,
if (err)
return err;
- err = complete_setattr (newport, p);
+ /* Ignore the rest of the sattr structure */
+
if (!err)
err = io_stat (newport, &st);
if (err)
@@ -465,7 +500,8 @@ op_mkdir (struct cache_handle *c,
static error_t
op_rmdir (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
char *name;
error_t err;
@@ -480,7 +516,8 @@ op_rmdir (struct cache_handle *c,
static error_t
op_readdir (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
int cookie;
unsigned count;
@@ -491,6 +528,7 @@ op_readdir (struct cache_handle *c,
int nentries;
int i;
int *replystart;
+ int *r;
cookie = ntohl (*p++);
count = ntohl (*p++);
@@ -501,10 +539,12 @@ op_readdir (struct cache_handle *c,
if (err)
return err;
+ r = *reply;
+
if (nentries == 0)
{
- *(*reply)++ = htonl (0); /* no entry */
- *(*reply)++ = htonl (1); /* EOF */
+ *r++ = htonl (0); /* no entry */
+ *r++ = htonl (1); /* EOF */
}
else
{
@@ -514,19 +554,22 @@ op_readdir (struct cache_handle *c,
&& (char *)reply < (char *)replystart + count);
i++, dp = (struct dirent *) ((char *)dp + dp->d_reclen))
{
- *(*reply)++ = htonl (1); /* entry present */
- *(*reply)++ = htonl (dp->d_ino);
- *reply = encode_string (*reply, dp->d_name);
- *(*reply)++ = htonl (i + cookie + 1); /* next entry */
+ *r++ = htonl (1); /* entry present */
+ *r++ = htonl (dp->d_ino);
+ r = encode_string (r, dp->d_name);
+ *r++ = htonl (i + cookie + 1); /* next entry */
}
- *(*reply)++ = htonl (0); /* not EOF */
+ *r++ = htonl (0); /* no more entries */
+ *r++ = htonl (0); /* not EOF */
}
+ *reply = r;
+
return 0;
}
static size_t
-count_readdir_buffersize (int *p)
+count_readdir_buffersize (int *p, int version)
{
return ntohl (*++p); /* skip COOKIE; return COUNT */
}
@@ -534,7 +577,8 @@ count_readdir_buffersize (int *p)
static error_t
op_statfs (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
struct statfs st;
error_t err;
@@ -548,7 +592,8 @@ op_statfs (struct cache_handle *c,
static error_t
op_mnt (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
file_t root;
struct cache_handle *newc;
@@ -574,7 +619,8 @@ op_mnt (struct cache_handle *c,
static error_t
op_getport (struct cache_handle *c,
int *p,
- int **reply)
+ int **reply,
+ int version)
{
int prog, vers, prot;
@@ -631,8 +677,8 @@ struct proctable mounttable =
{ op_null, 0, 0, 0},
{ op_mnt, 0, 0, 1},
{ 0, 0, 0, 0}, /* MOUNTPROC_DUMP */
- { 0, 0, 0, 0}, /* MOUNTPROC_UMNT */
- { 0, 0, 0, 0}, /* MOUNTPROC_UMNTALL */
+ { op_null, 0, 0, 0}, /* MOUNTPROC_UMNT */
+ { op_null, 0, 0, 0}, /* MOUNTPROC_UMNTALL */
{ 0, 0, 0, 0}, /* MOUNTPROC_EXPORT */
}
};
diff --git a/nfsd/proctables.c b/nfsd/proctables.c
deleted file mode 100644
index 1bc76a38..00000000
--- a/nfsd/proctables.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- Copyright (C) 1996 Free Software Foundation, Inc.
- Written by Michael I. Bushnell, p/BSG.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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.
-
- The GNU Hurd 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.
-
- 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
-
-struct proctable nfstable =
-{
- NFSPROC_NULL, /* first proc */
- NFSPROC_STATFS, /* last proc */
- { op_null, 0, 0},
- { op_getattr, 0, 1},
- { op_setattr, 0, 1},
- { 0, 0, 0 }, /* deprecated NFSPROC_ROOT */
- { op_lookup, 0, 1},
- { op_readlink, 0, 1},
- { op_read, count_read_buffersize, 1},
- { 0, 0, 0 }, /* nonexistent NFSPROC_WRITECACHE */
- { op_write, 0, 1},
- { op_create, 0, 1},
- { op_remove, 0, 1},
- { op_rename, 0, 1},
- { op_link, 0, 1},
- { op_symlink, 0, 1},
- { op_mkdir, 0, 1},
- { op_rmdir, 0, 1},
- { op_readdir, count_readdir_buffersize, 1},
- { op_statfs, 0, 1},
-};
-
-
-struct proctable mounttable =
-{
- MOUNTPROC_NULL, /* first proc */
- MOUNTPROC_EXPORT, /* last proc */
- { op_null, 0, 0},
- { op_mnt, 0, 0},
- { 0, 0, 0}, /* MOUNTPROC_DUMP */
- { 0, 0, 0}, /* MOUNTPROC_UMNT */
- { 0, 0, 0}, /* MOUNTPROC_UMNTALL */
- { 0, 0, 0}, /* MOUNTPROC_EXPORT */
-};
diff --git a/nfsd/xdr.c b/nfsd/xdr.c
index d5bea0bd..5b13b2a5 100644
--- a/nfsd/xdr.c
+++ b/nfsd/xdr.c
@@ -23,22 +23,11 @@
#include <string.h>
#include "nfsd.h"
-/* Return the address of the next thing after the credential at P. */
-int *
-skip_cred (int *p)
-{
- int size;
-
- p++; /* TYPE */
- size = ntohl (*p++);
- return p + INTSIZE (size);
-}
-
/* Any better ideas? */
static int
hurd_mode_to_nfs_mode (mode_t m)
{
- return m & 0x177777;
+ return m & 0177777;
}
static int
@@ -85,6 +74,14 @@ encode_fattr (int *p, struct stat *st)
*p++ = htonl (st->st_blksize);
*p++ = htonl (st->st_rdev);
*p++ = htonl (st->st_blocks);
+ *p++ = htonl (st->st_fsid);
+ *p++ = htonl (st->st_ino);
+ *p++ = htonl (st->st_atime);
+ *p++ = htonl (st->st_atime_usec);
+ *p++ = htonl (st->st_mtime);
+ *p++ = htonl (st->st_mtime_usec);
+ *p++ = htonl (st->st_ctime);
+ *p++ = htonl (st->st_ctime_usec);
return p;
}