174462Salfred/* $NetBSD: rpc_soc.c,v 1.6 2000/07/06 03:10:35 christos Exp $ */ 274462Salfred 3261046Smav/*- 4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261046Smav * All rights reserved. 6261046Smav * 7261046Smav * Redistribution and use in source and binary forms, with or without 8261046Smav * modification, are permitted provided that the following conditions are met: 9261046Smav * - Redistributions of source code must retain the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer. 11261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261046Smav * this list of conditions and the following disclaimer in the documentation 13261046Smav * and/or other materials provided with the distribution. 14261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261046Smav * contributors may be used to endorse or promote products derived 16261046Smav * from this software without specific prior written permission. 1774462Salfred * 18261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261046Smav * POSSIBILITY OF SUCH DAMAGE. 2974462Salfred */ 3074462Salfred 3174462Salfred/* #ident "@(#)rpc_soc.c 1.17 94/04/24 SMI" */ 3274462Salfred 3374462Salfred/* 3474462Salfred * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3574462Salfred * In addition, portions of such source code were derived from Berkeley 3674462Salfred * 4.3 BSD under license from the Regents of the University of 3774462Salfred * California. 3874462Salfred */ 3974462Salfred 40136581Sobrien#if defined(LIBC_SCCS) && !defined(lint) 4174462Salfredstatic char sccsid[] = "@(#)rpc_soc.c 1.41 89/05/02 Copyr 1988 Sun Micro"; 4274462Salfred#endif 4392990Sobrien#include <sys/cdefs.h> 4492990Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/rpc_soc.c 309489 2016-12-03 17:40:58Z ngie $"); 4574462Salfred 4674462Salfred#ifdef PORTMAP 4774462Salfred/* 4874462Salfred * rpc_soc.c 4974462Salfred * 5074462Salfred * The backward compatibility routines for the earlier implementation 5174462Salfred * of RPC, where the only transports supported were tcp/ip and udp/ip. 5274462Salfred * Based on berkeley socket abstraction, now implemented on the top 5374462Salfred * of TLI/Streams 5474462Salfred */ 5574462Salfred 5675094Siedowse#include "namespace.h" 5774462Salfred#include "reentrant.h" 5874462Salfred#include <sys/types.h> 5974462Salfred#include <sys/socket.h> 6074462Salfred#include <stdio.h> 6174462Salfred#include <rpc/rpc.h> 6274462Salfred#include <rpc/pmap_clnt.h> 6374462Salfred#include <rpc/pmap_prot.h> 6474462Salfred#include <rpc/nettype.h> 6574462Salfred#include <syslog.h> 6674462Salfred#include <netinet/in.h> 6774462Salfred#include <netdb.h> 6874462Salfred#include <errno.h> 6974462Salfred#include <syslog.h> 7074462Salfred#include <stdlib.h> 7174462Salfred#include <string.h> 7274462Salfred#include <unistd.h> 7374462Salfred#include "un-namespace.h" 7474462Salfred 7574462Salfred#include "rpc_com.h" 76156090Sdeischen#include "mt_misc.h" 7774462Salfred 7892941Sobrienstatic CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, 7992941Sobrien int *, u_int, u_int, char *); 8092905Sobrienstatic SVCXPRT *svc_com_create(int, u_int, u_int, char *); 8192905Sobrienstatic bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); 8274462Salfred 8374462Salfred/* XXX */ 8474462Salfred#define IN4_LOCALHOST_STRING "127.0.0.1" 8574462Salfred#define IN6_LOCALHOST_STRING "::1" 8674462Salfred 8774462Salfred/* 8874462Salfred * A common clnt create routine 8974462Salfred */ 9074462Salfredstatic CLIENT * 91309489Sngieclnt_com_create(struct sockaddr_in *raddr, rpcprog_t prog, rpcvers_t vers, int *sockp, 92309489Sngie u_int sendsz, u_int recvsz, char *tp) 9374462Salfred{ 9474462Salfred CLIENT *cl; 9574462Salfred int madefd = FALSE; 9674462Salfred int fd = *sockp; 9774462Salfred struct netconfig *nconf; 9874462Salfred struct netbuf bindaddr; 9974462Salfred 10074462Salfred mutex_lock(&rpcsoc_lock); 10174462Salfred if ((nconf = __rpc_getconfip(tp)) == NULL) { 10274462Salfred rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; 10374462Salfred mutex_unlock(&rpcsoc_lock); 10474462Salfred return (NULL); 10574462Salfred } 10674462Salfred if (fd == RPC_ANYSOCK) { 10774462Salfred fd = __rpc_nconf2fd(nconf); 10874462Salfred if (fd == -1) 10974462Salfred goto syserror; 11074462Salfred madefd = TRUE; 11174462Salfred } 11274462Salfred 11374462Salfred if (raddr->sin_port == 0) { 11474462Salfred u_int proto; 11574462Salfred u_short sport; 11674462Salfred 11774462Salfred mutex_unlock(&rpcsoc_lock); /* pmap_getport is recursive */ 11874462Salfred proto = strcmp(tp, "udp") == 0 ? IPPROTO_UDP : IPPROTO_TCP; 11974462Salfred sport = pmap_getport(raddr, (u_long)prog, (u_long)vers, 12074462Salfred proto); 12174462Salfred if (sport == 0) { 12274462Salfred goto err; 12374462Salfred } 12474462Salfred raddr->sin_port = htons(sport); 12574462Salfred mutex_lock(&rpcsoc_lock); /* pmap_getport is recursive */ 12674462Salfred } 12774462Salfred 12874462Salfred /* Transform sockaddr_in to netbuf */ 12974462Salfred bindaddr.maxlen = bindaddr.len = sizeof (struct sockaddr_in); 13074462Salfred bindaddr.buf = raddr; 13174462Salfred 13274462Salfred bindresvport(fd, NULL); 13374462Salfred cl = clnt_tli_create(fd, nconf, &bindaddr, prog, vers, 13474462Salfred sendsz, recvsz); 13574462Salfred if (cl) { 13674462Salfred if (madefd == TRUE) { 13774462Salfred /* 13874462Salfred * The fd should be closed while destroying the handle. 13974462Salfred */ 14074462Salfred (void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL); 14174462Salfred *sockp = fd; 14274462Salfred } 14374462Salfred (void) freenetconfigent(nconf); 14474462Salfred mutex_unlock(&rpcsoc_lock); 14574462Salfred return (cl); 14674462Salfred } 14774462Salfred goto err; 14874462Salfred 14974462Salfredsyserror: 15074462Salfred rpc_createerr.cf_stat = RPC_SYSTEMERROR; 15174462Salfred rpc_createerr.cf_error.re_errno = errno; 15274462Salfred 15374462Salfrederr: if (madefd == TRUE) 15474462Salfred (void)_close(fd); 15574462Salfred (void) freenetconfigent(nconf); 15674462Salfred mutex_unlock(&rpcsoc_lock); 15774462Salfred return (NULL); 15874462Salfred} 15974462Salfred 16074462SalfredCLIENT * 161309489Sngieclntudp_bufcreate(struct sockaddr_in *raddr, u_long prog, u_long vers, 162309489Sngie struct timeval wait, int *sockp, u_int sendsz, u_int recvsz) 16374462Salfred{ 16474462Salfred CLIENT *cl; 16574462Salfred 16674462Salfred cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 16774462Salfred sendsz, recvsz, "udp"); 16874462Salfred if (cl == NULL) { 16974462Salfred return (NULL); 17074462Salfred } 17195658Sdes (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait); 17274462Salfred return (cl); 17374462Salfred} 17474462Salfred 17574462SalfredCLIENT * 176309489Sngieclntudp_create(struct sockaddr_in *raddr, u_long program, u_long version, 177309489Sngie struct timeval wait, int *sockp) 17874462Salfred{ 17974462Salfred 18074462Salfred return clntudp_bufcreate(raddr, program, version, wait, sockp, 18174462Salfred UDPMSGSIZE, UDPMSGSIZE); 18274462Salfred} 18374462Salfred 18474462SalfredCLIENT * 185309489Sngieclnttcp_create(struct sockaddr_in *raddr, u_long prog, u_long vers, int *sockp, 186309489Sngie u_int sendsz, u_int recvsz) 18774462Salfred{ 18874462Salfred 18974462Salfred return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp, 19074462Salfred sendsz, recvsz, "tcp"); 19174462Salfred} 19274462Salfred 19374462SalfredCLIENT * 194309489Sngieclntraw_create(u_long prog, u_long vers) 19574462Salfred{ 19674462Salfred 19774462Salfred return clnt_raw_create((rpcprog_t)prog, (rpcvers_t)vers); 19874462Salfred} 19974462Salfred 20074462Salfred/* 20174462Salfred * A common server create routine 20274462Salfred */ 20374462Salfredstatic SVCXPRT * 204309489Sngiesvc_com_create(int fd, u_int sendsize, u_int recvsize, char *netid) 20574462Salfred{ 20674462Salfred struct netconfig *nconf; 20774462Salfred SVCXPRT *svc; 20874462Salfred int madefd = FALSE; 20974462Salfred int port; 21074462Salfred struct sockaddr_in sin; 21174462Salfred 21274462Salfred if ((nconf = __rpc_getconfip(netid)) == NULL) { 21374462Salfred (void) syslog(LOG_ERR, "Could not get %s transport", netid); 21474462Salfred return (NULL); 21574462Salfred } 21674462Salfred if (fd == RPC_ANYSOCK) { 21774462Salfred fd = __rpc_nconf2fd(nconf); 21874462Salfred if (fd == -1) { 21974462Salfred (void) freenetconfigent(nconf); 22074462Salfred (void) syslog(LOG_ERR, 22174462Salfred "svc%s_create: could not open connection", netid); 22274462Salfred return (NULL); 22374462Salfred } 22474462Salfred madefd = TRUE; 22574462Salfred } 22674462Salfred 22774462Salfred memset(&sin, 0, sizeof sin); 22874462Salfred sin.sin_family = AF_INET; 22974462Salfred bindresvport(fd, &sin); 23074462Salfred _listen(fd, SOMAXCONN); 23174462Salfred svc = svc_tli_create(fd, nconf, NULL, sendsize, recvsize); 23274462Salfred (void) freenetconfigent(nconf); 23374462Salfred if (svc == NULL) { 23474462Salfred if (madefd) 23574462Salfred (void)_close(fd); 23674462Salfred return (NULL); 23774462Salfred } 23874462Salfred port = (((struct sockaddr_in *)svc->xp_ltaddr.buf)->sin_port); 23974462Salfred svc->xp_port = ntohs(port); 24074462Salfred return (svc); 24174462Salfred} 24274462Salfred 24374462SalfredSVCXPRT * 244309489Sngiesvctcp_create(int fd, u_int sendsize, u_int recvsize) 24574462Salfred{ 24674462Salfred 24774462Salfred return svc_com_create(fd, sendsize, recvsize, "tcp"); 24874462Salfred} 24974462Salfred 25074462SalfredSVCXPRT * 251309489Sngiesvcudp_bufcreate(int fd, u_int sendsz, u_int recvsz) 25274462Salfred{ 25374462Salfred 25474462Salfred return svc_com_create(fd, sendsz, recvsz, "udp"); 25574462Salfred} 25674462Salfred 25774462SalfredSVCXPRT * 258309489Sngiesvcfd_create(int fd, u_int sendsize, u_int recvsize) 25974462Salfred{ 26074462Salfred 26174462Salfred return svc_fd_create(fd, sendsize, recvsize); 26274462Salfred} 26374462Salfred 26474462Salfred 26574462SalfredSVCXPRT * 266309489Sngiesvcudp_create(int fd) 26774462Salfred{ 26874462Salfred 26974462Salfred return svc_com_create(fd, UDPMSGSIZE, UDPMSGSIZE, "udp"); 27074462Salfred} 27174462Salfred 27274462SalfredSVCXPRT * 273309487Sngiesvcraw_create(void) 27474462Salfred{ 27574462Salfred 27674462Salfred return svc_raw_create(); 27774462Salfred} 27874462Salfred 27974462Salfredint 280309489Sngieget_myaddress(struct sockaddr_in *addr) 28174462Salfred{ 28274462Salfred 28374462Salfred memset((void *) addr, 0, sizeof(*addr)); 28474462Salfred addr->sin_family = AF_INET; 28574462Salfred addr->sin_port = htons(PMAPPORT); 28674462Salfred addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 28774462Salfred return (0); 28874462Salfred} 28974462Salfred 29074462Salfred/* 29174462Salfred * For connectionless "udp" transport. Obsoleted by rpc_call(). 29274462Salfred */ 29374462Salfredint 294309489Sngiecallrpc(const char *host, int prognum, int versnum, int procnum, 295309489Sngie xdrproc_t inproc, void *in, xdrproc_t outproc, void *out) 29674462Salfred{ 29774462Salfred 29874462Salfred return (int)rpc_call(host, (rpcprog_t)prognum, (rpcvers_t)versnum, 29974462Salfred (rpcproc_t)procnum, inproc, in, outproc, out, "udp"); 30074462Salfred} 30174462Salfred 30274462Salfred/* 30374462Salfred * For connectionless kind of transport. Obsoleted by rpc_reg() 30474462Salfred */ 30574462Salfredint 306309489Sngieregisterrpc(int prognum, int versnum, int procnum, 307309489Sngie char *(*progname)(char [UDPMSGSIZE]), 308309489Sngie xdrproc_t inproc, xdrproc_t outproc) 30974462Salfred{ 31074462Salfred 31174462Salfred return rpc_reg((rpcprog_t)prognum, (rpcvers_t)versnum, 31274462Salfred (rpcproc_t)procnum, progname, inproc, outproc, "udp"); 31374462Salfred} 31474462Salfred 31574462Salfred/* 31674462Salfred * All the following clnt_broadcast stuff is convulated; it supports 31774462Salfred * the earlier calling style of the callback function 31874462Salfred */ 31974462Salfredstatic thread_key_t clnt_broadcast_key; 32074462Salfredstatic resultproc_t clnt_broadcast_result_main; 321204950Sjhbstatic once_t clnt_broadcast_once = ONCE_INITIALIZER; 32274462Salfred 323204950Sjhbstatic void 324204950Sjhbclnt_broadcast_key_init(void) 325204950Sjhb{ 326204950Sjhb 327204950Sjhb thr_keycreate(&clnt_broadcast_key, free); 328204950Sjhb} 329204950Sjhb 33074462Salfred/* 33174462Salfred * Need to translate the netbuf address into sockaddr_in address. 33274462Salfred * Dont care about netid here. 33374462Salfred */ 33474462Salfred/* ARGSUSED */ 33574462Salfredstatic bool_t 336309489Sngierpc_wrap_bcast(char *resultp, struct netbuf *addr, struct netconfig *nconf) 337309489Sngie/* 338309489Sngie * char *resultp; // results of the call 339309489Sngie * struct netbuf *addr; // address of the guy who responded 340309489Sngie * struct netconfig *nconf; // Netconf of the transport 341309489Sngie */ 34274462Salfred{ 34374462Salfred resultproc_t clnt_broadcast_result; 34474462Salfred 34574462Salfred if (strcmp(nconf->nc_netid, "udp")) 34674462Salfred return (FALSE); 34774462Salfred if (thr_main()) 34874462Salfred clnt_broadcast_result = clnt_broadcast_result_main; 34974462Salfred else 35074462Salfred clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); 35174462Salfred return (*clnt_broadcast_result)(resultp, 35274462Salfred (struct sockaddr_in *)addr->buf); 35374462Salfred} 35474462Salfred 35574462Salfred/* 35674462Salfred * Broadcasts on UDP transport. Obsoleted by rpc_broadcast(). 35774462Salfred */ 35874462Salfredenum clnt_stat 359309489Sngieclnt_broadcast(u_long prog, u_long vers, u_long proc, xdrproc_t xargs, 360309489Sngie void *argsp, xdrproc_t xresults, void *resultsp, resultproc_t eachresult) 361309489Sngie/* 362309489Sngie * u_long prog; // program number 363309489Sngie * u_long vers; // version number 364309489Sngie * u_long proc; // procedure number 365309489Sngie * xdrproc_t xargs; // xdr routine for args 366309489Sngie * void *argsp; // pointer to args 367309489Sngie * xdrproc_t xresults; // xdr routine for results 368309489Sngie * void *resultsp; // pointer to results 369309489Sngie * resultproc_t eachresult; // call with each result obtained 370309489Sngie */ 37174462Salfred{ 37274462Salfred 37374462Salfred if (thr_main()) 37474462Salfred clnt_broadcast_result_main = eachresult; 37574462Salfred else { 376204950Sjhb thr_once(&clnt_broadcast_once, clnt_broadcast_key_init); 37774462Salfred thr_setspecific(clnt_broadcast_key, (void *) eachresult); 37874462Salfred } 37974462Salfred return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, 38074462Salfred (rpcproc_t)proc, xargs, argsp, xresults, resultsp, 38174462Salfred (resultproc_t) rpc_wrap_bcast, "udp"); 38274462Salfred} 38374462Salfred 38474462Salfred/* 38574462Salfred * Create the client des authentication object. Obsoleted by 38674462Salfred * authdes_seccreate(). 38774462Salfred */ 38874462SalfredAUTH * 389309489Sngieauthdes_create(char *servername, u_int window, struct sockaddr *syncaddr, 390309489Sngie des_block *ckey) 391309489Sngie/* 392309489Sngie * char *servername; // network name of server 393309489Sngie * u_int window; // time to live 394309489Sngie * struct sockaddr *syncaddr; // optional hostaddr to sync with 395309489Sngie * des_block *ckey; // optional conversation key to use 396309489Sngie */ 39774462Salfred{ 39874462Salfred AUTH *dummy; 39974462Salfred AUTH *nauth; 40074462Salfred char hostname[NI_MAXHOST]; 40174462Salfred 40274462Salfred if (syncaddr) { 40374462Salfred /* 40474462Salfred * Change addr to hostname, because that is the way 40574462Salfred * new interface takes it. 40674462Salfred */ 40774462Salfred if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, 40874462Salfred sizeof hostname, NULL, 0, 0) != 0) 40974462Salfred goto fallback; 41074462Salfred 41174462Salfred nauth = authdes_seccreate(servername, window, hostname, ckey); 41274462Salfred return (nauth); 41374462Salfred } 41474462Salfredfallback: 41574462Salfred dummy = authdes_seccreate(servername, window, NULL, ckey); 41674462Salfred return (dummy); 41774462Salfred} 41874462Salfred 41984487Swpaul/* 42084487Swpaul * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() 42184487Swpaul */ 42284487SwpaulCLIENT * 423309489Sngieclntunix_create(struct sockaddr_un *raddr, u_long prog, u_long vers, int *sockp, 424309489Sngie u_int sendsz, u_int recvsz) 42584487Swpaul{ 42684487Swpaul struct netbuf *svcaddr; 42784487Swpaul CLIENT *cl; 42884487Swpaul int len; 42984487Swpaul 43090271Salfred cl = NULL; 43190271Salfred svcaddr = NULL; 43284487Swpaul if ((raddr->sun_len == 0) || 43384487Swpaul ((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || 43484487Swpaul ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { 435290899Sngie free(svcaddr); 43684487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 43784487Swpaul rpc_createerr.cf_error.re_errno = errno; 43884487Swpaul return(cl); 43984487Swpaul } 44084487Swpaul if (*sockp < 0) { 44184487Swpaul *sockp = _socket(AF_LOCAL, SOCK_STREAM, 0); 44284487Swpaul len = raddr->sun_len = SUN_LEN(raddr); 44384487Swpaul if ((*sockp < 0) || (_connect(*sockp, 44484487Swpaul (struct sockaddr *)raddr, len) < 0)) { 44584487Swpaul rpc_createerr.cf_stat = RPC_SYSTEMERROR; 44684487Swpaul rpc_createerr.cf_error.re_errno = errno; 44784487Swpaul if (*sockp != -1) 44884487Swpaul (void)_close(*sockp); 44984487Swpaul goto done; 45084487Swpaul } 45184487Swpaul } 45284487Swpaul svcaddr->buf = raddr; 45384487Swpaul svcaddr->len = raddr->sun_len; 45484487Swpaul svcaddr->maxlen = sizeof (struct sockaddr_un); 45584487Swpaul cl = clnt_vc_create(*sockp, svcaddr, prog, 45684487Swpaul vers, sendsz, recvsz); 45784487Swpauldone: 45884487Swpaul free(svcaddr->buf); 45984487Swpaul free(svcaddr); 46084487Swpaul return(cl); 46184487Swpaul} 46284487Swpaul 46384487Swpaul/* 46484487Swpaul * Creates, registers, and returns a (rpc) unix based transporter. 46584487Swpaul * Obsoleted by svc_vc_create(). 46684487Swpaul */ 46784487SwpaulSVCXPRT * 468309489Sngiesvcunix_create(int sock, u_int sendsize, u_int recvsize, char *path) 46984487Swpaul{ 47084487Swpaul struct netconfig *nconf; 47184487Swpaul void *localhandle; 47284487Swpaul struct sockaddr_un sun; 47384487Swpaul struct sockaddr *sa; 47484487Swpaul struct t_bind taddr; 47584487Swpaul SVCXPRT *xprt; 47684487Swpaul int addrlen; 47784487Swpaul 47884487Swpaul xprt = (SVCXPRT *)NULL; 47984487Swpaul localhandle = setnetconfig(); 48084487Swpaul while ((nconf = getnetconfig(localhandle)) != NULL) { 48184487Swpaul if (nconf->nc_protofmly != NULL && 48284487Swpaul strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 48384487Swpaul break; 48484487Swpaul } 48584487Swpaul if (nconf == NULL) 486294239Sngie goto done; 48784487Swpaul 48884487Swpaul if ((sock = __rpc_nconf2fd(nconf)) < 0) 48984487Swpaul goto done; 49084487Swpaul 49184487Swpaul memset(&sun, 0, sizeof sun); 49284487Swpaul sun.sun_family = AF_LOCAL; 493114443Snectar if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 49484487Swpaul sizeof(sun.sun_path)) 49584487Swpaul goto done; 49684487Swpaul sun.sun_len = SUN_LEN(&sun); 49784487Swpaul addrlen = sizeof (struct sockaddr_un); 49884487Swpaul sa = (struct sockaddr *)&sun; 49984487Swpaul 50084487Swpaul if (_bind(sock, sa, addrlen) < 0) 50184487Swpaul goto done; 50284487Swpaul 50384487Swpaul taddr.addr.len = taddr.addr.maxlen = addrlen; 50484487Swpaul taddr.addr.buf = malloc(addrlen); 50584487Swpaul if (taddr.addr.buf == NULL) 50684487Swpaul goto done; 50784487Swpaul memcpy(taddr.addr.buf, sa, addrlen); 50884487Swpaul 50984487Swpaul if (nconf->nc_semantics != NC_TPI_CLTS) { 51084487Swpaul if (_listen(sock, SOMAXCONN) < 0) { 51184487Swpaul free(taddr.addr.buf); 51284487Swpaul goto done; 51384487Swpaul } 51484487Swpaul } 51584487Swpaul 51684487Swpaul xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); 51784487Swpaul 51884487Swpauldone: 51984487Swpaul endnetconfig(localhandle); 52084487Swpaul return(xprt); 52184487Swpaul} 52284487Swpaul 52384487Swpaul/* 52484487Swpaul * Like svunix_create(), except the routine takes any *open* UNIX file 52584487Swpaul * descriptor as its first input. Obsoleted by svc_fd_create(); 52684487Swpaul */ 52784487SwpaulSVCXPRT * 528309489Sngiesvcunixfd_create(int fd, u_int sendsize, u_int recvsize) 52984487Swpaul{ 53084487Swpaul return (svc_fd_create(fd, sendsize, recvsize)); 53184487Swpaul} 53284487Swpaul 53374462Salfred#endif /* PORTMAP */ 534