diff --git a/.gitignore b/.gitignore index e69de29..c4bb093 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,5 @@ +Makefile +cscope* +x86_64/ +libtirpc-1.2.6 +/libtirpc-1.2.6.tar.bz2 diff --git a/libtirpc-1.1.5-rc3.patch b/libtirpc-1.1.5-rc3.patch new file mode 100644 index 0000000..3478ad8 --- /dev/null +++ b/libtirpc-1.1.5-rc3.patch @@ -0,0 +1,417 @@ +diff --git a/man/rpc_secure.3t b/man/rpc_secure.3t +index 4a1ad93..404df0b 100644 +--- a/man/rpc_secure.3t ++++ b/man/rpc_secure.3t +@@ -19,7 +19,7 @@ + .Ft AUTH * + .Fo authdes_pk_create + .Fa "char *name" +-.FA "netobj *publickey" ++.Fa "netobj *publickey" + .Fa "unsigned window" + .Fa "struct sockaddr *addr" + .Fa "des_block *ckey" +diff --git a/src/Makefile.am b/src/Makefile.am +index 932414d..b40a6b4 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -38,7 +38,7 @@ endif + if GSS + libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c \ + rpc_gss_utils.c +- libtirpc_la_LDFLAGS += $(GSSAPI_LIBS) ++ libtirpc_la_LIBADD = $(GSSAPI_LIBS) + libtirpc_la_CFLAGS = -DHAVE_RPCSEC_GSS $(GSSAPI_CFLAGS) + endif + +diff --git a/src/auth_des.c b/src/auth_des.c +index af2f61f..c9af2e9 100644 +--- a/src/auth_des.c ++++ b/src/auth_des.c +@@ -396,7 +396,7 @@ authdes_validate(AUTH *auth, struct opaque_auth *rverf) + /* + * validate + */ +- if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, ++ if (memcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, + sizeof(struct timeval)) != 0) { + LIBTIRPC_DEBUG(1, ("authdes_validate: verifier mismatch")); + return (FALSE); +diff --git a/src/auth_gss.c b/src/auth_gss.c +index 5959893..7d08262 100644 +--- a/src/auth_gss.c ++++ b/src/auth_gss.c +@@ -207,6 +207,7 @@ authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec) + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = ENOMEM; + free(auth); ++ free(gd); + return (NULL); + } + } +@@ -592,7 +593,7 @@ _rpc_gss_refresh(AUTH *auth, rpc_gss_options_ret_t *options_ret) + if (rpc_gss_oid_to_mech(actual_mech_type, &mechanism)) { + strncpy(options_ret->actual_mechanism, + mechanism, +- sizeof(options_ret->actual_mechanism)); ++ (sizeof(options_ret->actual_mechanism)-1)); + } + + gd->established = TRUE; +diff --git a/src/auth_time.c b/src/auth_time.c +index 69400bc..936dd76 100644 +--- a/src/auth_time.c ++++ b/src/auth_time.c +@@ -104,7 +104,7 @@ static int uaddr_to_sockaddr(uaddr, sin) + p_bytes[1] = (unsigned char)a[5] & 0x000000FF; + + sin->sin_family = AF_INET; /* always */ +- bcopy((char *)&p_bytes, (char *)&sin->sin_port, 2); ++ memcpy((char *)&sin->sin_port, (char *)&p_bytes, 2); + + return (0); + } +diff --git a/src/clnt_bcast.c b/src/clnt_bcast.c +index 98cf061..2ad6c89 100644 +--- a/src/clnt_bcast.c ++++ b/src/clnt_bcast.c +@@ -330,6 +330,7 @@ rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp, + if (nettype == NULL) + nettype = "datagram_n"; + if ((handle = __rpc_setconf(nettype)) == NULL) { ++ AUTH_DESTROY(sys_auth); + return (RPC_UNKNOWNPROTO); + } + while ((nconf = __rpc_getconf(handle)) != NULL) { +diff --git a/src/crypt_client.c b/src/crypt_client.c +index f393926..cd6f7de 100644 +--- a/src/crypt_client.c ++++ b/src/crypt_client.c +@@ -75,8 +75,8 @@ _des_crypt_call(buf, len, dparms) + des_crypt_1_arg.desbuf.desbuf_val = buf; + des_crypt_1_arg.des_dir = dparms->des_dir; + des_crypt_1_arg.des_mode = dparms->des_mode; +- bcopy(dparms->des_ivec, des_crypt_1_arg.des_ivec, 8); +- bcopy(dparms->des_key, des_crypt_1_arg.des_key, 8); ++ memcpy(des_crypt_1_arg.des_ivec, dparms->des_ivec, 8); ++ memcpy(des_crypt_1_arg.des_key, dparms->des_key, 8); + + result_1 = des_crypt_1(&des_crypt_1_arg, clnt); + if (result_1 == (desresp *) NULL) { +@@ -88,8 +88,8 @@ _des_crypt_call(buf, len, dparms) + + if (result_1->stat == DESERR_NONE || + result_1->stat == DESERR_NOHWDEVICE) { +- bcopy(result_1->desbuf.desbuf_val, buf, len); +- bcopy(result_1->des_ivec, dparms->des_ivec, 8); ++ memcpy(buf, result_1->desbuf.desbuf_val, len); ++ memcpy(dparms->des_ivec, result_1->des_ivec, 8); + } + + clnt_freeres(clnt, (xdrproc_t)xdr_desresp, result_1); +diff --git a/src/getnetconfig.c b/src/getnetconfig.c +index 92e7c43..cfd33c2 100644 +--- a/src/getnetconfig.c ++++ b/src/getnetconfig.c +@@ -681,6 +681,7 @@ struct netconfig *ncp; + { + struct netconfig *p; + char *tmp; ++ char *t; + u_int i; + + if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL) +@@ -700,20 +701,21 @@ struct netconfig *ncp; + */ + *p = *ncp; + p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid); +- tmp = strchr(tmp, 0) + 1; +- p->nc_protofmly = (char *)strcpy(tmp,ncp->nc_protofmly); +- tmp = strchr(tmp, 0) + 1; +- p->nc_proto = (char *)strcpy(tmp,ncp->nc_proto); +- tmp = strchr(tmp, 0) + 1; +- p->nc_device = (char *)strcpy(tmp,ncp->nc_device); ++ t = strchr(tmp, 0) + 1; ++ p->nc_protofmly = (char *)strcpy(t,ncp->nc_protofmly); ++ t = strchr(t, 0) + 1; ++ p->nc_proto = (char *)strcpy(t,ncp->nc_proto); ++ t = strchr(t, 0) + 1; ++ p->nc_device = (char *)strcpy(t,ncp->nc_device); + p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *)); + if (p->nc_lookups == NULL) { +- free(p->nc_netid); ++ free(p); ++ free(tmp); + return(NULL); + } + for (i=0; i < p->nc_nlookups; i++) { +- tmp = strchr(tmp, 0) + 1; +- p->nc_lookups[i] = (char *)strcpy(tmp,ncp->nc_lookups[i]); ++ t = strchr(t, 0) + 1; ++ p->nc_lookups[i] = (char *)strcpy(t,ncp->nc_lookups[i]); + } + return(p); + } +diff --git a/src/getnetpath.c b/src/getnetpath.c +index 7c19932..ea1a18c 100644 +--- a/src/getnetpath.c ++++ b/src/getnetpath.c +@@ -88,6 +88,7 @@ setnetpath() + } + if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) { + syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); ++ free(np_sessionp); + return (NULL); + } + np_sessionp->valid = NP_VALID; +diff --git a/src/getpublickey.c b/src/getpublickey.c +index 8cf4dc2..be37a24 100644 +--- a/src/getpublickey.c ++++ b/src/getpublickey.c +@@ -74,7 +74,7 @@ __getpublickey_real(netname, publickey) + return (0); + } + *p = '\0'; +- (void) strncpy(publickey, lookup, HEXKEYBYTES); ++ memcpy(publickey, lookup, HEXKEYBYTES); + publickey[HEXKEYBYTES] = '\0'; + return (1); + } +diff --git a/src/getrpcent.c b/src/getrpcent.c +index cba4cd8..e49dc05 100644 +--- a/src/getrpcent.c ++++ b/src/getrpcent.c +@@ -100,7 +100,7 @@ _rpcdata() + return (d); + } + +-#if !HAVE_GETRPCBYNYMBER ++#if !HAVE_GETRPCBYNUMBER + struct rpcent * + getrpcbynumber(number) + int number; +diff --git a/src/rpc_generic.c b/src/rpc_generic.c +index 589cbd5..51f36ac 100644 +--- a/src/rpc_generic.c ++++ b/src/rpc_generic.c +@@ -319,6 +319,7 @@ __rpc_setconf(nettype) + handle->nflag = FALSE; + break; + default: ++ free(handle); + return (NULL); + } + +diff --git a/src/rpc_soc.c b/src/rpc_soc.c +index 5a6eeb7..a85cb17 100644 +--- a/src/rpc_soc.c ++++ b/src/rpc_soc.c +@@ -663,15 +663,17 @@ svcunix_create(sock, sendsize, recvsize, path) + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } +- if (nconf == NULL) ++ if (nconf == NULL) { ++ endnetconfig(localhandle); + return(xprt); ++ } + + if ((sock = __rpc_nconf2fd(nconf)) < 0) + goto done; + + memset(&sun, 0, sizeof sun); + sun.sun_family = AF_LOCAL; +- strncpy(sun.sun_path, path, sizeof(sun.sun_path)); ++ strncpy(sun.sun_path, path, (sizeof(sun.sun_path)-1)); + addrlen = sizeof(struct sockaddr_un); + sa = (struct sockaddr *)&sun; + +@@ -692,6 +694,8 @@ svcunix_create(sock, sendsize, recvsize, path) + } + + xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); ++ if (xprt == NULL) ++ close(sock); + + done: + endnetconfig(localhandle); +diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c +index e45736a..0c34cb7 100644 +--- a/src/rpcb_clnt.c ++++ b/src/rpcb_clnt.c +@@ -547,6 +547,7 @@ try_nconf: + if (tmpnconf == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; + mutex_unlock(&loopnconf_lock); ++ endnetconfig(nc_handle); + return (NULL); + } + loopnconf = getnetconfigent(tmpnconf->nc_netid); +diff --git a/src/rtime.c b/src/rtime.c +index b642840..29fbf0a 100644 +--- a/src/rtime.c ++++ b/src/rtime.c +@@ -90,6 +90,7 @@ rtime(addrp, timep, timeout) + + /* TCP and UDP port are the same in this case */ + if ((serv = getservbyname("time", "tcp")) == NULL) { ++ do_close(s); + return(-1); + } + +diff --git a/src/svc_auth_des.c b/src/svc_auth_des.c +index 19a7c60..b096e08 100644 +--- a/src/svc_auth_des.c ++++ b/src/svc_auth_des.c +@@ -145,7 +145,7 @@ _svcauth_des(rqst, msg) + return (AUTH_BADCRED); + } + cred->adc_fullname.name = area->area_netname; +- bcopy((char *)ixdr, cred->adc_fullname.name, ++ memcpy(cred->adc_fullname.name, (char *)ixdr, + (u_int)namelen); + cred->adc_fullname.name[namelen] = 0; + ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT); +@@ -419,7 +419,7 @@ cache_spot(key, name, timestamp) + if (cp->key.key.high == hi && + cp->key.key.low == key->key.low && + cp->rname != NULL && +- bcmp(cp->rname, name, strlen(name) + 1) == 0) { ++ memcmp(cp->rname, name, strlen(name) + 1) == 0) { + if (BEFORE(timestamp, &cp->laststamp)) { + svcauthdes_stats.ncachereplays++; + return (-1); /* replay */ +diff --git a/src/svc_generic.c b/src/svc_generic.c +index 52a56c2..20abaa2 100644 +--- a/src/svc_generic.c ++++ b/src/svc_generic.c +@@ -113,6 +113,7 @@ svc_create(dispatch, prognum, versnum, nettype) + if (l == NULL) { + warnx("svc_create: no memory"); + mutex_unlock(&xprtlist_lock); ++ __rpc_endconf(handle); + return (0); + } + l->xprt = xprt; +diff --git a/src/svc_simple.c b/src/svc_simple.c +index cb58002..c32fe0a 100644 +--- a/src/svc_simple.c ++++ b/src/svc_simple.c +@@ -157,6 +157,7 @@ rpc_reg(prognum, versnum, procnum, progname, inproc, outproc, nettype) + ((netid = strdup(nconf->nc_netid)) == NULL)) { + warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); + SVC_DESTROY(svcxprt); ++ free(xdrbuf); + break; + } + madenow = TRUE; +diff --git a/src/svc_vc.c b/src/svc_vc.c +index 97a76a3..c23cd36 100644 +--- a/src/svc_vc.c ++++ b/src/svc_vc.c +@@ -502,9 +502,14 @@ read_vc(xprtp, buf, len) + cfp = (struct cf_conn *)xprt->xp_p1; + + if (cfp->nonblock) { ++ /* Since len == 0 is returned on zero length ++ * read or EOF errno needs to be reset before ++ * the read ++ */ ++ errno = 0; + len = read(sock, buf, (size_t)len); + if (len < 0) { +- if (errno == EAGAIN) ++ if (errno == EAGAIN || errno == EWOULDBLOCK) + len = 0; + else + goto fatal_err; +diff --git a/src/xdr.c b/src/xdr.c +index b9a1558..28d1382 100644 +--- a/src/xdr.c ++++ b/src/xdr.c +@@ -877,7 +877,8 @@ xdr_int64_t(xdrs, llp) + if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) + return (FALSE); + *llp = (int64_t) +- (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); ++ (((u_int64_t)ul[0] << 32) | ++ ((u_int64_t)(ul[1]) & 0xffffffff)); + return (TRUE); + case XDR_FREE: + return (TRUE); +@@ -910,7 +911,8 @@ xdr_u_int64_t(xdrs, ullp) + if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) + return (FALSE); + *ullp = (u_int64_t) +- (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); ++ (((u_int64_t)ul[0] << 32) | ++ ((u_int64_t)(ul[1]) & 0xffffffff)); + return (TRUE); + case XDR_FREE: + return (TRUE); +diff --git a/src/xdr_rec.c b/src/xdr_rec.c +index 7d535cf..676cc82 100644 +--- a/src/xdr_rec.c ++++ b/src/xdr_rec.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + #include "rpc_com.h" + static bool_t xdrrec_getlong(XDR *, long *); + static bool_t xdrrec_putlong(XDR *, const long *); +@@ -537,7 +538,13 @@ __xdrrec_getrec(xdrs, statp, expectdata) + n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, + (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); + if (n == 0) { +- *statp = expectdata ? XPRT_DIED : XPRT_IDLE; ++ /* EAGAIN or EWOULDBLOCK means a zero length ++ * read not an EOF. ++ */ ++ if (errno == EAGAIN || errno == EWOULDBLOCK) ++ *statp = XPRT_IDLE; ++ else ++ *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + if (n < 0) { +@@ -564,6 +571,7 @@ __xdrrec_getrec(xdrs, statp, expectdata) + rstrm->in_header &= ~LAST_FRAG; + rstrm->last_frag = TRUE; + } ++ rstrm->in_haveheader = 1; + } + + n = rstrm->readit(rstrm->tcp_handle, +@@ -576,7 +584,13 @@ __xdrrec_getrec(xdrs, statp, expectdata) + } + + if (n == 0) { +- *statp = expectdata ? XPRT_DIED : XPRT_IDLE; ++ /* EAGAIN or EWOULDBLOCK means a zero length ++ * read not an EOF. ++ */ ++ if (errno == EAGAIN || errno == EWOULDBLOCK) ++ *statp = XPRT_IDLE; ++ else ++ *statp = expectdata ? XPRT_DIED : XPRT_IDLE; + return FALSE; + } + +diff --git a/tirpc/rpc/rpcent.h b/tirpc/rpc/rpcent.h +index 9d3ef9c..5bff876 100644 +--- a/tirpc/rpc/rpcent.h ++++ b/tirpc/rpc/rpcent.h +@@ -48,8 +48,9 @@ + extern "C" { + #endif + +-/* These are defined in /usr/include/rpc/netdb.h */ +-#if !defined(__GLIBC__) || defined(__UCLIBC__) ++/* These are defined in /usr/include/rpc/netdb.h, unless we are using ++ the C library without RPC support. */ ++#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_RPC__) || !defined(__GLIBC__) + struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ diff --git a/libtirpc-1.2.6-rc2.patch b/libtirpc-1.2.6-rc2.patch new file mode 100644 index 0000000..f80d40f --- /dev/null +++ b/libtirpc-1.2.6-rc2.patch @@ -0,0 +1,71 @@ +diff --git a/doc/bindresvport.blacklist b/doc/bindresvport.blacklist +index 8904277..a7ed193 100644 +--- a/doc/bindresvport.blacklist ++++ b/doc/bindresvport.blacklist +@@ -8,6 +8,7 @@ + 631 # cups + 636 # ldaps + 664 # Secure ASF, used by IPMI on some cards ++774 # rpasswd + 921 # lwresd + 993 # imaps + 995 # pops +diff --git a/src/rpc_com.h b/src/rpc_com.h +index 10bec79..76badef 100644 +--- a/src/rpc_com.h ++++ b/src/rpc_com.h +@@ -61,8 +61,7 @@ void __xprt_unregister_unlocked(SVCXPRT *); + void __xprt_set_raddr(SVCXPRT *, const struct sockaddr_storage *); + + +-SVCXPRT **__svc_xports; +-int __svc_maxrec; ++extern int __svc_maxrec; + + #ifdef __cplusplus + } +diff --git a/src/rpc_soc.c b/src/rpc_soc.c +index ac7d312..fde121d 100644 +--- a/src/rpc_soc.c ++++ b/src/rpc_soc.c +@@ -613,6 +613,13 @@ authdes_pk_create(servername, pkey, window, syncaddr, ckey) + des_block *ckey; /* optional conversation key to use */ + { return (NULL); } + ++AUTH * ++authdes_seccreate(const char *servername, const u_int win, ++ const char *timehost, const des_block *ckey) ++{ ++ return (NULL); ++} ++ + #endif + + +diff --git a/src/svc.c b/src/svc.c +index b59467b..6db164b 100644 +--- a/src/svc.c ++++ b/src/svc.c +@@ -57,6 +57,9 @@ + + #define max(a, b) (a > b ? a : b) + ++static SVCXPRT **__svc_xports; ++int __svc_maxrec; ++ + /* + * The services list + * Each entry represents a set of procedures (an rpc program). +diff --git a/src/xdr_float.c b/src/xdr_float.c +index 26bc865..349d48f 100644 +--- a/src/xdr_float.c ++++ b/src/xdr_float.c +@@ -83,7 +83,7 @@ static struct sgl_limits { + }; + #else + +-#include ++#include + #define IEEEFP + + #endif /* vax */ diff --git a/libtirpc-1.2.7-rc4.patch b/libtirpc-1.2.7-rc4.patch new file mode 100644 index 0000000..47b0acb --- /dev/null +++ b/libtirpc-1.2.7-rc4.patch @@ -0,0 +1,920 @@ +diff --git a/libtirpc.pc.in b/libtirpc.pc.in +index 38034c5..d2c7878 100644 +--- a/libtirpc.pc.in ++++ b/libtirpc.pc.in +@@ -7,6 +7,6 @@ Name: libtirpc + Description: Transport Independent RPC Library + Requires: + Version: @PACKAGE_VERSION@ +-Libs: -L@libdir@ -ltirpc ++Libs: -L${libdir} -ltirpc + Libs.private: -lpthread +-Cflags: -I@includedir@/tirpc ++Cflags: -I${includedir}/tirpc +diff --git a/src/clnt_dg.c b/src/clnt_dg.c +index eb5467f..abc09f1 100644 +--- a/src/clnt_dg.c ++++ b/src/clnt_dg.c +@@ -53,6 +53,7 @@ + #include + #include + #include "rpc_com.h" ++#include "clnt_fd_locks.h" + + #ifdef IP_RECVERR + #include +@@ -78,24 +79,28 @@ static void clnt_dg_destroy(CLIENT *); + * This machinery implements per-fd locks for MT-safety. It is not + * sufficient to do per-CLIENT handle locks for MT-safety because a + * user may create more than one CLIENT handle with the same fd behind +- * it. Therfore, we allocate an array of flags (dg_fd_locks), protected +- * by the clnt_fd_lock mutex, and an array (dg_cv) of condition variables +- * similarly protected. Dg_fd_lock[fd] == 1 => a call is activte on some +- * CLIENT handle created for that fd. ++ * it. ++ * ++ * We keep track of a list of per-fd locks, protected by the clnt_fd_lock ++ * mutex. Each per-fd lock consists of a predicate indicating whether is ++ * active or not: fd_lock->active == TRUE => a call is active on some ++ * CLIENT handle created for that fd. Each fd predicate is guarded by a ++ * condition variable so that the global mutex can be unlocked while ++ * waiting for the predicate to change. ++ * + * The current implementation holds locks across the entire RPC and reply, + * including retransmissions. Yes, this is silly, and as soon as this + * code is proven to work, this should be the first thing fixed. One step + * at a time. + */ +-static int *dg_fd_locks; ++static fd_locks_t *dg_fd_locks; + extern mutex_t clnt_fd_lock; +-static cond_t *dg_cv; +-#define release_fd_lock(fd, mask) { \ ++#define release_fd_lock(fd_lock, mask) { \ + mutex_lock(&clnt_fd_lock); \ +- dg_fd_locks[fd] = 0; \ ++ fd_lock->active = FALSE; \ + mutex_unlock(&clnt_fd_lock); \ + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \ +- cond_signal(&dg_cv[fd]); \ ++ cond_signal(&fd_lock->cv); \ + } + + static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory"; +@@ -107,6 +112,7 @@ static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory"; + */ + struct cu_data { + int cu_fd; /* connections fd */ ++ fd_lock_t *cu_fd_lock; + bool_t cu_closeit; /* opened by library */ + struct sockaddr_storage cu_raddr; /* remote address */ + int cu_rlen; +@@ -155,47 +161,20 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) + sigset_t newmask; + struct __rpc_sockinfo si; + int one = 1; ++ fd_lock_t *fd_lock; + + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- if (dg_fd_locks == (int *) NULL) { +- size_t cv_allocsz, fd_allocsz; +- unsigned int dtbsize = __rpc_dtbsize(); +- +- if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- errno = EOVERFLOW; +- goto err1; +- } +- +- fd_allocsz = dtbsize * sizeof (int); +- dg_fd_locks = (int *) mem_alloc(fd_allocsz); +- if (dg_fd_locks == (int *) NULL) { +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- errno = ENOMEM; +- goto err1; +- } else +- memset(dg_fd_locks, '\0', fd_allocsz); +- +- cv_allocsz = dtbsize * sizeof (cond_t); +- dg_cv = (cond_t *) mem_alloc(cv_allocsz); +- if (dg_cv == (cond_t *) NULL) { +- mem_free(dg_fd_locks, fd_allocsz); +- dg_fd_locks = (int *) NULL; +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- errno = ENOMEM; ++ if (dg_fd_locks == (fd_locks_t *) NULL) { ++ dg_fd_locks = fd_locks_init(); ++ if (dg_fd_locks == (fd_locks_t *) NULL) { + goto err1; +- } else { +- int i; +- +- for (i = 0; i < dtbsize; i++) +- cond_init(&dg_cv[i], 0, (void *) 0); + } + } ++ fd_lock = fd_lock_create(fd, dg_fd_locks); ++ if (fd_lock == (fd_lock_t *) NULL) ++ goto err1; + + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +@@ -274,6 +253,7 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) + */ + cu->cu_closeit = FALSE; + cu->cu_fd = fd; ++ cu->cu_fd_lock = fd_lock; + cl->cl_ops = clnt_dg_ops(); + cl->cl_private = (caddr_t)(void *)cu; + cl->cl_auth = authnone_create(); +@@ -319,17 +299,15 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) + sigset_t newmask; + socklen_t salen; + ssize_t recvlen = 0; +- int rpc_lock_value; + u_int32_t xid, inval, outval; + + outlen = 0; + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (dg_fd_locks[cu->cu_fd]) +- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); +- rpc_lock_value = 1; +- dg_fd_locks[cu->cu_fd] = rpc_lock_value; ++ while (cu->cu_fd_lock->active) ++ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); ++ cu->cu_fd_lock->active = TRUE; + mutex_unlock(&clnt_fd_lock); + if (cu->cu_total.tv_usec == -1) { + timeout = utimeout; /* use supplied timeout */ +@@ -473,7 +451,7 @@ get_reply: + mem_free(cbuf, (outlen + 256)); + e = (struct sock_extended_err *) CMSG_DATA(cmsg); + cu->cu_error.re_errno = e->ee_errno; +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (cu->cu_error.re_status = RPC_CANTRECV); + } + mem_free(cbuf, (outlen + 256)); +@@ -553,7 +531,7 @@ get_reply: + + } + out: +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (cu->cu_error.re_status); + } + +@@ -582,13 +560,14 @@ clnt_dg_freeres(cl, xdr_res, res_ptr) + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (dg_fd_locks[cu->cu_fd]) +- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); ++ while (cu->cu_fd_lock->active) ++ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); ++ cu->cu_fd_lock->active = TRUE; + xdrs->x_op = XDR_FREE; + dummy = (*xdr_res)(xdrs, res_ptr); + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &mask, NULL); +- cond_signal(&dg_cv[cu->cu_fd]); ++ cond_signal(&cu->cu_fd_lock->cv); + return (dummy); + } + +@@ -609,36 +588,34 @@ clnt_dg_control(cl, request, info) + struct netbuf *addr; + sigset_t mask; + sigset_t newmask; +- int rpc_lock_value; + + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (dg_fd_locks[cu->cu_fd]) +- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); +- rpc_lock_value = 1; +- dg_fd_locks[cu->cu_fd] = rpc_lock_value; ++ while (cu->cu_fd_lock->active) ++ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); ++ cu->cu_fd_lock->active = TRUE; + mutex_unlock(&clnt_fd_lock); + switch (request) { + case CLSET_FD_CLOSE: + cu->cu_closeit = TRUE; +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (TRUE); + case CLSET_FD_NCLOSE: + cu->cu_closeit = FALSE; +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (TRUE); + } + + /* for other requests which use info */ + if (info == NULL) { +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (FALSE); + } + switch (request) { + case CLSET_TIMEOUT: + if (time_not_ok((struct timeval *)info)) { +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (FALSE); + } + cu->cu_total = *(struct timeval *)info; +@@ -652,7 +629,7 @@ clnt_dg_control(cl, request, info) + break; + case CLSET_RETRY_TIMEOUT: + if (time_not_ok((struct timeval *)info)) { +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (FALSE); + } + cu->cu_wait = *(struct timeval *)info; +@@ -672,7 +649,7 @@ clnt_dg_control(cl, request, info) + case CLSET_SVC_ADDR: /* set to new address */ + addr = (struct netbuf *)info; + if (addr->len < sizeof cu->cu_raddr) { +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (FALSE); + } + (void) memcpy(&cu->cu_raddr, addr->buf, addr->len); +@@ -735,10 +712,10 @@ clnt_dg_control(cl, request, info) + cu->cu_connect = *(int *)info; + break; + default: +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (FALSE); + } +- release_fd_lock(cu->cu_fd, mask); ++ release_fd_lock(cu->cu_fd_lock, mask); + return (TRUE); + } + +@@ -748,14 +725,15 @@ clnt_dg_destroy(cl) + { + struct cu_data *cu = (struct cu_data *)cl->cl_private; + int cu_fd = cu->cu_fd; ++ fd_lock_t *cu_fd_lock = cu->cu_fd_lock; + sigset_t mask; + sigset_t newmask; + + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (dg_fd_locks[cu_fd]) +- cond_wait(&dg_cv[cu_fd], &clnt_fd_lock); ++ while (cu_fd_lock->active) ++ cond_wait(&cu_fd_lock->cv, &clnt_fd_lock); + if (cu->cu_closeit) + (void)close(cu_fd); + XDR_DESTROY(&(cu->cu_outxdrs)); +@@ -765,9 +743,10 @@ clnt_dg_destroy(cl) + if (cl->cl_tp && cl->cl_tp[0]) + mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); + mem_free(cl, sizeof (CLIENT)); ++ cond_signal(&cu_fd_lock->cv); ++ fd_lock_destroy(cu_fd, cu_fd_lock, dg_fd_locks); + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &mask, NULL); +- cond_signal(&dg_cv[cu_fd]); + } + + static struct clnt_ops * +diff --git a/src/clnt_fd_locks.h b/src/clnt_fd_locks.h +new file mode 100644 +index 0000000..359f995 +--- /dev/null ++++ b/src/clnt_fd_locks.h +@@ -0,0 +1,207 @@ ++/* ++ * debug.h -- debugging routines for libtirpc ++ * ++ * Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef _CLNT_FD_LOCKS_H ++#define _CLNT_FD_LOCKS_H ++ ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * This utility manages a list of per-fd locks for the clients. ++ * ++ * If MAX_FDLOCKS_PREALLOC is defined, a number of pre-fd locks will be ++ * pre-allocated. This number is the minimum of MAX_FDLOCKS_PREALLOC or ++ * the process soft limit of allowed fds. ++ */ ++#ifdef MAX_FDLOCKS_PREALLOC ++static unsigned int fd_locks_prealloc = 0; ++#endif ++ ++/* per-fd lock */ ++struct fd_lock_t { ++ bool_t active; ++ cond_t cv; ++}; ++typedef struct fd_lock_t fd_lock_t; ++ ++ ++/* internal type to store per-fd locks in a list */ ++struct fd_lock_item_t { ++ /* fd_lock_t first so we can cast to fd_lock_item_t */ ++ fd_lock_t fd_lock; ++ int fd; ++ unsigned int refs; ++ TAILQ_ENTRY(fd_lock_item_t) link; ++}; ++typedef struct fd_lock_item_t fd_lock_item_t; ++#define to_fd_lock_item(fdlock_t_ptr) ((fd_lock_item_t*) fdlock_t_ptr) ++ ++ ++/* internal list of per-fd locks */ ++typedef TAILQ_HEAD(,fd_lock_item_t) fd_lock_list_t; ++ ++ ++#ifdef MAX_FDLOCKS_PREALLOC ++ ++/* With pre-allocation, keep track of both an array and a list */ ++struct fd_locks_t { ++ fd_lock_list_t fd_lock_list; ++ fd_lock_t *fd_lock_array; ++}; ++typedef struct fd_locks_t fd_locks_t; ++#define to_fd_lock_list(fd_locks_t_ptr) (&fd_locks_t_ptr->fd_lock_list) ++ ++#else ++ ++/* With no pre-allocation, just keep track of a list */ ++typedef fd_lock_list_t fd_locks_t; ++#define to_fd_lock_list(fd_locks_t_ptr) ((fd_lock_list_t *) fd_locks_t_ptr) ++ ++#endif ++ ++ ++/* allocate fd locks */ ++static inline ++fd_locks_t* fd_locks_init() { ++ fd_locks_t *fd_locks; ++ ++ fd_locks = (fd_locks_t *) mem_alloc(sizeof(fd_locks_t)); ++ if (fd_locks == (fd_locks_t *) NULL) { ++ errno = ENOMEM; ++ return (NULL); ++ } ++ TAILQ_INIT(to_fd_lock_list(fd_locks)); ++ ++#ifdef MAX_FDLOCKS_PREALLOC ++ size_t fd_lock_arraysz; ++ ++ if (fd_locks_prealloc == 0) { ++ unsigned int dtbsize = __rpc_dtbsize(); ++ if (0 < dtbsize && dtbsize < MAX_FDLOCKS_PREALLOC) ++ fd_locks_prealloc = dtbsize; ++ else ++ fd_locks_prealloc = MAX_FDLOCKS_PREALLOC; ++ } ++ ++ if ( (size_t) fd_locks_prealloc > SIZE_MAX/sizeof(fd_lock_t)) { ++ mem_free(fd_locks, sizeof (*fd_locks)); ++ errno = EOVERFLOW; ++ return (NULL); ++ } ++ ++ fd_lock_arraysz = fd_locks_prealloc * sizeof (fd_lock_t); ++ fd_locks->fd_lock_array = (fd_lock_t *) mem_alloc(fd_lock_arraysz); ++ if (fd_locks->fd_lock_array == (fd_lock_t *) NULL) { ++ mem_free(fd_locks, sizeof (*fd_locks)); ++ errno = ENOMEM; ++ return (NULL); ++ } ++ else { ++ int i; ++ ++ for (i = 0; i < fd_locks_prealloc; i++) { ++ fd_locks->fd_lock_array[i].active = FALSE; ++ cond_init(&fd_locks->fd_lock_array[i].cv, 0, (void *) 0); ++ } ++ } ++#endif ++ ++ return fd_locks; ++} ++ ++/* de-allocate fd locks */ ++static inline ++void fd_locks_destroy(fd_locks_t *fd_locks) { ++#ifdef MAX_FDLOCKS_PREALLOC ++ fd_lock_t *array = fd_locks->fd_lock_array; ++ mem_free(array, fd_locks_prealloc * sizeof (fd_lock_t)); ++#endif ++ fd_lock_item_t *item; ++ fd_lock_list_t *list = to_fd_lock_list(fd_locks); ++ ++ TAILQ_FOREACH(item, list, link) { ++ cond_destroy(&item->fd_lock.cv); ++ mem_free(item, sizeof (*item)); ++ } ++ mem_free(fd_locks, sizeof (*fd_locks)); ++} ++ ++/* allocate per-fd lock */ ++static inline ++fd_lock_t* fd_lock_create(int fd, fd_locks_t *fd_locks) { ++#ifdef MAX_FDLOCKS_PREALLOC ++ if (fd < fd_locks_prealloc) { ++ return &fd_locks->fd_lock_array[fd]; ++ } ++#endif ++ fd_lock_item_t *item; ++ fd_lock_list_t *list = to_fd_lock_list(fd_locks); ++ ++ for (item = TAILQ_FIRST(list); ++ item != (fd_lock_item_t *) NULL && item->fd != fd; ++ item = TAILQ_NEXT(item, link)); ++ ++ if (item == (fd_lock_item_t *) NULL) { ++ item = (fd_lock_item_t *) mem_alloc(sizeof(fd_lock_item_t)); ++ if (item == (fd_lock_item_t *) NULL) { ++ errno = ENOMEM; ++ return (NULL); ++ } ++ item->fd = fd; ++ item->refs = 1; ++ item->fd_lock.active = FALSE; ++ cond_init(&item->fd_lock.cv, 0, (void *) 0); ++ TAILQ_INSERT_HEAD(list, item, link); ++ } else { ++ item->refs++; ++ } ++ return &item->fd_lock; ++} ++ ++/* de-allocate per-fd lock */ ++static inline ++void fd_lock_destroy(int fd, fd_lock_t *fd_lock, fd_locks_t *fd_locks) { ++#ifdef MAX_FDLOCKS_PREALLOC ++ if (fd < fd_locks_prealloc) ++ return; ++#endif ++ fd_lock_item_t* item = to_fd_lock_item(fd_lock); ++ item->refs--; ++ if (item->refs <= 0) { ++ TAILQ_REMOVE(to_fd_lock_list(fd_locks), item, link); ++ cond_destroy(&item->fd_lock.cv); ++ mem_free(item, sizeof (*item)); ++ } ++} ++ ++#endif /* _CLNT_FD_LOCKS_H */ +diff --git a/src/clnt_vc.c b/src/clnt_vc.c +index ec58892..6f7f7da 100644 +--- a/src/clnt_vc.c ++++ b/src/clnt_vc.c +@@ -67,6 +67,7 @@ + + #include + #include "rpc_com.h" ++#include "clnt_fd_locks.h" + + #define MCALL_MSG_SIZE 24 + +@@ -110,6 +111,7 @@ static int write_vc(void *, void *, int); + + struct ct_data { + int ct_fd; /* connection's fd */ ++ fd_lock_t *ct_fd_lock; + bool_t ct_closeit; /* close it on destroy */ + struct timeval ct_wait; /* wait interval in milliseconds */ + bool_t ct_waitset; /* wait set by clnt_control? */ +@@ -124,27 +126,32 @@ struct ct_data { + }; + + /* +- * This machinery implements per-fd locks for MT-safety. It is not +- * sufficient to do per-CLIENT handle locks for MT-safety because a +- * user may create more than one CLIENT handle with the same fd behind +- * it. Therfore, we allocate an array of flags (vc_fd_locks), protected +- * by the clnt_fd_lock mutex, and an array (vc_cv) of condition variables +- * similarly protected. Vc_fd_lock[fd] == 1 => a call is active on some +- * CLIENT handle created for that fd. +- * The current implementation holds locks across the entire RPC and reply. +- * Yes, this is silly, and as soon as this code is proven to work, this +- * should be the first thing fixed. One step at a time. ++ * This machinery implements per-fd locks for MT-safety. It is not ++ * sufficient to do per-CLIENT handle locks for MT-safety because a ++ * user may create more than one CLIENT handle with the same fd behind ++ * it. ++ * ++ * We keep track of a list of per-fd locks, protected by the clnt_fd_lock ++ * mutex. Each per-fd lock consists of a predicate indicating whether is ++ * active or not: fd_lock->active == TRUE => a call is active on some ++ * CLIENT handle created for that fd. Each fd predicate is guarded by a ++ * condition variable so that the global mutex can be unlocked while ++ * waiting for the predicate to change. ++ * ++ * The current implementation holds locks across the entire RPC and reply, ++ * including retransmissions. Yes, this is silly, and as soon as this ++ * code is proven to work, this should be the first thing fixed. One step ++ * at a time. + */ +-static int *vc_fd_locks; ++static fd_locks_t *vc_fd_locks; + extern pthread_mutex_t disrupt_lock; + extern mutex_t clnt_fd_lock; +-static cond_t *vc_cv; +-#define release_fd_lock(fd, mask) { \ ++#define release_fd_lock(fd_lock, mask) { \ + mutex_lock(&clnt_fd_lock); \ +- vc_fd_locks[fd] = 0; \ ++ fd_lock->active = FALSE; \ + mutex_unlock(&clnt_fd_lock); \ + thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \ +- cond_signal(&vc_cv[fd]); \ ++ cond_signal(&fd_lock->cv); \ + } + + static const char clnt_vc_errstr[] = "%s : %s"; +@@ -181,6 +188,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) + struct sockaddr_storage ss; + socklen_t slen; + struct __rpc_sockinfo si; ++ fd_lock_t *fd_lock; + + mutex_lock(&disrupt_lock); + if (disrupt == 0) +@@ -201,49 +209,22 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- if (vc_fd_locks == (int *) NULL) { +- size_t cv_allocsz, fd_allocsz; +- unsigned int dtbsize = __rpc_dtbsize(); +- struct rpc_createerr *ce = &get_rpc_createerr(); +- +- if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- ce->cf_stat = RPC_SYSTEMERROR; +- ce->cf_error.re_errno = EOVERFLOW; +- goto err; +- } +- +- fd_allocsz = dtbsize * sizeof (int); +- vc_fd_locks = (int *) mem_alloc(fd_allocsz); +- if (vc_fd_locks == (int *) NULL) { +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- ce->cf_stat = RPC_SYSTEMERROR; +- ce->cf_error.re_errno = ENOMEM; +- goto err; +- } else +- memset(vc_fd_locks, '\0', fd_allocsz); +- +- assert(vc_cv == (cond_t *) NULL); +- cv_allocsz = dtbsize * sizeof (cond_t); +- vc_cv = (cond_t *) mem_alloc(cv_allocsz); +- if (vc_cv == (cond_t *) NULL) { +- mem_free(vc_fd_locks, fd_allocsz); +- vc_fd_locks = (int *) NULL; +- mutex_unlock(&clnt_fd_lock); +- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); ++ if (vc_fd_locks == (fd_locks_t *) NULL) { ++ vc_fd_locks = fd_locks_init(); ++ if (vc_fd_locks == (fd_locks_t *) NULL) { ++ struct rpc_createerr *ce = &get_rpc_createerr(); + ce->cf_stat = RPC_SYSTEMERROR; +- ce->cf_error.re_errno = ENOMEM; ++ ce->cf_error.re_errno = errno; + goto err; +- } else { +- int i; +- +- for (i = 0; i < dtbsize; i++) +- cond_init(&vc_cv[i], 0, (void *) 0); + } +- } else +- assert(vc_cv != (cond_t *) NULL); ++ } ++ fd_lock = fd_lock_create(fd, vc_fd_locks); ++ if (fd_lock == (fd_lock_t *) NULL) { ++ struct rpc_createerr *ce = &get_rpc_createerr(); ++ ce->cf_stat = RPC_SYSTEMERROR; ++ ce->cf_error.re_errno = errno; ++ goto err; ++ } + + /* + * Do not hold mutex during connect +@@ -279,6 +260,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) + * Set up private data struct + */ + ct->ct_fd = fd; ++ ct->ct_fd_lock = fd_lock; + ct->ct_wait.tv_usec = 0; + ct->ct_waitset = FALSE; + ct->ct_addr.buf = malloc(raddr->maxlen); +@@ -361,17 +343,15 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + bool_t shipnow; + int refreshes = 2; + sigset_t mask, newmask; +- int rpc_lock_value; + + assert(cl != NULL); + + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (vc_fd_locks[ct->ct_fd]) +- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); +- rpc_lock_value = 1; +- vc_fd_locks[ct->ct_fd] = rpc_lock_value; ++ while (ct->ct_fd_lock->active) ++ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); ++ ct->ct_fd_lock->active = TRUE; + mutex_unlock(&clnt_fd_lock); + if (!ct->ct_waitset) { + /* If time is not within limits, we ignore it. */ +@@ -395,22 +375,22 @@ call_again: + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTENCODEARGS; + (void)xdrrec_endofrecord(xdrs, TRUE); +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (ct->ct_error.re_status); + } + if (! xdrrec_endofrecord(xdrs, shipnow)) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (ct->ct_error.re_status = RPC_CANTSEND); + } + if (! shipnow) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (RPC_SUCCESS); + } + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return(ct->ct_error.re_status = RPC_TIMEDOUT); + } + +@@ -424,14 +404,14 @@ call_again: + reply_msg.acpted_rply.ar_results.where = NULL; + reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; + if (! xdrrec_skiprecord(xdrs)) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (ct->ct_error.re_status); + } + /* now decode and validate the response header */ + if (! xdr_replymsg(xdrs, &reply_msg)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (ct->ct_error.re_status); + } + if (reply_msg.rm_xid == x_id) +@@ -464,7 +444,7 @@ call_again: + if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg)) + goto call_again; + } /* end of unsuccessful completion */ +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (ct->ct_error.re_status); + } + +@@ -502,13 +482,13 @@ clnt_vc_freeres(cl, xdr_res, res_ptr) + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (vc_fd_locks[ct->ct_fd]) +- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); ++ while (ct->ct_fd_lock->active) ++ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); + xdrs->x_op = XDR_FREE; + dummy = (*xdr_res)(xdrs, res_ptr); + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- cond_signal(&vc_cv[ct->ct_fd]); ++ cond_signal(&ct->ct_fd_lock->cv); + + return dummy; + } +@@ -530,7 +510,6 @@ clnt_vc_control(cl, request, info) + void *infop = info; + sigset_t mask; + sigset_t newmask; +- int rpc_lock_value; + u_int32_t tmp; + u_int32_t ltmp; + +@@ -541,20 +520,19 @@ clnt_vc_control(cl, request, info) + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (vc_fd_locks[ct->ct_fd]) +- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); +- rpc_lock_value = 1; +- vc_fd_locks[ct->ct_fd] = rpc_lock_value; ++ while (ct->ct_fd_lock->active) ++ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); ++ ct->ct_fd_lock->active = TRUE; + mutex_unlock(&clnt_fd_lock); + + switch (request) { + case CLSET_FD_CLOSE: + ct->ct_closeit = TRUE; +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (TRUE); + case CLSET_FD_NCLOSE: + ct->ct_closeit = FALSE; +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (TRUE); + default: + break; +@@ -562,13 +540,13 @@ clnt_vc_control(cl, request, info) + + /* for other requests which use info */ + if (info == NULL) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (FALSE); + } + switch (request) { + case CLSET_TIMEOUT: + if (time_not_ok((struct timeval *)info)) { +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (FALSE); + } + ct->ct_wait = *(struct timeval *)infop; +@@ -588,7 +566,7 @@ clnt_vc_control(cl, request, info) + *(struct netbuf *)info = ct->ct_addr; + break; + case CLSET_SVC_ADDR: /* set to new address */ +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (FALSE); + case CLGET_XID: + /* +@@ -642,10 +620,10 @@ clnt_vc_control(cl, request, info) + break; + + default: +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (FALSE); + } +- release_fd_lock(ct->ct_fd, mask); ++ release_fd_lock(ct->ct_fd_lock, mask); + return (TRUE); + } + +@@ -654,20 +632,18 @@ static void + clnt_vc_destroy(cl) + CLIENT *cl; + { ++ assert(cl != NULL); + struct ct_data *ct = (struct ct_data *) cl->cl_private; + int ct_fd = ct->ct_fd; ++ fd_lock_t *ct_fd_lock = ct->ct_fd_lock; + sigset_t mask; + sigset_t newmask; + +- assert(cl != NULL); +- +- ct = (struct ct_data *) cl->cl_private; +- + sigfillset(&newmask); + thr_sigsetmask(SIG_SETMASK, &newmask, &mask); + mutex_lock(&clnt_fd_lock); +- while (vc_fd_locks[ct_fd]) +- cond_wait(&vc_cv[ct_fd], &clnt_fd_lock); ++ while (ct_fd_lock->active) ++ cond_wait(&ct_fd_lock->cv, &clnt_fd_lock); + if (ct->ct_closeit && ct->ct_fd != -1) { + (void)close(ct->ct_fd); + } +@@ -680,9 +656,10 @@ clnt_vc_destroy(cl) + if (cl->cl_tp && cl->cl_tp[0]) + mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); + mem_free(cl, sizeof(CLIENT)); ++ cond_signal(&ct_fd_lock->cv); ++ fd_lock_destroy(ct_fd, ct_fd_lock, vc_fd_locks); + mutex_unlock(&clnt_fd_lock); + thr_sigsetmask(SIG_SETMASK, &(mask), NULL); +- cond_signal(&vc_cv[ct_fd]); + } + + /* +diff --git a/src/rpc_generic.c b/src/rpc_generic.c +index 51f36ac..aabbe4b 100644 +--- a/src/rpc_generic.c ++++ b/src/rpc_generic.c +@@ -112,7 +112,7 @@ __rpc_dtbsize() + return (tbsize); + } + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { +- return (tbsize = (int)rl.rlim_max); ++ return (tbsize = (int)rl.rlim_cur); + } + /* + * Something wrong. I'll try to save face by returning a +diff --git a/src/svc_dg.c b/src/svc_dg.c +index 894ee9b..a9f63ff 100644 +--- a/src/svc_dg.c ++++ b/src/svc_dg.c +@@ -328,6 +328,8 @@ svc_dg_destroy(xprt) + (void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); + if (xprt->xp_tp) + (void) free(xprt->xp_tp); ++ if (xprt->xp_netid) ++ (void) free(xprt->xp_netid); + (void) mem_free(xprt, sizeof (SVCXPRT)); + } + +diff --git a/src/svc_vc.c b/src/svc_vc.c +index c23cd36..f1d9f00 100644 +--- a/src/svc_vc.c ++++ b/src/svc_vc.c +@@ -243,7 +243,7 @@ svc_fd_create(fd, sendsize, recvsize) + goto freedata; + } + if (!__rpc_set_netbuf(&ret->xp_rtaddr, &ss, sizeof(ss))) { +- warnx("svc_fd_create: no mem for local addr"); ++ warnx("svc_fd_create: no mem for remote addr"); + goto freedata; + } + +@@ -253,9 +253,10 @@ svc_fd_create(fd, sendsize, recvsize) + return ret; + + freedata: +- if (ret->xp_ltaddr.buf != NULL) ++ if (ret->xp_ltaddr.buf != NULL) { + mem_free(ret->xp_ltaddr.buf, rep->xp_ltaddr.maxlen); +- ++ ret->xp_ltaddr.buf = NULL; ++ } + return NULL; + } + +diff --git a/tirpc/reentrant.h b/tirpc/reentrant.h +index 5f5c96e..5bb581a 100644 +--- a/tirpc/reentrant.h ++++ b/tirpc/reentrant.h +@@ -57,6 +57,7 @@ + #define mutex_unlock(m) pthread_mutex_unlock(m) + + #define cond_init(c, a, p) pthread_cond_init(c, a) ++#define cond_destroy(c) pthread_cond_destroy(c) + #define cond_signal(m) pthread_cond_signal(m) + #define cond_broadcast(m) pthread_cond_broadcast(m) + #define cond_wait(c, m) pthread_cond_wait(c, m) diff --git a/libtirpc.spec b/libtirpc.spec new file mode 100644 index 0000000..77e7c13 --- /dev/null +++ b/libtirpc.spec @@ -0,0 +1,506 @@ +%define _root_libdir /%{_lib} + +Name: libtirpc +Version: 1.2.6 +Release: 2.rc4%{?dist} +Summary: Transport Independent RPC Library +License: SISSL and BSD +URL: http://git.linux-nfs.org/?p=steved/libtirpc.git;a=summary +Source0: http://downloads.sourceforge.net/libtirpc/libtirpc-%{version}.tar.bz2 + +BuildRequires: automake, autoconf, libtool, pkgconfig +BuildRequires: krb5-devel +BuildRequires: gcc + +Patch001: libtirpc-1.2.7-rc4.patch + +%description +This package contains SunLib's implementation of transport-independent +RPC (TI-RPC) documentation. This library forms a piece of the base of +Open Network Computing (ONC), and is derived directly from the +Solaris 2.3 source. + +TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V +Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface +(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported +by almost 70 vendors on all major operating systems. TS-RPC source code +(RPCSRC 4.0) remains available from several internet sites. + +%package devel +Summary: Development files for the libtirpc library +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: pkgconfig + +%description devel +This package includes header files and libraries necessary for +developing programs which use the tirpc library. + + +%prep +%autosetup -p1 + +# Remove .orig files +find . -name "*.orig" | xargs rm -f + +%build +sh autogen.sh +autoreconf -fisv +%configure +make all + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/etc +mkdir -p %{buildroot}%{_root_libdir} +mkdir -p %{buildroot}%{_libdir}/pkgconfig +make install DESTDIR=%{buildroot} \ + libdir=%{_root_libdir} pkgconfigdir=%{_libdir}/pkgconfig +# Don't package .a or .la files +rm -f %{buildroot}%{_root_libdir}/*.{a,la} + +# Creat the man diretory +mv %{buildroot}%{_mandir}/man3 %{buildroot}%{_mandir}/man3t + + +%files +%doc AUTHORS ChangeLog NEWS README +%{_root_libdir}/libtirpc.so.* +%config(noreplace)%{_sysconfdir}/netconfig +%config(noreplace)%{_sysconfdir}/bindresvport.blacklist + +%files devel +%{!?_licensedir:%global license %%doc} +%license COPYING +%dir %{_includedir}/tirpc +%dir %{_includedir}/tirpc/rpc +%dir %{_includedir}/tirpc/rpcsvc +%{_root_libdir}/libtirpc.so +%{_libdir}/pkgconfig/libtirpc.pc +%{_includedir}/tirpc/netconfig.h +%{_includedir}/tirpc/rpc/auth.h +%{_includedir}/tirpc/rpc/auth_des.h +%{_includedir}/tirpc/rpc/auth_gss.h +%{_includedir}/tirpc/rpc/auth_unix.h +%{_includedir}/tirpc/rpc/des.h +%{_includedir}/tirpc/rpc/des_crypt.h +%{_includedir}/tirpc/rpc/rpcsec_gss.h +%{_includedir}/tirpc/rpc/clnt.h +%{_includedir}/tirpc/rpc/clnt_soc.h +%{_includedir}/tirpc/rpc/clnt_stat.h +%{_includedir}/tirpc/rpc/key_prot.h +%{_includedir}/tirpc/rpc/nettype.h +%{_includedir}/tirpc/rpc/pmap_clnt.h +%{_includedir}/tirpc/rpc/pmap_prot.h +%{_includedir}/tirpc/rpc/pmap_rmt.h +%{_includedir}/tirpc/rpc/raw.h +%{_includedir}/tirpc/rpc/rpc.h +%{_includedir}/tirpc/rpc/rpc_com.h +%{_includedir}/tirpc/rpc/rpc_msg.h +%{_includedir}/tirpc/rpc/rpcb_clnt.h +%{_includedir}/tirpc/rpc/rpcb_prot.h +%{_includedir}/tirpc/rpc/rpcb_prot.x +%{_includedir}/tirpc/rpc/rpcent.h +%{_includedir}/tirpc/rpc/svc.h +%{_includedir}/tirpc/rpc/svc_auth.h +%{_includedir}/tirpc/rpc/svc_auth_gss.h +%{_includedir}/tirpc/rpc/svc_dg.h +%{_includedir}/tirpc/rpc/svc_mt.h +%{_includedir}/tirpc/rpc/svc_soc.h +%{_includedir}/tirpc/rpc/types.h +%{_includedir}/tirpc/rpc/xdr.h +%{_includedir}/tirpc/rpcsvc/crypt.h +%{_includedir}/tirpc/rpcsvc/crypt.x +%{_mandir}/*/* + +%changelog +* Tue Aug 04 2020 Steve Dickson 1.2.6-1.rc4 +- Updated to the latest upstream RC release: libtirpc-1-2-7-rc4 + +* Tue Aug 04 2020 Tom Stellard - 1.2.6-2 +- Add BuildRequires: gcc +- https://docs.fedoraproject.org/en-US/packaging-guidelines/C_and_C++/#_packaging + +* Tue Jul 28 2020 Fedora Release Engineering - 1.2.6-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Apr 14 2020 Steve Dickson 1.2.6-0 +- Updated to the latest upstream release: libtirpc-1-2-6 (bz 1822751) + +* Tue Feb 18 2020 Steve Dickson 1.2.5-1.rc2 +- Updated to the latest upstream RC release: libtirpc-1-2-6-rc2 (bz 1799601) + +* Wed Jan 29 2020 Fedora Release Engineering - 1.2.5-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Dec 20 2019 Steve Dickson 1.2.5-0 + Updated to latest upstream release: libtirpc-1-2-5 (bz 1785684) + +* Fri Nov 01 2019 Petr Pisar - 1.1.4-3.rc3 +- Remove a useless dependency on man-db from libtirpc-devel package + (bug #1496422) + +* Thu Sep 05 2019 Steve Dickson 1.1.4-2.rc3 +- Updated to latest upstream RC release: libtirpc-1-1-5-rc3 + +* Thu Jul 25 2019 Fedora Release Engineering - 1.1.4-2.rc2.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 1.1.4-2.rc2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Nov 8 2018 Steve Dickson 1.1.4-2.rc2 +- Updated to latest upstream RC release: libtirpc-1-1-5-rc2 + +* Tue Nov 6 2018 Steve Dickson 1.1.4-2.rc1 +- Remove ldconfig scriptlet (bz 1644103) + +* Thu Sep 13 2018 Steve Dickson 1.1.4-1.rc1 +- Removed a false positive from the covscan + +* Tue Sep 11 2018 Steve Dickson 1.1.4-0.rc1 +- Updated to latest upstream RC releasse (bz 1627832) + +* Mon Aug 27 2018 Steve Dickson 1.1.4 +- Updated to latest upstream release: libtirpc-1-1-4 (bz 1585558) + +* Tue Jul 31 2018 Florian Weimer - 1.0.3-4.rc2 +- Rebuild with fixed binutils + +* Sun Jul 29 2018 Steve Dickson 1.0.3-3.rc2 +- Update the libtirpc-1.0.4-rc2.patch to include big endian fixes (bz 1609208) + +* Fri Jul 20 2018 Steve Dickson 1.0.3-2.rc2 +- Updated to latest upstream RC release: libtirpc-1-0-4-rc2 + +* Fri Jul 13 2018 Fedora Release Engineering - 1.0.3-2.rc1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jul 10 2018 Steve Dickson 1.0.3-2.rc1 +- Updated the URL (bz 1599795) + +* Wed Apr 18 2018 Steve Dickson 1.0.3-1.rc1 +- Updated to latest upstream RC release: libtirpc-1-0-4-rc1 + +* Thu Apr 12 2018 Steve Dickson 1.0.3-1 +- Restore the use of reserve ports in clnt_create (bz 1562169) + +* Wed Mar 14 2018 Steve Dickson 1.0.3-0 +- Update to latest upstream release: libtirpc-1-0-3 + +* Tue Mar 6 2018 Steve Dickson 1.0.2-6.rc2 +- clnt_dg_call: Change the memory allocation + +* Thu Mar 1 2018 Steve Dickson 1.0.2-5.rc2 +- Update to latest upstream RC release: libtirpc-1-0-3-rc2 (bz 1337142) + +* Wed Feb 07 2018 Fedora Release Engineering - 1.0.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Nov 14 2017 Steve Dickson 1.0.2-4 +- Update to latest upstream RC release: libtirpc-1-0-3-rc1 + +* Tue Aug 22 2017 Petr abata - 1.0.2-3 +- Fixing the FTBFS on behalf of Rafael Fonseca (rhbz#1482063) + +* Thu Aug 03 2017 Fedora Release Engineering - 1.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.0.2-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 5 2017 Steve Dickson 1.0.2 +- Updated to the latest upstream release: 1.0.2 + +* Mon May 15 2017 Steve Dickson 1.0.1-4.rc3 +- Fix for CVE-2017-8779 (bz 1448127) + +* Fri Feb 10 2017 Fedora Release Engineering - 1.0.1-3.rc3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Apr 4 2016 Steve Dickson 1.0.1-3.rc3 +- Updated to latest upstream RC release: libtirpc-1-0-2-rc3 + +* Thu Mar 3 2016 Steve Dickson 1.0.1-2.rc2 +- Updated to latest upstream RC release: libtirpc-1-0-2-rc2 + +* Thu Feb 04 2016 Fedora Release Engineering - 1.0.1-1.rc1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Nov 16 2015 Steve Dickson 1.0.1-1.rc1 +- Updated to latest upstream RC release: libtirpc-1-0-2-rc1 (bz 1282463) + +* Wed Nov 4 2015 Steve Dickson 1.0.1-1 +- Add missing rwlock_unlocks in xprt_register (bz 1278149) + +* Fri Oct 30 2015 Steve Dickson 1.0.1-0.1 +- Updated to latest upstream release: libtirpc-1-0-1 + +* Fri Aug 28 2015 Steve Dickson 0.3.2-3.0 +- Updated to latest upstream release: libtirpc-0-3-3-rc3 + +* Fri Jul 10 2015 Steve Dickson 0.3.2-2.0 +- Updated to latest upstream release: libtirpc-0-3-3-rc2 + +* Fri Jun 26 2015 Steve Dickson 0.3.2-1.0 +- Updated to latest upstream release: libtirpc-0-3-3-rc1 + +* Thu Jun 18 2015 Steve Dickson 0.3.2-0.1 +- Added back __rpc_get_default_domain() + +* Fri Jun 12 2015 Steve Dickson 0.3.2-0.0 +- Updated to latest upstream release: libtirpc-0-3-2 + +* Mon Jun 1 2015 Steve Dickson 0.3.1-0.0 +- Updated to latest upstream release: libtirpc-0-3-1 + +* Thu May 7 2015 Steve Dickson 0.3.0-0.0 +- Updated to latest upstream release: libtirpc-0-3-0 + +* Thu Apr 23 2015 Steve Dickson 0.2.5-3.0 +- Update to latest RC release: libtirpc-0-2-6-rc3 + +* Tue Dec 16 2014 Tom Callaway 0.2.5-2.1 +- minor spec cleanups, add license texts + +* Tue Dec 16 2014 Steve Dickson 0.2.5-1.0 +- Update to latest RC release: libtirpc-0-2-6-rc2 + +* Tue Nov 11 2014 Steve Dickson 0.2.5-1.0 +- Update to latest RC release: libtirpc-0-2-6-rc1 (bz 1162711) + +* Sun Aug 17 2014 Fedora Release Engineering - 0.2.5-0.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Aug 8 2014 Steve Dickson 0.2.5-0.0 +- Update to latest upstream release: libtirpc-0.2.5 + +* Sat Jun 07 2014 Fedora Release Engineering - 0.2.4-4.0 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 29 2014 Steve Dickson 0.2.4-3.0 +- Update to latest RC release: libtirpc-0-2-5-rc3 + +* Thu Jan 23 2014 Steve Dickson 0.2.4-1.0 +- Update to latest RC release: libtirpc-0-2-5-rc1 + +* Mon Dec 9 2013 Steve Dickson 0.2.4-0 +- Update to the latest upstream release: 0.2.4 (bz 862318) + +* Mon Nov 25 2013 Steve Dickson 0.2.3-5 +- Update to latest RC release: libtirpc-0-2-4-rc3 (bz 1034438) + +* Sat Aug 03 2013 Fedora Release Engineering - 0.2.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jul 1 2013 Steve Dickson 0.2.3-3 +- Update to latest RC release: libtirpc-0-2-4-rc2 + +* Mon Apr 22 2013 Steve Dickson 0.2.3-2 +- Update to latest RC release: libtirpc-0-2-4-rc1 (bz 948378) + +* Thu Apr 11 2013 Guenther Deschner 0.2.3-1 +- Removed libgssglue dependency (patch from master) + +* Wed Feb 13 2013 Steve Dickson 0.2.3-0 +- Updated to latest upstream release: 0.2.3 + +* Tue Nov 13 2012 Steve Dickson 0.2.1-43 +- Updated to latest upstream RC release: 0.2.3-rc4 + +* Thu Jul 19 2012 Fedora Release Engineering - 0.2.2-42 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Apr 26 2012 Steve Dickson 0.2.1-4.1 +- Updated to latest upstream RC release: libtirpc-0.2.3-rc3 + +* Mon Mar 19 2012 Steve Dickson 0.2.1-3.1 +- Fixed the install path in doc/Makefile.am + +* Fri Jan 13 2012 Fedora Release Engineering - 0.2.2-2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Jul 20 2011 Steve Dickson 0.2.1-1.1 +- Fixed segfault in SVCAUTH_WRAP call (bz 722594) + +* Tue Jun 21 2011 Steve Dickson 0.2.1-1 +- Updated to latest upstream version: 0.2.3-rc1 + +* Mon May 2 2011 Steve Dickson 0.2.1-0 +- Updated to latest upstream version: 0.2.2 + +* Tue Apr 12 2011 Karsten Hopp 0.2.1-7.1 +- replace Requires(devel) with a simple Requires as the new rpm + aborts otherwise with "Bad Requireflags: qualifiers: Requires(devel)" + +* Tue Feb 08 2011 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Dec 2 2010 Steve Dickson 0.2.1-6 +- Moved the libraries from /usr/lib to /lib + +* Mon Aug 30 2010 Steve Dickson 0.2.1-5 +- Relicense these SISSL files to 3 clause BSD +- Fixed last remaining BSD license issues + +* Fri Jul 16 2010 Steve Dickson 0.2.1-4 +- Add back SISSL license attribution + +* Fri Jul 09 2010 Mike McGrath 0.2.1-3.1 +- Rebuild to fix broken man dep s/man/man-db/ + +* Tue May 18 2010 Steve Dickson 0.2.1-3 +- Updated to latest RC release: libtirpc-0-2-2-rc2 [bz 519430] + +* Mon Mar 22 2010 Steve Dickson 0.2.1-2 +- Updated to latest RC release: libtirpc-0-2-2-rc1 + +* Mon Nov 30 2009 Steve Dickson 0.2.1-1 +- Updated to latest upstream version: 0.2.1 + +* Sat Jul 25 2009 Fedora Release Engineering - 0.2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 9 2009 Steve Dickson 0.2.0-3 +- Updated to latest upstream tag: 0-2-1-rc3 + Fixed the --disable-gss options + Fixed a number of warnings + Change how architectures are define in xdr_float.c + +* Mon Jun 29 2009 Steve Dickson 0.2.0-2 +- Updated to latest upstream tag: 0-2-1-rc2 + rpcb_clnt: RPC_PROGNOTREGISTERED is a permanent error + clnt_dg: Fix infinite loop when datagram call times ou + Updated .gitignore file + Replace the hard coded path name with the top_srcdir macrc + Added 'doc' to the SUBDIRS list so make install work correctly. + +* Fri May 29 2009 Steve Dickson 0.2.0-1 +- Updated to latest upstream version: 0.2.0 + +* Tue May 19 2009 Tom "spot" Callaway 0.1.11-3 +- Replace the Sun RPC license with the BSD license, with the explicit permission of Sun Microsystems + +* Mon Apr 20 2009 Steve Dickson 0.1.11-2 +- Updated to libtirpc-0.1.12-rc1 + +* Mon Apr 20 2009 Steve Dickson 0.1.11-1 +- Updated to the latest release: 0.1.11 + +* Fri Mar 13 2009 Steve Dickson 0.1.10-6 +- libtirpc: set r_netid and r_owner in __rpcb_findaddr_timed +- libtirpc: be sure to free cl_netid and cl_tp +- libtirpc: must free saved wire verifier when destroying context + +* Wed Feb 25 2009 Fedora Release Engineering - 0.1.10-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Jan 28 2009 Steve Dickson 0.1.10-4 +- Converted all uids and uids to type uid_t and gid_t (sf 2446314) + +* Wed Jan 28 2009 Steve Dickson 0.1.10-3 +- backwards compatibility: fix order of fields in TI-RPC's + svc_req (bz 481388) +- Removed a number warnings. + +* Thu Jan 22 2009 Steve Dickson 0.1.10-2 +- Header file fixes for C++ + +* Thu Nov 20 2008 Steve Dickson 0.1.10-1 +- Updated to latest upstream version: 0.1.10 + +* Tue Oct 28 2008 Steve Dickson 0.1.9-7 +- Fixed some incorrect function declarations (bz468815) + +* Mon Oct 27 2008 Steve Dickson 0.1.9-6 +- Fix bad assumption taddr2uaddr processing that + caused a segfault (bz468014) + +* Tue Sep 16 2008 Steve Dickson 0.1.9-5 +- Fix for taddr2addr conversion bug of local addresses +- Fixed some of warnings in: src/auth_time.c, src/clnt_dg.c and + src/clnt_raw.c +- Added some #ifdef NOTUSED around some code in src/rpbc_clnt.c + that was not being used... + +* Thu Sep 4 2008 Steve Dickson 0.1.9-4 +- Always make IPv6 sockets V6ONLY +- Fix incorrect sizeof() in __rpc_getbroadifs + +* Thu Aug 7 2008 Tom "spot" Callaway 0.1.9-3 +- fix license tag + +* Tue Jul 8 2008 Steve Dickson 0.1.9-1 +- Update to latest upstream version 0.1.9 + +* Fri Jun 27 2008 Steve Dickson 0.1.8-2 +- Added super-H(sh3,4) architecture support (bz 446559) + +* Tue Jun 10 2008 Steve Dickson 0.1.8-1 +- Update to latest upstream version 0.1.8 + +* Wed Mar 12 2008 Steve Dickson 0.1.7-18 +- Install man pages in the 3t section + +* Tue Feb 19 2008 Fedora Release Engineering - 0.1.7-17 +- Autorebuild for GCC 4.3 + +* Mon Feb 18 2008 Steve Dickson 0.1.7-16 +- Added patch that creates a libtirpc.pc used by the + pkg-config command. + +* Thu Jan 24 2008 Steve Dickson 0.1.7-15 +- Protect from buffer overflow in the GSS code. (bz 362121) + +* Mon Dec 17 2007 Steve Dickson 0.1.7-14 +- Fixed typo in /etc/netconfig file (bz 414471) + +* Thu Oct 25 2007 Steve Dickson 0.1.7-13 +- Added a check for the ARM arch (bz 351071) + +* Wed Oct 17 2007 Steve Dickson 0.1.7-12 +- Switch the libgssapi dependency to libgssglue + +* Mon Oct 15 2007 Steve Dickson 0.1.7-11 +- Made tcp6/udp6 network ids no longer visible in the netconfig + file since the ipv6 code is not fully baked yet in rpcbind. (bz 249121) + +* Wed Aug 29 2007 Fedora Release Engineering - 0.1.7-10 +- Rebuild for selinux ppc32 issue. + +* Mon Jul 30 2007 0.1.7-9 +- Fixed mutex lock problem in clnt_raw_create() +- Ignore the return value of snprintf() and use strlen() instead + to bump the pointer in clnt_sperror() +- A couple ntohs() were needed in bindresvport_sa() +- Added IP_RECVERR processing with to clnt_dg_call() so + application will see errors instead of timing out +- Make sure remote address (xp_rtaddr) is populated + with the correct type of address. +- Change the order of network ids in /etc/netconfg + putting ipv4 ids before ipv6. +- Bumped up Release from 8 to 9. + +* Mon Jul 9 2007 0.1.7-7 +- Fixed infinite loop in svc_run() (bz 246677) + +* Thu Apr 26 2007 0.1.7-6 +- Fixed potential buffer overflow in xdr_strings +- Added a optimization to bindresvport that allows more + ports to be tried. + +* Mon Mar 26 2007 Steve Dickson 0.1.7-5 +- Fixed Unowned Directory RPM problem (bz 233873) + +* Mon Aug 28 2006 Steve Dickson 0.1.7-4 +- Fixed undefined symbol (bz 204296) + +* Mon Aug 14 2006 Steve Dickson 0.1.7-3 +- Added in svc_auth_none needed by the GSSAPI code. +- Added compile define for ppc64 archs + +* Fri Aug 11 2006 Steve Dickson 0.1.7-2 +- Uncommented tcp6 and udp6 in the default /etc/netconfig file. +- Added hooks to used the libgssapi library. + +* Fri Aug 4 2006 Steve Dickson 0.1.7-1 +- Initial commit diff --git a/sources b/sources new file mode 100644 index 0000000..7b9a2dc --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (libtirpc-1.2.6.tar.bz2) = bcb6b5c062c1301aa1246ec93ae0a5c1d221b8421126d020863517cb814b43ed038fb6c0c2faf4e68ff133b69abefe4f4d42bfc870671da6c27ca941a30b155a