summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nfs/nfs.c174
1 files changed, 149 insertions, 25 deletions
diff --git a/nfs/nfs.c b/nfs/nfs.c
index 8687e113..d5ebc5f4 100644
--- a/nfs/nfs.c
+++ b/nfs/nfs.c
@@ -19,47 +19,171 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-/* Round a number up to be a multiple of four. */
-#define NFS_ROUNDUP(foo) ((foo + 3) & ~3)
+/* Count how many four-byte chunks it takss to hold LEN bytes. */
+#define INTSIZE(len) (((len)+3)>>2)
/* Each of these functions copies its second arg to *P, converting it
- to XDR representation along the way. They then the address after
+ to XDR representation along the way. They then return the address after
the copied value. */
-static inline void *
-xdr_encode_int (void *p, int foo)
+inline int *
+xdr_encode_fhandle (int *p, void *fhandle)
{
- *(int *)p = htonl (foo);
- return p + sizeof (int);
+ bcopy (fhandle, p, NFSV2_FHSIZE);
+ return p + INTSIZE (NFSV2_FHSIZE);
}
-static inline void *
-xdr_encode_fhandle (void *p, void *fhandle)
+inline void *
+xdr_encode_data (void *p, char *data, size_t len)
{
- bcopy (fhandle, p, NFSV2_FHSIZE);
- return p + NFSV2_FHSIZE;
+ int nints = INTLEN (len);
+
+ p[nints] = 0;
+ *p++ = htonl (len);
+ bcopy (string, p, len);
+ return p + nints;
}
-static inline void *
+inline void *
xdr_encode_string (void *p, char *string)
{
- int len = strlen (string);
+ return xdr_encode_data (p, string, strlen (string));
+}
+
+/* The SATTR calls are different; they each only fill in one
+ or two attributes; the rest get -1. */
+inline int *
+xdr_encode_sattr_mode (int *p, u_int mode)
+{
+ *p++ = htonl (sattr->mode);
+ *p++ = -1; /* uid */
+ *p++ = -1; /* gid */
+ *p++ = -1; /* size */
+ *p++ = -1; /* atime secs */
+ *p++ = -1; /* atime usecs */
+ *p++ = -1; /* mtime secs */
+ *p++ = -1; /* mtime usecs */
+ return p;
+}
+
+inline int *
+xdr_encode_sattr_ids (int *p, u_int uid, u_int gid)
+{
+ *p++ = -1; /* mode */
+ *p++ = htonl (uid);
+ *p++ = htonl (gid);
+ *p++ = -1; /* size */
+ *p++ = -1; /* atime secs */
+ *p++ = -1; /* atime usecs */
+ *p++ = -1; /* mtime secs */
+ *p++ = -1; /* mtime usecs */
+ return p;
+}
- /* length */
- p = xdr_encode_int (p, len);
+inline int *
+xdr_encode_sattr_size (int *p, off_t size)
+{
+ *p++ = -1; /* mode */
+ *p++ = -1; /* uid */
+ *p++ = -1; /* gid */
+ *p++ = htonl (size);
+ *p++ = -1; /* atime secs */
+ *p++ = -1; /* atime usecs */
+ *p++ = -1; /* mtime secs */
+ *p++ = -1; /* mtime secs */
+ return p;
+}
- /* Fill in string */
- bcopy (string, p, len);
- p += len;
+inline int *
+xdr_encode_sattr_times (int *p, struct timeval *atime, struct timeval *mtime)
+{
+ *p++ = -1; /* mode */
+ *p++ = -1; /* uid */
+ *p++ = -1; /* gid */
+ *p++ = -1; /* size */
+ *p++ = htonl (atime->secs);
+ *p++ = htonl (atime->usecs);
+ *p++ = htonl (mtime->secs);
+ *p++ = htonl (mtime->usecs);
+ return p;
+}
+
+/* Decode *P into a stat structure; return the address of the
+ following data. */
+int *
+xdr_decode_fattr (int *p, struct stat *st)
+{
+ int type, mode;
- /* Zero extra */
- if (NFS_ROUNDUP (len) > len)
- {
- bzero (p, NFS_ROUNDUP (len) - len);
- p += NFS_ROUNDUP (len) - len;
- }
+ type = ntohl (*p++);
+ mode = ntohl (*p++);
+ st->st_mode = nfsv2mode_to_hurdmode (type, mode);
+ st->st_nlink = ntohl (*p++);
+ st->st_uid = ntohl (*p++);
+ st->st_gid = ntohl (*p++);
+ st->st_size = ntohl (*p++);
+ st->st_blksize = ntohl (*p++);
+ st->st_rdev = ntohl (*p++);
+ st->st_blocks = ntohl (*p++);
+ st->st_fsid = ntohl (*p++); /* surely wrong */
+ st->st_ino = ntohl (*p++);
+ st->st_atime = ntohl (*p++);
+ st->st_atime_usec = ntohl (*p++);
+ st->st_mtime = ntohl (*p++);
+ st->st_mtime_usec = ntohl (*p++);
+ st->st_ctime = ntohl (*p++);
+ st->st_ctime_usec = ntohl (*p++);
+
+ st->st_fstype = FSTYPE_NFS;
+ st->st_gen = 0; /* ??? */
+ st->st_author = st->st_uid; /* ??? */
+ st->st_flags = 0; /* ??? */
+
+ return p;
+
+}
+
+
+/* Create, initialize, and return a buffer suitable for sending an RPC
+ of type RPC_PROC for the user identified in CRED. For types READ,
+ WRITE, READLINK, and READDIR, parm LEN is the amount of data the
+ user desires. Return the address of where RPC args should go;
+ fill *pp with the address of the allocated memory. */
+int *
+nfs_initialize_rpc (int rpc_proc, struct protid *cred,
+ size_t len, void **pp)
+{
+ void *buf = malloc (len + 1024);
+ int *p = buf, *lenaddr, *ngraddr, i;
+
+ /* RPC header */
+ *p++ = ntohl (generate_xid);
+ *p++ = ntohl (RPCV2_CALL);
+ *p++ = ntohl (RPCV2_VERSION);
+ *p++ = ntohl (NFSV2_RPC_PROGRAM);
+ *p++ = ntohl (NFSV2_RPC_VERSION);
+ *p++ = ntohl (rpc_proc);
+ /* CRED field */
+ *p++ = htonl (RPCV2_AUTH_UNIX);
+ lenaddr = p++;
+ *p++ = htonl (mapped_time->seconds);
+ p = xdr_encode_string (p, hostname);
+ *p++ = htonl (cred->uids[0]);
+ *p++ = htonl (cred->gids[0]);
+ ngraddr = p++;
+ for (i = 0; i , 16 && i < cred->ngids - 1; i++)
+ *p++ = htonl (cred->gids[i+1]);
+ *ngraddr = htonl (i);
+ *lenaddr = htonl ((p - (nlenaddr + 1)) * sizeof (int));
+
+ /* VERF field */
+ *p++ = htonl (RPC_AUTH_NULL);
+ *p++ = 0;
+
+ *pp = buf;
return p;
}
-
+
+