Пример #1
0
int
getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto)
{
  struct sockaddr_in addr;
  struct hostent hostbuf, *hp;
  size_t buflen;
  char *buffer;
  int herr;

  buflen = 1024;
  buffer = __alloca (buflen);
  while (__gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr) != 0
	 || hp == NULL)
    if (herr != NETDB_INTERNAL || errno != ERANGE)
      return 0;
    else
      {
	/* Enlarge the buffer.  */
	buflen *= 2;
	buffer = __alloca (buflen);
      }

  memcpy ((char *) &addr.sin_addr, hp->h_addr, hp->h_length);
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  return pmap_getport (&addr, prognum, versnum, proto);
}
Пример #2
0
/*
 * Generic client creation: takes (hostname, program-number, protocol) and
 * returns client handle. Default options are set, which the user can
 * change using the rpc equivalent of ioctl()'s.
 */
CLIENT *
clnt_create (const char *hostname, u_long prog, u_long vers,
	     const char *proto)
{
  struct hostent hostbuf, *h;
  size_t hstbuflen;
  char *hsttmpbuf;
  struct protoent protobuf, *p;
  size_t prtbuflen;
  char *prttmpbuf;
  struct sockaddr_in sin;
  struct sockaddr_un sun;
  int sock;
  struct timeval tv;
  CLIENT *client;
  int herr;

  if (strcmp (proto, "unix") == 0)
    {
      __bzero ((char *)&sun, sizeof (sun));
      sun.sun_family = AF_UNIX;
      strcpy (sun.sun_path, hostname);
      sock = RPC_ANYSOCK;
      client = INTUSE(clntunix_create) (&sun, prog, vers, &sock, 0, 0);
      if (client == NULL)
	return NULL;
#if 0
      /* This is not wanted.  This would disable the user from having
	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
	 by the user should set the timeout value.  */
      tv.tv_sec = 25;
      tv.tv_usec = 0;
      clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
#endif
      return client;
    }

  hstbuflen = 1024;
  hsttmpbuf = __alloca (hstbuflen);
  while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen,
			    &h, &herr) != 0
	 || h == NULL)
    if (herr != NETDB_INTERNAL || errno != ERANGE)
      {
	get_rpc_createerr().cf_stat = RPC_UNKNOWNHOST;
	return NULL;
      }
    else
      {
	/* Enlarge the buffer.  */
	hstbuflen *= 2;
	hsttmpbuf = __alloca (hstbuflen);
      }

  if (h->h_addrtype != AF_INET)
    {
      /*
       * Only support INET for now
       */
      struct rpc_createerr *ce = &get_rpc_createerr ();
      ce->cf_stat = RPC_SYSTEMERROR;
      ce->cf_error.re_errno = EAFNOSUPPORT;
      return NULL;
    }
  sin.sin_family = h->h_addrtype;
  sin.sin_port = 0;
  __bzero (sin.sin_zero, sizeof (sin.sin_zero));
  memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);

  prtbuflen = 1024;
  prttmpbuf = __alloca (prtbuflen);
  while (__getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
	 || p == NULL)
    if (errno != ERANGE)
      {
	struct rpc_createerr *ce = &get_rpc_createerr ();
	ce->cf_stat = RPC_UNKNOWNPROTO;
	ce->cf_error.re_errno = EPFNOSUPPORT;
	return NULL;
      }
    else
      {
	/* Enlarge the buffer.  */
	prtbuflen *= 2;
	prttmpbuf = __alloca (prtbuflen);
      }

  sock = RPC_ANYSOCK;
  switch (p->p_proto)
    {
    case IPPROTO_UDP:
      tv.tv_sec = 5;
      tv.tv_usec = 0;
      client = INTUSE(clntudp_create) (&sin, prog, vers, tv, &sock);
      if (client == NULL)
	{
	  return NULL;
	}
#if 0
      /* This is not wanted.  This would disable the user from having
	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
	 by the user should set the timeout value.  */
      tv.tv_sec = 25;
      clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
#endif
      break;
    case IPPROTO_TCP:
      client = INTUSE(clnttcp_create) (&sin, prog, vers, &sock, 0, 0);
      if (client == NULL)
	{
	  return NULL;
	}
#if 0
      /* This is not wanted.  This would disable the user from having
	 a timeout in the clnt_call() call.  Only a call to cnlt_control()
	 by the user should set the timeout value.  */
      tv.tv_sec = 25;
      tv.tv_usec = 0;
      clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
#endif
      break;
    default:
      {
	struct rpc_createerr *ce = &get_rpc_createerr ();
	ce->cf_stat = RPC_SYSTEMERROR;
	ce->cf_error.re_errno = EPFNOSUPPORT;
      }
      return (NULL);
    }
  return client;
}
Пример #3
0
int
callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
	 xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
{
  struct callrpc_private_s *crp = callrpc_private;
  struct sockaddr_in server_addr;
  enum clnt_stat clnt_stat;
  struct hostent hostbuf, *hp;
  struct timeval timeout, tottimeout;

  if (crp == 0)
    {
      crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
      if (crp == 0)
	return 0;
      callrpc_private = crp;
    }
  if (crp->oldhost == NULL)
    {
      crp->oldhost = malloc (256);
      crp->oldhost[0] = 0;
      crp->socket = RPC_ANYSOCK;
    }
  if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
      && strcmp (crp->oldhost, host) == 0)
    {
      /* reuse old client */
    }
  else
    {
      size_t buflen;
      char *buffer;
      int herr;

      crp->valid = 0;
      if (crp->socket != RPC_ANYSOCK)
	{
	  (void) __close (crp->socket);
	  crp->socket = RPC_ANYSOCK;
	}
      if (crp->client)
	{
	  clnt_destroy (crp->client);
	  crp->client = NULL;
	}

      buflen = 1024;
      buffer = __alloca (buflen);
      while (__gethostbyname_r (host, &hostbuf, buffer, buflen,
				&hp, &herr) != 0
	     || hp == NULL)
	if (herr != NETDB_INTERNAL || errno != ERANGE)
	  return (int) RPC_UNKNOWNHOST;
	else
	  {
	    /* Enlarge the buffer.  */
	    buflen *= 2;
	    buffer = __alloca (buflen);
	  }

      timeout.tv_usec = 0;
      timeout.tv_sec = 5;
      memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length);
      server_addr.sin_family = AF_INET;
      server_addr.sin_port = 0;
      if ((crp->client = clntudp_create (&server_addr, (u_long) prognum,
			  (u_long) versnum, timeout, &crp->socket)) == NULL)
	return (int) get_rpc_createerr().cf_stat;
      crp->valid = 1;
      crp->oldprognum = prognum;
      crp->oldversnum = versnum;
      (void) strncpy (crp->oldhost, host, 255);
      crp->oldhost[255] = '\0';
    }
  tottimeout.tv_sec = 25;
  tottimeout.tv_usec = 0;
  clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in,
			 outproc, out, tottimeout);
  /*
   * if call failed, empty cache
   */
  if (clnt_stat != RPC_SUCCESS)
    crp->valid = 0;
  return (int) clnt_stat;
}