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