yppush.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 844 行 · 第 1/2 页

C
844
字号
#ifndef lintstatic char *sccsid = "@(#)yppush.c	4.1      ULTRIX  7/2/90";#endif lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************/#include <stdio.h>#include <errno.h>#include <signal.h>#include <sys/time.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <netdb.h>#include <rpc/rpc.h>#include <sys/socket.h>#include <rpc/pmap_clnt.h>#include <rpcsvc/ypclnt.h>#include <rpcsvc/yp_prot.h>#include <rpcsvc/ypv1_prot.h>#define INTER_TRY 12			/* Seconds between tries */#define TIMEOUT INTER_TRY*4		/* Total time for timeout */#define GRACE_PERIOD 300		/* Total seconds we'll wait for					 *  responses from ypxfrs */char *pusage;char *domain = NULL;char default_domain_name[YPMAXDOMAIN];char *map = NULL;char *host = NULL;bool verbose = FALSE;bool callback_timeout = FALSE;		/* set when a callback times out */static char ypdbpath[] = "/etc/yp";char ypmapname[1024];           /* Used to check for the map's existence */bool INTERRUPT = FALSE;	/* Set when an interrupt signal is detected */struct timeval udp_intertry = {	INTER_TRY,			/* Seconds */	0				/* Microseconds */};struct timeval udp_timeout = {	TIMEOUT,			/* Seconds */	0				/* Microseconds */};SVCXPRT *transport;struct server {	struct server *pnext;	char name[YPMAXPEER];	struct dom_binding domb;	unsigned long xactid;	unsigned short state;	unsigned long status;	bool oldvers;};struct server *server_list = (struct server *) NULL;/*  State values for server.state field */#define SSTAT_INIT 0#define SSTAT_CALLED 1#define SSTAT_RESPONDED 2#define SSTAT_PROGNOTREG 3#define SSTAT_RPC 4#define SSTAT_RSCRC 5#define SSTAT_SYSTEM 6char err_usage[] ="Usage:\n\	yppush [-d <domainname>] [-v] map\n";char err_bad_args[] =	"The %s argument is bad.\n";char err_cant_get_kname[] =	"Can't get %s from system call.\n";char err_null_kname[] =	"The %s hasn't been set on this machine.\n";char err_bad_hostname[] = "hostname";char err_bad_mapname[] = "mapname";char err_bad_domainname[] = "domainname";char err_cant_bind[] =	"Can't find a yp server for domain %s.  Reason:  %s.\n";char err_cant_build_serverlist[] =	"Can't build server list from map \"ypservers\".  Reason:  %s.\n";/* * State_duple table.  All messages should take 1 arg - the node name. */struct state_duple {	int state;	char *state_msg;};struct state_duple state_duples[] = {	{SSTAT_INIT, "Internal error trying to talk to %s."},	{SSTAT_CALLED, "%s has been called."},	{SSTAT_RESPONDED, "%s (v1 ypserv) sent an old-style request."},	{SSTAT_PROGNOTREG, "yp server not registered at %s."},	{SSTAT_RPC, "RPC error to %s:  "},	{SSTAT_RSCRC, "Local resource allocation failure - can't talk to %s."},	{SSTAT_SYSTEM, "System error talking to %s:  "},	{0, (char *) NULL}};/* * Status_duple table.  No messages should require any args. */struct status_duple {	long status;	char *status_msg;};struct status_duple status_duples[] = {	{YPPUSH_SUCC, "Map successfully transferred."},	{YPPUSH_AGE,	    "Transfer not done:  master's version isn't newer."},	{YPPUSH_NOMAP, "Failed - ypxfr there can't find a server for map."},	{YPPUSH_NODOM, "Failed - domain isn't supported."},	{YPPUSH_RSRC, "Failed - local resource allocation failure."},	{YPPUSH_RPC, "Failed - ypxfr had an RPC failure"},	{YPPUSH_MADDR, "Failed - ypxfr couldn't get the map master's address."},	{YPPUSH_YPERR, "Failed - yp server or map format error."},	{YPPUSH_BADARGS, "Failed - args to ypxfr were bad."},	{YPPUSH_DBM, "Failed - dbm operation on map failed."},	{YPPUSH_FILE, "Failed - file I/O operation on map failed"},	{YPPUSH_SKEW, "Failed - map version skew during transfer."},	{YPPUSH_CLEAR,"Map successfully transferred, but ypxfr couldn't send \"Clear map\" to ypserv "},	{YPPUSH_FORCE,	    "Failed - no local order number in map - use -f flag to ypxfr."},	{YPPUSH_XFRERR, "Failed - ypxfr internal error."},	{YPPUSH_REFUSED, "Failed - Transfer request refused."},	{0, (char *) NULL}};/* * rpcerr_duple table */struct rpcerr_duple {	enum clnt_stat rpc_stat;	char *rpc_msg;};struct rpcerr_duple rpcerr_duples[] = {	{RPC_SUCCESS, "RPC success"},	{RPC_CANTENCODEARGS, "RPC Can't encode args"},	{RPC_CANTDECODERES, "RPC Can't decode results"},	{RPC_CANTSEND, "RPC Can't send"},	{RPC_CANTRECV, "RPC Can't recv"},	{RPC_TIMEDOUT, "YP server registered, but does not respond"},	{RPC_VERSMISMATCH, "RPC version mismatch"},	{RPC_AUTHERROR, "RPC auth error"},	{RPC_PROGUNAVAIL, "RPC remote program unavailable"},	{RPC_PROGVERSMISMATCH, "RPC program mismatch"},	{RPC_PROCUNAVAIL, "RPC unknown procedure"},	{RPC_CANTDECODEARGS, "RPC Can't decode args"},	{RPC_UNKNOWNHOST, "unknown host"},	{RPC_PMAPFAILURE, "portmap failure (host is down?)"},	{RPC_PROGNOTREGISTERED, "RPC prog not registered"},	{RPC_SYSTEMERROR, "RPC system error"},	{RPC_SUCCESS, (char *) NULL}		/* Duplicate rpc_stat unused					         *  in list-end entry */};void get_default_domain_name();void get_command_line_args();unsigned short send_message();void make_server_list();void add_server();void generate_callback();void xactid_seed();void main_loop();void listener_exit();void listener_dispatch();bool read_server_state();void print_state_msg();void print_callback_msg();void rpcerr_msg();void get_xfr_response();void set_time_up();void set_interrupt();extern unsigned long inet_addr();extern long errno;extern struct rpc_createerr rpc_createerr;extern unsigned sys_nerr;extern char *sys_errlist[];voidmain (argc, argv)	int argc;	char **argv;	{	unsigned long program;	unsigned short port;        struct  stat    sbuf; 		get_command_line_args(argc, argv);	if (!domain) {		get_default_domain_name();	}        /* check to see if the map exists in this domain */        sprintf(ypmapname,"%s/%s/%s.dir",ypdbpath,domain,map);        if (stat(ypmapname,&sbuf) < 0) {                (void) fprintf(stderr,"yppush: Map does not exist.\n");                exit(1);        }		make_server_list();		/*	 * All process exits after the call to generate_callback should be	 * through listener_exit(program, status), not exit(status), so the	 * transient server can get unregistered with the portmapper.	 */	generate_callback(&program, &port, &transport);		main_loop(program, port);		listener_exit(program, 0);}/* * This does the command line parsing. */voidget_command_line_args(argc, argv)	int argc;	char **argv;	{	pusage = err_usage;	argv++;	if (argc < 2) {		(void) fprintf(stderr, pusage);		exit(1);	}		while (--argc) {		if ( (*argv)[0] == '-') {			switch ((*argv)[1]) {			case 'v':				verbose = TRUE;				argv++;				break;							case 'd': {				if (argc > 1) {					argv++;					argc--;					domain = *argv;					argv++;					if (strlen(domain) > YPMAXDOMAIN) {						(void) fprintf(stderr,						    err_bad_args,						    err_bad_domainname);						exit(1);					}									} else {					(void) fprintf(stderr, pusage);					exit(1);				}								break;			}							default: {				(void) fprintf(stderr, pusage);				exit(1);			}						}					} else {			if (!map) {				map = *argv;			} else {				(void) fprintf(stderr, pusage);				exit(1);			}						argv++;					}	}	if (!map) {		(void) fprintf(stderr, pusage);		exit(1);	}}/* *  This gets the local kernel domainname, and sets the global domain to it. */voidget_default_domain_name(){	if (!getdomainname(default_domain_name, YPMAXDOMAIN) ) {		domain = default_domain_name;	} else {		(void) fprintf(stderr, err_cant_get_kname,		    err_bad_domainname);		exit(1);	}	if (strlen(domain) == 0) {		(void) fprintf(stderr, err_null_kname, err_bad_domainname);		exit(1);	}}/* * This uses yp operations to retrieve each server name in the map *  "ypservers".  add_server is called for each one to add it to the list of *  servers. */voidmake_server_list(){	char *key;	int keylen;	char *outkey;	int outkeylen;	char *val;	int vallen;	int err;	char *ypservers = "ypservers";	int count;	if (verbose) {	    printf("Finding YP servers:", outkey);	    fflush(stdout);	    count = 4;	}	if (err = yp_bind(domain) ) {		(void) fprintf(stderr, err_cant_bind, domain,		    yperr_string(err) );		exit(1);	}		if (err = yp_first(domain, ypservers, &outkey, &outkeylen,	    &val, &vallen) ) {		(void) fprintf(stderr, err_cant_build_serverlist,		     yperr_string(err) );		exit(1);	}	while (TRUE) {		add_server(outkey, outkeylen, server_list);		if (verbose) {		    printf(" %s", outkey);		    fflush(stdout);		    if (count++ == 8) {		    	printf("\n");		        count = 0;		    }		}		free(val);		key = outkey;		keylen = outkeylen;				if (err = yp_next(domain, ypservers, key, keylen,		    &outkey, &outkeylen, &val, &vallen) ) {			if (err == YPERR_NOMORE) {				break;			} else {				(void) fprintf(stderr,				    err_cant_build_serverlist,				    yperr_string(err) );				exit(1);			}		}		free(key);	}	if (count != 0) {	    printf("\n");	}}/* *  This adds a single server to the server list.  The servers name is *  translated to an IP address by calling gethostbyname(3n), which will *  probably make use of yp services. */voidadd_server(name, namelen)	char *name;	int namelen;{	struct server *ps;	struct hostent *h;	static unsigned long seq;	static unsigned long xactid = 0;	if (xactid == 0) {		xactid_seed(&xactid);	}		ps = (struct server *) malloc( (unsigned) sizeof (struct server));	if (ps == (struct server *) NULL) {		perror("yppush malloc failure");		exit(1);	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?