Annotation of src/usr.bin/rpcinfo/rpcinfo.c, Revision 1.7
1.7 ! pvalchev 1: /* $OpenBSD: rpcinfo.c,v 1.6 2001/07/07 00:31:55 millert Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: #ifndef lint
4: /*static char sccsid[] = "from: @(#)rpcinfo.c 1.22 87/08/12 SMI";*/
5: /*static char sccsid[] = "from: @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC";*/
1.7 ! pvalchev 6: static char rcsid[] = "$OpenBSD: rpcinfo.c,v 1.6 2001/07/07 00:31:55 millert Exp $";
1.1 deraadt 7: #endif
8:
9: /*
10: * Copyright (C) 1986, Sun Microsystems, Inc.
11: */
12:
13: /*
14: * rpcinfo: ping a particular rpc program
15: * or dump the portmapper
16: */
17:
18: /*
19: * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
20: * unrestricted use provided that this legend is included on all tape
21: * media and as a part of the software program in whole or part. Users
22: * may copy or modify Sun RPC without charge, but are not authorized
23: * to license or distribute it to anyone else except as part of a product or
24: * program developed by the user.
25: *
26: * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
27: * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
28: * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
29: *
30: * Sun RPC is provided with no support and without any obligation on the
31: * part of Sun Microsystems, Inc. to assist in its use, correction,
32: * modification or enhancement.
33: *
34: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
35: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
36: * OR ANY PART THEREOF.
37: *
38: * In no event will Sun Microsystems, Inc. be liable for any lost revenue
39: * or profits or other special, indirect and consequential damages, even if
40: * Sun has been advised of the possibility of such damages.
41: *
42: * Sun Microsystems, Inc.
43: * 2550 Garcia Avenue
44: * Mountain View, California 94043
45: */
46:
47: #include <rpc/rpc.h>
48: #include <stdio.h>
49: #include <sys/socket.h>
50: #include <netdb.h>
51: #include <rpc/pmap_prot.h>
52: #include <rpc/pmap_clnt.h>
53: #include <signal.h>
1.7 ! pvalchev 54: #include <string.h>
! 55: #include <stdlib.h>
! 56: #include <unistd.h>
1.1 deraadt 57: #include <ctype.h>
1.5 deraadt 58: #include <errno.h>
1.1 deraadt 59: #include <arpa/inet.h>
60:
61: #define MAXHOSTLEN 256
62:
63: #define MIN_VERS ((u_long) 0)
64: #define MAX_VERS ((u_long) 4294967295UL)
65:
1.5 deraadt 66: void udpping(u_short portflag, int argc, char **argv);
67: void tcpping(u_short portflag, int argc, char **argv);
68: int pstatus(CLIENT *client, u_long prognum, u_long vers);
69: void pmapdump(int argc, char **argv);
1.6 millert 70: bool_t reply_proc(caddr_t res, struct sockaddr_in *who);
1.5 deraadt 71: void brdcst(int argc, char **argv);
72: void deletereg(int argc, char **argv);
73: void setreg(int argc, char **argv);
74: void usage(char *);
75: int getprognum(char *arg, u_long *ulp);
76: int getul(char *arg, u_long *ulp);
77: void get_inet_address(struct sockaddr_in *addr, char *host);
1.1 deraadt 78:
79: /*
80: * Functions to be performed.
81: */
82: #define NONE 0 /* no function */
83: #define PMAPDUMP 1 /* dump portmapper registrations */
84: #define TCPPING 2 /* ping TCP service */
85: #define UDPPING 3 /* ping UDP service */
86: #define BRDCST 4 /* ping broadcast UDP service */
87: #define DELETES 5 /* delete registration for the service */
1.5 deraadt 88: #define SETS 6 /* set registration for the service */
1.1 deraadt 89:
90: int
91: main(argc, argv)
92: int argc;
93: char **argv;
94: {
95: register int c;
96: extern char *optarg;
97: extern int optind;
98: int errflg;
99: int function;
100: u_short portnum;
1.5 deraadt 101: u_long tmp;
1.1 deraadt 102:
103: function = NONE;
104: portnum = 0;
105: errflg = 0;
1.5 deraadt 106: while ((c = getopt(argc, argv, "ptubdsn:")) != -1) {
1.1 deraadt 107: switch (c) {
108:
109: case 'p':
110: if (function != NONE)
111: errflg = 1;
112: else
113: function = PMAPDUMP;
114: break;
115:
116: case 't':
117: if (function != NONE)
118: errflg = 1;
119: else
120: function = TCPPING;
121: break;
122:
123: case 'u':
124: if (function != NONE)
125: errflg = 1;
126: else
127: function = UDPPING;
128: break;
129:
130: case 'b':
131: if (function != NONE)
132: errflg = 1;
133: else
134: function = BRDCST;
135: break;
136:
137: case 'n':
1.5 deraadt 138: if (getul(optarg, &tmp))
139: usage("invalid port number");
140: if (tmp >= 65536)
141: usage("port number out of range");
142: portnum = (u_short)tmp;
1.1 deraadt 143: break;
144:
145: case 'd':
146: if (function != NONE)
147: errflg = 1;
148: else
149: function = DELETES;
150: break;
151:
1.5 deraadt 152: case 's':
153: if (function != NONE)
154: errflg = 1;
155: else
156: function = SETS;
157: break;
158:
159:
1.1 deraadt 160: case '?':
161: errflg = 1;
162: }
163: }
164:
1.5 deraadt 165: if (errflg || function == NONE)
166: usage(NULL);
1.1 deraadt 167:
168: switch (function) {
169:
170: case PMAPDUMP:
1.5 deraadt 171: if (portnum != 0)
172: usage(NULL);
1.1 deraadt 173: pmapdump(argc - optind, argv + optind);
174: break;
175:
176: case UDPPING:
177: udpping(portnum, argc - optind, argv + optind);
178: break;
179:
180: case TCPPING:
181: tcpping(portnum, argc - optind, argv + optind);
182: break;
183:
184: case BRDCST:
1.5 deraadt 185: if (portnum != 0)
186: usage(NULL);
187:
1.1 deraadt 188: brdcst(argc - optind, argv + optind);
189: break;
190:
191: case DELETES:
192: deletereg(argc - optind, argv + optind);
193: break;
1.5 deraadt 194:
195: case SETS:
196: setreg(argc - optind, argv + optind);
197: break;
1.1 deraadt 198: }
199:
200: return (0);
201: }
202:
1.5 deraadt 203: void
1.1 deraadt 204: udpping(portnum, argc, argv)
205: u_short portnum;
206: int argc;
207: char **argv;
208: {
209: struct timeval to;
210: struct sockaddr_in addr;
211: enum clnt_stat rpc_stat;
212: CLIENT *client;
213: u_long prognum, vers, minvers, maxvers;
214: int sock = RPC_ANYSOCK;
215: struct rpc_err rpcerr;
216: int failure;
217:
1.5 deraadt 218: if (argc < 2)
219: usage("too few arguments");
220: if (argc > 3)
221: usage("too many arguments");
222: if (getprognum(argv[1], &prognum))
223: usage("program number out of range");
224:
1.1 deraadt 225: get_inet_address(&addr, argv[0]);
226: /* Open the socket here so it will survive calls to clnt_destroy */
1.3 deraadt 227: sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1.1 deraadt 228: if (sock < 0) {
229: perror("rpcinfo: socket");
230: exit(1);
231: }
1.3 deraadt 232: if (getuid() == 0)
233: bindresvport(sock, NULL);
1.1 deraadt 234: failure = 0;
235: if (argc == 2) {
236: /*
237: * A call to version 0 should fail with a program/version
238: * mismatch, and give us the range of versions supported.
239: */
240: addr.sin_port = htons(portnum);
241: to.tv_sec = 5;
242: to.tv_usec = 0;
243: if ((client = clntudp_create(&addr, prognum, (u_long)0,
244: to, &sock)) == NULL) {
245: clnt_pcreateerror("rpcinfo");
246: printf("program %lu is not available\n",
247: prognum);
248: exit(1);
249: }
250: to.tv_sec = 10;
251: to.tv_usec = 0;
252: rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
253: xdr_void, (char *)NULL, to);
254: if (rpc_stat == RPC_PROGVERSMISMATCH) {
255: clnt_geterr(client, &rpcerr);
256: minvers = rpcerr.re_vers.low;
257: maxvers = rpcerr.re_vers.high;
258: } else if (rpc_stat == RPC_SUCCESS) {
259: /*
260: * Oh dear, it DOES support version 0.
261: * Let's try version MAX_VERS.
262: */
263: addr.sin_port = htons(portnum);
264: to.tv_sec = 5;
265: to.tv_usec = 0;
266: if ((client = clntudp_create(&addr, prognum, MAX_VERS,
267: to, &sock)) == NULL) {
268: clnt_pcreateerror("rpcinfo");
269: printf("program %lu version %lu is not available\n",
270: prognum, MAX_VERS);
271: exit(1);
272: }
273: to.tv_sec = 10;
274: to.tv_usec = 0;
275: rpc_stat = clnt_call(client, NULLPROC, xdr_void,
276: (char *)NULL, xdr_void, (char *)NULL, to);
277: if (rpc_stat == RPC_PROGVERSMISMATCH) {
278: clnt_geterr(client, &rpcerr);
279: minvers = rpcerr.re_vers.low;
280: maxvers = rpcerr.re_vers.high;
281: } else if (rpc_stat == RPC_SUCCESS) {
282: /*
283: * It also supports version MAX_VERS.
284: * Looks like we have a wise guy.
285: * OK, we give them information on all
286: * 4 billion versions they support...
287: */
288: minvers = 0;
289: maxvers = MAX_VERS;
290: } else {
291: (void) pstatus(client, prognum, MAX_VERS);
292: exit(1);
293: }
294: } else {
295: (void) pstatus(client, prognum, (u_long)0);
296: exit(1);
297: }
298: clnt_destroy(client);
299: for (vers = minvers; vers <= maxvers; vers++) {
300: addr.sin_port = htons(portnum);
301: to.tv_sec = 5;
302: to.tv_usec = 0;
303: if ((client = clntudp_create(&addr, prognum, vers,
304: to, &sock)) == NULL) {
305: clnt_pcreateerror("rpcinfo");
306: printf("program %lu version %lu is not available\n",
307: prognum, vers);
308: exit(1);
309: }
310: to.tv_sec = 10;
311: to.tv_usec = 0;
312: rpc_stat = clnt_call(client, NULLPROC, xdr_void,
313: (char *)NULL, xdr_void, (char *)NULL, to);
314: if (pstatus(client, prognum, vers) < 0)
315: failure = 1;
316: clnt_destroy(client);
317: }
1.5 deraadt 318: } else {
319: getul(argv[2], &vers); /* XXX */
1.1 deraadt 320: addr.sin_port = htons(portnum);
321: to.tv_sec = 5;
322: to.tv_usec = 0;
323: if ((client = clntudp_create(&addr, prognum, vers,
324: to, &sock)) == NULL) {
325: clnt_pcreateerror("rpcinfo");
326: printf("program %lu version %lu is not available\n",
327: prognum, vers);
328: exit(1);
329: }
330: to.tv_sec = 10;
331: to.tv_usec = 0;
332: rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
333: xdr_void, (char *)NULL, to);
334: if (pstatus(client, prognum, vers) < 0)
335: failure = 1;
336: }
337: (void) close(sock); /* Close it up again */
338: if (failure)
339: exit(1);
340: }
341:
1.5 deraadt 342: void
1.1 deraadt 343: tcpping(portnum, argc, argv)
344: u_short portnum;
345: int argc;
346: char **argv;
347: {
348: struct timeval to;
349: struct sockaddr_in addr;
350: enum clnt_stat rpc_stat;
351: CLIENT *client;
352: u_long prognum, vers, minvers, maxvers;
353: int sock = RPC_ANYSOCK;
354: struct rpc_err rpcerr;
355: int failure;
356:
1.5 deraadt 357: if (argc < 2)
358: usage("too few arguments");
359: if (argc > 3)
360: usage("too many arguments");
361: if (getprognum(argv[1], &prognum))
362: usage("program number out of range");
363:
1.1 deraadt 364: get_inet_address(&addr, argv[0]);
365: failure = 0;
366: if (argc == 2) {
367: /*
368: * A call to version 0 should fail with a program/version
369: * mismatch, and give us the range of versions supported.
370: */
371: addr.sin_port = htons(portnum);
372: if ((client = clnttcp_create(&addr, prognum, MIN_VERS,
373: &sock, 0, 0)) == NULL) {
374: clnt_pcreateerror("rpcinfo");
375: printf("program %lu is not available\n",
376: prognum);
377: exit(1);
378: }
379: to.tv_sec = 10;
380: to.tv_usec = 0;
381: rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
382: xdr_void, (char *)NULL, to);
383: if (rpc_stat == RPC_PROGVERSMISMATCH) {
384: clnt_geterr(client, &rpcerr);
385: minvers = rpcerr.re_vers.low;
386: maxvers = rpcerr.re_vers.high;
387: } else if (rpc_stat == RPC_SUCCESS) {
388: /*
389: * Oh dear, it DOES support version 0.
390: * Let's try version MAX_VERS.
391: */
392: addr.sin_port = htons(portnum);
393: if ((client = clnttcp_create(&addr, prognum, MAX_VERS,
394: &sock, 0, 0)) == NULL) {
395: clnt_pcreateerror("rpcinfo");
396: printf("program %lu version %lu is not available\n",
397: prognum, MAX_VERS);
398: exit(1);
399: }
400: to.tv_sec = 10;
401: to.tv_usec = 0;
402: rpc_stat = clnt_call(client, NULLPROC, xdr_void,
403: (char *)NULL, xdr_void, (char *)NULL, to);
404: if (rpc_stat == RPC_PROGVERSMISMATCH) {
405: clnt_geterr(client, &rpcerr);
406: minvers = rpcerr.re_vers.low;
407: maxvers = rpcerr.re_vers.high;
408: } else if (rpc_stat == RPC_SUCCESS) {
409: /*
410: * It also supports version MAX_VERS.
411: * Looks like we have a wise guy.
412: * OK, we give them information on all
413: * 4 billion versions they support...
414: */
415: minvers = 0;
416: maxvers = MAX_VERS;
417: } else {
418: (void) pstatus(client, prognum, MAX_VERS);
419: exit(1);
420: }
421: } else {
422: (void) pstatus(client, prognum, MIN_VERS);
423: exit(1);
424: }
425: clnt_destroy(client);
426: (void) close(sock);
427: sock = RPC_ANYSOCK; /* Re-initialize it for later */
428: for (vers = minvers; vers <= maxvers; vers++) {
429: addr.sin_port = htons(portnum);
430: if ((client = clnttcp_create(&addr, prognum, vers,
431: &sock, 0, 0)) == NULL) {
432: clnt_pcreateerror("rpcinfo");
433: printf("program %lu version %lu is not available\n",
434: prognum, vers);
435: exit(1);
436: }
437: to.tv_usec = 0;
438: to.tv_sec = 10;
439: rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
440: xdr_void, (char *)NULL, to);
441: if (pstatus(client, prognum, vers) < 0)
442: failure = 1;
443: clnt_destroy(client);
444: (void) close(sock);
445: sock = RPC_ANYSOCK;
446: }
1.5 deraadt 447: } else {
448: getul(argv[2], &vers); /* XXX */
1.1 deraadt 449: addr.sin_port = htons(portnum);
450: if ((client = clnttcp_create(&addr, prognum, vers, &sock,
451: 0, 0)) == NULL) {
452: clnt_pcreateerror("rpcinfo");
453: printf("program %lu version %lu is not available\n",
454: prognum, vers);
455: exit(1);
456: }
457: to.tv_usec = 0;
458: to.tv_sec = 10;
459: rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
460: xdr_void, (char *)NULL, to);
461: if (pstatus(client, prognum, vers) < 0)
462: failure = 1;
463: }
464: if (failure)
465: exit(1);
466: }
467:
468: /*
469: * This routine should take a pointer to an "rpc_err" structure, rather than
470: * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
471: * a CLIENT structure rather than a pointer to an "rpc_err" structure.
472: * As such, we have to keep the CLIENT structure around in order to print
473: * a good error message.
474: */
1.5 deraadt 475: int
1.1 deraadt 476: pstatus(client, prognum, vers)
477: register CLIENT *client;
478: u_long prognum;
479: u_long vers;
480: {
481: struct rpc_err rpcerr;
482:
483: clnt_geterr(client, &rpcerr);
484: if (rpcerr.re_status != RPC_SUCCESS) {
485: clnt_perror(client, "rpcinfo");
486: printf("program %lu version %lu is not available\n",
487: prognum, vers);
488: return (-1);
489: } else {
490: printf("program %lu version %lu ready and waiting\n",
491: prognum, vers);
492: return (0);
493: }
494: }
495:
1.5 deraadt 496: void
1.1 deraadt 497: pmapdump(argc, argv)
498: int argc;
499: char **argv;
500: {
501: struct sockaddr_in server_addr;
502: register struct hostent *hp;
503: struct pmaplist *head = NULL;
504: int socket = RPC_ANYSOCK;
505: struct timeval minutetimeout;
506: register CLIENT *client;
507: struct rpcent *rpc;
508:
1.5 deraadt 509: if (argc > 1)
510: usage("too many arguments");
511:
1.1 deraadt 512: if (argc == 1)
513: get_inet_address(&server_addr, argv[0]);
514: else {
515: bzero((char *)&server_addr, sizeof server_addr);
516: server_addr.sin_family = AF_INET;
517: if ((hp = gethostbyname("localhost")) != NULL)
518: bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
519: hp->h_length);
520: else
521: (void) inet_aton("0.0.0.0", &server_addr.sin_addr);
522: }
523: minutetimeout.tv_sec = 60;
524: minutetimeout.tv_usec = 0;
525: server_addr.sin_port = htons(PMAPPORT);
526: if ((client = clnttcp_create(&server_addr, PMAPPROG,
527: PMAPVERS, &socket, 50, 500)) == NULL) {
528: clnt_pcreateerror("rpcinfo: can't contact portmapper");
529: exit(1);
530: }
531: if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
532: xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
533: fprintf(stderr, "rpcinfo: can't contact portmapper: ");
534: clnt_perror(client, "rpcinfo");
535: exit(1);
536: }
537: if (head == NULL) {
538: printf("No remote programs registered.\n");
539: } else {
540: printf(" program vers proto port\n");
541: for (; head != NULL; head = head->pml_next) {
542: printf("%10ld%5ld",
543: head->pml_map.pm_prog,
544: head->pml_map.pm_vers);
545: if (head->pml_map.pm_prot == IPPROTO_UDP)
546: printf("%6s", "udp");
547: else if (head->pml_map.pm_prot == IPPROTO_TCP)
548: printf("%6s", "tcp");
549: else
550: printf("%6ld", head->pml_map.pm_prot);
551: printf("%7ld", head->pml_map.pm_port);
552: rpc = getrpcbynumber(head->pml_map.pm_prog);
553: if (rpc)
554: printf(" %s\n", rpc->r_name);
555: else
556: printf("\n");
557: }
558: }
559: }
560:
561: /*
562: * reply_proc collects replies from the broadcast.
563: * to get a unique list of responses the output of rpcinfo should
564: * be piped through sort(1) and then uniq(1).
565: */
566: /*ARGSUSED*/
1.5 deraadt 567: bool_t
1.1 deraadt 568: reply_proc(res, who)
1.6 millert 569: caddr_t res; /* Nothing comes back */
1.5 deraadt 570: struct sockaddr_in *who; /* Who sent us the reply */
1.1 deraadt 571: {
572: register struct hostent *hp;
573:
574: hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr,
575: AF_INET);
576: printf("%s %s\n", inet_ntoa(who->sin_addr),
577: (hp == NULL) ? "(unknown)" : hp->h_name);
578: return(FALSE);
579: }
580:
1.5 deraadt 581: void
1.1 deraadt 582: brdcst(argc, argv)
583: int argc;
584: char **argv;
585: {
586: enum clnt_stat rpc_stat;
1.5 deraadt 587: u_long prognum, vers_num;
1.1 deraadt 588:
1.5 deraadt 589: if (argc != 2)
590: usage("incorrect number of arguments");
591: if (getprognum(argv[1], &prognum))
592: usage("program number out of range");
593: if (getul(argv[1], &vers_num))
594: usage("version number out of range");
595:
596: rpc_stat = clnt_broadcast(prognum, vers_num, NULLPROC, xdr_void,
1.6 millert 597: (char *)NULL, xdr_void, (char *)NULL, reply_proc);
1.1 deraadt 598: if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
599: fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
600: clnt_sperrno(rpc_stat));
601: exit(1);
602: }
603: exit(0);
604: }
605:
1.5 deraadt 606: void
1.1 deraadt 607: deletereg(argc, argv)
608: int argc;
609: char **argv;
1.5 deraadt 610: {
611: u_long prog_num, version_num;
612:
613: if (argc != 2)
614: usage("incorrect number of arguments");
615: if (getprognum(argv[0], &prog_num))
616: usage("program number out of range");
617: if (getul(argv[1], &version_num))
618: usage("version number out of range");
1.1 deraadt 619:
1.5 deraadt 620: if ((pmap_unset(prog_num, version_num)) == 0) {
621: fprintf(stderr, "rpcinfo: Could not delete "
622: "registration for prog %s version %s\n",
623: argv[0], argv[1]);
624: exit(1);
1.1 deraadt 625: }
1.5 deraadt 626: }
627:
628: void
629: setreg(argc, argv)
630: int argc;
631: char **argv;
632: {
633: u_long prog_num, version_num, port_num;
634:
635: if (argc != 3)
636: usage("incorrect number of arguments");
637: if (getprognum(argv[0], &prog_num))
638: usage("cannot parse program number");
639: if (getul(argv[1], &version_num))
640: usage("cannot parse version number");
641: if (getul(argv[2], &port_num))
642: usage("cannot parse port number");
643: if (port_num >= 65536)
644: usage("port number out of range");
645:
646: if ((pmap_set(prog_num, version_num, PF_INET,
647: (u_short)port_num)) == 0) {
648: fprintf(stderr, "rpcinfo: Could not set registration "
649: "for prog %s version %s port %s\n",
650: argv[0], argv[1], argv[2]);
651: exit(1);
1.1 deraadt 652: }
653: }
654:
1.5 deraadt 655: void
656: usage(char *msg)
1.1 deraadt 657: {
1.5 deraadt 658: if (msg)
659: fprintf(stderr,
660: "rpcinfo: %s\n", msg);
661: fprintf(stderr,
662: "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
663: fprintf(stderr,
664: " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
1.1 deraadt 665: fprintf(stderr, " rpcinfo -p [ host ]\n");
666: fprintf(stderr, " rpcinfo -b prognum versnum\n");
1.5 deraadt 667: fprintf(stderr, " rpcinfo -d prognum versnum\n");
668: fprintf(stderr, " rpcinfo -s prognum versnum portnum\n");
669: exit(1);
1.1 deraadt 670: }
671:
1.5 deraadt 672: int
673: getprognum(arg, ulp)
1.1 deraadt 674: char *arg;
1.5 deraadt 675: u_long *ulp;
1.1 deraadt 676: {
677: register struct rpcent *rpc;
678:
679: if (isalpha(*arg)) {
680: rpc = getrpcbyname(arg);
681: if (rpc == NULL) {
682: fprintf(stderr, "rpcinfo: %s is unknown service\n",
683: arg);
684: exit(1);
685: }
1.5 deraadt 686: *ulp = rpc->r_number;
687: return 0;
1.1 deraadt 688: }
1.5 deraadt 689: return getul(arg, ulp);
1.1 deraadt 690: }
691:
1.5 deraadt 692: int
693: getul(arg, ulp)
1.1 deraadt 694: char *arg;
1.5 deraadt 695: u_long *ulp;
1.1 deraadt 696: {
1.5 deraadt 697: u_long ul;
698: int save_errno = errno;
699: char *ep;
700: int ret = 1;
701:
702: errno = 0;
703: ul = strtoul(arg, &ep, 10);
704: if (arg[0] == '\0' || *ep != '\0')
705: goto fail;
706: if (errno == ERANGE && ul == ULONG_MAX)
707: goto fail;
708: *ulp = ul;
709: ret = 0;
710: fail:
711: errno = save_errno;
712: return (ret);
1.1 deraadt 713: }
714:
1.5 deraadt 715: void
1.1 deraadt 716: get_inet_address(addr, host)
717: struct sockaddr_in *addr;
718: char *host;
719: {
720: register struct hostent *hp;
721:
722: bzero((char *)addr, sizeof *addr);
723: if (inet_aton(host, &addr->sin_addr) == 0) {
724: if ((hp = gethostbyname(host)) == NULL) {
1.5 deraadt 725: fprintf(stderr, "rpcinfo: %s is unknown host\n",
726: host);
1.1 deraadt 727: exit(1);
728: }
729: bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
730: }
731: addr->sin_family = AF_INET;
732: }