summaryrefslogtreecommitdiff
path: root/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'sunrpc')
-rw-r--r--sunrpc/Makefile27
-rw-r--r--sunrpc/bindrsvprt.c23
-rw-r--r--sunrpc/pm_getmaps.c15
-rw-r--r--sunrpc/pm_getport.c52
-rw-r--r--sunrpc/pmap_rmt.c3
-rw-r--r--sunrpc/rpc_main.c6
-rw-r--r--sunrpc/tst-xdrmem.c205
-rw-r--r--sunrpc/xdr.c4
-rw-r--r--sunrpc/xdr_stdio.c12
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;
}