summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/libtirpc
diff options
context:
space:
mode:
authorAndre McCurdy <armccurdy@gmail.com>2016-01-26 16:16:54 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-30 11:36:59 +0000
commitd5b3b97126507aee07eb33c638873eab36b779eb (patch)
tree1b200cbdc2d3096aa176580e6942eb65229ae2f3 /meta/recipes-extended/libtirpc
parent209066ccce1f211b7982372dcb9b9795493aaece (diff)
downloadpoky-d5b3b97126507aee07eb33c638873eab36b779eb.tar.gz
libtirpc: remove stray .orig file from Use-netbsd-queue.h.patch
The file 'src/clnt_bcast.c.orig' seems to have been accidentally included when the Use-netbsd-queue.h.patch patch was created. (From OE-Core rev: e5d8c575e8ba5d8d56409f45aa081ecec576dcd0) Signed-off-by: Andre McCurdy <armccurdy@gmail.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/libtirpc')
-rw-r--r--meta/recipes-extended/libtirpc/libtirpc/Use-netbsd-queue.h.patch701
1 files changed, 0 insertions, 701 deletions
diff --git a/meta/recipes-extended/libtirpc/libtirpc/Use-netbsd-queue.h.patch b/meta/recipes-extended/libtirpc/libtirpc/Use-netbsd-queue.h.patch
index 21c6c53a85..f93223feb4 100644
--- a/meta/recipes-extended/libtirpc/libtirpc/Use-netbsd-queue.h.patch
+++ b/meta/recipes-extended/libtirpc/libtirpc/Use-netbsd-queue.h.patch
@@ -26,707 +26,6 @@ diff -Naur libtirpc-1.0.1-orig/src/clnt_bcast.c libtirpc-1.0.1/src/clnt_bcast.c
26 #include "rpc_com.h" 26 #include "rpc_com.h"
27 #include "debug.h" 27 #include "debug.h"
28 28
29diff -Naur libtirpc-1.0.1-orig/src/clnt_bcast.c.orig libtirpc-1.0.1/src/clnt_bcast.c.orig
30--- libtirpc-1.0.1-orig/src/clnt_bcast.c.orig 1970-01-01 02:00:00.000000000 +0200
31+++ libtirpc-1.0.1/src/clnt_bcast.c.orig 2015-10-30 17:15:14.000000000 +0200
32@@ -0,0 +1,697 @@
33+/*
34+ * Copyright (c) 2009, Sun Microsystems, Inc.
35+ * All rights reserved.
36+ *
37+ * Redistribution and use in source and binary forms, with or without
38+ * modification, are permitted provided that the following conditions are met:
39+ * - Redistributions of source code must retain the above copyright notice,
40+ * this list of conditions and the following disclaimer.
41+ * - Redistributions in binary form must reproduce the above copyright notice,
42+ * this list of conditions and the following disclaimer in the documentation
43+ * and/or other materials provided with the distribution.
44+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
45+ * contributors may be used to endorse or promote products derived
46+ * from this software without specific prior written permission.
47+ *
48+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
52+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58+ * POSSIBILITY OF SUCH DAMAGE.
59+ */
60+/*
61+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
62+ */
63+
64+/*
65+ * clnt_bcast.c
66+ * Client interface to broadcast service.
67+ *
68+ * Copyright (C) 1988, Sun Microsystems, Inc.
69+ *
70+ * The following is kludged-up support for simple rpc broadcasts.
71+ * Someday a large, complicated system will replace these routines.
72+ */
73+#include <sys/socket.h>
74+#include <sys/types.h>
75+#include <sys/queue.h>
76+
77+#include <net/if.h>
78+#include <netinet/in.h>
79+#include <ifaddrs.h>
80+#include <poll.h>
81+#include <rpc/rpc.h>
82+#ifdef PORTMAP
83+#include <rpc/pmap_prot.h>
84+#include <rpc/pmap_clnt.h>
85+#include <rpc/pmap_rmt.h>
86+#endif /* PORTMAP */
87+#include <rpc/nettype.h>
88+#include <arpa/inet.h>
89+#include <stdio.h>
90+#include <errno.h>
91+#include <stdlib.h>
92+#include <unistd.h>
93+#include <netdb.h>
94+#include <err.h>
95+#include <string.h>
96+
97+#include "rpc_com.h"
98+#include "debug.h"
99+
100+#define MAXBCAST 20 /* Max no of broadcasting transports */
101+#define INITTIME 4000 /* Time to wait initially */
102+#define WAITTIME 8000 /* Maximum time to wait */
103+
104+# define POLLRDNORM 0x040 /* Normal data may be read. */
105+# define POLLRDBAND 0x080 /* Priority data may be read. */
106+
107+
108+
109+/*
110+ * If nettype is NULL, it broadcasts on all the available
111+ * datagram_n transports. May potentially lead to broadacst storms
112+ * and hence should be used with caution, care and courage.
113+ *
114+ * The current parameter xdr packet size is limited by the max tsdu
115+ * size of the transport. If the max tsdu size of any transport is
116+ * smaller than the parameter xdr packet, then broadcast is not
117+ * sent on that transport.
118+ *
119+ * Also, the packet size should be less the packet size of
120+ * the data link layer (for ethernet it is 1400 bytes). There is
121+ * no easy way to find out the max size of the data link layer and
122+ * we are assuming that the args would be smaller than that.
123+ *
124+ * The result size has to be smaller than the transport tsdu size.
125+ *
126+ * If PORTMAP has been defined, we send two packets for UDP, one for
127+ * rpcbind and one for portmap. For those machines which support
128+ * both rpcbind and portmap, it will cause them to reply twice, and
129+ * also here it will get two responses ... inefficient and clumsy.
130+ */
131+
132+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
133+
134+#define TAILQ_FIRST(head) ((head)->tqh_first)
135+
136+
137+struct broadif {
138+ int index;
139+ struct sockaddr_storage broadaddr;
140+ TAILQ_ENTRY(broadif) link;
141+};
142+
143+typedef TAILQ_HEAD(, broadif) broadlist_t;
144+
145+int __rpc_getbroadifs(int, int, int, broadlist_t *);
146+void __rpc_freebroadifs(broadlist_t *);
147+int __rpc_broadenable(int, int, struct broadif *);
148+
149+int __rpc_lowvers = 0;
150+
151+int
152+__rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list)
153+{
154+ int count = 0;
155+ struct broadif *bip;
156+ struct ifaddrs *ifap, *ifp;
157+#ifdef INET6
158+ struct sockaddr_in6 *sin6;
159+#endif
160+ struct sockaddr_in *sin;
161+ struct addrinfo hints, *res;
162+
163+ if (getifaddrs(&ifp) < 0)
164+ return 0;
165+
166+ memset(&hints, 0, sizeof hints);
167+
168+ hints.ai_family = af;
169+ hints.ai_protocol = proto;
170+ hints.ai_socktype = socktype;
171+
172+ if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0)
173+ return 0;
174+
175+ for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
176+ if (ifap->ifa_addr == NULL || /* happens for eg tuntap devices */
177+ ifap->ifa_addr->sa_family != af ||
178+ !(ifap->ifa_flags & IFF_UP))
179+ continue;
180+ bip = (struct broadif *)malloc(sizeof *bip);
181+ if (bip == NULL)
182+ break;
183+ bip->index = if_nametoindex(ifap->ifa_name);
184+ if (
185+#ifdef INET6
186+ af != AF_INET6 &&
187+#endif
188+ (ifap->ifa_flags & IFF_BROADCAST) &&
189+ ifap->ifa_broadaddr) {
190+ /* memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
191+ (size_t)ifap->ifa_broadaddr->sa_len);*/
192+ memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
193+ sizeof(bip->broadaddr));
194+ sin = (struct sockaddr_in *)(void *)&bip->broadaddr;
195+ sin->sin_port =
196+ ((struct sockaddr_in *)
197+ (void *)res->ai_addr)->sin_port;
198+ } else
199+#ifdef INET6
200+ if (af == AF_INET6 && (ifap->ifa_flags & IFF_MULTICAST)) {
201+ sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr;
202+ inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr);
203+ sin6->sin6_family = af;
204+ sin6->sin6_port =
205+ ((struct sockaddr_in6 *)
206+ (void *)res->ai_addr)->sin6_port;
207+ sin6->sin6_scope_id = bip->index;
208+ } else
209+#endif
210+ {
211+ free(bip);
212+ continue;
213+ }
214+ TAILQ_INSERT_TAIL(list, bip, link);
215+ count++;
216+ }
217+ freeifaddrs(ifp);
218+ freeaddrinfo(res);
219+
220+ return count;
221+}
222+
223+void
224+__rpc_freebroadifs(broadlist_t *list)
225+{
226+ struct broadif *bip, *next;
227+
228+ bip = TAILQ_FIRST(list);
229+
230+ while (bip != NULL) {
231+ next = TAILQ_NEXT(bip, link);
232+ free(bip);
233+ bip = next;
234+ }
235+}
236+
237+int
238+/*ARGSUSED*/
239+__rpc_broadenable(int af, int s, struct broadif *bip)
240+{
241+ int o = 1;
242+
243+#if 0
244+ if (af == AF_INET6) {
245+ fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
246+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
247+ sizeof bip->index) < 0)
248+ return -1;
249+ } else
250+#endif
251+ if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0)
252+ return -1;
253+
254+ return 0;
255+}
256+
257+/*
258+ * Some rpcbind implementations use an IPv6 socket to serve both
259+ * IPv4 and IPv6 messages, but neglect to check for the caller's
260+ * address family when sending broadcast replies. These rpcbind
261+ * implementations return an IPv6 address in reply to an IPv4
262+ * broadcast. We can either ignore them, or try to patch them up.
263+ */
264+static struct netbuf *
265+__ipv6v4_fixup(struct sockaddr_storage *ss, const char *uaddr)
266+{
267+ struct sockaddr_in sin;
268+ struct netbuf *np;
269+
270+ /* ss is the remote rpcbind server's address */
271+ if (ss->ss_family != AF_INET)
272+ return NULL;
273+ memcpy(&sin, ss, sizeof(sin));
274+
275+ np = __rpc_uaddr2taddr_af(AF_INET6, uaddr);
276+ if (np == NULL)
277+ return NULL;
278+
279+ /* Overwrite the port with that of the service we
280+ * wanted to talk to. */
281+ sin.sin_port = ((struct sockaddr_in6 *) np)->sin6_port;
282+
283+ /* We know netbuf holds a sockaddr_in6, so it can easily
284+ * hold a sockaddr_in as well. */
285+ memcpy(np->buf, &sin, sizeof(sin));
286+ np->len = sizeof(sin);
287+
288+ return np;
289+}
290+
291+enum clnt_stat
292+rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
293+ eachresult, inittime, waittime, nettype)
294+ rpcprog_t prog; /* program number */
295+ rpcvers_t vers; /* version number */
296+ rpcproc_t proc; /* procedure number */
297+ xdrproc_t xargs; /* xdr routine for args */
298+ caddr_t argsp; /* pointer to args */
299+ xdrproc_t xresults; /* xdr routine for results */
300+ caddr_t resultsp; /* pointer to results */
301+ resultproc_t eachresult; /* call with each result obtained */
302+ int inittime; /* how long to wait initially */
303+ int waittime; /* maximum time to wait */
304+ const char *nettype; /* transport type */
305+{
306+ enum clnt_stat stat = RPC_SUCCESS; /* Return status */
307+ XDR xdr_stream; /* XDR stream */
308+ XDR *xdrs = &xdr_stream;
309+ struct rpc_msg msg; /* RPC message */
310+ struct timeval t;
311+ char *outbuf = NULL; /* Broadcast msg buffer */
312+ char *inbuf = NULL; /* Reply buf */
313+ int inlen;
314+ u_int maxbufsize = 0;
315+ AUTH *sys_auth = authunix_create_default();
316+ int i;
317+ void *handle;
318+ char uaddress[1024]; /* A self imposed limit */
319+ char *uaddrp = uaddress;
320+ int pmap_reply_flag; /* reply recvd from PORTMAP */
321+ /* An array of all the suitable broadcast transports */
322+ struct {
323+ int fd; /* File descriptor */
324+ int af;
325+ int proto;
326+ struct netconfig *nconf; /* Netconfig structure */
327+ u_int asize; /* Size of the addr buf */
328+ u_int dsize; /* Size of the data buf */
329+ struct sockaddr_storage raddr; /* Remote address */
330+ broadlist_t nal;
331+ } fdlist[MAXBCAST];
332+ struct pollfd pfd[MAXBCAST];
333+ size_t fdlistno = 0;
334+ struct r_rpcb_rmtcallargs barg; /* Remote arguments */
335+ struct r_rpcb_rmtcallres bres; /* Remote results */
336+ size_t outlen;
337+ struct netconfig *nconf;
338+ int msec;
339+ int pollretval;
340+ int fds_found;
341+
342+#ifdef PORTMAP
343+ size_t outlen_pmap = 0;
344+ u_long port; /* Remote port number */
345+ int pmap_flag = 0; /* UDP exists ? */
346+ char *outbuf_pmap = NULL;
347+ struct rmtcallargs barg_pmap; /* Remote arguments */
348+ struct rmtcallres bres_pmap; /* Remote results */
349+ u_int udpbufsz = 0;
350+#endif /* PORTMAP */
351+
352+ if (sys_auth == NULL) {
353+ return (RPC_SYSTEMERROR);
354+ }
355+ /*
356+ * initialization: create a fd, a broadcast address, and send the
357+ * request on the broadcast transport.
358+ * Listen on all of them and on replies, call the user supplied
359+ * function.
360+ */
361+
362+ if (nettype == NULL)
363+ nettype = "datagram_n";
364+ if ((handle = __rpc_setconf(nettype)) == NULL) {
365+ return (RPC_UNKNOWNPROTO);
366+ }
367+ while ((nconf = __rpc_getconf(handle)) != NULL) {
368+ int fd;
369+ struct __rpc_sockinfo si;
370+
371+ if (nconf->nc_semantics != NC_TPI_CLTS)
372+ continue;
373+ if (fdlistno >= MAXBCAST)
374+ break; /* No more slots available */
375+ if (!__rpc_nconf2sockinfo(nconf, &si))
376+ continue;
377+
378+ TAILQ_INIT(&fdlist[fdlistno].nal);
379+ if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype,
380+ &fdlist[fdlistno].nal) == 0)
381+ continue;
382+
383+ fd = socket(si.si_af, si.si_socktype, si.si_proto);
384+ if (fd < 0) {
385+ stat = RPC_CANTSEND;
386+ continue;
387+ }
388+ fdlist[fdlistno].af = si.si_af;
389+ fdlist[fdlistno].proto = si.si_proto;
390+ fdlist[fdlistno].fd = fd;
391+ fdlist[fdlistno].nconf = nconf;
392+ fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
393+ pfd[fdlistno].events = POLLIN | POLLPRI |
394+ POLLRDNORM | POLLRDBAND;
395+ pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
396+ fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
397+ 0);
398+
399+ if (maxbufsize <= fdlist[fdlistno].dsize)
400+ maxbufsize = fdlist[fdlistno].dsize;
401+
402+#ifdef PORTMAP
403+ if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
404+ udpbufsz = fdlist[fdlistno].dsize;
405+ if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
406+ close(fd);
407+ stat = RPC_SYSTEMERROR;
408+ goto done_broad;
409+ }
410+ pmap_flag = 1;
411+ }
412+#endif /* PORTMAP */
413+ fdlistno++;
414+ }
415+
416+ if (fdlistno == 0) {
417+ if (stat == RPC_SUCCESS)
418+ stat = RPC_UNKNOWNPROTO;
419+ goto done_broad;
420+ }
421+ if (maxbufsize == 0) {
422+ if (stat == RPC_SUCCESS)
423+ stat = RPC_CANTSEND;
424+ goto done_broad;
425+ }
426+ inbuf = malloc(maxbufsize);
427+ outbuf = malloc(maxbufsize);
428+ if ((inbuf == NULL) || (outbuf == NULL)) {
429+ stat = RPC_SYSTEMERROR;
430+ goto done_broad;
431+ }
432+
433+ /* Serialize all the arguments which have to be sent */
434+ (void) gettimeofday(&t, NULL);
435+ msg.rm_xid = __RPC_GETXID(&t);
436+ msg.rm_direction = CALL;
437+ msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
438+ msg.rm_call.cb_prog = RPCBPROG;
439+ msg.rm_call.cb_vers = RPCBVERS;
440+ msg.rm_call.cb_proc = RPCBPROC_CALLIT;
441+ barg.prog = prog;
442+ barg.vers = vers;
443+ barg.proc = proc;
444+ barg.args.args_val = argsp;
445+ barg.xdr_args = xargs;
446+ bres.addr = uaddrp;
447+ bres.results.results_val = resultsp;
448+ bres.xdr_res = xresults;
449+ msg.rm_call.cb_cred = sys_auth->ah_cred;
450+ msg.rm_call.cb_verf = sys_auth->ah_verf;
451+ xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
452+ if ((!xdr_callmsg(xdrs, &msg)) ||
453+ (!xdr_rpcb_rmtcallargs(xdrs,
454+ (struct rpcb_rmtcallargs *)(void *)&barg))) {
455+ stat = RPC_CANTENCODEARGS;
456+ goto done_broad;
457+ }
458+ outlen = xdr_getpos(xdrs);
459+ xdr_destroy(xdrs);
460+
461+#ifdef PORTMAP
462+ /* Prepare the packet for version 2 PORTMAP */
463+ if (pmap_flag) {
464+ msg.rm_xid++; /* One way to distinguish */
465+ msg.rm_call.cb_prog = PMAPPROG;
466+ msg.rm_call.cb_vers = PMAPVERS;
467+ msg.rm_call.cb_proc = PMAPPROC_CALLIT;
468+ barg_pmap.prog = prog;
469+ barg_pmap.vers = vers;
470+ barg_pmap.proc = proc;
471+ barg_pmap.args_ptr = argsp;
472+ barg_pmap.xdr_args = xargs;
473+ bres_pmap.port_ptr = &port;
474+ bres_pmap.xdr_results = xresults;
475+ bres_pmap.results_ptr = resultsp;
476+ xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
477+ if ((! xdr_callmsg(xdrs, &msg)) ||
478+ (! xdr_rmtcall_args(xdrs, &barg_pmap))) {
479+ stat = RPC_CANTENCODEARGS;
480+ goto done_broad;
481+ }
482+ outlen_pmap = xdr_getpos(xdrs);
483+ xdr_destroy(xdrs);
484+ }
485+#endif /* PORTMAP */
486+
487+ /*
488+ * Basic loop: broadcast the packets to transports which
489+ * support data packets of size such that one can encode
490+ * all the arguments.
491+ * Wait a while for response(s).
492+ * The response timeout grows larger per iteration.
493+ */
494+ for (msec = inittime; msec <= waittime; msec += msec) {
495+ struct broadif *bip;
496+
497+ /* Broadcast all the packets now */
498+ for (i = 0; i < fdlistno; i++) {
499+ if (fdlist[i].dsize < outlen) {
500+ stat = RPC_CANTSEND;
501+ continue;
502+ }
503+ for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
504+ bip = TAILQ_NEXT(bip, link)) {
505+ void *addr;
506+
507+ addr = &bip->broadaddr;
508+
509+ __rpc_broadenable(fdlist[i].af, fdlist[i].fd,
510+ bip);
511+
512+ /*
513+ * Only use version 3 if lowvers is not set
514+ */
515+
516+ if (!__rpc_lowvers)
517+ if (sendto(fdlist[i].fd, outbuf,
518+ outlen, 0, (struct sockaddr*)addr,
519+ (size_t)fdlist[i].asize) !=
520+ outlen) {
521+ LIBTIRPC_DEBUG(1,
522+ ("rpc_broadcast_exp: sendto failed: errno %d", errno));
523+ warnx("rpc_broadcast_exp: cannot send broadcast packet");
524+ stat = RPC_CANTSEND;
525+ continue;
526+ };
527+ if (!__rpc_lowvers)
528+ LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: Broadcast packet sent for %s\n",
529+ fdlist[i].nconf->nc_netid));
530+#ifdef PORTMAP
531+ /*
532+ * Send the version 2 packet also
533+ * for UDP/IP
534+ */
535+ if (pmap_flag &&
536+ fdlist[i].proto == IPPROTO_UDP) {
537+ if (sendto(fdlist[i].fd, outbuf_pmap,
538+ outlen_pmap, 0, addr,
539+ (size_t)fdlist[i].asize) !=
540+ outlen_pmap) {
541+ warnx("clnt_bcast: "
542+ "Cannot send broadcast packet");
543+ stat = RPC_CANTSEND;
544+ continue;
545+ }
546+ }
547+ LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: PMAP Broadcast packet sent for %s\n",
548+ fdlist[i].nconf->nc_netid));
549+#endif /* PORTMAP */
550+ }
551+ /* End for sending all packets on this transport */
552+ } /* End for sending on all transports */
553+
554+ if (eachresult == NULL) {
555+ stat = RPC_SUCCESS;
556+ goto done_broad;
557+ }
558+
559+ /*
560+ * Get all the replies from these broadcast requests
561+ */
562+ recv_again:
563+
564+ switch (pollretval = poll(pfd, fdlistno, msec)) {
565+ case 0: /* timed out */
566+ stat = RPC_TIMEDOUT;
567+ continue;
568+ case -1: /* some kind of error - we ignore it */
569+ goto recv_again;
570+ } /* end of poll results switch */
571+
572+ for (i = fds_found = 0;
573+ i < fdlistno && fds_found < pollretval; i++) {
574+ bool_t done = FALSE;
575+
576+ if (pfd[i].revents == 0)
577+ continue;
578+ else if (pfd[i].revents & POLLNVAL) {
579+ /*
580+ * Something bad has happened to this descri-
581+ * ptor. We can cause _poll() to ignore
582+ * it simply by using a negative fd. We do that
583+ * rather than compacting the pfd[] and fdlist[]
584+ * arrays.
585+ */
586+ pfd[i].fd = -1;
587+ fds_found++;
588+ continue;
589+ } else
590+ fds_found++;
591+ LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: response for %s\n",
592+ fdlist[i].nconf->nc_netid));
593+ try_again:
594+ inlen = recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
595+ 0, (struct sockaddr *)(void *)&fdlist[i].raddr,
596+ &fdlist[i].asize);
597+ if (inlen < 0) {
598+ if (errno == EINTR)
599+ goto try_again;
600+ warnx("clnt_bcast: Cannot receive reply to "
601+ "broadcast");
602+ stat = RPC_CANTRECV;
603+ continue;
604+ }
605+ if (inlen < sizeof (u_int32_t))
606+ continue; /* Drop that and go ahead */
607+ /*
608+ * see if reply transaction id matches sent id.
609+ * If so, decode the results. If return id is xid + 1
610+ * it was a PORTMAP reply
611+ */
612+ if (*((u_int32_t *)(void *)(inbuf)) ==
613+ *((u_int32_t *)(void *)(outbuf))) {
614+ pmap_reply_flag = 0;
615+ msg.acpted_rply.ar_verf = _null_auth;
616+ msg.acpted_rply.ar_results.where =
617+ (caddr_t)(void *)&bres;
618+ msg.acpted_rply.ar_results.proc =
619+ (xdrproc_t)xdr_rpcb_rmtcallres;
620+#ifdef PORTMAP
621+ } else if (pmap_flag &&
622+ *((u_int32_t *)(void *)(inbuf)) ==
623+ *((u_int32_t *)(void *)(outbuf_pmap))) {
624+ pmap_reply_flag = 1;
625+ msg.acpted_rply.ar_verf = _null_auth;
626+ msg.acpted_rply.ar_results.where =
627+ (caddr_t)(void *)&bres_pmap;
628+ msg.acpted_rply.ar_results.proc =
629+ (xdrproc_t)xdr_rmtcallres;
630+#endif /* PORTMAP */
631+ } else
632+ continue;
633+ xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
634+ if (xdr_replymsg(xdrs, &msg)) {
635+ if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
636+ (msg.acpted_rply.ar_stat == SUCCESS)) {
637+ struct netbuf *np;
638+#ifdef PORTMAP
639+ struct netbuf taddr;
640+ struct sockaddr_in sin;
641+
642+ if (pmap_flag && pmap_reply_flag) {
643+ memcpy(&sin, &fdlist[i].raddr, sizeof(sin));
644+ sin.sin_port = htons((u_short)port);
645+ memcpy(&fdlist[i].raddr, &sin, sizeof(sin));
646+ taddr.len = taddr.maxlen =
647+ sizeof(fdlist[i].raddr);
648+ taddr.buf = &fdlist[i].raddr;
649+ done = (*eachresult)(resultsp,
650+ &taddr, fdlist[i].nconf);
651+ } else {
652+#endif /* PORTMAP */
653+ LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: uaddr %s\n", uaddrp));
654+ np = uaddr2taddr(
655+ fdlist[i].nconf, uaddrp);
656+ /* Some misguided rpcbind implemenations
657+ * seem to return an IPv6 uaddr in IPv4
658+ * responses. */
659+ if (np == NULL)
660+ np = __ipv6v4_fixup(
661+ &fdlist[i].raddr,
662+ uaddrp);
663+ if (np != NULL) {
664+ done = (*eachresult)(resultsp,
665+ np, fdlist[i].nconf);
666+ free(np);
667+ }
668+#ifdef PORTMAP
669+ }
670+#endif /* PORTMAP */
671+ }
672+ /* otherwise, we just ignore the errors ... */
673+ }
674+ /* else some kind of deserialization problem ... */
675+
676+ xdrs->x_op = XDR_FREE;
677+ msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
678+ (void) xdr_replymsg(xdrs, &msg);
679+ (void) (*xresults)(xdrs, resultsp);
680+ XDR_DESTROY(xdrs);
681+ if (done) {
682+ stat = RPC_SUCCESS;
683+ goto done_broad;
684+ } else {
685+ goto recv_again;
686+ }
687+ } /* The recv for loop */
688+ } /* The giant for loop */
689+
690+done_broad:
691+ if (inbuf)
692+ (void) free(inbuf);
693+ if (outbuf)
694+ (void) free(outbuf);
695+#ifdef PORTMAP
696+ if (outbuf_pmap)
697+ (void) free(outbuf_pmap);
698+#endif /* PORTMAP */
699+ for (i = 0; i < fdlistno; i++) {
700+ (void)close(fdlist[i].fd);
701+ __rpc_freebroadifs(&fdlist[i].nal);
702+ }
703+ AUTH_DESTROY(sys_auth);
704+ (void) __rpc_endconf(handle);
705+
706+ return (stat);
707+}
708+
709+
710+enum clnt_stat
711+rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
712+ eachresult, nettype)
713+ rpcprog_t prog; /* program number */
714+ rpcvers_t vers; /* version number */
715+ rpcproc_t proc; /* procedure number */
716+ xdrproc_t xargs; /* xdr routine for args */
717+ caddr_t argsp; /* pointer to args */
718+ xdrproc_t xresults; /* xdr routine for results */
719+ caddr_t resultsp; /* pointer to results */
720+ resultproc_t eachresult; /* call with each result obtained */
721+ const char *nettype; /* transport type */
722+{
723+ enum clnt_stat dummy;
724+
725+ dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp,
726+ xresults, resultsp, eachresult,
727+ INITTIME, WAITTIME, nettype);
728+ return (dummy);
729+}
730diff -Naur libtirpc-1.0.1-orig/tirpc/queue.h libtirpc-1.0.1/tirpc/queue.h 29diff -Naur libtirpc-1.0.1-orig/tirpc/queue.h libtirpc-1.0.1/tirpc/queue.h
731--- libtirpc-1.0.1-orig/tirpc/queue.h 1970-01-01 02:00:00.000000000 +0200 30--- libtirpc-1.0.1-orig/tirpc/queue.h 1970-01-01 02:00:00.000000000 +0200
732+++ libtirpc-1.0.1/tirpc/queue.h 2015-12-21 17:02:44.427853905 +0200 31+++ libtirpc-1.0.1/tirpc/queue.h 2015-12-21 17:02:44.427853905 +0200