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 + -
显示快捷键?