[BACK]Return to rpcinfo.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rpcinfo

Annotation of src/usr.bin/rpcinfo/rpcinfo.c, Revision 1.1

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