rpc_soc.c revision 114443
174462Salfred/* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ 274462Salfred 374462Salfred/* 474462Salfred * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 574462Salfred * unrestricted use provided that this legend is included on all tape 674462Salfred * media and as a part of the software program in whole or part. Users 774462Salfred * may copy or modify Sun RPC without charge, but are not authorized 874462Salfred * to license or distribute it to anyone else except as part of a product or 974462Salfred * program developed by the user. 1074462Salfred * 1174462Salfred * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1274462Salfred * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1374462Salfred * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1474462Salfred * 1574462Salfred * Sun RPC is provided with no support and without any obligation on the 1674462Salfred * part of Sun Microsystems, Inc. to assist in its use, correction, 1774462Salfred * modification or enhancement. 1874462Salfred * 1974462Salfred * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2074462Salfred * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2174462Salfred * OR ANY PART THEREOF. 2274462Salfred * 2374462Salfred * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2474462Salfred * or profits or other special, indirect and consequential damages, even if 2574462Salfred * Sun has been advised of the possibility of such damages. 2674462Salfred * 2774462Salfred * Sun Microsystems, Inc. 2874462Salfred * 2550 Garcia Avenue 2974462Salfred * Mountain View, California 94043 3074462Salfred */ 3174462Salfred 3274462Salfred/* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ 3374462Salfred 3474462Salfred/* 3574462Salfred * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3674462Salfred * In addition, portions of such source code were derived from Berkeley 3774462Salfred * 4.3 BSD under license from the Regents of the University of 3874462Salfred * California. 3974462Salfred */ 4074462Salfred 4174462Salfred#if !defined(lint) && defined(SCCSIDS) 4274462Salfredstatic char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; 4374462Salfred#endif 4492990Sobrien#include <sys/cdefs.h> 4592990Sobrien__FBSDID("$FreeBSD: head/lib/libc/rpc/rpc_soc.c 114443 2003-05-01 19:03:14Z nectar $"); 4674462Salfred 4774462Salfred#ifdef PORTMAP 4874462Salfred/* 4974462Salfred * rpc_soc.c 5074462Salfred * 5174462Salfred * The backward compatibility routines for the earlier implementation 5274462Salfred * of RPC, where the only transports supported were tcp/ip and udp/ip. 5374462Salfred * Based on berkeley socket abstraction, now implemented on the top 5474462Salfred * of TLI/Streams 5574462Salfred */ 5674462Salfred 5775094Siedowse#include "namespace.h" 5874462Salfred#include "reentrant.h" 5974462Salfred#include <sys/types.h> 6074462Salfred#include <sys/socket.h> 6174462Salfred#include <stdio.h> 6274462Salfred#include <rpc/rpc.h> 6374462Salfred#include <rpc/pmap_clnt.h> 6474462Salfred#include <rpc/pmap_prot.h> 6574462Salfred#include <rpc/nettype.h> 6674462Salfred#include <syslog.h> 6774462Salfred#include <netinet/in.h> 6874462Salfred#include <netdb.h> 6974462Salfred#include <errno.h> 7074462Salfred#include <syslog.h> 7174462Salfred#include <stdlib.h> 7274462Salfred#include <string.h> 7374462Salfred#include <unistd.h> 7474462Salfred#include "un-namespace.h" 7574462Salfred 7674462Salfred#include "rpc_com.h" 7774462Salfred 7874462Salfredextern mutex_t rpcsoc_lock; 7974462Salfred 8092941Sobrienstatic CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 8192941Sobrien int *, u_int, u_int, char *); 8292905Sobrienstatic SVCXPRT *svc_com_create(int, u_int, u_int, char *); 8392905Sobrienstatic bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 8474462Salfred 8574462Salfred/* XXX */ 8674462Salfred#define IN4_LOCALHOST_STRING "127.0.0.1" 8774462Salfred#define IN6_LOCALHOST_STRING "::1" 8874462Salfred 8974462Salfred/* 9074462Salfred * A common clnt create routine 9174462Salfred */ 9274462Salfredstatic CLIENT * 9374462Salfredclnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp) 9474462Salfred struct sockaddr_in *raddr; 9574462Salfred rpcprog_t prog; 9674462Salfred rpcvers_t vers; 9774462Salfred int *sockp; 9874462Salfred u_int sendsz; 9974462Salfred u_int recvsz; 10074462Salfred char *tp; 10174462Salfred{ 10274462Salfred CLIENT *cl; 10374462Salfred int madefd = FALSE; 10474462Salfred int fd = *sockp; 10574462Salfred struct netconfig *nconf; 10674462Salfred struct netbuf bindaddr; 10774462Salfred 10874462Salfred mutex_lock(&rpcsoc_lock); 10974462Salfred if ((nconf = __rpc_getconfip(tp)) == NULL) { 11074462Salfred rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 11174462Salfred mutex_unlock(&rpcsoc_lock); 11274462Salfred return (NULL); 11374462Salfred } 11474462Salfred if (fd == RPC_ANYSOCK) { 11574462Salfred fd = __rpc_nconf2fd(nconf); 11674462Salfred if (fd == -1) 11774462Salfred goto syserror; 11874462Salfred madefd = TRUE; 11974462Salfred } 12074462Salfred 12174462Salfred if (raddr->sin_port == 0) { 12274462Salfred u_int proto; 12374462Salfred u_short sport; 12474462Salfred 12574462Salfred mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 12674462Salfred proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 12774462Salfred sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 12874462Salfred proto); 12974462Salfred if (sport == 0) { 13074462Salfred goto err; 13174462Salfred } 13274462Salfred raddr->sin_port = htons(sport); 13374462Salfred mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 13474462Salfred } 13574462Salfred 13674462Salfred /* Transform sockaddr_in to netbuf */ 13774462Salfred bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 13874462Salfred bindaddr.buf = raddr; 13974462Salfred 14074462Salfred bindresvport(fd, NULL); 14174462Salfred cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 14274462Salfred sendsz, recvsz); 14374462Salfred if (cl) { 14474462Salfred if (madefd == TRUE) { 14574462Salfred /* 14674462Salfred * The fd should be closed while destroying the handle. 14774462Salfred */ 14874462Salfred (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 14974462Salfred *sockp = fd; 15074462Salfred } 15174462Salfred (void) freenetconfigent(nconf); 15274462Salfred mutex_unlock(&rpcsoc_lock); 15374462Salfred return (cl); 15474462Salfred } 15574462Salfred goto err; 15674462Salfred 15774462Salfredsyserror: 15874462Salfred rpc_createerr.cf_stat = RPC_SYSTEMERROR; 15974462Salfred rpc_createerr.cf_error.re_errno = errno; 16074462Salfred 16174462Salfrederr: if (madefd == TRUE) 16274462Salfred (void)_close(fd); 16374462Salfred (void) freenetconfigent(nconf); 16474462Salfred mutex_unlock(&rpcsoc_lock); 16574462Salfred return (NULL); 16674462Salfred} 16774462Salfred 16874462SalfredCLIENT * 16974462Salfredclntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz) 17074462Salfred struct sockaddr_in *raddr; 17174462Salfred u_long prog; 17274462Salfred u_long vers; 17374462Salfred struct timeval wait; 17474462Salfred int *sockp; 17574462Salfred u_int sendsz; 17674462Salfred u_int recvsz; 17774462Salfred{ 17874462Salfred CLIENT *cl; 17974462Salfred 18074462Salfred cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 18174462Salfred sendsz, recvsz, "udp"); 18274462Salfred if (cl == NULL) { 18374462Salfred return (NULL); 18474462Salfred } 18595658Sdes (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 18674462Salfred return (cl); 18774462Salfred} 18874462Salfred 18974462SalfredCLIENT * 19074462Salfredclntudp_create(raddr, program, version, wait, sockp) 19174462Salfred struct sockaddr_in *raddr; 19274462Salfred u_long program; 19374462Salfred u_long version; 19474462Salfred struct timeval wait; 19574462Salfred int *sockp; 19674462Salfred{ 19774462Salfred 19874462Salfred return clntudp_bufcreate(raddr, program, version, wait, sockp, 19974462Salfred UDPMSGSIZE, UDPMSGSIZE); 20074462Salfred} 20174462Salfred 20274462SalfredCLIENT * 20374462Salfredclnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) 20474462Salfred struct sockaddr_in *raddr; 20574462Salfred u_long prog; 20674462Salfred u_long vers; 20774462Salfred int *sockp; 20874462Salfred u_int sendsz; 20974462Salfred u_int recvsz; 21074462Salfred{ 21174462Salfred 21274462Salfred return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 21374462Salfred sendsz, recvsz, "tcp"); 21474462Salfred} 21574462Salfred 21674462SalfredCLIENT * 21774462Salfredclntraw_create(prog, vers) 21874462Salfred u_long prog; 21974462Salfred u_long vers; 22074462Salfred{ 22174462Salfred 22274462Salfred return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 22374462Salfred} 22474462Salfred 22574462Salfred/* 22674462Salfred * A common server create routine 22774462Salfred */ 22874462Salfredstatic SVCXPRT * 22974462Salfredsvc_com_create(fd, sendsize, recvsize, netid) 23074462Salfred int fd; 23174462Salfred u_int sendsize; 23274462Salfred u_int recvsize; 23374462Salfred char *netid; 23474462Salfred{ 23574462Salfred struct netconfig *nconf; 23674462Salfred SVCXPRT *svc; 23774462Salfred int madefd = FALSE; 23874462Salfred int port; 23974462Salfred struct sockaddr_in sin; 24074462Salfred 24174462Salfred if ((nconf = __rpc_getconfip(netid)) == NULL) { 24274462Salfred (void) syslog(LOG_ERR, "Could not get %s transport", netid); 24374462Salfred return (NULL); 24474462Salfred } 24574462Salfred if (fd == RPC_ANYSOCK) { 24674462Salfred fd = __rpc_nconf2fd(nconf); 24774462Salfred if (fd == -1) { 24874462Salfred (void) freenetconfigent(nconf); 24974462Salfred (void) syslog(LOG_ERR, 25074462Salfred "svc%s_create: could not open connection", netid); 25174462Salfred return (NULL); 25274462Salfred } 25374462Salfred madefd = TRUE; 25474462Salfred } 25574462Salfred 25674462Salfred memset(&sin, 0, sizeof sin); 25774462Salfred sin.sin_family = AF_INET; 25874462Salfred bindresvport(fd, &sin); 25974462Salfred _listen(fd, SOMAXCONN); 26074462Salfred svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 26174462Salfred (void) freenetconfigent(nconf); 26274462Salfred if (svc == NULL) { 26374462Salfred if (madefd) 26474462Salfred (void)_close(fd); 26574462Salfred return (NULL); 26674462Salfred } 26774462Salfred port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 26874462Salfred svc->xp_port = ntohs(port); 26974462Salfred return (svc); 27074462Salfred} 27174462Salfred 27274462SalfredSVCXPRT * 27374462Salfredsvctcp_create(fd, sendsize, recvsize) 27474462Salfred int fd; 27574462Salfred u_int sendsize; 27674462Salfred u_int recvsize; 27774462Salfred{ 27874462Salfred 27974462Salfred return svc_com_create(fd, sendsize, recvsize, "tcp"); 28074462Salfred} 28174462Salfred 28274462SalfredSVCXPRT * 28374462Salfredsvcudp_bufcreate(fd, sendsz, recvsz) 28474462Salfred int fd; 28574462Salfred u_int sendsz, recvsz; 28674462Salfred{ 28774462Salfred 28874462Salfred return svc_com_create(fd, sendsz, recvsz, "udp"); 28974462Salfred} 29074462Salfred 29174462SalfredSVCXPRT * 29274462Salfredsvcfd_create(fd, sendsize, recvsize) 29374462Salfred int fd; 29474462Salfred u_int sendsize; 29574462Salfred u_int recvsize; 29674462Salfred{ 29774462Salfred 29874462Salfred return svc_fd_create(fd, sendsize, recvsize); 29974462Salfred} 30074462Salfred 30174462Salfred 30274462SalfredSVCXPRT * 30374462Salfredsvcudp_create(fd) 30474462Salfred int fd; 30574462Salfred{ 30674462Salfred 30774462Salfred return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 30874462Salfred} 30974462Salfred 31074462SalfredSVCXPRT * 31174462Salfredsvcraw_create() 31274462Salfred{ 31374462Salfred 31474462Salfred return svc_raw_create(); 31574462Salfred} 31674462Salfred 31774462Salfredint 31874462Salfredget_myaddress(addr) 31974462Salfred struct sockaddr_in *addr; 32074462Salfred{ 32174462Salfred 32274462Salfred memset((void *) addr, 0, sizeof(*addr)); 32374462Salfred addr->sin_family = AF_INET; 32474462Salfred addr->sin_port = htons(PMAPPORT); 32574462Salfred addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 32674462Salfred return (0); 32774462Salfred} 32874462Salfred 32974462Salfred/* 33074462Salfred * For connectionless "udp" transport. Obsoleted by rpc_call(). 33174462Salfred */ 33274462Salfredint 33374462Salfredcallrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) 33492968Salfred const char *host; 33574462Salfred int prognum, versnum, procnum; 33674462Salfred xdrproc_t inproc, outproc; 33774695Salfred void *in, *out; 33874462Salfred{ 33974462Salfred 34074462Salfred return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 34174462Salfred (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 34274462Salfred} 34374462Salfred 34474462Salfred/* 34574462Salfred * For connectionless kind of transport. Obsoleted by rpc_reg() 34674462Salfred */ 34774462Salfredint 34874462Salfredregisterrpc(prognum, versnum, procnum, progname, inproc, outproc) 34974462Salfred int prognum, versnum, procnum; 35092905Sobrien char *(*progname)(char [UDPMSGSIZE]); 35174462Salfred xdrproc_t inproc, outproc; 35274462Salfred{ 35374462Salfred 35474462Salfred return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 35574462Salfred (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 35674462Salfred} 35774462Salfred 35874462Salfred/* 35974462Salfred * All the following clnt_broadcast stuff is convulated; it supports 36074462Salfred * the earlier calling style of the callback function 36174462Salfred */ 36274462Salfredstatic thread_key_t clnt_broadcast_key; 36374462Salfredstatic resultproc_t clnt_broadcast_result_main; 36474462Salfred 36574462Salfred/* 36674462Salfred * Need to translate the netbuf address into sockaddr_in address. 36774462Salfred * Dont care about netid here. 36874462Salfred */ 36974462Salfred/* ARGSUSED */ 37074462Salfredstatic bool_t 37174462Salfredrpc_wrap_bcast(resultp, addr, nconf) 37274462Salfred char *resultp; /* results of the call */ 37374462Salfred struct netbuf *addr; /* address of the guy who responded */ 37474462Salfred struct netconfig *nconf; /* Netconf of the transport */ 37574462Salfred{ 37674462Salfred resultproc_t clnt_broadcast_result; 37774462Salfred 37874462Salfred if (strcmp(nconf->nc_netid, "udp")) 37974462Salfred return (FALSE); 38074462Salfred if (thr_main()) 38174462Salfred clnt_broadcast_result = clnt_broadcast_result_main; 38274462Salfred else 38374462Salfred clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 38474462Salfred return (*clnt_broadcast_result)(resultp, 38574462Salfred (struct sockaddr_in *)addr->buf); 38674462Salfred} 38774462Salfred 38874462Salfred/* 38974462Salfred * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 39074462Salfred */ 39174462Salfredenum clnt_stat 39274462Salfredclnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) 39374462Salfred u_long prog; /* program number */ 39474462Salfred u_long vers; /* version number */ 39574462Salfred u_long proc; /* procedure number */ 39674462Salfred xdrproc_t xargs; /* xdr routine for args */ 39795658Sdes void *argsp; /* pointer to args */ 39874462Salfred xdrproc_t xresults; /* xdr routine for results */ 39995658Sdes void *resultsp; /* pointer to results */ 40074462Salfred resultproc_t eachresult; /* call with each result obtained */ 40174462Salfred{ 40274462Salfred extern mutex_t tsd_lock; 40374462Salfred 40474462Salfred if (thr_main()) 40574462Salfred clnt_broadcast_result_main = eachresult; 40674462Salfred else { 40774462Salfred if (clnt_broadcast_key == 0) { 40874462Salfred mutex_lock(&tsd_lock); 40974462Salfred if (clnt_broadcast_key == 0) 41074462Salfred thr_keycreate(&clnt_broadcast_key, free); 41174462Salfred mutex_unlock(&tsd_lock); 41274462Salfred } 41374462Salfred thr_setspecific(clnt_broadcast_key, (void *) eachresult); 41474462Salfred } 41574462Salfred return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 41674462Salfred (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 41774462Salfred (resultproc_t) rpc_wrap_bcast, "udp"); 41874462Salfred} 41974462Salfred 42074462Salfred/* 42174462Salfred * Create the client des authentication object. Obsoleted by 42274462Salfred * authdes_seccreate(). 42374462Salfred */ 42474462SalfredAUTH * 42574462Salfredauthdes_create(servername, window, syncaddr, ckey) 42674462Salfred char *servername; /* network name of server */ 42774462Salfred u_int window; /* time to live */ 42874462Salfred struct sockaddr *syncaddr; /* optional hostaddr to sync with */ 42974462Salfred des_block *ckey; /* optional conversation key to use */ 43074462Salfred{ 43174462Salfred AUTH *dummy; 43274462Salfred AUTH *nauth; 43374462Salfred char hostname[NI_MAXHOST]; 43474462Salfred 43574462Salfred if (syncaddr) { 43674462Salfred /* 43774462Salfred * Change addr to hostname, because that is the way 43874462Salfred * new interface takes it. 43974462Salfred */ 44074462Salfred if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 44174462Salfred sizeof hostname, NULL, 0, 0) != 0) 44274462Salfred goto fallback; 44374462Salfred 44474462Salfred nauth = authdes_seccreate(servername, window, hostname, ckey); 44574462Salfred return (nauth); 44674462Salfred } 44774462Salfredfallback: 44874462Salfred dummy = authdes_seccreate(servername, window, NULL, ckey); 44974462Salfred return (dummy); 45074462Salfred} 45174462Salfred 45284487Swpaul/* 45384487Swpaul * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 45484487Swpaul */ 45584487SwpaulCLIENT * 45684487Swpaulclntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) 45784487Swpaul struct sockaddr_un *raddr; 45884487Swpaul u_long prog; 45984487Swpaul u_long vers; 46092889Sobrien int *sockp; 46184487Swpaul u_int sendsz; 46284487Swpaul u_int recvsz; 46384487Swpaul{ 46484487Swpaul struct netbuf *svcaddr; 46584487Swpaul struct netconfig *nconf; 46684487Swpaul CLIENT *cl; 46784487Swpaul int len; 46884487Swpaul 46990271Salfred cl = NULL; 47084487Swpaul nconf = NULL; 47190271Salfred svcaddr = NULL; 47284487Swpaul if ((raddr->sun_len == 0) || 47384487Swpaul ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 47484487Swpaul ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 47584487Swpaul if (svcaddr != NULL) 47684487Swpaul free(svcaddr); 47784487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 47884487Swpaul rpc_createerr.cf_error.re_errno = errno; 47984487Swpaul return(cl); 48084487Swpaul } 48184487Swpaul if (*sockp < 0) { 48284487Swpaul *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 48384487Swpaul len = raddr->sun_len = SUN_LEN(raddr); 48484487Swpaul if ((*sockp < 0) || (_connect(*sockp, 48584487Swpaul (struct sockaddr *)raddr, len) < 0)) { 48684487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 48784487Swpaul rpc_createerr.cf_error.re_errno = errno; 48884487Swpaul if (*sockp != -1) 48984487Swpaul (void)_close(*sockp); 49084487Swpaul goto done; 49184487Swpaul } 49284487Swpaul } 49384487Swpaul svcaddr->buf = raddr; 49484487Swpaul svcaddr->len = raddr->sun_len; 49584487Swpaul svcaddr->maxlen = sizeof (struct sockaddr_un); 49684487Swpaul cl = clnt_vc_create(*sockp, svcaddr, prog, 49784487Swpaul vers, sendsz, recvsz); 49884487Swpauldone: 49984487Swpaul free(svcaddr->buf); 50084487Swpaul free(svcaddr); 50184487Swpaul return(cl); 50284487Swpaul} 50384487Swpaul 50484487Swpaul/* 50584487Swpaul * Creates, registers, and returns a (rpc) unix based transporter. 50684487Swpaul * Obsoleted by svc_vc_create(). 50784487Swpaul */ 50884487SwpaulSVCXPRT * 50984487Swpaulsvcunix_create(sock, sendsize, recvsize, path) 51092889Sobrien int sock; 51184487Swpaul u_int sendsize; 51284487Swpaul u_int recvsize; 51384487Swpaul char *path; 51484487Swpaul{ 51584487Swpaul struct netconfig *nconf; 51684487Swpaul void *localhandle; 51784487Swpaul struct sockaddr_un sun; 51884487Swpaul struct sockaddr *sa; 51984487Swpaul struct t_bind taddr; 52084487Swpaul SVCXPRT *xprt; 52184487Swpaul int addrlen; 52284487Swpaul 52384487Swpaul xprt = (SVCXPRT *)NULL; 52484487Swpaul localhandle = setnetconfig(); 52584487Swpaul while ((nconf = getnetconfig(localhandle)) != NULL) { 52684487Swpaul if (nconf->nc_protofmly != NULL && 52784487Swpaul strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 52884487Swpaul break; 52984487Swpaul } 53084487Swpaul if (nconf == NULL) 53184487Swpaul return(xprt); 53284487Swpaul 53384487Swpaul if ((sock = __rpc_nconf2fd(nconf)) < 0) 53484487Swpaul goto done; 53584487Swpaul 53684487Swpaul memset(&sun, 0, sizeof sun); 53784487Swpaul sun.sun_family = AF_LOCAL; 538114443Snectar if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 53984487Swpaul sizeof(sun.sun_path)) 54084487Swpaul goto done; 54184487Swpaul sun.sun_len = SUN_LEN(&sun); 54284487Swpaul addrlen = sizeof (struct sockaddr_un); 54384487Swpaul sa = (struct sockaddr *)&sun; 54484487Swpaul 54584487Swpaul if (_bind(sock, sa, addrlen) < 0) 54684487Swpaul goto done; 54784487Swpaul 54884487Swpaul taddr.addr.len = taddr.addr.maxlen = addrlen; 54984487Swpaul taddr.addr.buf = malloc(addrlen); 55084487Swpaul if (taddr.addr.buf == NULL) 55184487Swpaul goto done; 55284487Swpaul memcpy(taddr.addr.buf, sa, addrlen); 55384487Swpaul 55484487Swpaul if (nconf->nc_semantics != NC_TPI_CLTS) { 55584487Swpaul if (_listen(sock, SOMAXCONN) < 0) { 55684487Swpaul free(taddr.addr.buf); 55784487Swpaul goto done; 55884487Swpaul } 55984487Swpaul } 56084487Swpaul 56184487Swpaul xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 56284487Swpaul 56384487Swpauldone: 56484487Swpaul endnetconfig(localhandle); 56584487Swpaul return(xprt); 56684487Swpaul} 56784487Swpaul 56884487Swpaul/* 56984487Swpaul * Like svunix_create(), except the routine takes any *open* UNIX file 57084487Swpaul * descriptor as its first input. Obsoleted by svc_fd_create(); 57184487Swpaul */ 57284487SwpaulSVCXPRT * 57384487Swpaulsvcunixfd_create(fd, sendsize, recvsize) 57484487Swpaul int fd; 57584487Swpaul u_int sendsize; 57684487Swpaul u_int recvsize; 57784487Swpaul{ 57884487Swpaul return (svc_fd_create(fd, sendsize, recvsize)); 57984487Swpaul} 58084487Swpaul 58174462Salfred#endif /* PORTMAP */ 582