📄 rpcinfo.c
字号:
if (argc < 2 || argc > 3) { usage(); exit(1); } prognum = getprognum(argv[1]); get_inet_address(&addr, argv[0]); failure = 0; if (argc == 2) { /* * A call to version 0 should fail with a program/version * mismatch, and give us the range of versions supported. */ addr.sin_port = htons(portnum); if ((client = clnttcp_create(&addr, prognum, MIN_VERS, &sock, 0, 0)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu is not available\n", prognum); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (rpc_stat == RPC_PROGVERSMISMATCH) { clnt_geterr(client, &rpcerr); minvers = rpcerr.re_vers.low; maxvers = rpcerr.re_vers.high; } else if (rpc_stat == RPC_SUCCESS) { /* * Oh dear, it DOES support version 0. * Let's try version MAX_VERS. */ addr.sin_port = htons(portnum); if ((client = clnttcp_create(&addr, prognum, MAX_VERS, &sock, 0, 0)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, MAX_VERS); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (rpc_stat == RPC_PROGVERSMISMATCH) { clnt_geterr(client, &rpcerr); minvers = rpcerr.re_vers.low; maxvers = rpcerr.re_vers.high; } else if (rpc_stat == RPC_SUCCESS) { /* * It also supports version MAX_VERS. * Looks like we have a wise guy. * OK, we give them information on all * 4 billion versions they support... */ minvers = 0; maxvers = MAX_VERS; } else { (void) pstatus(client, prognum, MAX_VERS); exit(1); } } else { (void) pstatus(client, prognum, MIN_VERS); exit(1); } clnt_destroy(client); (void) close(sock); sock = RPC_ANYSOCK; /* Re-initialize it for later */ for (vers = minvers; vers <= maxvers; vers++) { addr.sin_port = htons(portnum); if ((client = clnttcp_create(&addr, prognum, vers, &sock, 0, 0)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, vers); exit(1); } to.tv_usec = 0; to.tv_sec = 10; rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (pstatus(client, prognum, vers) < 0) failure = 1; clnt_destroy(client); (void) close(sock); sock = RPC_ANYSOCK; } } else { vers = getvers(argv[2]); addr.sin_port = htons(portnum); if ((client = clnttcp_create(&addr, prognum, vers, &sock, 0, 0)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, vers); exit(1); } to.tv_usec = 0; to.tv_sec = 10; rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (pstatus(client, prognum, vers) < 0) failure = 1; } if (failure) exit(1);}/* * This routine should take a pointer to an "rpc_err" structure, rather than * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to * a CLIENT structure rather than a pointer to an "rpc_err" structure. * As such, we have to keep the CLIENT structure around in order to print * a good error message. */static intpstatus(client, prognum, vers) register CLIENT *client; u_long prognum; u_long vers;{ struct rpc_err rpcerr; clnt_geterr(client, &rpcerr); if (rpcerr.re_status != RPC_SUCCESS) { clnt_perror(client, "rpcinfo"); printf("program %lu version %lu is not available\n", prognum, vers); return (-1); } else { printf("program %lu version %lu ready and waiting\n", prognum, vers); return (0); }}static voidpmapdump(argc, argv) int argc; char **argv;{ struct sockaddr_in server_addr; register struct hostent *hp; struct pmaplist *head = NULL; int socket = RPC_ANYSOCK; struct timeval minutetimeout; register CLIENT *client; struct rpcent *rpc; if (argc > 1) { usage(); exit(1); } if (argc == 1) get_inet_address(&server_addr, argv[0]); else { bzero((char *)&server_addr, sizeof server_addr); server_addr.sin_family = AF_INET; if ((hp = gethostbyname("localhost")) != NULL) bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length); else server_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); } minutetimeout.tv_sec = 60; minutetimeout.tv_usec = 0; server_addr.sin_port = htons(PMAPPORT); if ((client = clnttcp_create(&server_addr, PMAPPROG, PMAPVERS, &socket, 50, 500)) == NULL) { clnt_pcreateerror("rpcinfo: can't contact portmapper"); exit(1); } if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { fprintf(stderr, "rpcinfo: can't contact portmapper: "); clnt_perror(client, "rpcinfo"); exit(1); } if (head == NULL) { printf("No remote programs registered.\n"); } else { printf(" program vers proto port\n"); for (; head != NULL; head = head->pml_next) { printf("%10ld%5ld", head->pml_map.pm_prog, head->pml_map.pm_vers); if (head->pml_map.pm_prot == IPPROTO_UDP) printf("%6s", "udp"); else if (head->pml_map.pm_prot == IPPROTO_TCP) printf("%6s", "tcp"); else printf("%6ld", head->pml_map.pm_prot); printf("%7ld", head->pml_map.pm_port); rpc = getrpcbynumber(head->pml_map.pm_prog); if (rpc) printf(" %s\n", rpc->r_name); else printf("\n"); } }}/* * reply_proc collects replies from the broadcast. * to get a unique list of responses the output of rpcinfo should * be piped through sort(1) and then uniq(1). *//*ARGSUSED*/static bool_treply_proc(res, who) void *res; /* Nothing comes back */ struct sockaddr_in *who; /* Who sent us the reply */{ register struct hostent *hp; hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr, AF_INET); printf("%s %s\n", inet_ntoa(who->sin_addr), (hp == NULL) ? "(unknown)" : hp->h_name); return(FALSE);}static voidbrdcst(argc, argv) int argc; char **argv;{ enum clnt_stat rpc_stat; u_long prognum, vers; if (argc != 2) { usage(); exit(1); } prognum = getprognum(argv[0]); vers = getvers(argv[1]); rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, reply_proc); if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) { fprintf(stderr, "rpcinfo: broadcast failed: %s\n", clnt_sperrno(rpc_stat)); exit(1); } exit(0);}static voiddeletereg(argc, argv) int argc; char **argv;{ u_long prog_num, version_num ; if (argc != 2) { usage() ; exit(1) ; } if (getuid()) { /* This command allowed only to root */ fprintf(stderr, "Sorry. You are not root\n") ; exit(1) ; } prog_num = getprognum(argv[0]); version_num = getvers(argv[1]); if ((pmap_unset(prog_num, version_num)) == 0) { fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n", argv[0], argv[1]) ; exit(1) ; }}static voidusage(){ fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"); fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"); fprintf(stderr, " rpcinfo -p [ host ]\n"); fprintf(stderr, " rpcinfo -b prognum versnum\n"); fprintf(stderr, " rpcinfo -d prognum versnum\n") ;}static u_longgetprognum(arg) char *arg;{ register struct rpcent *rpc; register u_long prognum; if (isalpha(*arg)) { rpc = getrpcbyname(arg); if (rpc == NULL) { fprintf(stderr, "rpcinfo: %s is unknown service\n", arg); exit(1); } prognum = rpc->r_number; } else { prognum = (u_long) atoi(arg); } return (prognum);}static u_longgetvers(arg) char *arg;{ register u_long vers; vers = (int) atoi(arg); return (vers);}static voidget_inet_address(addr, host) struct sockaddr_in *addr; char *host;{ register struct hostent *hp; bzero((char *)addr, sizeof *addr); addr->sin_addr.s_addr = (u_long) inet_addr(host); if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { if ((hp = gethostbyname(host)) == NULL) { fprintf(stderr, "rpcinfo: %s is unknown host\n", host); exit(1); } bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length); } addr->sin_family = AF_INET;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -