 /*
  * try - program to try out host access-control tables, including the
  * optional shell commands.
  * 
  * usage: try process_name host_name_or_address
  * 
  * where process_name is a daemon process name (argv[0] value). If a host name
  * is specified, both the name and address will be used to check the address
  * control tables. If a host address is specified, the program pretends that
  * host name lookup failed.
  * 
  * Most errors will be reported to the syslog daemon, so you'd better keep a
  * tail on the logfile.
  */

#ifndef lint
static char sccsid[] = "@(#) try.c 1.3 93/03/07 22:47:43";
#endif

#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <syslog.h>

#ifdef HOSTS_ACCESS

#ifndef	INADDR_NONE
#define	INADDR_NONE	(-1)		/* XXX should be 0xffffffff */
#endif

#include "log_tcp.h"

#ifdef INET_ADDR_BUG
#include "inet_addr_fix"
#endif

int     log_severity = SEVERITY;	/* run-time adjustable */

/* Try out a (daemon,client) pair */

try(daemon, name, addr)
char   *daemon;
char   *name;
char   *addr;
{
    printf(" Daemon:   %s\n", daemon);
    printf(" Hostname: %s\n", name);
    printf(" Address:  %s\n", addr);
    printf(" Access:   %s\n",
	   hosts_ctl(daemon, name, addr, "you") ? "granted" : "denied");
}

/* function to intercept the real shell_cmd() */

void    shell_cmd(cmd, daemon, client)
char   *cmd;
char   *daemon;
struct from_host *client;
{
    char    buf[BUFSIZ];
    int     pid = getpid();

    percent_x(buf, sizeof(buf), cmd, daemon, client, pid);
    printf(" Command:  %s\n", buf);
}

/* function to intercept the real process_options() */

process_options(options, daemon, client)
char   *options;
char   *daemon;
struct from_host *client;
{
    char    buf[BUFSIZ];
    int     pid = getpid();

    percent_x(buf, sizeof(buf), options, daemon, client, pid);
    printf(" Options:  %s\n", buf);
}

main(argc, argv)
int     argc;
char  **argv;
{
    struct hostent *hp;

#ifdef LOG_MAIL
    openlog(argv[0], LOG_PID, FACILITY);
#else
    openlog(argv[0], LOG_PID);
#endif

    /*
     * Abuse inet_addr() to find out if a host name or address was specified.
     * 
     * If a host address is specified, pretend that the host name lookup failed.
     * This allows us to simulate the effect of host name lookup failures.
     * 
     * If a host name is specified, insist that the address is known. The reason
     * for giving up is that in real life, a host address is always
     * available.
     */

    if (argc != 3) {
	fprintf(stderr, "usage: %s process_name host_name_or_address\n",
		argv[0]);
	return (1);
    }
    if (inet_addr(argv[2]) != INADDR_NONE) {	/* address specified */
	try(argv[1], FROM_UNKNOWN, argv[2]);
	return (0);
    }
    if ((hp = gethostbyname(argv[2])) == 0) {	/* address lookup fails */
	fprintf(stderr, "host %s: address lookup failed\n", argv[2]);
	return (1);
    }
    while (hp->h_addr_list[0])			/* name and address known */
	try(argv[1], hp->h_name,
	    inet_ntoa(*(struct in_addr *) * hp->h_addr_list++));
    return (0);
}

#else

main()
{
    fprintf(stderr, "host access control is not enabled.\n");
    return (1);
}

#endif
