Back to index

glibc  2.9
rpcinfo.c
Go to the documentation of this file.
00001 
00002 /* @(#)rpcinfo.c        2.2 88/08/11 4.0 RPCSRC */
00003 #if !defined(lint) && defined (SCCSID)
00004 static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";
00005 #endif
00006 
00007 /*
00008  * Copyright (C) 1986, Sun Microsystems, Inc.
00009  */
00010 
00011 /*
00012  * rpcinfo: ping a particular rpc program
00013  *     or dump the portmapper
00014  */
00015 
00016 /*
00017  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00018  * unrestricted use provided that this legend is included on all tape
00019  * media and as a part of the software program in whole or part.  Users
00020  * may copy or modify Sun RPC without charge, but are not authorized
00021  * to license or distribute it to anyone else except as part of a product or
00022  * program developed by the user.
00023  *
00024  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00025  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00026  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00027  *
00028  * Sun RPC is provided with no support and without any obligation on the
00029  * part of Sun Microsystems, Inc. to assist in its use, correction,
00030  * modification or enhancement.
00031  *
00032  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00033  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00034  * OR ANY PART THEREOF.
00035  *
00036  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00037  * or profits or other special, indirect and consequential damages, even if
00038  * Sun has been advised of the possibility of such damages.
00039  *
00040  * Sun Microsystems, Inc.
00041  * 2550 Garcia Avenue
00042  * Mountain View, California  94043
00043  */
00044 
00045 #include <getopt.h>
00046 #include <string.h>
00047 #include <unistd.h>
00048 #include <rpc/rpc.h>
00049 #include <stdio.h>
00050 #include <sys/socket.h>
00051 #include <netinet/in.h>
00052 #include <arpa/inet.h>
00053 #include <netdb.h>
00054 #include <rpc/pmap_prot.h>
00055 #include <rpc/pmap_clnt.h>
00056 #include <signal.h>
00057 #include <ctype.h>
00058 #include <locale.h>
00059 #include <libintl.h>
00060 
00061 #define MAXHOSTLEN 256
00062 
00063 #define       MIN_VERS      ((u_long) 0)
00064 #define       MAX_VERS      ((u_long) 4294967295UL)
00065 
00066 static void udpping (u_short portflag, int argc, char **argv);
00067 static void tcpping (u_short portflag, int argc, char **argv);
00068 static int pstatus (CLIENT *client, u_long prognum, u_long vers);
00069 static void pmapdump (int argc, char **argv);
00070 static bool_t reply_proc (void *res, struct sockaddr_in *who);
00071 static void brdcst (int argc, char **argv) __attribute__ ((noreturn));
00072 static void deletereg (int argc, char **argv);
00073 static void usage (void);
00074 static u_long getprognum (char *arg);
00075 static u_long getvers (char *arg);
00076 static void get_inet_address (struct sockaddr_in *addr, char *host);
00077 
00078 /*
00079  * Functions to be performed.
00080  */
00081 #define       NONE          0      /* no function */
00082 #define       PMAPDUMP      1      /* dump portmapper registrations */
00083 #define       TCPPING              2      /* ping TCP service */
00084 #define       UDPPING              3      /* ping UDP service */
00085 #define       BRDCST        4      /* ping broadcast UDP service */
00086 #define DELETES             5      /* delete registration for the service */
00087 
00088 int
00089 main (int argc, char **argv)
00090 {
00091   register int c;
00092   int errflg;
00093   int function;
00094   u_short portnum;
00095 
00096   setlocale (LC_ALL, "");
00097   textdomain (_libc_intl_domainname);
00098 
00099   function = NONE;
00100   portnum = 0;
00101   errflg = 0;
00102   while ((c = getopt (argc, argv, "ptubdn:")) != -1)
00103     {
00104       switch (c)
00105        {
00106 
00107        case 'p':
00108          if (function != NONE)
00109            errflg = 1;
00110          else
00111            function = PMAPDUMP;
00112          break;
00113 
00114        case 't':
00115          if (function != NONE)
00116            errflg = 1;
00117          else
00118            function = TCPPING;
00119          break;
00120 
00121        case 'u':
00122          if (function != NONE)
00123            errflg = 1;
00124          else
00125            function = UDPPING;
00126          break;
00127 
00128        case 'b':
00129          if (function != NONE)
00130            errflg = 1;
00131          else
00132            function = BRDCST;
00133          break;
00134 
00135        case 'n':
00136          portnum = (u_short) atoi (optarg);      /* hope we don't get bogus # */
00137          break;
00138 
00139        case 'd':
00140          if (function != NONE)
00141            errflg = 1;
00142          else
00143            function = DELETES;
00144          break;
00145 
00146        case '?':
00147          errflg = 1;
00148        }
00149     }
00150 
00151   if (errflg || function == NONE)
00152     {
00153       usage ();
00154       return 1;
00155     }
00156 
00157   switch (function)
00158     {
00159 
00160     case PMAPDUMP:
00161       if (portnum != 0)
00162        {
00163          usage ();
00164          return 1;
00165        }
00166       pmapdump (argc - optind, argv + optind);
00167       break;
00168 
00169     case UDPPING:
00170       udpping (portnum, argc - optind, argv + optind);
00171       break;
00172 
00173     case TCPPING:
00174       tcpping (portnum, argc - optind, argv + optind);
00175       break;
00176 
00177     case BRDCST:
00178       if (portnum != 0)
00179        {
00180          usage ();
00181          return 1;
00182        }
00183       brdcst (argc - optind, argv + optind);
00184       break;
00185 
00186     case DELETES:
00187       deletereg (argc - optind, argv + optind);
00188       break;
00189     }
00190 
00191   return 0;
00192 }
00193 
00194 static void
00195 udpping (portnum, argc, argv)
00196      u_short portnum;
00197      int argc;
00198      char **argv;
00199 {
00200   struct timeval to;
00201   struct sockaddr_in addr;
00202   enum clnt_stat rpc_stat;
00203   CLIENT *client;
00204   u_long prognum, vers, minvers, maxvers;
00205   int sock = RPC_ANYSOCK;
00206   struct rpc_err rpcerr;
00207   int failure;
00208 
00209   if (argc < 2 || argc > 3)
00210     {
00211       usage ();
00212       exit (1);
00213     }
00214   prognum = getprognum (argv[1]);
00215   get_inet_address (&addr, argv[0]);
00216   /* Open the socket here so it will survive calls to clnt_destroy */
00217   sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00218   if (sock < 0)
00219     {
00220       perror ("rpcinfo: socket");
00221       exit (1);
00222     }
00223   failure = 0;
00224   if (argc == 2)
00225     {
00226       /*
00227        * A call to version 0 should fail with a program/version
00228        * mismatch, and give us the range of versions supported.
00229        */
00230       addr.sin_port = htons (portnum);
00231       to.tv_sec = 5;
00232       to.tv_usec = 0;
00233       if ((client = clntudp_create (&addr, prognum, (u_long) 0,
00234                                 to, &sock)) == NULL)
00235        {
00236          clnt_pcreateerror ("rpcinfo");
00237          printf (_("program %lu is not available\n"), prognum);
00238          exit (1);
00239        }
00240       to.tv_sec = 10;
00241       to.tv_usec = 0;
00242       rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
00243                          (char *) NULL, (xdrproc_t) xdr_void,
00244                          (char *) NULL, to);
00245       if (rpc_stat == RPC_PROGVERSMISMATCH)
00246        {
00247          clnt_geterr (client, &rpcerr);
00248          minvers = rpcerr.re_vers.low;
00249          maxvers = rpcerr.re_vers.high;
00250        }
00251       else if (rpc_stat == RPC_SUCCESS)
00252        {
00253          /*
00254           * Oh dear, it DOES support version 0.
00255           * Let's try version MAX_VERS.
00256           */
00257          addr.sin_port = htons (portnum);
00258          to.tv_sec = 5;
00259          to.tv_usec = 0;
00260          if ((client = clntudp_create (&addr, prognum, MAX_VERS,
00261                                    to, &sock)) == NULL)
00262            {
00263              clnt_pcreateerror ("rpcinfo");
00264              printf (_("program %lu version %lu is not available\n"),
00265                     prognum, MAX_VERS);
00266              exit (1);
00267            }
00268          to.tv_sec = 10;
00269          to.tv_usec = 0;
00270          rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
00271                             NULL, (xdrproc_t) xdr_void, NULL, to);
00272          if (rpc_stat == RPC_PROGVERSMISMATCH)
00273            {
00274              clnt_geterr (client, &rpcerr);
00275              minvers = rpcerr.re_vers.low;
00276              maxvers = rpcerr.re_vers.high;
00277            }
00278          else if (rpc_stat == RPC_SUCCESS)
00279            {
00280              /*
00281               * It also supports version MAX_VERS.
00282               * Looks like we have a wise guy.
00283               * OK, we give them information on all
00284               * 4 billion versions they support...
00285               */
00286              minvers = 0;
00287              maxvers = MAX_VERS;
00288            }
00289          else
00290            {
00291              (void) pstatus (client, prognum, MAX_VERS);
00292              exit (1);
00293            }
00294        }
00295       else
00296        {
00297          (void) pstatus (client, prognum, (u_long) 0);
00298          exit (1);
00299        }
00300       clnt_destroy (client);
00301       for (vers = minvers; vers <= maxvers; vers++)
00302        {
00303          addr.sin_port = htons (portnum);
00304          to.tv_sec = 5;
00305          to.tv_usec = 0;
00306          if ((client = clntudp_create (&addr, prognum, vers,
00307                                    to, &sock)) == NULL)
00308            {
00309              clnt_pcreateerror ("rpcinfo");
00310              printf (_("program %lu version %lu is not available\n"),
00311                     prognum, vers);
00312              exit (1);
00313            }
00314          to.tv_sec = 10;
00315          to.tv_usec = 0;
00316          rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
00317                             NULL, (xdrproc_t) xdr_void, NULL, to);
00318          if (pstatus (client, prognum, vers) < 0)
00319            failure = 1;
00320          clnt_destroy (client);
00321        }
00322     }
00323   else
00324     {
00325       vers = getvers (argv[2]);
00326       addr.sin_port = htons (portnum);
00327       to.tv_sec = 5;
00328       to.tv_usec = 0;
00329       if ((client = clntudp_create (&addr, prognum, vers,
00330                                 to, &sock)) == NULL)
00331        {
00332          clnt_pcreateerror ("rpcinfo");
00333          printf (_("program %lu version %lu is not available\n"),
00334                 prognum, vers);
00335          exit (1);
00336        }
00337       to.tv_sec = 10;
00338       to.tv_usec = 0;
00339       rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
00340                          (xdrproc_t) xdr_void, NULL, to);
00341       if (pstatus (client, prognum, vers) < 0)
00342        failure = 1;
00343     }
00344   (void) close (sock);             /* Close it up again */
00345   if (failure)
00346     exit (1);
00347 }
00348 
00349 static void
00350 tcpping (portnum, argc, argv)
00351      u_short portnum;
00352      int argc;
00353      char **argv;
00354 {
00355   struct timeval to;
00356   struct sockaddr_in addr;
00357   enum clnt_stat rpc_stat;
00358   CLIENT *client;
00359   u_long prognum, vers, minvers, maxvers;
00360   int sock = RPC_ANYSOCK;
00361   struct rpc_err rpcerr;
00362   int failure;
00363 
00364   if (argc < 2 || argc > 3)
00365     {
00366       usage ();
00367       exit (1);
00368     }
00369   prognum = getprognum (argv[1]);
00370   get_inet_address (&addr, argv[0]);
00371   failure = 0;
00372   if (argc == 2)
00373     {
00374       /*
00375        * A call to version 0 should fail with a program/version
00376        * mismatch, and give us the range of versions supported.
00377        */
00378       addr.sin_port = htons (portnum);
00379       if ((client = clnttcp_create (&addr, prognum, MIN_VERS,
00380                                 &sock, 0, 0)) == NULL)
00381        {
00382          clnt_pcreateerror ("rpcinfo");
00383          printf (_("program %lu is not available\n"), prognum);
00384          exit (1);
00385        }
00386       to.tv_sec = 10;
00387       to.tv_usec = 0;
00388       rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, NULL,
00389                          (xdrproc_t) xdr_void, NULL, to);
00390       if (rpc_stat == RPC_PROGVERSMISMATCH)
00391        {
00392          clnt_geterr (client, &rpcerr);
00393          minvers = rpcerr.re_vers.low;
00394          maxvers = rpcerr.re_vers.high;
00395        }
00396       else if (rpc_stat == RPC_SUCCESS)
00397        {
00398          /*
00399           * Oh dear, it DOES support version 0.
00400           * Let's try version MAX_VERS.
00401           */
00402          addr.sin_port = htons (portnum);
00403          if ((client = clnttcp_create (&addr, prognum, MAX_VERS,
00404                                    &sock, 0, 0)) == NULL)
00405            {
00406              clnt_pcreateerror ("rpcinfo");
00407              printf (_("program %lu version %lu is not available\n"),
00408                     prognum, MAX_VERS);
00409              exit (1);
00410            }
00411          to.tv_sec = 10;
00412          to.tv_usec = 0;
00413          rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
00414                             NULL, (xdrproc_t) xdr_void, NULL, to);
00415          if (rpc_stat == RPC_PROGVERSMISMATCH)
00416            {
00417              clnt_geterr (client, &rpcerr);
00418              minvers = rpcerr.re_vers.low;
00419              maxvers = rpcerr.re_vers.high;
00420            }
00421          else if (rpc_stat == RPC_SUCCESS)
00422            {
00423              /*
00424               * It also supports version MAX_VERS.
00425               * Looks like we have a wise guy.
00426               * OK, we give them information on all
00427               * 4 billion versions they support...
00428               */
00429              minvers = 0;
00430              maxvers = MAX_VERS;
00431            }
00432          else
00433            {
00434              (void) pstatus (client, prognum, MAX_VERS);
00435              exit (1);
00436            }
00437        }
00438       else
00439        {
00440          (void) pstatus (client, prognum, MIN_VERS);
00441          exit (1);
00442        }
00443       clnt_destroy (client);
00444       (void) close (sock);
00445       sock = RPC_ANYSOCK;   /* Re-initialize it for later */
00446       for (vers = minvers; vers <= maxvers; vers++)
00447        {
00448          addr.sin_port = htons (portnum);
00449          if ((client = clnttcp_create (&addr, prognum, vers,
00450                                    &sock, 0, 0)) == NULL)
00451            {
00452              clnt_pcreateerror ("rpcinfo");
00453              printf (_("program %lu version %lu is not available\n"),
00454                     prognum, vers);
00455              exit (1);
00456            }
00457          to.tv_usec = 0;
00458          to.tv_sec = 10;
00459          rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
00460                             (xdrproc_t) xdr_void, NULL, to);
00461          if (pstatus (client, prognum, vers) < 0)
00462            failure = 1;
00463          clnt_destroy (client);
00464          (void) close (sock);
00465          sock = RPC_ANYSOCK;
00466        }
00467     }
00468   else
00469     {
00470       vers = getvers (argv[2]);
00471       addr.sin_port = htons (portnum);
00472       if ((client = clnttcp_create (&addr, prognum, vers, &sock,
00473                                 0, 0)) == NULL)
00474        {
00475          clnt_pcreateerror ("rpcinfo");
00476          printf (_("program %lu version %lu is not available\n"),
00477                 prognum, vers);
00478          exit (1);
00479        }
00480       to.tv_usec = 0;
00481       to.tv_sec = 10;
00482       rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
00483                          (xdrproc_t) xdr_void, NULL, to);
00484       if (pstatus (client, prognum, vers) < 0)
00485        failure = 1;
00486     }
00487   if (failure)
00488     exit (1);
00489 }
00490 
00491 /*
00492  * This routine should take a pointer to an "rpc_err" structure, rather than
00493  * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
00494  * a CLIENT structure rather than a pointer to an "rpc_err" structure.
00495  * As such, we have to keep the CLIENT structure around in order to print
00496  * a good error message.
00497  */
00498 static int
00499 pstatus (client, prognum, vers)
00500      register CLIENT *client;
00501      u_long prognum;
00502      u_long vers;
00503 {
00504   struct rpc_err rpcerr;
00505 
00506   clnt_geterr (client, &rpcerr);
00507   if (rpcerr.re_status != RPC_SUCCESS)
00508     {
00509       clnt_perror (client, "rpcinfo");
00510       printf (_("program %lu version %lu is not available\n"), prognum, vers);
00511       return -1;
00512     }
00513   else
00514     {
00515       printf (_("program %lu version %lu ready and waiting\n"), prognum, vers);
00516       return 0;
00517     }
00518 }
00519 
00520 static void
00521 pmapdump (argc, argv)
00522      int argc;
00523      char **argv;
00524 {
00525   struct sockaddr_in server_addr;
00526   register struct hostent *hp;
00527   struct pmaplist *head = NULL;
00528   int socket = RPC_ANYSOCK;
00529   struct timeval minutetimeout;
00530   register CLIENT *client;
00531   struct rpcent *rpc;
00532 
00533   if (argc > 1)
00534     {
00535       usage ();
00536       exit (1);
00537     }
00538   if (argc == 1)
00539     get_inet_address (&server_addr, argv[0]);
00540   else
00541     {
00542       bzero ((char *) &server_addr, sizeof server_addr);
00543       server_addr.sin_family = AF_INET;
00544       if ((hp = gethostbyname ("localhost")) != NULL)
00545        memcpy ((caddr_t) & server_addr.sin_addr, hp->h_addr,
00546                hp->h_length);
00547       else
00548        server_addr.sin_addr.s_addr = inet_addr ("0.0.0.0");
00549     }
00550   minutetimeout.tv_sec = 60;
00551   minutetimeout.tv_usec = 0;
00552   server_addr.sin_port = htons (PMAPPORT);
00553   if ((client = clnttcp_create (&server_addr, PMAPPROG,
00554                             PMAPVERS, &socket, 50, 500)) == NULL)
00555     {
00556       clnt_pcreateerror (_("rpcinfo: can't contact portmapper"));
00557       exit (1);
00558     }
00559   if (clnt_call (client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, NULL,
00560                (xdrproc_t) xdr_pmaplist, (caddr_t) &head,
00561                minutetimeout) != RPC_SUCCESS)
00562     {
00563       fputs (_("rpcinfo: can't contact portmapper"), stderr);
00564       fputs (": ", stderr);
00565       clnt_perror (client, "rpcinfo");
00566       exit (1);
00567     }
00568   if (head == NULL)
00569     {
00570       fputs (_("No remote programs registered.\n"), stdout);
00571     }
00572   else
00573     {
00574       fputs (_("   program vers proto   port\n"), stdout);
00575       for (; head != NULL; head = head->pml_next)
00576        {
00577          printf ("%10ld%5ld",
00578                 head->pml_map.pm_prog,
00579                 head->pml_map.pm_vers);
00580          if (head->pml_map.pm_prot == IPPROTO_UDP)
00581            printf ("%6s", "udp");
00582          else if (head->pml_map.pm_prot == IPPROTO_TCP)
00583            printf ("%6s", "tcp");
00584          else
00585            printf ("%6ld", head->pml_map.pm_prot);
00586          printf ("%7ld", head->pml_map.pm_port);
00587          rpc = getrpcbynumber (head->pml_map.pm_prog);
00588          if (rpc)
00589            printf ("  %s\n", rpc->r_name);
00590          else
00591            printf ("\n");
00592        }
00593     }
00594 }
00595 
00596 /*
00597  * reply_proc collects replies from the broadcast.
00598  * to get a unique list of responses the output of rpcinfo should
00599  * be piped through sort(1) and then uniq(1).
00600  */
00601 
00602 /*ARGSUSED */
00603 static bool_t
00604 reply_proc (res, who)
00605      void *res;                    /* Nothing comes back */
00606      struct sockaddr_in *who;      /* Who sent us the reply */
00607 {
00608   register struct hostent *hp;
00609 
00610   hp = gethostbyaddr ((char *) &who->sin_addr, sizeof who->sin_addr,
00611                     AF_INET);
00612   printf ("%s %s\n", inet_ntoa (who->sin_addr),
00613          (hp == NULL) ? _("(unknown)") : hp->h_name);
00614   return FALSE;
00615 }
00616 
00617 static void
00618 brdcst (argc, argv)
00619      int argc;
00620      char **argv;
00621 {
00622   enum clnt_stat rpc_stat;
00623   u_long prognum, vers;
00624 
00625   if (argc != 2)
00626     {
00627       usage ();
00628       exit (1);
00629     }
00630   prognum = getprognum (argv[0]);
00631   vers = getvers (argv[1]);
00632   rpc_stat = clnt_broadcast (prognum, vers, NULLPROC, (xdrproc_t) xdr_void,
00633                           NULL, (xdrproc_t) xdr_void, NULL,
00634                           (resultproc_t) reply_proc);
00635   if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT))
00636     {
00637       fprintf (stderr, _("rpcinfo: broadcast failed: %s\n"),
00638               clnt_sperrno (rpc_stat));
00639       exit (1);
00640     }
00641   exit (0);
00642 }
00643 
00644 static void
00645 deletereg (argc, argv)
00646      int argc;
00647      char **argv;
00648 {
00649   u_long prog_num, version_num;
00650 
00651   if (argc != 2)
00652     {
00653       usage ();
00654       exit (1);
00655     }
00656   if (getuid ())
00657     {                       /* This command allowed only to root */
00658       fputs (_("Sorry. You are not root\n"), stderr);
00659       exit (1);
00660     }
00661   prog_num = getprognum (argv[0]);
00662   version_num = getvers (argv[1]);
00663   if ((pmap_unset (prog_num, version_num)) == 0)
00664     {
00665       fprintf (stderr, _("rpcinfo: Could not delete registration for prog %s version %s\n"),
00666               argv[0], argv[1]);
00667       exit (1);
00668     }
00669 }
00670 
00671 static void
00672 usage ()
00673 {
00674   fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"),
00675         stderr);
00676   fputs (_("       rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"),
00677         stderr);
00678   fputs (_("       rpcinfo -p [ host ]\n"), stderr);
00679   fputs (_("       rpcinfo -b prognum versnum\n"), stderr);
00680   fputs (_("       rpcinfo -d prognum versnum\n"), stderr);
00681 }
00682 
00683 static u_long
00684 getprognum (arg)
00685      char *arg;
00686 {
00687   register struct rpcent *rpc;
00688   register u_long prognum;
00689 
00690   if (isalpha (*arg))
00691     {
00692       rpc = getrpcbyname (arg);
00693       if (rpc == NULL)
00694        {
00695          fprintf (stderr, _("rpcinfo: %s is unknown service\n"), arg);
00696          exit (1);
00697        }
00698       prognum = rpc->r_number;
00699     }
00700   else
00701     {
00702       prognum = (u_long) atoi (arg);
00703     }
00704 
00705   return prognum;
00706 }
00707 
00708 static u_long
00709 getvers (arg)
00710      char *arg;
00711 {
00712   register u_long vers;
00713 
00714   vers = (int) atoi (arg);
00715   return vers;
00716 }
00717 
00718 static void
00719 get_inet_address (addr, host)
00720      struct sockaddr_in *addr;
00721      char *host;
00722 {
00723   register struct hostent *hp;
00724 
00725   bzero ((char *) addr, sizeof *addr);
00726   addr->sin_addr.s_addr = (u_long) inet_addr (host);
00727   if (addr->sin_addr.s_addr == INADDR_NONE
00728       || addr->sin_addr.s_addr == INADDR_ANY)
00729     {
00730       if ((hp = gethostbyname (host)) == NULL)
00731        {
00732          fprintf (stderr, _("rpcinfo: %s is unknown host\n"),
00733                  host);
00734          exit (1);
00735        }
00736       memmove ((char *) &addr->sin_addr, hp->h_addr, hp->h_length);
00737     }
00738   addr->sin_family = AF_INET;
00739 }