4.3BSD-UWisc/src/usr.etc/yp/ypset.c
#ifndef lint
/* @(#)ypset.c 2.1 86/04/16 NFSSRC */
static char sccsid[] = "@(#)ypset.c 1.1 86/02/05 Copyr 1985 Sun Micro";
#endif
/*
* This is a user command which issues a "Set domain binding" command to a
* yellowpages binder (ypbind) process
*
* ypset [-V1] [-h <host>] [-d <domainname>] server_to_use
*
* where host and server_to_use may be either names or internet addresses.
*/
#include <stdio.h>
#include <sys/time.h>
#include <ctype.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypv1_prot.h>
#ifdef NULL
#undef NULL
#endif
#define NULL 0
#define TIMEOUT 30 /* Total seconds for timeout */
#define INTER_TRY 10 /* Seconds between tries */
bool oldvers = FALSE;
char *pusage;
char *domain = NULL;
char default_domain_name[YPMAXDOMAIN];
char default_host_name[256];
char *host = NULL;
struct in_addr host_addr;
char *server_to_use;
struct in_addr server_to_use_addr;
struct timeval udp_intertry = {
INTER_TRY, /* Seconds */
0 /* Microseconds */
};
struct timeval udp_timeout = {
TIMEOUT, /* Seconds */
0 /* Microseconds */
};
char err_usage_set[] =
"Usage:\n\
ypset [-V1] [-h <host>] [-d <domainname>] server_to_use\n\n\
where host and server_to_use may be either names or internet \n\
addresses of form ww.xx.yy.zz\n";
char err_cant_find_server_addr[] =
"Sorry, I can't get an address for host %s from the yellow pages.\n";
char err_cant_decipher_server_addr[] =
"Sorry, I got a garbage address for host %s back from the yellow pages.\n";
char err_bad_args[] =
"Sorry, the %s argument is bad.\n";
char err_cant_get_kname[] =
"Sorry, can't get %s back from system call.\n";
char err_null_kname[] =
"Sorry, the %s hasn't been set on this machine.\n";
char err_bad_hostname[] = "hostname";
char err_bad_domainname[] = "domainname";
char err_bad_server[] = "server_to_use";
char err_cant_bind[] =
"Sorry, I can't make use of the yellow pages. I give up.\n";
char err_udp_failure[] =
"Sorry, I can't set up a udp connection to ypbind on host %s.\n";
char err_rpc_failure[] =
"Sorry, I couldn't send my rpc message to ypbind on host %s.\n";
void get_command_line_args();
void get_host_addr();
void send_message();
/*
* Funny external reference to inet_addr to make the reference agree with the
* code, not the documentation. Should be:
* extern struct in_addr inet_addr();
* according to the documentation, but that's not what the code does.
*/
extern u_long inet_addr();
/*
* This is the mainline for the ypset process. It pulls whatever arguments
* have been passed from the command line, and uses defaults for the rest.
*/
void
main (argc, argv)
int argc;
char **argv;
{
struct sockaddr_in myaddr;
get_command_line_args(argc, argv);
if (!domain) {
if (!getdomainname(default_domain_name, YPMAXDOMAIN) ) {
domain = default_domain_name;
} else {
fprintf(stderr, err_cant_get_kname, err_bad_domainname);
exit(1);
}
if (strlen(domain) == 0) {
fprintf(stderr, err_null_kname, err_bad_domainname);
exit(1);
}
}
if (!host) {
if (! gethostname(default_host_name, 256)) {
host = default_host_name;
} else {
fprintf(stderr, err_cant_get_kname, err_bad_hostname);
exit(1);
}
get_myaddress(&myaddr);
host_addr = myaddr.sin_addr;
} else {
get_host_addr(host, &host_addr);
}
get_host_addr(server_to_use, &server_to_use_addr);
send_message();
exit(0);
}
/*
* This does the command line argument processing.
*/
void
get_command_line_args(argc, argv)
int argc;
char **argv;
{
pusage = err_usage_set;
argv++;
while (--argc > 1) {
if ( (*argv)[0] == '-') {
switch ((*argv)[1]) {
case 'V':
if ((*argv)[2] == '1') {
oldvers = TRUE;
argv++;
break;
} else {
fprintf(stderr, pusage);
exit(1);
}
case 'h': {
if (argc > 1) {
argv++;
argc--;
host = *argv;
argv++;
if (strlen(host) > 256) {
fprintf(stderr, err_bad_args,
err_bad_hostname);
exit(1);
}
} else {
fprintf(stderr, pusage);
exit(1);
}
break;
}
case 'd': {
if (argc > 1) {
argv++;
argc--;
domain = *argv;
argv++;
if (strlen(domain) > YPMAXDOMAIN) {
fprintf(stderr, err_bad_args,
err_bad_domainname);
exit(1);
}
} else {
fprintf(stderr, pusage);
exit(1);
}
break;
}
default: {
fprintf(stderr, pusage);
exit(1);
}
}
} else {
fprintf(stderr, pusage);
exit(1);
}
}
if (argc == 1) {
if ( (*argv)[0] == '-') {
fprintf(stderr, pusage);
exit(1);
}
server_to_use = *argv;
if (strlen(server_to_use) > 256) {
fprintf(stderr, err_bad_args,
err_bad_server);
exit(1);
}
} else {
fprintf(stderr, pusage);
exit(1);
}
}
/*
* This gets an address for the host to which the request will be directed,
* or the host to be used as the yp server.
*
* If the first character of the host string is a digit, it calls inet_addr(3)
* to do the translation. If that fails, it then tries to contact the yellow
* pages (any server) and tries to get a match on the host name. It then calls
* inet_addr to turn the returned string (equivalent to that which is in
* /etc/hosts) to an internet address.
*/
void
get_host_addr(name, addr)
char *name;
struct in_addr *addr;
{
char *ascii_addr;
int addr_len;
struct in_addr tempaddr;
if (isdigit(*name) ) {
tempaddr.s_addr = inet_addr(name);
if ((int) tempaddr.s_addr != -1) {
*addr = tempaddr;
return;
}
}
if (!yp_bind(domain) ) {
if (!yp_match (domain, "hosts.byname", name, strlen(name),
&ascii_addr, &addr_len) ) {
tempaddr.s_addr = inet_addr(ascii_addr);
if ((int) tempaddr.s_addr != -1) {
*addr = tempaddr;
} else {
fprintf(stderr, err_cant_decipher_server_addr,
name);
exit(1);
}
} else {
fprintf(stderr, err_cant_find_server_addr, name);
exit(1);
}
} else {
fprintf(stderr, err_cant_bind);
exit(1);
}
}
/*
* This takes the internet address of the yellow pages host of interest,
* and fires off the "set domain binding" message to the ypbind process.
*/
void
send_message()
{
struct dom_binding domb;
struct ypbind_setdom req;
struct ypbind_oldsetdom oldreq;
enum clnt_stat clnt_stat;
int vers;
vers = oldvers ? YPBINDOLDVERS : YPBINDVERS;
domb.dom_server_addr.sin_addr = host_addr;
domb.dom_server_addr.sin_family = AF_INET;
domb.dom_server_addr.sin_port = 0;
domb.dom_server_port = 0;
domb.dom_socket = RPC_ANYSOCK;
/*
* Open up a udp path to the server
*/
if ((domb.dom_client = clntudp_create(&(domb.dom_server_addr),
YPBINDPROG, vers, udp_intertry, &(domb.dom_socket))) == NULL) {
fprintf(stderr, err_udp_failure, host);
exit(1);
}
/*
* Load up the message structure and fire it off.
*/
if (oldvers) {
strcpy(oldreq.ypoldsetdom_domain, domain);
oldreq.ypoldsetdom_addr = server_to_use_addr;
oldreq.ypoldsetdom_port = 0;
if( (clnt_stat = (enum clnt_stat) clnt_call(domb.dom_client,
YPBINDPROC_SETDOM, _xdr_ypbind_oldsetdom, &oldreq,
xdr_void, 0, udp_timeout) ) != RPC_SUCCESS) {
fprintf(stderr, err_rpc_failure, host);
exit(1);
}
} else {
strcpy(req.ypsetdom_domain, domain);
req.ypsetdom_addr = server_to_use_addr;
req.ypsetdom_port = 0;
req.ypsetdom_vers = YPVERS;
if( (clnt_stat = (enum clnt_stat) clnt_call(domb.dom_client,
YPBINDPROC_SETDOM, xdr_ypbind_setdom, &req, xdr_void, 0,
udp_timeout) ) != RPC_SUCCESS) {
fprintf(stderr, err_rpc_failure, host);
exit(1);
}
}
}