From 314859a4872032b07c5d0e57adf3d596049e2fdc Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Mon, 20 Aug 2001 22:05:05 +0000 Subject: basic nfs handling in drakx --- perl-install/Makefile | 2 +- perl-install/Makefile.drakxtools | 4 +- perl-install/fs.pm | 9 +- perl-install/network/nfs.pm | 42 +++ tools/.cvsignore | 1 + tools/Makefile | 4 +- tools/rpcinfo-flushed.c | 740 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 791 insertions(+), 11 deletions(-) create mode 100644 perl-install/network/nfs.pm create mode 100644 tools/rpcinfo-flushed.c 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 () { + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- cgit v1.2.1