diff options
Diffstat (limited to 'sunrpc')
-rw-r--r-- | sunrpc/rpc/xdr.h | 23 | ||||
-rw-r--r-- | sunrpc/svc_tcp.c | 5 | ||||
-rw-r--r-- | sunrpc/xdr_mem.c | 38 | ||||
-rw-r--r-- | sunrpc/xdr_rec.c | 60 | ||||
-rw-r--r-- | sunrpc/xdr_sizeof.c | 10 | ||||
-rw-r--r-- | sunrpc/xdr_stdio.c | 28 |
6 files changed, 145 insertions, 19 deletions
diff --git a/sunrpc/rpc/xdr.h b/sunrpc/rpc/xdr.h index 44e30dfabe..8e74d3cd7f 100644 --- a/sunrpc/rpc/xdr.h +++ b/sunrpc/rpc/xdr.h @@ -82,12 +82,11 @@ __BEGIN_DECLS * XDR_FREE can be used to release the space allocated by an XDR_DECODE * request. */ -enum xdr_op - { - XDR_ENCODE = 0, - XDR_DECODE = 1, - XDR_FREE = 2 - }; +enum xdr_op { + XDR_ENCODE = 0, + XDR_DECODE = 1, + XDR_FREE = 2 +}; /* * This is the number of bytes per unit of external data. @@ -135,6 +134,10 @@ struct XDR /* buf quick ptr to buffered data */ void (*x_destroy) __PMT ((XDR *__xdrs)); /* free privates of this xdr_stream */ + bool_t (*x_getint32) __PMT ((XDR *__xdrs, int32_t *__ip)); + /* get a int from underlying stream */ + bool_t (*x_putint32) __PMT ((XDR *__xdrs, __const int32_t *__ip)); + /* put a int to " */ } *x_ops; caddr_t x_public; /* users' data */ @@ -165,14 +168,14 @@ typedef bool_t (*xdrproc_t) __PMT ((XDR *, void *,...)); * u_int pos; */ #define XDR_GETINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p) + (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) #define xdr_getint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p) + (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) #define XDR_PUTINT32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p) + (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) #define xdr_putint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p) + (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) #define XDR_GETLONG(xdrs, longp) \ (*(xdrs)->x_ops->x_getlong)(xdrs, longp) diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c index cd5cecf0f7..cd24f726c9 100644 --- a/sunrpc/svc_tcp.c +++ b/sunrpc/svc_tcp.c @@ -312,8 +312,11 @@ readtcp (char *xprtptr, char *buf, int len) case 0: goto fatal_err; default: + if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP) + || (pollfd.revents & POLLNVAL)) + goto fatal_err; break; - } + } } while ((pollfd.revents & POLLIN) == 0); diff --git a/sunrpc/xdr_mem.c b/sunrpc/xdr_mem.c index 47b87eaf7a..9379048bf7 100644 --- a/sunrpc/xdr_mem.c +++ b/sunrpc/xdr_mem.c @@ -54,6 +54,8 @@ static u_int xdrmem_getpos (const XDR *); static bool_t xdrmem_setpos (XDR *, u_int); static long *xdrmem_inline (XDR *, int); static void xdrmem_destroy (XDR *); +static bool_t xdrmem_getint32 (XDR *, int32_t *); +static bool_t xdrmem_putint32 (XDR *, const int32_t *); static const struct xdr_ops xdrmem_ops = { @@ -64,7 +66,9 @@ static const struct xdr_ops xdrmem_ops = xdrmem_getpos, xdrmem_setpos, xdrmem_inline, - xdrmem_destroy + xdrmem_destroy, + xdrmem_getint32, + xdrmem_putint32 }; /* @@ -219,3 +223,35 @@ xdrmem_inline (xdrs, len) } return buf; } + +/* + * Gets the next word from the memory referenced by xdrs and places it + * in the int pointed to by ip. It then increments the private word to + * point at the next element. Neither object pointed to is const + */ +static bool_t +xdrmem_getint32 (XDR *xdrs, int32_t *ip) +{ + + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *ip = ntohl ((*((int32_t *) (xdrs->x_private)))); + xdrs->x_private += 4; + return TRUE; +} + +/* + * Puts the long pointed to by lp in the memory referenced by xdrs. It + * then increments the private word to point at the next element. The + * long pointed at is const + */ +static bool_t +xdrmem_putint32 (XDR *xdrs, const int32_t *ip) +{ + + if ((xdrs->x_handy -= 4) < 0) + return FALSE; + *(int32_t *) xdrs->x_private = htonl (*ip); + xdrs->x_private += 4; + return TRUE; +} diff --git a/sunrpc/xdr_rec.c b/sunrpc/xdr_rec.c index 30be6393a2..e0f22c5595 100644 --- a/sunrpc/xdr_rec.c +++ b/sunrpc/xdr_rec.c @@ -66,6 +66,8 @@ static u_int xdrrec_getpos (const XDR *); static bool_t xdrrec_setpos (XDR *, u_int); static long *xdrrec_inline (XDR *, int); static void xdrrec_destroy (XDR *); +static bool_t xdrrec_getint32 (XDR *, int32_t *); +static bool_t xdrrec_putint32 (XDR *, const int32_t *); static const struct xdr_ops xdrrec_ops = { @@ -76,7 +78,9 @@ static const struct xdr_ops xdrrec_ops = xdrrec_getpos, xdrrec_setpos, xdrrec_inline, - xdrrec_destroy + xdrrec_destroy, + xdrrec_getint32, + xdrrec_putint32 }; /* @@ -251,11 +255,8 @@ xdrrec_putlong (xdrs, lp) return TRUE; } -static bool_t /* must manage buffers, fragments, and records */ -xdrrec_getbytes (xdrs, addr, len) - XDR *xdrs; - caddr_t addr; - u_int len; +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes (XDR *xdrs, caddr_t addr, u_int len) { RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; u_int current; @@ -420,6 +421,53 @@ xdrrec_destroy (xdrs) mem_free ((caddr_t) rstrm, sizeof (RECSTREAM)); } +static bool_t +xdrrec_getint32 (XDR *xdrs, int32_t *ip) +{ + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *bufip = (int32_t *) rstrm->in_finger; + int32_t mylong; + + /* first try the inline, fast case */ + if (rstrm->fbtbc >= BYTES_PER_XDR_UNIT && + rstrm->in_boundry - (char *) bufip >= BYTES_PER_XDR_UNIT) + { + *ip = ntohl (*bufip); + rstrm->fbtbc -= BYTES_PER_XDR_UNIT; + rstrm->in_finger += BYTES_PER_XDR_UNIT; + } + else + { + if (!xdrrec_getbytes (xdrs, (caddr_t) &mylong, + BYTES_PER_XDR_UNIT)) + return FALSE; + *ip = ntohl (mylong); + } + return TRUE; +} + +static bool_t +xdrrec_putint32 (XDR *xdrs, const int32_t *ip) +{ + RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private; + int32_t *dest_ip = (int32_t *) rstrm->out_finger; + + if ((rstrm->out_finger += BYTES_PER_XDR_UNIT) > rstrm->out_boundry) + { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= BYTES_PER_XDR_UNIT; + rstrm->frag_sent = TRUE; + if (!flush_out (rstrm, FALSE)) + return FALSE; + dest_ip = (int32_t *) rstrm->out_finger; + rstrm->out_finger += BYTES_PER_XDR_UNIT; + } + *dest_ip = htonl (*ip); + return TRUE; +} /* * Exported routines to manage xdr records diff --git a/sunrpc/xdr_sizeof.c b/sunrpc/xdr_sizeof.c index 72403e0a26..e999e0ef51 100644 --- a/sunrpc/xdr_sizeof.c +++ b/sunrpc/xdr_sizeof.c @@ -123,6 +123,13 @@ x_destroy (XDR *xdrs) return; } +static bool_t +x_putint32 (XDR *xdrs, const int32_t *int32p) +{ + xdrs->x_handy += BYTES_PER_XDR_UNIT; + return TRUE; +} + unsigned long xdr_sizeof (xdrproc_t func, void *data) { @@ -132,6 +139,7 @@ xdr_sizeof (xdrproc_t func, void *data) /* to stop ANSI-C compiler from complaining */ typedef bool_t (*dummyfunc1) (XDR *, long *); typedef bool_t (*dummyfunc2) (XDR *, caddr_t, u_int); + typedef bool_t (*dummyfunc3) (XDR *, int32_t *); ops.x_putlong = x_putlong; ops.x_putbytes = x_putbytes; @@ -139,10 +147,12 @@ xdr_sizeof (xdrproc_t func, void *data) ops.x_getpostn = x_getpostn; ops.x_setpostn = x_setpostn; ops.x_destroy = x_destroy; + ops.x_putint32 = x_putint32; /* the other harmless ones */ ops.x_getlong = (dummyfunc1) harmless; ops.x_getbytes = (dummyfunc2) harmless; + ops.x_getint32 = (dummyfunc3) harmless; x.x_op = XDR_ENCODE; x.x_ops = &ops; diff --git a/sunrpc/xdr_stdio.c b/sunrpc/xdr_stdio.c index 8588042eeb..e58137c559 100644 --- a/sunrpc/xdr_stdio.c +++ b/sunrpc/xdr_stdio.c @@ -61,6 +61,8 @@ static u_int xdrstdio_getpos (const XDR *); static bool_t xdrstdio_setpos (XDR *, u_int); static long *xdrstdio_inline (XDR *, int); static void xdrstdio_destroy (XDR *); +static bool_t xdrstdio_getint32 (XDR *, int32_t *); +static bool_t xdrstdio_putint32 (XDR *, const int32_t *); /* * Ops vector for stdio type XDR @@ -74,7 +76,9 @@ static const struct xdr_ops xdrstdio_ops = xdrstdio_getpos, /* get offset in the stream */ xdrstdio_setpos, /* set offset in the stream */ xdrstdio_inline, /* prime stream for inline macros */ - xdrstdio_destroy /* destroy stream */ + xdrstdio_destroy, /* destroy stream */ + xdrstdio_getint32, /* deserialize a int */ + xdrstdio_putint32 /* serialize a int */ }; /* @@ -181,3 +185,25 @@ xdrstdio_inline (XDR *xdrs, int len) */ return NULL; } + +static bool_t +xdrstdio_getint32 (XDR *xdrs, int32_t *ip) +{ + int32_t mycopy; + + if (fread ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) + return FALSE; + *ip = ntohl (mycopy); + return TRUE; +} + +static bool_t +xdrstdio_putint32 (XDR *xdrs, const int32_t *ip) +{ + int32_t mycopy = htonl (*ip); + + ip = &mycopy; + if (fwrite ((caddr_t) ip, 4, 1, (FILE *) xdrs->x_private) != 1) + return FALSE; + return TRUE; +} |