mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 03:10:05 +00:00
e7fd8a39ab
1997-03-27 02:28 Ulrich Drepper <drepper@cygnus.com> * gmon/gmon.c (monstartup): Mark all messages. (write_call_graph): Rewrite to use larger I/O vector for writev call to reduce syscall overhead. (write_bb_counts): Simplify writev handling. * inet/rexec.c: Make string parameters `const'. * resolv/netdb.h: Add prototypes for rcmd, rexec, ruserok, and rresvport. * math/Makefile: Don't define CFLAGS-* macros to prevent inlining in libm-test. * math/libm-test.c (this_does_nothing): Remove functions. It's notuseful on any platform but ix86. (inverse_func_pair_test): Don't use this_does_nothing. Use memory reference. (identities1_test): Likewise. (identities2_test): Likewise. (identities3_test): Likewise. (basic_test): Likewise. Patch by Andreas Schwab. (BUILD_COMPLEX): New macro. Create complex number from real and imaginary parts. This works around bugs/inefficiencies in current gcc. (cexp_test): Use BUILD_COMPLEX. Add more tests. * nss/nsswitch.c: Fix typo. * posix/glob.h: Add declaration for glob_pattern_p. * posix/glob.c: Rename glob_pattern_p to __glob_pattern_p and make glob_pattern_p a weak alias. This function is used in other packages (e.g. bash). * signal/Makefile (routines): Add sigisempty, sigandset, and sigorset. * signal/signal.h: Add prototypes for sigisempty, sigandset, and sigorset. * signal/sigisempty.c: New file. * signal/sigandset.c: New file. * signal/sigorset.c: New file. * sysdeps/generic/sigset.h: Define __sigisemptyset, __sigandset, and __sigorset. * sysdeps/unix/sysv/linux/sigset.h: Likewise. * stdlib/strtod.c: Handle `n-char-sequence' in NaN parsing. It determines the bits in the mantissa part of the NaN. * stdlib/strtof.c: Define SET_MANTISSA for float type. * wcsmbs/wcstof.c: Define SET_MANTISSA for float type. * stdlib/strtold.c: Define SET_MANTISSA for long double type. * wcsmbs/wcstold.c: Define SET_MANTISSA for long double type. * sysdeps/libm-ieee754/s_cexp.c: Use explicit assignment to complex number components. Some more corrects for special cases. * sysdeps/libm-ieee754/s_cexpf.c: Likewise. * sysdeps/libm-ieee754/s_cexpl.c: Likewise. * sysdeps/sparc/elf/start.S: Remove as per request of Miguel de Icaza. * sysdeps/unix/sysv/linux/netinet/icmp.h: Remove since we have ip_icmp.h. Reported by HJ Lu. 1997-03-25 03:50 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/Makefile (CFLAGS-rtld.c): Add -Wno-unused. * sysdeps/m68k/dl-machine.h (elf_machine_rela): Rewritten as for i386. (elf_machine_lookup_noexec_p, elf_machine_lookup_noplt_p, ELF_MACHINE_RELOC_NOPLT): Define. 1997-03-25 03:48 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * grp/grp.h: Include <stddef.h> only once. 1997-03-25 09:38 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/termbits.h (OXTABS): Don't define. * sysdeps/unix/sysv/linux/alpha/termbits.h (OXTABS): Likewise. * termios/sys/ttydefaults.h (TTYDEF_OFLAG): Use either OXTABS or TAB3, if one of them is defined. 1997-03-26 04:53 Ulrich Drepper <drepper@cygnus.com> * posix/glob.c (next_brace_sub): Decrement depth counter when '}' is found. Patch by Dennis Henriksen <opus@flamingo.osrl.dk>. 1997-03-25 16:25 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * sunrpc/Makefile: Comment gccwarn out. * sunrpc/auth_none.c: Fix prototypes and parameters for compiling with enabled warnings. * sunrpc/auth_unix.c: Likewise. * sunrpc/authuxprot.c: Likewise. * sunrpc/bindrsvprt.c: Likewise. * sunrpc/clnt_gen.c: Likewise. * sunrpc/clnt_perr.c: Likewise. * sunrpc/clnt_raw.c: Likewise. * sunrpc/clnt_simp.c: Likewise. * sunrpc/clnt_tcp.c: Likewise. * sunrpc/clnt_udp.c: Likewise. * sunrpc/get_myaddr.c: Likewise. * sunrpc/getrpcport.c: Likewise. * sunrpc/pm_getmaps.c: Likewise. * sunrpc/pm_getport.c: Likewise. * sunrpc/pmap_clnt.c: Likewise. * sunrpc/pmap_prot.c: Likewise. * sunrpc/pmap_prot2.c: Likewise. * sunrpc/pmap_rmt.c: Likewise. * sunrpc/rpc/auth.h: Likewise. * sunrpc/rpc/clnt.h: Likewise. * sunrpc/rpc/pmap_clnt.h: Likewise. * sunrpc/rpc/svc.h: Likewise. * sunrpc/rpc/svc_auth.h: Likewise. * sunrpc/rpc/types.h: Likewise. * sunrpc/rpc/xdr.h: Likewise. * sunrpc/rpc_clntout.c: Likewise. * sunrpc/rpc_cmsg.c: Likewise. * sunrpc/rpc_dtable.c: Likewise. * sunrpc/rpc_prot.c: Likewise. * sunrpc/svc.c: Likewise. * sunrpc/svc_auth.c: Likewise. * sunrpc/svc_authux.c: Likewise. * sunrpc/svc_raw.c: Likewise. * sunrpc/svc_run.c: Likewise. * sunrpc/svc_simple.c: Likewise. * sunrpc/svc_tcp.c: Likewise. * sunrpc/svc_udp.c: Likewise. * sunrpc/xdr.c: Likewise. * sunrpc/xdr_array.c: Likewise. * sunrpc/xdr_mem.c: Likewise. * sunrpc/xdr_rec.c: Likewise. * sunrpc/xdr_ref.c: Likewise. * sunrpc/xdr_stdio.c: Likewise. 1997-03-25 13:39 Ulrich Drepper <drepper@cygnus.com> * math/libm-test.c (log2_test): Compile this function and call it. (exp2_test): Likewise, but check whether function really exists before testing. * math/Makefile (libm-calls): Add s_log2 and s_exp2. 1997-03-25 04:50 Ulrich Drepper <drepper@cygnus.com> Implement exp2 function. * sysdeps/libm-i387/s_exp2.S: New file. * sysdeps/libm-i387/s_exp2f.S: New file. * sysdeps/libm-i387/s_exp2l.S: New file. Implement log2 function. * sysdeps/libm-i387/s_log2.S: New file. * sysdeps/libm-i387/s_log2f.S: New file. * sysdeps/libm-i387/s_log2l.S: New file. * sysdeps/libm-ieee754/s_log2.c: New file. * sysdeps/libm-ieee754/s_log2f.c: New file. * sysdeps/stub/s_log2.c: New file. Stub version.
741 lines
18 KiB
C
741 lines
18 KiB
C
|
|
/* @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC */
|
|
#if !defined(lint) && defined (SCCSID)
|
|
static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (C) 1986, Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* rpcinfo: ping a particular rpc program
|
|
* or dump the portmapper
|
|
*/
|
|
|
|
/*
|
|
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
|
* unrestricted use provided that this legend is included on all tape
|
|
* media and as a part of the software program in whole or part. Users
|
|
* may copy or modify Sun RPC without charge, but are not authorized
|
|
* to license or distribute it to anyone else except as part of a product or
|
|
* program developed by the user.
|
|
*
|
|
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
|
*
|
|
* Sun RPC is provided with no support and without any obligation on the
|
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
|
* modification or enhancement.
|
|
*
|
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
|
* OR ANY PART THEREOF.
|
|
*
|
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
|
* or profits or other special, indirect and consequential damages, even if
|
|
* Sun has been advised of the possibility of such damages.
|
|
*
|
|
* Sun Microsystems, Inc.
|
|
* 2550 Garcia Avenue
|
|
* Mountain View, California 94043
|
|
*/
|
|
|
|
#include <getopt.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <rpc/rpc.h>
|
|
#include <stdio.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <rpc/pmap_prot.h>
|
|
#include <rpc/pmap_clnt.h>
|
|
#include <signal.h>
|
|
#include <ctype.h>
|
|
#include <locale.h>
|
|
#include <libintl.h>
|
|
|
|
#define MAXHOSTLEN 256
|
|
|
|
#define MIN_VERS ((u_long) 0)
|
|
#define MAX_VERS ((u_long) 4294967295UL)
|
|
|
|
static void udpping (u_short portflag, int argc, char **argv);
|
|
static void tcpping (u_short portflag, int argc, char **argv);
|
|
static int pstatus (CLIENT *client, u_long prognum, u_long vers);
|
|
static void pmapdump (int argc, char **argv);
|
|
static bool_t reply_proc (void *res, struct sockaddr_in *who);
|
|
static void brdcst (int argc, char **argv);
|
|
static void deletereg (int argc, char **argv);
|
|
static void usage (void);
|
|
static u_long getprognum (char *arg);
|
|
static u_long getvers (char *arg);
|
|
static void get_inet_address (struct sockaddr_in *addr, char *host);
|
|
|
|
/*
|
|
* Functions to be performed.
|
|
*/
|
|
#define NONE 0 /* no function */
|
|
#define PMAPDUMP 1 /* dump portmapper registrations */
|
|
#define TCPPING 2 /* ping TCP service */
|
|
#define UDPPING 3 /* ping UDP service */
|
|
#define BRDCST 4 /* ping broadcast UDP service */
|
|
#define DELETES 5 /* delete registration for the service */
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
register int c;
|
|
int errflg;
|
|
int function;
|
|
u_short portnum;
|
|
|
|
setlocale (LC_ALL, "");
|
|
textdomain (_libc_intl_domainname);
|
|
|
|
function = NONE;
|
|
portnum = 0;
|
|
errflg = 0;
|
|
while ((c = getopt (argc, argv, "ptubdn:")) != -1)
|
|
{
|
|
switch (c)
|
|
{
|
|
|
|
case 'p':
|
|
if (function != NONE)
|
|
errflg = 1;
|
|
else
|
|
function = PMAPDUMP;
|
|
break;
|
|
|
|
case 't':
|
|
if (function != NONE)
|
|
errflg = 1;
|
|
else
|
|
function = TCPPING;
|
|
break;
|
|
|
|
case 'u':
|
|
if (function != NONE)
|
|
errflg = 1;
|
|
else
|
|
function = UDPPING;
|
|
break;
|
|
|
|
case 'b':
|
|
if (function != NONE)
|
|
errflg = 1;
|
|
else
|
|
function = BRDCST;
|
|
break;
|
|
|
|
case 'n':
|
|
portnum = (u_short) atoi (optarg); /* hope we don't get bogus # */
|
|
break;
|
|
|
|
case 'd':
|
|
if (function != NONE)
|
|
errflg = 1;
|
|
else
|
|
function = DELETES;
|
|
break;
|
|
|
|
case '?':
|
|
errflg = 1;
|
|
}
|
|
}
|
|
|
|
if (errflg || function == NONE)
|
|
{
|
|
usage ();
|
|
return (1);
|
|
}
|
|
|
|
switch (function)
|
|
{
|
|
|
|
case PMAPDUMP:
|
|
if (portnum != 0)
|
|
{
|
|
usage ();
|
|
return (1);
|
|
}
|
|
pmapdump (argc - optind, argv + optind);
|
|
break;
|
|
|
|
case UDPPING:
|
|
udpping (portnum, argc - optind, argv + optind);
|
|
break;
|
|
|
|
case TCPPING:
|
|
tcpping (portnum, argc - optind, argv + optind);
|
|
break;
|
|
|
|
case BRDCST:
|
|
if (portnum != 0)
|
|
{
|
|
usage ();
|
|
return (1);
|
|
}
|
|
brdcst (argc - optind, argv + optind);
|
|
break;
|
|
|
|
case DELETES:
|
|
deletereg (argc - optind, argv + optind);
|
|
break;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void
|
|
udpping (portnum, argc, argv)
|
|
u_short portnum;
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
struct timeval to;
|
|
struct sockaddr_in addr;
|
|
enum clnt_stat rpc_stat;
|
|
CLIENT *client;
|
|
u_long prognum, vers, minvers, maxvers;
|
|
int sock = RPC_ANYSOCK;
|
|
struct rpc_err rpcerr;
|
|
int failure;
|
|
|
|
if (argc < 2 || argc > 3)
|
|
{
|
|
usage ();
|
|
exit (1);
|
|
}
|
|
prognum = getprognum (argv[1]);
|
|
get_inet_address (&addr, argv[0]);
|
|
/* Open the socket here so it will survive calls to clnt_destroy */
|
|
sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
if (sock < 0)
|
|
{
|
|
perror ("rpcinfo: socket");
|
|
exit (1);
|
|
}
|
|
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);
|
|
to.tv_sec = 5;
|
|
to.tv_usec = 0;
|
|
if ((client = clntudp_create (&addr, prognum, (u_long) 0,
|
|
to, &sock)) == 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, (xdrproc_t) xdr_void,
|
|
(char *) NULL, (xdrproc_t) 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);
|
|
to.tv_sec = 5;
|
|
to.tv_usec = 0;
|
|
if ((client = clntudp_create (&addr, prognum, MAX_VERS,
|
|
to, &sock)) == 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, (xdrproc_t) xdr_void,
|
|
NULL, (xdrproc_t) xdr_void, 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, (u_long) 0);
|
|
exit (1);
|
|
}
|
|
clnt_destroy (client);
|
|
for (vers = minvers; vers <= maxvers; vers++)
|
|
{
|
|
addr.sin_port = htons (portnum);
|
|
to.tv_sec = 5;
|
|
to.tv_usec = 0;
|
|
if ((client = clntudp_create (&addr, prognum, vers,
|
|
to, &sock)) == NULL)
|
|
{
|
|
clnt_pcreateerror ("rpcinfo");
|
|
printf (_ ("program %lu version %lu is not available\n"),
|
|
prognum, vers);
|
|
exit (1);
|
|
}
|
|
to.tv_sec = 10;
|
|
to.tv_usec = 0;
|
|
rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
|
|
NULL, (xdrproc_t) xdr_void, NULL, to);
|
|
if (pstatus (client, prognum, vers) < 0)
|
|
failure = 1;
|
|
clnt_destroy (client);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vers = getvers (argv[2]);
|
|
addr.sin_port = htons (portnum);
|
|
to.tv_sec = 5;
|
|
to.tv_usec = 0;
|
|
if ((client = clntudp_create (&addr, prognum, vers,
|
|
to, &sock)) == NULL)
|
|
{
|
|
clnt_pcreateerror ("rpcinfo");
|
|
printf ("program %lu version %lu is not available\n",
|
|
prognum, vers);
|
|
exit (1);
|
|
}
|
|
to.tv_sec = 10;
|
|
to.tv_usec = 0;
|
|
rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
|
|
(xdrproc_t) xdr_void, NULL, to);
|
|
if (pstatus (client, prognum, vers) < 0)
|
|
failure = 1;
|
|
}
|
|
(void) close (sock); /* Close it up again */
|
|
if (failure)
|
|
exit (1);
|
|
}
|
|
|
|
static void
|
|
tcpping (portnum, argc, argv)
|
|
u_short portnum;
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
struct timeval to;
|
|
struct sockaddr_in addr;
|
|
enum clnt_stat rpc_stat;
|
|
CLIENT *client;
|
|
u_long prognum, vers, minvers, maxvers;
|
|
int sock = RPC_ANYSOCK;
|
|
struct rpc_err rpcerr;
|
|
int failure;
|
|
|
|
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, (xdrproc_t) xdr_void, NULL,
|
|
(xdrproc_t) xdr_void, 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, (xdrproc_t) xdr_void,
|
|
NULL, (xdrproc_t) xdr_void, 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, (xdrproc_t) xdr_void, NULL,
|
|
(xdrproc_t) xdr_void, 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, (xdrproc_t) xdr_void, NULL,
|
|
(xdrproc_t) xdr_void, 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 int
|
|
pstatus (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 void
|
|
pmapdump (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, (xdrproc_t) xdr_void, NULL,
|
|
(xdrproc_t) xdr_pmaplist, (caddr_t) &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_t
|
|
reply_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 void
|
|
brdcst (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, (xdrproc_t) xdr_void,
|
|
NULL, (xdrproc_t) xdr_void, NULL,
|
|
(resultproc_t) 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 void
|
|
deletereg (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 void
|
|
usage ()
|
|
{
|
|
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_long
|
|
getprognum (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_long
|
|
getvers (arg)
|
|
char *arg;
|
|
{
|
|
register u_long vers;
|
|
|
|
vers = (int) atoi (arg);
|
|
return (vers);
|
|
}
|
|
|
|
static void
|
|
get_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;
|
|
}
|