xref: /csrg-svn/lib/librpc/rpc/clnt_generic.c (revision 45075)
1*45075Smckusick /* @(#)clnt_generic.c	2.2 88/08/01 4.0 RPCSRC */
2*45075Smckusick /*
3*45075Smckusick  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4*45075Smckusick  * unrestricted use provided that this legend is included on all tape
5*45075Smckusick  * media and as a part of the software program in whole or part.  Users
6*45075Smckusick  * may copy or modify Sun RPC without charge, but are not authorized
7*45075Smckusick  * to license or distribute it to anyone else except as part of a product or
8*45075Smckusick  * program developed by the user.
9*45075Smckusick  *
10*45075Smckusick  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11*45075Smckusick  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12*45075Smckusick  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13*45075Smckusick  *
14*45075Smckusick  * Sun RPC is provided with no support and without any obligation on the
15*45075Smckusick  * part of Sun Microsystems, Inc. to assist in its use, correction,
16*45075Smckusick  * modification or enhancement.
17*45075Smckusick  *
18*45075Smckusick  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19*45075Smckusick  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20*45075Smckusick  * OR ANY PART THEREOF.
21*45075Smckusick  *
22*45075Smckusick  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23*45075Smckusick  * or profits or other special, indirect and consequential damages, even if
24*45075Smckusick  * Sun has been advised of the possibility of such damages.
25*45075Smckusick  *
26*45075Smckusick  * Sun Microsystems, Inc.
27*45075Smckusick  * 2550 Garcia Avenue
28*45075Smckusick  * Mountain View, California  94043
29*45075Smckusick  */
30*45075Smckusick #if !defined(lint) && defined(SCCSIDS)
31*45075Smckusick static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
32*45075Smckusick #endif
33*45075Smckusick /*
34*45075Smckusick  * Copyright (C) 1987, Sun Microsystems, Inc.
35*45075Smckusick  */
36*45075Smckusick #include <rpc/rpc.h>
37*45075Smckusick #include <sys/socket.h>
38*45075Smckusick #include <sys/errno.h>
39*45075Smckusick #include <netdb.h>
40*45075Smckusick 
41*45075Smckusick /*
42*45075Smckusick  * Generic client creation: takes (hostname, program-number, protocol) and
43*45075Smckusick  * returns client handle. Default options are set, which the user can
44*45075Smckusick  * change using the rpc equivalent of ioctl()'s.
45*45075Smckusick  */
46*45075Smckusick CLIENT *
clnt_create(hostname,prog,vers,proto)47*45075Smckusick clnt_create(hostname, prog, vers, proto)
48*45075Smckusick 	char *hostname;
49*45075Smckusick 	unsigned prog;
50*45075Smckusick 	unsigned vers;
51*45075Smckusick 	char *proto;
52*45075Smckusick {
53*45075Smckusick 	struct hostent *h;
54*45075Smckusick 	struct protoent *p;
55*45075Smckusick 	struct sockaddr_in sin;
56*45075Smckusick 	int sock;
57*45075Smckusick 	struct timeval tv;
58*45075Smckusick 	CLIENT *client;
59*45075Smckusick 
60*45075Smckusick 	h = gethostbyname(hostname);
61*45075Smckusick 	if (h == NULL) {
62*45075Smckusick 		rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
63*45075Smckusick 		return (NULL);
64*45075Smckusick 	}
65*45075Smckusick 	if (h->h_addrtype != AF_INET) {
66*45075Smckusick 		/*
67*45075Smckusick 		 * Only support INET for now
68*45075Smckusick 		 */
69*45075Smckusick 		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
70*45075Smckusick 		rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
71*45075Smckusick 		return (NULL);
72*45075Smckusick 	}
73*45075Smckusick 	sin.sin_family = h->h_addrtype;
74*45075Smckusick 	sin.sin_port = 0;
75*45075Smckusick 	bzero(sin.sin_zero, sizeof(sin.sin_zero));
76*45075Smckusick 	bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length);
77*45075Smckusick 	p = getprotobyname(proto);
78*45075Smckusick 	if (p == NULL) {
79*45075Smckusick 		rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
80*45075Smckusick 		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
81*45075Smckusick 		return (NULL);
82*45075Smckusick 	}
83*45075Smckusick 	sock = RPC_ANYSOCK;
84*45075Smckusick 	switch (p->p_proto) {
85*45075Smckusick 	case IPPROTO_UDP:
86*45075Smckusick 		tv.tv_sec = 5;
87*45075Smckusick 		tv.tv_usec = 0;
88*45075Smckusick 		client = clntudp_create(&sin, prog, vers, tv, &sock);
89*45075Smckusick 		if (client == NULL) {
90*45075Smckusick 			return (NULL);
91*45075Smckusick 		}
92*45075Smckusick 		tv.tv_sec = 25;
93*45075Smckusick 		clnt_control(client, CLSET_TIMEOUT, &tv);
94*45075Smckusick 		break;
95*45075Smckusick 	case IPPROTO_TCP:
96*45075Smckusick 		client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
97*45075Smckusick 		if (client == NULL) {
98*45075Smckusick 			return (NULL);
99*45075Smckusick 		}
100*45075Smckusick 		tv.tv_sec = 25;
101*45075Smckusick 		tv.tv_usec = 0;
102*45075Smckusick 		clnt_control(client, CLSET_TIMEOUT, &tv);
103*45075Smckusick 		break;
104*45075Smckusick 	default:
105*45075Smckusick 		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
106*45075Smckusick 		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
107*45075Smckusick 		return (NULL);
108*45075Smckusick 	}
109*45075Smckusick 	return (client);
110*45075Smckusick }
111