diff options
Diffstat (limited to 'sunrpc')
-rw-r--r-- | sunrpc/Makefile | 27 | ||||
-rw-r--r-- | sunrpc/bindrsvprt.c | 23 | ||||
-rw-r--r-- | sunrpc/pm_getmaps.c | 15 | ||||
-rw-r--r-- | sunrpc/pm_getport.c | 52 | ||||
-rw-r--r-- | sunrpc/pmap_rmt.c | 3 | ||||
-rw-r--r-- | sunrpc/rpc_main.c | 6 | ||||
-rw-r--r-- | sunrpc/tst-xdrmem.c | 205 | ||||
-rw-r--r-- | sunrpc/xdr.c | 4 | ||||
-rw-r--r-- | sunrpc/xdr_stdio.c | 12 |
9 files changed, 311 insertions, 36 deletions
diff --git a/sunrpc/Makefile b/sunrpc/Makefile index 284e355cc3..083ab676ab 100644 --- a/sunrpc/Makefile +++ b/sunrpc/Makefile @@ -85,6 +85,7 @@ all: # Make this the default target; it will be defined in Rules. include ../Makeconfig +tests = tst-xdrmem xtests := tst-getmyaddr ifeq ($(have-thread-library),yes) @@ -107,19 +108,19 @@ librpcsvc-inhibit-o = .os # Build no shared rpcsvc library. omit-deps = $(librpcsvc-routines) endif -CFLAGS-xbootparam_prot.c = -Wno-unused -CFLAGS-xnlm_prot.c = -Wno-unused -CFLAGS-xrstat.c = -Wno-unused -CFLAGS-xyppasswd.c = -Wno-unused -CFLAGS-xklm_prot.c = -Wno-unused -CFLAGS-xrex.c = -Wno-unused -CFLAGS-xsm_inter.c = -Wno-unused -CFLAGS-xmount.c = -Wno-unused -CFLAGS-xrusers.c = -Wno-unused -CFLAGS-xspray.c = -Wno-unused -CFLAGS-xnfs_prot.c = -Wno-unused -CFLAGS-xrquota.c = -Wno-unused -CFLAGS-xkey_prot.c = -Wno-unused +CFLAGS-xbootparam_prot.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xnlm_prot.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xrstat.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xyppasswd.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xklm_prot.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xrex.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xsm_inter.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xmount.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xrusers.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xspray.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xnfs_prot.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xrquota.c = -Wno-unused $(PIC-ccflag) +CFLAGS-xkey_prot.c = -Wno-unused $(PIC-ccflag) CFLAGS-auth_unix.c = -fexceptions CFLAGS-key_call.c = -fexceptions CFLAGS-pmap_rmt.c = -fexceptions diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c index 374518716e..f58d3b2a8b 100644 --- a/sunrpc/bindrsvprt.c +++ b/sunrpc/bindrsvprt.c @@ -43,14 +43,15 @@ int bindresvport (int sd, struct sockaddr_in *sin) { - int res; static short port; struct sockaddr_in myaddr; int i; #define STARTPORT 600 +#define LOWPORT 512 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) + static short startport = STARTPORT; if (sin == (struct sockaddr_in *) 0) { @@ -68,17 +69,29 @@ bindresvport (int sd, struct sockaddr_in *sin) { port = (__getpid () % NPORTS) + STARTPORT; } - res = -1; - __set_errno (EADDRINUSE); - for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; ++i) + /* Initialize to make gcc happy. */ + int res = -1; + + int nports = ENDPORT - startport + 1; + again: + for (i = 0; i < nports; ++i) { sin->sin_port = htons (port++); if (port > ENDPORT) { - port = STARTPORT; + port = startport; } res = __bind (sd, sin, sizeof (struct sockaddr_in)); + if (res >= 0 || errno != EADDRINUSE) + break; + } + + if (i == nports && startport != LOWPORT) + { + startport = LOWPORT; + nports = STARTPORT - LOWPORT; + goto again; } return res; diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c index d1d4ca8769..2a6876d9d8 100644 --- a/sunrpc/pm_getmaps.c +++ b/sunrpc/pm_getmaps.c @@ -44,9 +44,12 @@ static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; #include <rpc/pmap_clnt.h> #include <sys/socket.h> #include <netdb.h> +#include <stdbool.h> #include <stdio.h> #include <errno.h> #include <libintl.h> +#include <unistd.h> + /* * Get a copy of the current port maps. @@ -56,13 +59,19 @@ struct pmaplist * pmap_getmaps (struct sockaddr_in *address) { struct pmaplist *head = (struct pmaplist *) NULL; - int socket = -1; struct timeval minutetimeout; CLIENT *client; + bool closeit = false; minutetimeout.tv_sec = 60; minutetimeout.tv_usec = 0; address->sin_port = htons (PMAPPORT); + + /* Don't need a reserved port to get ports from the portmapper. */ + int socket = __get_socket (address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, 50, 500); if (client != (CLIENT *) NULL) @@ -75,7 +84,9 @@ pmap_getmaps (struct sockaddr_in *address) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return head; } diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c index 00e1ba95bf..2d309841f3 100644 --- a/sunrpc/pm_getport.c +++ b/sunrpc/pm_getport.c @@ -38,6 +38,8 @@ static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; * Copyright (C) 1984, Sun Microsystems, Inc. */ +#include <stdbool.h> +#include <unistd.h> #include <rpc/rpc.h> #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> @@ -49,6 +51,41 @@ static const struct timeval tottimeout = {60, 0}; /* + * Create a socket that is locally bound to a non-reserve port. For + * any failures, -1 is returned which will cause the RPC code to + * create the socket. + */ +int +internal_function +__get_socket (struct sockaddr_in *saddr) +{ + int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (so < 0) + return -1; + + struct sockaddr_in laddr; + socklen_t namelen = sizeof (laddr); + laddr.sin_family = AF_INET; + laddr.sin_port = 0; + laddr.sin_addr.s_addr = htonl (INADDR_ANY); + + int cc = __bind (so, (struct sockaddr *) &laddr, namelen); + if (__builtin_expect (cc < 0, 0)) + { + fail: + __close (so); + return -1; + } + + cc = __connect (so, (struct sockaddr *) saddr, namelen); + if (__builtin_expect (cc < 0, 0)) + goto fail; + + return so; +} + + +/* * Find the mapped port for program,version. * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. @@ -64,11 +101,18 @@ pmap_getport (address, program, version, protocol) int socket = -1; CLIENT *client; struct pmap parms; + bool closeit = false; address->sin_port = htons (PMAPPORT); if (protocol == IPPROTO_TCP) - client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, - RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + { + /* Don't need a reserved port to get ports from the portmapper. */ + socket = __get_socket(address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, + RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + } else client = INTUSE(clntudp_bufcreate) (address, PMAPPROG, PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, @@ -93,7 +137,9 @@ pmap_getport (address, program, version, protocol) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return port; } diff --git a/sunrpc/pmap_rmt.c b/sunrpc/pmap_rmt.c index 644d503a1f..e068848919 100644 --- a/sunrpc/pmap_rmt.c +++ b/sunrpc/pmap_rmt.c @@ -125,8 +125,9 @@ xdr_rmtcall_args (XDR *xdrs, struct rmtcallargs *cap) INTUSE(xdr_u_long) (xdrs, &(cap->vers)) && INTUSE(xdr_u_long) (xdrs, &(cap->proc))) { + u_long dummy_arglen = 0; lenposition = XDR_GETPOS (xdrs); - if (!INTUSE(xdr_u_long) (xdrs, &(cap->arglen))) + if (!INTUSE(xdr_u_long) (xdrs, &dummy_arglen)) return FALSE; argposition = XDR_GETPOS (xdrs); if (!(*(cap->xdr_args)) (xdrs, cap->args_ptr)) diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c index fee83514d1..acc0132603 100644 --- a/sunrpc/rpc_main.c +++ b/sunrpc/rpc_main.c @@ -695,11 +695,9 @@ s_output (int argc, const char *argv[], const char *infile, const char *define, fprintf (fout, "#include <stdio.h>\n"); fprintf (fout, "#include <stdlib.h>\n"); + fprintf (fout, "#include <rpc/pmap_clnt.h>\n"); if (Cflag) - { - fprintf (fout, "#include <rpc/pmap_clnt.h>\n"); - fprintf (fout, "#include <string.h>\n"); - } + fprintf (fout, "#include <string.h>\n"); if (strcmp (svcclosetime, "-1") == 0) indefinitewait = 1; else if (strcmp (svcclosetime, "0") == 0) diff --git a/sunrpc/tst-xdrmem.c b/sunrpc/tst-xdrmem.c new file mode 100644 index 0000000000..0c9929c6ed --- /dev/null +++ b/sunrpc/tst-xdrmem.c @@ -0,0 +1,205 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2005. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <limits.h> +#include <stdio.h> +#include <string.h> +#include <rpc/rpc.h> + +static int +do_test (void) +{ + XDR xdrs; + unsigned char buf[8192]; + int v_int; + u_int v_u_int; + long v_long; + u_long v_u_long; + quad_t v_hyper; + u_quad_t v_u_hyper; + quad_t v_longlong_t; + u_quad_t v_u_longlong_t; + short v_short; + u_short v_u_short; + char v_char; + u_char v_u_char; + bool_t v_bool; + enum_t v_enum; + char *v_wrapstring; + + xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_ENCODE); + +#define TESTS \ + T(int, 0) \ + T(int, CHAR_MAX) \ + T(int, CHAR_MIN) \ + T(int, SHRT_MAX) \ + T(int, SHRT_MIN) \ + T(int, INT_MAX) \ + T(int, INT_MIN) \ + T(int, 0x123) \ + T(u_int, 0) \ + T(u_int, UCHAR_MAX) \ + T(u_int, USHRT_MAX) \ + T(u_int, UINT_MAX) \ + T(u_int, 0xdeadbeef) \ + T(u_int, 0x12345678) \ + T(long, 0) \ + T(long, 2147483647L) \ + T(long, -2147483648L) \ + T(long, -305419896L) \ + T(long, -305419896L) \ + T(u_long, 0) \ + T(u_long, 0xffffffffUL) \ + T(u_long, 0xdeadbeefUL) \ + T(u_long, 0x12345678UL) \ + T(hyper, 0) \ + T(hyper, CHAR_MAX) \ + T(hyper, CHAR_MIN) \ + T(hyper, SHRT_MAX) \ + T(hyper, SHRT_MIN) \ + T(hyper, INT_MAX) \ + T(hyper, INT_MIN) \ + T(hyper, LONG_MAX) \ + T(hyper, LONG_MIN) \ + T(hyper, LONG_LONG_MAX) \ + T(hyper, LONG_LONG_MIN) \ + T(hyper, 0x12312345678LL) \ + T(hyper, 0x12387654321LL) \ + T(u_hyper, 0) \ + T(u_hyper, UCHAR_MAX) \ + T(u_hyper, USHRT_MAX) \ + T(u_hyper, UINT_MAX) \ + T(u_hyper, ULONG_MAX) \ + T(u_hyper, ULONG_LONG_MAX) \ + T(u_hyper, 0xdeadbeefdeadbeefULL) \ + T(u_hyper, 0x12312345678ULL) \ + T(u_hyper, 0x12387654321ULL) \ + T(longlong_t, 0) \ + T(longlong_t, CHAR_MAX) \ + T(longlong_t, CHAR_MIN) \ + T(longlong_t, SHRT_MAX) \ + T(longlong_t, SHRT_MIN) \ + T(longlong_t, INT_MAX) \ + T(longlong_t, INT_MIN) \ + T(longlong_t, LONG_MAX) \ + T(longlong_t, LONG_MIN) \ + T(longlong_t, LONG_LONG_MAX) \ + T(longlong_t, LONG_LONG_MIN) \ + T(longlong_t, 0x12312345678LL) \ + T(longlong_t, 0x12387654321LL) \ + T(u_longlong_t, 0) \ + T(u_longlong_t, UCHAR_MAX) \ + T(u_longlong_t, USHRT_MAX) \ + T(u_longlong_t, UINT_MAX) \ + T(u_longlong_t, ULONG_MAX) \ + T(u_longlong_t, ULONG_LONG_MAX) \ + T(u_longlong_t, 0xdeadbeefdeadbeefULL)\ + T(u_longlong_t, 0x12312345678ULL) \ + T(u_longlong_t, 0x12387654321ULL) \ + T(short, CHAR_MAX) \ + T(short, CHAR_MIN) \ + T(short, SHRT_MAX) \ + T(short, SHRT_MIN) \ + T(short, 0x123) \ + T(u_short, 0) \ + T(u_short, UCHAR_MAX) \ + T(u_short, USHRT_MAX) \ + T(u_short, 0xbeef) \ + T(u_short, 0x5678) \ + T(char, CHAR_MAX) \ + T(char, CHAR_MIN) \ + T(char, 0x23) \ + T(u_char, 0) \ + T(u_char, UCHAR_MAX) \ + T(u_char, 0xef) \ + T(u_char, 0x78) \ + T(bool, 0) \ + T(bool, 1) \ + T(enum, 0) \ + T(enum, CHAR_MAX) \ + T(enum, CHAR_MIN) \ + T(enum, SHRT_MAX) \ + T(enum, SHRT_MIN) \ + T(enum, INT_MAX) \ + T(enum, INT_MIN) \ + T(enum, 0x123) \ + S(wrapstring, (char *) "") \ + S(wrapstring, (char *) "hello, world") + +#define T(type, val) \ + v_##type = val; \ + if (! xdr_##type (&xdrs, &v_##type)) \ + { \ + puts ("encoding of " #type \ + " " #val " failed"); \ + return 1; \ + } +#define S(type, val) T(type, val) + + TESTS +#undef T +#undef S + + xdr_destroy (&xdrs); + + xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_DECODE); + +#define T(type, val) \ + v_##type = 0x15; \ + if (! xdr_##type (&xdrs, &v_##type)) \ + { \ + puts ("decoding of " #type \ + " " #val " failed"); \ + return 1; \ + } \ + if (v_##type != val) \ + { \ + puts ("decoded value differs, " \ + "type " #type " " #val); \ + return 1; \ + } +#define S(type, val) \ + v_##type = NULL; \ + if (! xdr_##type (&xdrs, &v_##type)) \ + { \ + puts ("decoding of " #type \ + " " #val " failed"); \ + return 1; \ + } \ + if (strcmp (v_##type, val)) \ + { \ + puts ("decoded value differs, " \ + "type " #type " " #val); \ + return 1; \ + } \ + free (v_##type); \ + v_##type = NULL; + + TESTS +#undef T +#undef S + + xdr_destroy (&xdrs); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c index d99a9985c4..4213907d96 100644 --- a/sunrpc/xdr.c +++ b/sunrpc/xdr.c @@ -240,7 +240,7 @@ xdr_hyper (XDR *xdrs, quad_t *llp) if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) return FALSE; *llp = ((quad_t) t1) << 32; - *llp |= t2; + *llp |= (uint32_t) t2; return TRUE; } @@ -274,7 +274,7 @@ xdr_u_hyper (XDR *xdrs, u_quad_t *ullp) if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2)) return FALSE; *ullp = ((u_quad_t) t1) << 32; - *ullp |= t2; + *ullp |= (uint32_t) t2; return TRUE; } diff --git a/sunrpc/xdr_stdio.c b/sunrpc/xdr_stdio.c index 4daa062c82..e73c5a5202 100644 --- a/sunrpc/xdr_stdio.c +++ b/sunrpc/xdr_stdio.c @@ -108,20 +108,20 @@ xdrstdio_destroy (XDR *xdrs) static bool_t xdrstdio_getlong (XDR *xdrs, long *lp) { - int32_t mycopy; + u_int32_t mycopy; - if (fread ((caddr_t) & mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) + if (fread ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) return FALSE; - *lp = (int32_t) ntohl (mycopy); + *lp = (long) ntohl (mycopy); return TRUE; } static bool_t xdrstdio_putlong (XDR *xdrs, const long *lp) { - long mycopy = htonl (*lp); - lp = &mycopy; - if (fwrite ((caddr_t) lp, 4, 1, (FILE *) xdrs->x_private) != 1) + int32_t mycopy = htonl ((u_int32_t) *lp); + + if (fwrite ((caddr_t) &mycopy, 4, 1, (FILE *) xdrs->x_private) != 1) return FALSE; return TRUE; } |