/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley
* 4.3 BSD under license from the Regents of the University of
* California.
*/
#include "mt.h"
#include "rpc_mt.h"
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdir.h>
#include <string.h>
#include <syslog.h>
extern int __td_setnodelay(int);
extern bool_t __rpc_is_local_host(const char *);
#ifndef NETIDLEN
#endif
/*
* Generic client creation with version checking the value of
* vers_out is set to the highest server supported value
* vers_low <= vers_out <= vers_high AND an error results
* if this can not be done.
*
* It calls clnt_create_vers_timed() with a NULL value for the timeout
* pointer, which indicates that the default timeout should be used.
*/
CLIENT *
{
}
/*
* This routine has the same definition as clnt_create_vers(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*/
CLIENT *
{
return (NULL);
} else
if (rpc_stat == RPC_SUCCESS) {
return (clnt);
}
else
v_high--;
goto error;
}
if (rpc_stat == RPC_SUCCESS) {
return (clnt);
}
}
return (NULL);
}
/*
* Top level client creation routine.
* Generic client creation: takes (servers name, program-number, nettype) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of ioctl()'s.
*
* It tries for all the netids in that particular class of netid until
* it succeeds.
* XXX The error message in the case of failure will be the one
* pertaining to the last create error.
*
* It calls clnt_create_timed() with the default timeout.
*/
CLIENT *
const char *nettype)
{
}
/*
* This the routine has the same definition as clnt_create(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*
* This function calls clnt_tp_create_timed().
*/
CLIENT *
{
void *handle;
else {
if (len >= sizeof (nettype_array)) {
return (NULL);
}
}
/*
* Check to see if a rendezvous over doors should be attempted.
*/
/*
* Make sure this is the local host.
*/
if (__rpc_is_local_host(hostname)) {
return (clnt);
else {
return (NULL);
}
} else {
}
}
if (!try_others)
return (NULL);
return (NULL);
}
break;
}
if (clnt)
break;
else {
/*
* Since we didn't get a name-to-address
* translation failure here, we remember
* this particular error. The object of
* this is to enable us to return to the
* caller a more-specific error than the
* unhelpful ``Name to address translation
* failed'' which might well occur if we
* merely returned the last error (because
* the local loopbacks are typically the
* likely to be unable to translate a host
* name). We also check for a more
* meaningful error than ``unknown host
* name'' for the same reasons.
*/
"RPC_SYSTEMERROR.");
break;
}
}
}
}
/*
* Attempt to return an error more specific than ``Name to address
* translation failed'' or ``unknown host name''
*/
(save_cf_stat != RPC_SUCCESS)) {
}
return (clnt);
}
/*
* Create a client handle for a well known service or a specific port on
* host. This routine bypasses rpcbind and can be use to construct a client
* handle to services that are not registered with rpcbind or where the remote
* rpcbind is not available, e.g., the remote rpcbind port is blocked by a
* firewall. We construct a client handle and then ping the service's NULL
* proc to see that the service is really available. If the caller supplies
* a non zero port number, the service name is ignored and the port will be
* used. A non-zero port number limits the protocol family to inet or inet6.
*/
CLIENT *
{
int fd;
void *handle;
/*
* handle const of netclass
*/
else {
if (len >= sizeof (nettype_array)) {
return (NULL);
}
}
} else
return (NULL);
}
/*
* Sinct host, and service are const
*/
return (NULL);
}
return (NULL);
}
/*
* Check to see if a rendezvous over doors should be attempted.
*/
/*
* Make sure this is the local host.
*/
if (__rpc_is_local_host(hostname)) {
goto done;
goto done;
} else {
}
}
if (!try_others)
goto done;
break;
}
if (port) {
continue;
}
continue;
}
== NULL) {
continue;
}
if (tbind)
continue;
}
if (port) {
((struct sockaddr_in *)
((struct sockaddr_in6 *)
}
if (tbind)
continue;
}
/*
* Check if we can reach the server with this clnt handle
* Other clnt_create calls do a ping by contacting the
* remote rpcbind, here will just try to execute the service's
* NULL proc.
*/
if (tbind)
continue;
} else
break;
}
if (tbind)
done:
if (hostname)
if (serv)
return (clnt);
}
/*
* Generic client creation: takes (servers name, program-number, netconf) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of ioctl()'s : clnt_control()
* It finds out the server address from rpcbind and calls clnt_tli_create().
*
* It calls clnt_tp_create_timed() with the default timeout.
*/
CLIENT *
{
}
/*
* This has the same definition as clnt_tp_create(), except it
* takes an additional parameter - a pointer to a timeval structure.
* A NULL value for the timeout pointer indicates that the default
* value for the timeout should be used.
*/
CLIENT *
{
return (NULL);
}
/*
* Get the address of the server
*/
/* appropriate error number is set by rpcbind libraries */
return (NULL);
}
} else {
/* Reuse the CLIENT handle and change the appropriate fields */
"clnt_tp_create_timed: "
"strdup failed.");
return (NULL);
}
}
"clnt_tp_create_timed: "
"strdup failed.");
return (NULL);
}
}
} else {
}
}
return (cl);
}
/*
* Generic client creation: returns client handle.
* Default options are set, which the user can
* change using the rpc equivalent of ioctl()'s : clnt_control().
* If fd is RPC_ANYFD, it will be opened using nconf.
* It will be bound if not so.
* If sizes are 0; appropriate defaults will be chosen.
*/
CLIENT *
{
}
/*
* This has the same definition as clnt_tli_create(), except it
* takes an additional parameter - a pointer to a timeval structure.
*
* Not a public interface. This is for clnt_create_timed,
* clnt_create_vers_times, clnt_tp_create_timed to pass down the
* timeout value to COTS creation routine.
* (for bug 4049792: clnt_create_timed does not time out)
*/
CLIENT *
{
int retval;
return (NULL);
}
if (fd == -1)
goto err;
goto err;
switch (nconf->nc_semantics) {
case NC_TPI_CLTS:
break;
case NC_TPI_COTS:
break;
case NC_TPI_COTS_ORD:
break;
default:
goto err;
break;
}
} else {
/*
* Sync the opened fd.
* Check whether bound or not, else bind it
*/
goto err;
}
switch (servtype) {
case T_COTS:
break;
case T_COTS_ORD:
if (retval == -1)
goto err;
}
break;
case T_CLTS:
break;
default:
goto err;
}
if (nconf) {
"clnt_tli_create: strdup failed");
goto err1;
}
"clnt_tli_create: strdup failed");
goto err1;
}
} else {
"clnt_tli_create: "
"strdup failed");
goto err1;
}
}
"clnt_tli_create: "
"strdup failed");
goto err1;
}
}
}
}
if (madefd) {
/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL); */
};
return (cl);
err:
return (NULL);
}
/*
* To avoid conflicts with the "magic" file descriptors (0, 1, and 2),
* we try to not use them. The __rpc_raise_fd() routine will dup
* a descriptor to a higher value. If we fail to do it, we continue
* to use the old one (and hope for the best).
*/
int
{
int nfd;
return (fd);
return (fd);
}
/* this is okay, we will syslog an error, then use the new fd */
"could not t_close() fd %d; mem & fd leak", fd);
}
return (nfd);
}