2 * showmount.c -- show mount information for an NFS server
3 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
20 #include <sys/socket.h>
21 #include <netinet/in.h>
24 #include <sys/types.h>
30 #include <arpa/inet.h>
36 static char * version = "showmount for " VERSION;
37 static char * program_name;
38 static int headers = 1;
44 static struct option longopts[] =
47 { "directories", 0, 0, 'd' },
48 { "exports", 0, 0, 'e' },
49 { "no-headers", 0, &headers, 0 },
50 { "version", 0, 0, 'v' },
51 { "help", 0, 0, 'h' },
55 #define MAXHOSTLEN 256
61 return strcmp(*p, *q);
64 static void usage(fp, n)
68 fprintf(fp, "Usage: %s [-adehv]\n", program_name);
69 fprintf(fp, " [--all] [--directories] [--exports]\n");
70 fprintf(fp, " [--no-headers] [--help] [--version] [host]\n");
78 char hostname_buf[MAXHOSTLEN];
80 enum clnt_stat clnt_stat;
82 struct sockaddr_in server_addr;
84 struct timeval total_timeout;
85 struct timeval pertry_timeout;
89 exports exportlist, exl;
97 program_name = argv[0];
98 while ((c = getopt_long(argc, argv, "adehv", longopts, NULL)) != EOF) {
113 printf("%s\n", version);
126 switch (aflag + dflag + eflag) {
133 fprintf(stderr, "%s: only one of -a, -d or -e is allowed\n",
141 if (gethostname(hostname_buf, MAXHOSTLEN) < 0) {
142 perror("getting hostname");
145 hostname = hostname_buf;
151 fprintf(stderr, "%s: only one hostname is allowed\n",
157 if (hostname[0] >= '0' && hostname[0] <= '9') {
158 server_addr.sin_family = AF_INET;
159 server_addr.sin_addr.s_addr = inet_addr(hostname);
162 if ((hp = gethostbyname(hostname)) == NULL) {
163 fprintf(stderr, "%s: can't get address for %s\n",
164 program_name, hostname);
167 server_addr.sin_family = AF_INET;
168 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
171 /* create mount deamon client */
173 server_addr.sin_port = 0;
175 if ((mclient = clnttcp_create(&server_addr,
176 MOUNTPROG, MOUNTVERS, &msock, 0, 0)) == NULL) {
177 server_addr.sin_port = 0;
179 pertry_timeout.tv_sec = 3;
180 pertry_timeout.tv_usec = 0;
181 if ((mclient = clntudp_create(&server_addr,
182 MOUNTPROG, MOUNTVERS, pertry_timeout, &msock)) == NULL) {
183 clnt_pcreateerror("mount clntudp_create");
187 mclient->cl_auth = authunix_create_default();
188 total_timeout.tv_sec = 20;
189 total_timeout.tv_usec = 0;
192 memset(&exportlist, '\0', sizeof(exportlist));
193 clnt_stat = clnt_call(mclient, MOUNTPROC_EXPORT,
194 (xdrproc_t) xdr_void, NULL,
195 (xdrproc_t) xdr_exports, (caddr_t) &exportlist,
197 if (clnt_stat != RPC_SUCCESS) {
198 clnt_perror(mclient, "rpc mount export");
202 printf("Export list for %s:\n", hostname);
204 for (exl = exportlist; exl; exl = exl->ex_next) {
205 if ((n = strlen(exl->ex_dir)) > maxlen)
209 printf("%-*s ", maxlen, exportlist->ex_dir);
210 grouplist = exportlist->ex_groups;
213 printf("%s%s", grouplist->gr_name,
214 grouplist->gr_next ? "," : "");
215 grouplist = grouplist->gr_next;
218 printf("(everyone)");
220 exportlist = exportlist->ex_next;
225 memset(&dumplist, '\0', sizeof(dumplist));
226 clnt_stat = clnt_call(mclient, MOUNTPROC_DUMP,
227 (xdrproc_t) xdr_void, NULL,
228 (xdrproc_t) xdr_mountlist, (caddr_t) &dumplist,
230 if (clnt_stat != RPC_SUCCESS) {
231 clnt_perror(mclient, "rpc mount dump");
236 for (list = dumplist; list; list = list->ml_next)
238 dumpv = (char **) calloc(n, sizeof (char *));
240 fprintf(stderr, "%s: out of memory\n", program_name);
247 printf("Hosts on %s:\n", hostname);
249 dumpv[i++] = dumplist->ml_hostname;
250 dumplist = dumplist->ml_next;
255 printf("All mount points on %s:\n", hostname);
259 t=malloc(strlen(dumplist->ml_hostname)+strlen(dumplist->ml_directory)+2);
262 fprintf(stderr, "%s: out of memory\n", program_name);
265 sprintf(t, "%s:%s", dumplist->ml_hostname, dumplist->ml_directory);
267 dumplist = dumplist->ml_next;
272 printf("Directories on %s:\n", hostname);
274 dumpv[i++] = dumplist->ml_directory;
275 dumplist = dumplist->ml_next;
279 qsort(dumpv, n, sizeof (char *), dump_cmp);
281 for (i = 0; i < n; i++) {
282 if (i == 0 || strcmp(dumpv[i], dumpv[i - 1]) != 0)
283 printf("%s\n", dumpv[i]);