#ifndef lint /* @(#)yppoll.c 2.1 86/04/16 NFSSRC */ static char sccsid[] = "@(#)yppoll.c 1.1 86/02/05 Copyr 1985 Sun Micro"; #endif /* * This is a user command which asks a particular ypserv which version of a * map it is using. Usage is: * * yppoll [-h <host>] [-d <domainname>] mapname * * where host may be either a name or an internet address of form ww.xx.yy.zz * * If the host is ommitted, the local host will be used. If host is specified * as an internet address, no yp services need to be locally available. * */ #include <stdio.h> #include <sys/time.h> #include <ctype.h> #include <netdb.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 */ int status = 0; /* exit status */ char *domain = NULL; char default_domain_name[YPMAXDOMAIN]; char *map = NULL; char *host = NULL; char default_host_name[256]; struct in_addr host_addr; struct timeval udp_intertry = { INTER_TRY, /* Seconds */ 0 /* Microseconds */ }; struct timeval udp_timeout = { TIMEOUT, /* Seconds */ 0 /* Microseconds */ }; char err_usage[] = "Usage:\n\ yppoll [-h <host>] [-d <domainname>] mapname\n\n\ where host may be either a name or an internet \n\ address of form ww.xx.yy.zz\n"; char err_bad_args[] = "Bad %s argument.\n"; char err_cant_get_kname[] = "Can't get %s back from system call.\n"; char err_null_kname[] = "%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_bad_resp[] = "Ill-formed response returned from ypserv on host %s.\n"; void get_command_line_args(); void getdomain(); void getlochost(); void getrmthost(); void getmapparms(); void newresults(); void oldresults(); extern u_long inet_addr(); /* * This is the mainline for the yppoll process. */ void main (argc, argv) int argc; char **argv; { struct sockaddr_in myaddr; get_command_line_args(argc, argv); if (!domain) { getdomain(); } if (!host) { getypserv(); } else { getrmthost(); } getmapparms(); exit(status); } /* * This does the command line argument processing. */ void get_command_line_args(argc, argv) int argc; char **argv; { argv++; while (--argc) { if ( (*argv)[0] == '-') { switch ((*argv)[1]) { case 'h': if (argc > 1) { argv++; argc--; host = *argv; argv++; if (strlen(host) > 256) { (void) fprintf(stderr, err_bad_args, err_bad_hostname); exit(1); } } else { (void) fprintf(stderr, err_usage); exit(1); } 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, err_usage); exit(1); } break; default: (void) fprintf(stderr, err_usage); exit(1); } } else { if (!map) { map = *argv; if (strlen(map) > YPMAXMAP) { (void) fprintf(stderr, err_bad_args, err_bad_mapname); exit(1); } } else { (void) fprintf(stderr, err_usage); exit(1); } } } if (!map) { (void) fprintf(stderr, err_usage); exit(1); } } /* * This gets the local default domainname, and makes sure that it's set * to something reasonable. domain is set here. */ void getdomain() { 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); } } /* * This gets the local hostname back from the kernel, and comes up with an * address for the local node without using the yp. host_addr is set here. */ void getlochost() { struct sockaddr_in myaddr; 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; } /* * This gets an address for some named node by calling the standard library * routine gethostbyname. host_addr is set here. */ void getrmthost() { struct in_addr tempaddr; struct hostent *hp; if (isdigit(*host) ) { tempaddr.s_addr = inet_addr(host); if ((int) tempaddr.s_addr != -1) { host_addr = tempaddr; return; } } hp = gethostbyname(host); if (hp == NULL) { fprintf(stderr, "ypwhich: can't find %s\n", host); exit(1); } host_addr.s_addr = *(u_long *)hp->h_addr; } void getmapparms() { struct dom_binding domb; struct ypreq_nokey req; struct ypresp_master mresp; struct ypresp_order oresp; struct ypresp_master *mresults = (struct ypresp_master *) NULL; struct ypresp_order *oresults = (struct ypresp_order *) NULL; struct yprequest oldreq; struct ypresponse oldresp; enum clnt_stat s; 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; req.domain = domain; req.map = map; mresp.master = NULL; if ((domb.dom_client = clntudp_create(&(domb.dom_server_addr), YPPROG, YPVERS, udp_intertry, &(domb.dom_socket))) == NULL) { (void) fprintf(stderr, "Can't create UDP connection to %s.\n ", host); clnt_pcreateerror("Reason"); exit(1); } s = (enum clnt_stat) clnt_call(domb.dom_client, YPPROC_MASTER, xdr_ypreq_nokey, &req, xdr_ypresp_master, &mresp, udp_timeout); if(s == RPC_SUCCESS) { mresults = &mresp; s = (enum clnt_stat) clnt_call(domb.dom_client, YPPROC_ORDER, xdr_ypreq_nokey, &req, xdr_ypresp_order, &oresp, udp_timeout); if(s == RPC_SUCCESS) { oresults = &oresp; newresults(mresults, oresults); } else { (void) fprintf(stderr, "Can't make YPPROC_ORDER call to ypserv at %s.\n ", host); clnt_perror(domb.dom_client, "Reason"); exit(1); } } else { if (s == RPC_PROGVERSMISMATCH) { clnt_destroy(domb.dom_client); close(domb.dom_socket); domb.dom_server_addr.sin_port = 0; domb.dom_server_port = 0; domb.dom_socket = RPC_ANYSOCK; if ((domb.dom_client = clntudp_create( &(domb.dom_server_addr), YPPROG, YPOLDVERS, udp_intertry, &(domb.dom_socket))) == NULL) { (void) fprintf(stderr, "Can't create V1 UDP connection to %s.\n ", host); clnt_pcreateerror("Reason"); exit(1); } oldreq.yp_reqtype = YPPOLL_REQTYPE; oldreq.yppoll_req_domain = domain; oldreq.yppoll_req_map = map; oldresp.yppoll_resp_domain = NULL; oldresp.yppoll_resp_map = NULL; oldresp.yppoll_resp_ordernum = 0; oldresp.yppoll_resp_owner = NULL; s = (enum clnt_stat) clnt_call(domb.dom_client, YPOLDPROC_POLL, _xdr_yprequest, &oldreq, _xdr_ypresponse, &oldresp, udp_timeout); if(s == RPC_SUCCESS) { oldresults(&oldresp); } else { (void) fprintf(stderr, "Can't make YPPROC_POLL call to ypserv at %s.\n ", host); clnt_perror(domb.dom_client, "yppoll"); exit(1); } } else { (void) fprintf(stderr, "Can't make YPPROC_MASTER call to ypserv at %s.\n ", host); clnt_perror(domb.dom_client, "Reason"); exit(1); } } } void newresults(m, o) struct ypresp_master *m; struct ypresp_order *o; { char *s_domok = "Domain %s is supported.\n"; char *s_ook = "Map %s has order number %d.\n"; char *s_mok = "The master server is %s.\n"; char *s_mbad = "Can't get master for map %s.\n Reason: %s\n"; char *s_obad = "Can't get order number for map %s.\n Reason: %s\n"; if (m->status == YP_TRUE && o->status == YP_TRUE) { (void) printf(s_domok, domain); (void) printf(s_ook, map, o->ordernum); (void) printf(s_mok, m->master); } else if (o->status == YP_TRUE) { (void) printf(s_domok, domain); (void) printf(s_ook, map, o->ordernum); (void) printf(s_mbad, map, yperr_string(ypprot_err(m->status)) ); status = 1; } else if (m->status == YP_TRUE) { (void) printf(s_domok, domain); (void) printf(s_obad, map, yperr_string(ypprot_err(o->status)) ); (void) printf(s_mok, m->master); status = 1; } else { (void) printf("Can't get any map parameter information.\n"); (void) printf(s_obad, map, yperr_string(ypprot_err(o->status)) ); (void) printf(s_mbad, map, yperr_string(ypprot_err(m->status)) ); status = 1; } } void oldresults(resp) struct ypresponse *resp; { if (resp->yp_resptype != YPPOLL_RESPTYPE) { (void) fprintf(stderr, err_bad_resp, host); status = 1; } if (!strcmp(resp->yppoll_resp_domain, domain) ) { (void) printf("Domain %s is supported.\n", domain); if (!strcmp(resp->yppoll_resp_map, map) ) { if (resp->yppoll_resp_ordernum != 0) { (void) printf("Map %s has order number %d.\n", map, resp->yppoll_resp_ordernum); if (strcmp(resp->yppoll_resp_owner, "") ) { (void) printf( "The master server is %s.\n", resp->yppoll_resp_owner); } else { (void) printf( "Unknown master server.\n"); status = 1; } } else { (void) printf("Map %s is not supported.\n", map); status = 1; } } else { (void) printf("Map %s does not exist at %s.\n", map, host); status = 1; } } else { (void) printf("Domain %s is not supported.\n", domain); status = 1; } } getypserv() { int x; char host[256]; struct in_addr addr; struct ypbind_resp response; if (gethostname(host, sizeof(host)) != 0) { fprintf(stderr, "can't get hostname\n"); exit(1); } x = callrpc(host, YPBINDPROG, YPBINDVERS, YPBINDPROC_DOMAIN, xdr_ypdomain_wrap_string, &domain, xdr_ypbind_resp, &response); if (x) { x = callrpc(host, YPBINDPROG, YPBINDOLDVERS, YPBINDPROC_DOMAIN, xdr_ypdomain_wrap_string, &domain, xdr_ypbind_resp, &response); if (x) { clnt_perrno(x); fprintf(stderr, "\n"); exit(1); } } if (response.ypbind_status != YPBIND_SUCC_VAL) { fprintf(stderr, "couldn't get yp server %d\n", response.ypbind_status); exit(1); } host_addr=response.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr; }