From 6c9e575b196d51cc925335b293fd6b2b5c65741c Mon Sep 17 00:00:00 2001 From: wpaul Date: Thu, 4 Oct 2001 21:03:17 +0000 Subject: Add compatibility functions for the AF_LOCAL RPC transport stuff that used to live in RPC 4.0. This is needed for yppasswd and rpc.yppasswdd to work correctly. Patch supplied by Martin Blapp. --- include/rpc/clnt.h | 5 ++ include/rpc/svc.h | 10 ++++ lib/libc/rpc/Makefile.inc | 3 ++ lib/libc/rpc/rpc_soc.3 | 103 ++++++++++++++++++++++++++++++++++++ lib/libc/rpc/rpc_soc.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+) diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h index 1303690..f8af9a2 100644 --- a/include/rpc/clnt.h +++ b/include/rpc/clnt.h @@ -338,6 +338,11 @@ extern CLIENT *clnt_vc_create __P((const int, const struct netbuf *, const rpcprog_t, const rpcvers_t, const u_int, const u_int)); /* + * Added for compatibility to old rpc 4.0. Obsoleted by clnt_vc_create(). + */ +extern CLIENT *clntunix_create __P((struct sockaddr_un *, + u_long, u_long, int *, u_int, u_int)); +/* * const int fd; -- open file descriptor * const struct netbuf *svcaddr; -- servers address * const rpcprog_t prog; -- program number diff --git a/include/rpc/svc.h b/include/rpc/svc.h index 1f3c725..f779646 100644 --- a/include/rpc/svc.h +++ b/include/rpc/svc.h @@ -381,6 +381,11 @@ extern SVCXPRT *svc_vc_create __P((const int, const u_int, const u_int)); * const u_int recvsize; -- max recv size */ +/* + * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). + */ +extern SVCXPRT *svcunix_create __P((int, u_int, u_int, char *)); + extern SVCXPRT *svc_dg_create __P((const int, const u_int, const u_int)); /* * const int fd; -- open connection @@ -401,6 +406,11 @@ extern SVCXPRT *svc_fd_create __P((const int, const u_int, const u_int)); */ /* + * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). + */ +extern SVCXPRT *svcunixfd_create __P((int, u_int, u_int)); + +/* * Memory based rpc (for speed check and testing) */ extern SVCXPRT *svc_raw_create __P((void)); diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index 800ff96..5234e89 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -133,6 +133,7 @@ MLINKS+= bindresvport.3 bindresvport_sa.3 \ rpc_soc.3 clnt_broadcast.3 \ rpc_soc.3 clntraw_create.3 \ rpc_soc.3 clnttcp_create.3 \ + rpc_soc.3 clntunix_create.3 \ rpc_soc.3 clntudp_bufcreate.3 \ rpc_soc.3 clntudp_create.3 \ rpc_soc.3 get_myaddress.3 \ @@ -149,8 +150,10 @@ MLINKS+= bindresvport.3 bindresvport_sa.3 \ rpc_soc.3 svc_register.3 \ rpc_soc.3 svc_unregister.3 \ rpc_soc.3 svcfd_create.3 \ + rpc_soc.3 svcunixfd_create.3 \ rpc_soc.3 svcraw_create.3 \ rpc_soc.3 svctcp_create.3 \ rpc_soc.3 svcudp_bufcreate.3 \ + rpc_soc.3 svcunix_create.3 \ rpc_soc.3 xdr_pmap.3 \ rpc_soc.3 xdr_pmaplist.3 diff --git a/lib/libc/rpc/rpc_soc.3 b/lib/libc/rpc/rpc_soc.3 index f7a8653..360ce3a 100644 --- a/lib/libc/rpc/rpc_soc.3 +++ b/lib/libc/rpc/rpc_soc.3 @@ -29,6 +29,7 @@ .Nm clnttcp_create , .Nm clntudp_bufcreate , .Nm clntudp_create , +.Nm clntunix_create , .Nm get_myaddress , .Nm pmap_getmaps , .Nm pmap_getport , @@ -56,7 +57,9 @@ .Nm svcerr_systemerr , .Nm svcerr_weakauth , .Nm svcfd_create , +.Nm svcunixfd_create , .Nm svcraw_create , +.Nm svcunix_create , .Nm xdr_accepted_reply , .Nm xdr_authunix_parms , .Nm xdr_callhdr , @@ -761,6 +764,53 @@ for sending and receiving messages. .Pp .It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fo clntunix_create +.Fa "struct sockaddr_un *raddr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "int *sockp" +.Fa "u_int sendsz" +.Fa "u_int recvsz" +.Fc +.Xc +.Pp +This routine creates an +.Tn RPC +client for the local +program +.Fa prognum , +version +.Fa versnum ; +the client uses +.Tn UNIX Ns -domain +sockets as a transport. +The local program is located at the +.Fa *raddr . +The parameter +.Fa sockp +is a socket; if it is +.Dv RPC_ANYSOCK , +then this routine opens a new one and sets +.Fa sockp . +Since +.Tn UNIX Ns \-based +.Tn RPC +uses buffered +.Tn I/O , +the user may specify the size of the send and receive buffers +with the parameters +.Fa sendsz +and +.Fa recvsz ; +values of zero choose suitable defaults. +This routine returns +.Dv NULL +if it fails. +.Pp +.It Xo .Ft int .Xc .It Xo @@ -1363,6 +1413,59 @@ choose suitable defaults. .Ft "SVCXPRT *" .Xc .It Xo +.Fn svcunix_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" "char *path" +.Xc +.Pp +This routine creates a +.Tn UNIX Ns \-based +.Tn RPC +service transport, to which it returns a pointer. +The transport is associated with the socket +.Fa sock , +which may be +.Dv RPC_ANYSOCK , +in which case a new socket is created. +.Fa *path +is a variable-length filesystem pathname of +at most 104 characters. +This file is +.Em not +removed when the socket is closed. +.Xr unlink 2 +must be used to remove the file. +Upon completion, +.Fa xprt\->xp_fd +is the transport's socket descriptor. +This routine returns +.Dv NULL +if it fails. +Since +.Tn UNIX Ns \-based +.Tn RPC +uses buffered +.Tn I/O , +users may specify the size of buffers; values of zero +choose suitable defaults. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcunixfd_create "int fd" "u_int sendsize" "u_int recvsize" +.Xc +.Pp +Create a service on top of any open descriptor. +.Fa sendsize +and +.Fa recvsize +indicate sizes for the send and receive buffers. +If they are +zero, a reasonable default is chosen. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo .Fn svcfd_create "int fd" "u_int sendsize" "u_int recvsize" .Xc .Pp diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index b342cce..39f8199 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -450,4 +450,133 @@ fallback: return (dummy); } +/* + * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() + */ +CLIENT * +clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) + struct sockaddr_un *raddr; + u_long prog; + u_long vers; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + struct netbuf *svcaddr; + void *localhandle; + struct netconfig *nconf; + CLIENT *cl; + int len; + + nconf = NULL; + cl = NULL; + if ((raddr->sun_len == 0) || + ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || + ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { + if (svcaddr != NULL) + free(svcaddr); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + return(cl); + } + if (*sockp < 0) { + *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); + len = raddr->sun_len = SUN_LEN(raddr); + if ((*sockp < 0) || (_connect(*sockp, + (struct sockaddr *)raddr, len) < 0)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + if (*sockp != -1) + (void)_close(*sockp); + goto done; + } + } + svcaddr->buf = raddr; + svcaddr->len = raddr->sun_len; + svcaddr->maxlen = sizeof (struct sockaddr_un); + cl = clnt_vc_create(*sockp, svcaddr, prog, + vers, sendsz, recvsz); +done: + free(svcaddr->buf); + free(svcaddr); + return(cl); +} + +/* + * Creates, registers, and returns a (rpc) unix based transporter. + * Obsoleted by svc_vc_create(). + */ +SVCXPRT * +svcunix_create(sock, sendsize, recvsize, path) + register int sock; + u_int sendsize; + u_int recvsize; + char *path; +{ + struct netconfig *nconf; + void *localhandle; + struct sockaddr_un sun; + struct sockaddr *sa; + struct t_bind taddr; + SVCXPRT *xprt; + int addrlen; + + xprt = (SVCXPRT *)NULL; + localhandle = setnetconfig(); + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) + break; + } + if (nconf == NULL) + return(xprt); + + if ((sock = __rpc_nconf2fd(nconf)) < 0) + goto done; + + memset(&sun, 0, sizeof sun); + sun.sun_family = AF_LOCAL; + if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= + sizeof(sun.sun_path)) + goto done; + sun.sun_len = SUN_LEN(&sun); + addrlen = sizeof (struct sockaddr_un); + sa = (struct sockaddr *)&sun; + + if (_bind(sock, sa, addrlen) < 0) + goto done; + + taddr.addr.len = taddr.addr.maxlen = addrlen; + taddr.addr.buf = malloc(addrlen); + if (taddr.addr.buf == NULL) + goto done; + memcpy(taddr.addr.buf, sa, addrlen); + + if (nconf->nc_semantics != NC_TPI_CLTS) { + if (_listen(sock, SOMAXCONN) < 0) { + free(taddr.addr.buf); + goto done; + } + } + + xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); + +done: + endnetconfig(localhandle); + return(xprt); +} + +/* + * Like svunix_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. Obsoleted by svc_fd_create(); + */ +SVCXPRT * +svcunixfd_create(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + return (svc_fd_create(fd, sendsize, recvsize)); +} + #endif /* PORTMAP */ -- cgit v1.1