~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/sunrpc/xdr.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/net/sunrpc/xdr.c
  3  *
  4  * Generic XDR support.
  5  *
  6  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  7  */
  8 
  9 #include <linux/types.h>
 10 #include <linux/socket.h>
 11 #include <linux/string.h>
 12 #include <linux/kernel.h>
 13 #include <linux/in.h>
 14 #include <linux/sunrpc/xdr.h>
 15 #include <linux/sunrpc/msg_prot.h>
 16 
 17 u32     rpc_success, rpc_prog_unavail, rpc_prog_mismatch, rpc_proc_unavail,
 18         rpc_garbage_args, rpc_system_err;
 19 u32     rpc_auth_ok, rpc_autherr_badcred, rpc_autherr_rejectedcred,
 20         rpc_autherr_badverf, rpc_autherr_rejectedverf, rpc_autherr_tooweak;
 21 u32     xdr_zero, xdr_one, xdr_two;
 22 
 23 void
 24 xdr_init(void)
 25 {
 26         static int      inited = 0;
 27 
 28         if (inited)
 29                 return;
 30 
 31         xdr_zero = htonl(0);
 32         xdr_one = htonl(1);
 33         xdr_two = htonl(2);
 34 
 35         rpc_success = htonl(RPC_SUCCESS);
 36         rpc_prog_unavail = htonl(RPC_PROG_UNAVAIL);
 37         rpc_prog_mismatch = htonl(RPC_PROG_MISMATCH);
 38         rpc_proc_unavail = htonl(RPC_PROC_UNAVAIL);
 39         rpc_garbage_args = htonl(RPC_GARBAGE_ARGS);
 40         rpc_system_err = htonl(RPC_SYSTEM_ERR);
 41 
 42         rpc_auth_ok = htonl(RPC_AUTH_OK);
 43         rpc_autherr_badcred = htonl(RPC_AUTH_BADCRED);
 44         rpc_autherr_rejectedcred = htonl(RPC_AUTH_REJECTEDCRED);
 45         rpc_autherr_badverf = htonl(RPC_AUTH_BADVERF);
 46         rpc_autherr_rejectedverf = htonl(RPC_AUTH_REJECTEDVERF);
 47         rpc_autherr_tooweak = htonl(RPC_AUTH_TOOWEAK);
 48 
 49         inited = 1;
 50 }
 51 
 52 /*
 53  * XDR functions for basic NFS types
 54  */
 55 u32 *
 56 xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj)
 57 {
 58         unsigned int    quadlen = XDR_QUADLEN(obj->len);
 59 
 60         p[quadlen] = 0;         /* zero trailing bytes */
 61         *p++ = htonl(obj->len);
 62         memcpy(p, obj->data, obj->len);
 63         return p + XDR_QUADLEN(obj->len);
 64 }
 65 
 66 u32 *
 67 xdr_decode_netobj_fixed(u32 *p, void *obj, unsigned int len)
 68 {
 69         if (ntohl(*p++) != len)
 70                 return NULL;
 71         memcpy(obj, p, len);
 72         return p + XDR_QUADLEN(len);
 73 }
 74 
 75 u32 *
 76 xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
 77 {
 78         unsigned int    len;
 79 
 80         if ((len = ntohl(*p++)) > XDR_MAX_NETOBJ)
 81                 return NULL;
 82         obj->len  = len;
 83         obj->data = (u8 *) p;
 84         return p + XDR_QUADLEN(len);
 85 }
 86 
 87 u32 *
 88 xdr_encode_array(u32 *p, const char *array, unsigned int len)
 89 {
 90         int quadlen = XDR_QUADLEN(len);
 91 
 92         p[quadlen] = 0;
 93         *p++ = htonl(len);
 94         memcpy(p, array, len);
 95         return p + quadlen;
 96 }
 97 
 98 u32 *
 99 xdr_encode_string(u32 *p, const char *string)
100 {
101         return xdr_encode_array(p, string, strlen(string));
102 }
103 
104 u32 *
105 xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen)
106 {
107         unsigned int    len;
108         char            *string;
109 
110         if ((len = ntohl(*p++)) > maxlen)
111                 return NULL;
112         if (lenp)
113                 *lenp = len;
114         if ((len % 4) != 0) {
115                 string = (char *) p;
116         } else {
117                 string = (char *) (p - 1);
118                 memmove(string, p, len);
119         }
120         string[len] = '\0';
121         *sp = string;
122         return p + XDR_QUADLEN(len);
123 }
124 
125 /*
126  * Realign the iovec if the server missed out some reply elements
127  * (such as post-op attributes,...)
128  * Note: This is a simple implementation that assumes that
129  *            len <= iov->iov_len !!!
130  *       The RPC header (assumed to be the 1st element in the iov array)
131  *            is not shifted.
132  */
133 void xdr_shift_iovec(struct iovec *iov, int nr, size_t len)
134 {
135         struct iovec *pvec;
136 
137         for (pvec = iov + nr - 1; nr > 1; nr--, pvec--) {
138                 struct iovec *svec = pvec - 1;
139 
140                 if (len > pvec->iov_len) {
141                         printk(KERN_DEBUG "RPC: Urk! Large shift of short iovec.\n");
142                         return;
143                 }
144                 memmove((char *)pvec->iov_base + len, pvec->iov_base,
145                         pvec->iov_len - len);
146 
147                 if (len > svec->iov_len) {
148                         printk(KERN_DEBUG "RPC: Urk! Large shift of short iovec.\n");
149                         return;
150                 }
151                 memcpy(pvec->iov_base,
152                        (char *)svec->iov_base + svec->iov_len - len, len);
153         }
154 }
155 
156 /*
157  * Zero the last n bytes in an iovec array of 'nr' elements
158  */
159 void xdr_zero_iovec(struct iovec *iov, int nr, size_t n)
160 {
161         struct iovec *pvec;
162 
163         for (pvec = iov + nr - 1; n && nr > 0; nr--, pvec--) {
164                 if (n < pvec->iov_len) {
165                         memset((char *)pvec->iov_base + pvec->iov_len - n, 0, n);
166                         n = 0;
167                 } else {
168                         memset(pvec->iov_base, 0, pvec->iov_len);
169                         n -= pvec->iov_len;
170                 }
171         }
172 }
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.