Back to index

glibc  2.9
clnt_simp.c
Go to the documentation of this file.
00001 /* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */
00002 /*
00003  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00004  * unrestricted use provided that this legend is included on all tape
00005  * media and as a part of the software program in whole or part.  Users
00006  * may copy or modify Sun RPC without charge, but are not authorized
00007  * to license or distribute it to anyone else except as part of a product or
00008  * program developed by the user.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 #if !defined(lint) && defined(SCCSIDS)
00031 static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
00032 #endif
00033 
00034 /*
00035  * clnt_simple.c
00036  * Simplified front end to rpc.
00037  *
00038  * Copyright (C) 1984, Sun Microsystems, Inc.
00039  */
00040 
00041 #include <alloca.h>
00042 #include <errno.h>
00043 #include <stdio.h>
00044 #include <unistd.h>
00045 #include <rpc/rpc.h>
00046 #include <sys/socket.h>
00047 #include <netdb.h>
00048 #include <string.h>
00049 
00050 struct callrpc_private_s
00051   {
00052     CLIENT *client;
00053     int socket;
00054     u_long oldprognum, oldversnum, valid;
00055     char *oldhost;
00056   };
00057 #ifdef _RPC_THREAD_SAFE_
00058 #define callrpc_private RPC_THREAD_VARIABLE(callrpc_private_s)
00059 #else
00060 static struct callrpc_private_s *callrpc_private;
00061 #endif
00062 
00063 int
00064 callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
00065         xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
00066 {
00067   struct callrpc_private_s *crp = callrpc_private;
00068   struct sockaddr_in server_addr;
00069   enum clnt_stat clnt_stat;
00070   struct hostent hostbuf, *hp;
00071   struct timeval timeout, tottimeout;
00072 
00073   if (crp == 0)
00074     {
00075       crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
00076       if (crp == 0)
00077        return 0;
00078       callrpc_private = crp;
00079     }
00080   if (crp->oldhost == NULL)
00081     {
00082       crp->oldhost = malloc (256);
00083       crp->oldhost[0] = 0;
00084       crp->socket = RPC_ANYSOCK;
00085     }
00086   if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
00087       && strcmp (crp->oldhost, host) == 0)
00088     {
00089       /* reuse old client */
00090     }
00091   else
00092     {
00093       size_t buflen;
00094       char *buffer;
00095       int herr;
00096 
00097       crp->valid = 0;
00098       if (crp->socket != RPC_ANYSOCK)
00099        {
00100          (void) __close (crp->socket);
00101          crp->socket = RPC_ANYSOCK;
00102        }
00103       if (crp->client)
00104        {
00105          clnt_destroy (crp->client);
00106          crp->client = NULL;
00107        }
00108 
00109       buflen = 1024;
00110       buffer = __alloca (buflen);
00111       while (__gethostbyname_r (host, &hostbuf, buffer, buflen,
00112                             &hp, &herr) != 0
00113             || hp == NULL)
00114        if (herr != NETDB_INTERNAL || errno != ERANGE)
00115          return (int) RPC_UNKNOWNHOST;
00116        else
00117          {
00118            /* Enlarge the buffer.  */
00119            buflen *= 2;
00120            buffer = __alloca (buflen);
00121          }
00122 
00123       timeout.tv_usec = 0;
00124       timeout.tv_sec = 5;
00125       memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length);
00126       server_addr.sin_family = AF_INET;
00127       server_addr.sin_port = 0;
00128       if ((crp->client = INTUSE(clntudp_create) (&server_addr, (u_long) prognum,
00129                        (u_long) versnum, timeout, &crp->socket)) == NULL)
00130        return (int) get_rpc_createerr().cf_stat;
00131       crp->valid = 1;
00132       crp->oldprognum = prognum;
00133       crp->oldversnum = versnum;
00134       (void) strncpy (crp->oldhost, host, 255);
00135       crp->oldhost[255] = '\0';
00136     }
00137   tottimeout.tv_sec = 25;
00138   tottimeout.tv_usec = 0;
00139   clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in,
00140                       outproc, out, tottimeout);
00141   /*
00142    * if call failed, empty cache
00143    */
00144   if (clnt_stat != RPC_SUCCESS)
00145     crp->valid = 0;
00146   return (int) clnt_stat;
00147 }
00148 
00149 #ifdef _RPC_THREAD_SAFE_
00150 void
00151 __rpc_thread_clnt_cleanup (void)
00152 {
00153        struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s);
00154 
00155        if (rcp) {
00156               if (rcp->client)
00157                      CLNT_DESTROY (rcp->client);
00158               free (rcp);
00159        }
00160 }
00161 #endif /* _RPC_THREAD_SAFE_ */