summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>2001-08-20 22:05:05 +0000
committerPascal Rigaux <pixel@mandriva.com>2001-08-20 22:05:05 +0000
commit314859a4872032b07c5d0e57adf3d596049e2fdc (patch)
tree462d0e3624917538602f4ad456a384ebb8b45edc
parentb0ca1896edd65eb0a43d6d031ba3b4d2fd0c008f (diff)
downloaddrakx-backup-do-not-use-314859a4872032b07c5d0e57adf3d596049e2fdc.tar
drakx-backup-do-not-use-314859a4872032b07c5d0e57adf3d596049e2fdc.tar.gz
drakx-backup-do-not-use-314859a4872032b07c5d0e57adf3d596049e2fdc.tar.bz2
drakx-backup-do-not-use-314859a4872032b07c5d0e57adf3d596049e2fdc.tar.xz
drakx-backup-do-not-use-314859a4872032b07c5d0e57adf3d596049e2fdc.zip
basic nfs handling in drakx
-rw-r--r--perl-install/Makefile2
-rw-r--r--perl-install/Makefile.drakxtools4
-rw-r--r--perl-install/fs.pm9
-rw-r--r--perl-install/network/nfs.pm42
-rw-r--r--tools/.cvsignore1
-rw-r--r--tools/Makefile4
-rw-r--r--tools/rpcinfo-flushed.c740
7 files changed, 791 insertions, 11 deletions
diff --git a/perl-install/Makefile b/perl-install/Makefile
index b872c7de1..ffa280b4f 100644
--- a/perl-install/Makefile
+++ b/perl-install/Makefile
@@ -17,7 +17,7 @@ clean:
tar-drakxtools: clean
$(MAKE) -C ../tools clean
- cd .. ; rm -rf drakxtools ; cp -af perl-install drakxtools ; cp -af tools/ddcprobe tools/serial_probe drakxtools
+ cd .. ; rm -rf drakxtools ; cp -af perl-install drakxtools ; cp -af rpcinfo-flushed.c tools/ddcprobe tools/serial_probe drakxtools
cd ../drakxtools ; perl -pi -e 's/^C_RPM.*/C_RPM=0/; s/^C_DRAKX.*/C_DRAKX=0/' c/Makefile
cd ../drakxtools ; rm -rf install* pkgs.pm help.pm ftp.pm t.pm */CVS ; mv Makefile.drakxtools Makefile ; mv -f standalone/* .
cd .. ; tar cfj drakxtools.tar.bz2 --exclude CVS $(patsubst %,drakxtools/%,Makefile Makefile.config Newt c ddcprobe serial_probe share/po sbus_probing resize_fat share/diskdrake.rc share/wizard.rc $(STANDALONEPMS) icons pixmaps network interactive_http *.pm)
diff --git a/perl-install/Makefile.drakxtools b/perl-install/Makefile.drakxtools
index adfde50e5..153212f4c 100644
--- a/perl-install/Makefile.drakxtools
+++ b/perl-install/Makefile.drakxtools
@@ -17,7 +17,7 @@ NETLIBDEST = $(LIBDIR)/$(NAME)/network
PIXDIR = $(DATADIR)/$(NAME)/pixmaps
.PHONY: $(DIRS)
-all: $(DIRS)
+all: rpcinfo-flushed $(DIRS)
$(DIRS):
install -d auto
@@ -29,7 +29,7 @@ install:
install -d $(BINDEST) $(ETCDEST) $(SBINDEST) $(DATADIR) $(LIBDEST) $(NETLIBDEST) $(BINX11DEST) $(LIBX11DEST) $(PIXDIR)
install -d $(INLIBDEST_DIRS:%=$(LIBDEST)/%)
install $(STANDALONEPMS) $(SBINDEST)
- install -s ddcprobe/ddcxinfos serial_probe/serial_probe $(SBINDEST)
+ install -s rpcinfo-flushed ddcprobe/ddcxinfos serial_probe/serial_probe $(SBINDEST)
ln -s ../../$(patsubst $(PREFIX)/usr%,%,$(SBINDEST))/XFdrake $(BINX11DEST)/Xdrakres
install -m 644 *.pm $(LIBDEST)
diff --git a/perl-install/fs.pm b/perl-install/fs.pm
index a511ce931..3562f3cf1 100644
--- a/perl-install/fs.pm
+++ b/perl-install/fs.pm
@@ -507,11 +507,8 @@ sub mount {
my @fs_modules = qw(vfat hfs romfs ufs reiserfs xfs jfs ext3);
- if ($fs eq 'nfs') {
- log::l("calling nfs::mount($dev, $where)");
-# nfs::mount($dev, $where) or die _("nfs mount failed");
- } elsif ($fs eq 'smbfs') {
- die "no smb yet...";
+ if (member($fs, 'smb', 'nfs') && $::isStandalone) {
+ system('mount', $dev, $where) == 0 or die _("mount failed");
} elsif (member($fs, 'ext2', @fs_modules)) {
$dev = devices::make($dev) if $fs ne 'proc' && $fs ne 'usbdevfs';
@@ -579,7 +576,7 @@ sub mount_part {
} elsif (loopback::carryRootLoopback($part)) {
$mntpoint = "/initrd/loopfs";
}
- mount(devices::make($dev), $mntpoint, type2fs($part), $rdonly);
+ mount($dev, $mntpoint, type2fs($part), $rdonly);
rmdir "$mntpoint/lost+found";
}
}
diff --git a/perl-install/network/nfs.pm b/perl-install/network/nfs.pm
new file mode 100644
index 000000000..8429d1a69
--- /dev/null
+++ b/perl-install/network/nfs.pm
@@ -0,0 +1,42 @@
+package network::nfs;
+
+use common;
+use network::network;
+
+sub check {
+ my ($in) = @_;
+
+ my $f = '/usr/sbin/showmount';
+ -e $f or $in->do_pkgs->install('nfs-utils-clients');
+ -e $f or $in->ask_warn('', "Mandatory package nfs-utils-clients is missing"), return;
+ 1;
+}
+
+
+sub find_servers() {
+ local (*F, $_);
+ my $pid = open F, "rpcinfo-flushed -b mountd 2 |";
+ $SIG{ALRM} = sub { kill(15, $pid) };
+ alarm 1;
+
+ my $domain = chomp_(`domainname`);
+ my @servers;
+ while (<F>) {
+ chomp;
+ my ($ip, $name) = /(\S+)\s+(\S+)/ or log::l("bad line in rpcinfo output"), next;
+ $name =~ s/\Q.$domain//;
+ $name =~ s/\.$//;
+ push @servers, { ip => $ip, if_($name ne '(unknown)', name => $name) };
+ }
+ @servers;
+}
+
+sub find_exports {
+ my ($server) = @_;
+
+ my (undef, @l) = `showmount -e $server->{ip}`;
+ map { /(\S+)\s*(\S+)/; { name => $1, comment => $2 } } @l;
+}
+
+1;
+
diff --git a/tools/.cvsignore b/tools/.cvsignore
index 21a6d396b..88754bc8b 100644
--- a/tools/.cvsignore
+++ b/tools/.cvsignore
@@ -1,3 +1,4 @@
rpm2header
gendepslist
xhost+
+rpcinfo-flushed
diff --git a/tools/Makefile b/tools/Makefile
index 681f5748f..551c4fefc 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -7,7 +7,7 @@ CFLAGS = -Wall
.PHONY: clean install $(DIRS)
-all: $(BASE)/depslist.ordered $(BASE)/compss $(DIRS) xhost+ install
+all: $(BASE)/depslist.ordered $(BASE)/compss $(DIRS) xhost+ rpcinfo-flushed install
$(DIRS):
make -C $@
@@ -35,4 +35,4 @@ $(BASE)/hdlist.cz: $(BASE)/hdlists $(RPMS)
clean:
for i in $(DIRS); do $(MAKE) -C $$i clean; done
- rm -rf *~ xhost+ ddcprobe/ddcxinfos */*.o
+ rm -rf *~ xhost+ rpcinfo-flushed ddcprobe/ddcxinfos */*.o
diff --git a/tools/rpcinfo-flushed.c b/tools/rpcinfo-flushed.c
new file mode 100644
index 000000000..16303406d
--- /dev/null
+++ b/tools/rpcinfo-flushed.c
@@ -0,0 +1,740 @@
+#define _(x) x
+
+/* @(#)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) __attribute__ ((noreturn));
+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, "");
+
+ 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)
+ {
+ fputs (_("rpcinfo: can't contact portmapper"), stderr);
+ fputs (": ", stderr);
+ clnt_perror (client, "rpcinfo");
+ exit (1);
+ }
+ if (head == NULL)
+ {
+ fputs (_("No remote programs registered.\n"), stdout);
+ }
+ else
+ {
+ fputs (_(" program vers proto port\n"), stdout);
+ 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);
+ fflush(stdout);
+ 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 */
+ fputs (_("Sorry. You are not root\n"), stderr);
+ 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 ()
+{
+ fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"),
+ stderr);
+ fputs (_(" rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"),
+ stderr);
+ fputs (_(" rpcinfo -p [ host ]\n"), stderr);
+ fputs (_(" rpcinfo -b prognum versnum\n"), stderr);
+ fputs (_(" rpcinfo -d prognum versnum\n"), stderr);
+}
+
+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 == INADDR_NONE
+ || addr->sin_addr.s_addr == INADDR_ANY)
+ {
+ 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;
+}