NFSv2/usr/src/usr.bin/ypcat.c

Compare this file to the similar file:
Show the results in this format:

#ifndef lint
static	char sccsid[] = "@(#)ypcat.c 1.1 85/05/31 Copyr 1984 Sun Micro";
#endif

/*
 * This is a user command which dumps each entry in a yp data base.  It gets
 * the stuff using the normal ypclnt package; the user doesn't get to choose
 * which server gives him the input.  Usage is:
 *	ypcat [-a] [-k] [-d domain] [-t] map
 * where the -a switch will dump all records in the map, including the yp
 * private symbols, the -k switch will dump keys followed by a single blank
 * space before the value, and the -d switch can be used to specify a domain
 * other than the default domain.

 * Normally, passwd gets converted to passwd.byname, and similarly
 * for the other standard files.  -t inhibits this translation
 */
#include <dbm.h>
#ifdef NULL
#undef NULL
#endif
#define NULL 0
#include <stdio.h>
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>

int dumpkeys = FALSE;
int translate = TRUE;
char *domain = NULL;
char default_domain_name[YPMAXDOMAIN];
char *map = NULL;
int (*getfirst) () = yp_first;
int (*getnext) () = yp_next;
char nullstring[] = "";
char err_usage[] =
"Usage:\n\
	ypcat [-a] [-k] [-d domainname] [-t] mapname\n";
char err_bad_args[] =
	"ypcat:  %s argument is bad.\n";
char err_cant_get_kname[] =
	"ypcat:  can't get %s back from system call.\n";
char err_null_kname[] =
	"ypcat:  the %s hasn't been set on this machine.\n";
char err_bad_mapname[] = "mapname";
char err_bad_domainname[] = "domainname";
char err_cant_bind[] =
	"ypcat:  can't bind to yp server for domain %s.  Reason:  %s.\n";
char err_first_failed[] =
	"ypcat:  can't get first record from yp.  Reason:  %s.\n";
char err_next_failed[] =
	"ypcat:  can't get next record from yp.  Reason:  %s.\n";

void get_command_line_args();
char *ypclnterr2string();

char *transtable[] = {
	"passwd", "passwd.byname",
	"group", "group.byname",
	"networks", "networks.byaddr",
	"hosts", "hosts.byaddr",
	"protocols","protocols.bynumber",
	"services","services.byname",
	NULL
};

/*
 * 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 ypcat 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;
	
{
	char *key;
	int keylen;
	char *outkey;
	int outkeylen;
	char *val;
	int vallen;
	int err;
	char *scan;
	int i;
	
	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 (err = yp_bind(domain) ) {
		fprintf(stderr, err_cant_bind, domain,
		    ypclnterr2string(err) );
		exit(1);
	}

	key = nullstring;
	keylen = 0;
	val = nullstring;
	vallen = 0;
	
	if (translate) {
		for (i = 0; transtable[i]; i+=2)
			if (strcmp(map, transtable[i]) == 0) {
			    map = transtable[i+1];
			    break;
			}
	}

	if (err = getfirst(domain, map, &outkey, &outkeylen, &val, &vallen) ) {

		if (err == YPERR_NOMORE) {
			exit(0);
		} else {
			fprintf(stderr, err_first_failed,
			    ypclnterr2string(err) );
			exit(1);
		}
	}

	while (TRUE) {

		if (dumpkeys) {

			for (scan = outkey; *scan != NULL; scan++) {

				if (*scan == '\n') {
					*scan = ' ';  
				}
			}

			printf(outkey);
		}

		printf(val);
		free(val);
		key = outkey;
		keylen = outkeylen;
		
		if (err = getnext(domain, map, key, keylen, &outkey, &outkeylen,
		    &val, &vallen) ) {

			if (err == YPERR_NOMORE) {
				break;
			} else {
				fprintf(stderr, err_next_failed,
				    ypclnterr2string(err) );
				exit(1);
			}
		}

		free(key);
	}
	
	exit(0);
}

/*
 * This does the command line argument processing.
 */
void
get_command_line_args(argc, argv)
	int argc;
	char **argv;
	
{

	argv++;
	
	while (--argc > 1) {

		if ( (*argv)[0] == '-') {

			switch ((*argv)[1]) {

			case 'a': {
				getfirst = ypclnt_first;
				getnext = ypclnt_next;
				argv++;
				break;
			}
				

			case 't': {
				translate = FALSE;
				argv++;
				break;
			}
				

			case 'k': {
				dumpkeys = TRUE;
				argv++;
				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, err_usage);
					exit(1);
				}
				
				break;
			}
				
			default: {
				fprintf(stderr, err_usage);
				exit(1);
			}
			
			}
			
		} else {
			fprintf(stderr, err_usage);
			exit(1);
		}
	}

	if (argc == 1) {
		
		if ( (*argv)[0] == '-') {
			fprintf(stderr, err_usage);
			exit(1);
		}
		
		map = *argv;

		if (strlen(map) > YPMAXMAP) {
			fprintf(stderr, err_bad_args,
			    err_bad_mapname);
			exit(1);
		}

	} else {
		fprintf(stderr, err_usage);
		exit(1);
	}
}
/*
 * This maps a ypclnt error code into a printable string for inclusion in
 * a logging error message.
 */
static char *
ypclnterr2string(err)
	unsigned int err;
	
{
	char *p;

	switch (err) {

	case YPERR_BADARGS:  {
		p = "args to function are bad";
		break;
	}

	case YPERR_RPC:  {
		p = "RPC failure";
		break;
	}

	case YPERR_DOMAIN:  {
		p = "can't bind to a server which serves this domain";
		break;
	}

	case YPERR_MAP:  {
		p = "no such map in server's domain";
		break;
	}

	case YPERR_KEY:  {
		p = "no such key in map";
		break;
	}

	case YPERR_YPERR:  {
		p = "internal yp server or client interface error";
		break;
	}

	case YPERR_RESRC:  {
		p = "local resource allocation failure";
		break;
	}

	case YPERR_NOMORE:  {
		p = "no more records in map database";
		break;
	}
	case YPERR_PMAP:  {
		p = "can't communicate with portmapper";
		break;
	}

	case YPERR_YPBIND:  {
		p = "can't communicate with ypbind";
		break;
	}

	case YPERR_YPSERV:  {
		p = "can't communicate with ypserv";
		break;
	}

	case YPERR_NODOM:  {
		p = "local domain name not set";
		break;
	}

	default: {
		p = "unknown yp client error code";
		break;
	}

	}

	return(p);
	
}