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.
22 #include <sys/socket.h>
23 #include <netinet/in.h>
26 #include <sys/types.h>
32 #include <arpa/inet.h>
38 static char * version = "showmount for " VERSION;
39 static char * program_name;
40 static int headers = 1;
46 static struct option longopts[] =
49 { "directories", 0, 0, 'd' },
50 { "exports", 0, 0, 'e' },
51 { "no-headers", 0, &headers, 0 },
52 { "version", 0, 0, 'v' },
53 { "help", 0, 0, 'h' },
57 #define MAXHOSTLEN 256
63 return strcmp(*p, *q);
66 static void usage(fp, n)
70 fprintf(fp, "Usage: %s [-adehv]\n", program_name);
71 fprintf(fp, " [--all] [--directories] [--exports]\n");
72 fprintf(fp, " [--no-headers] [--help] [--version] [host]\n");
80 char hostname_buf[MAXHOSTLEN];
82 enum clnt_stat clnt_stat;
84 struct sockaddr_in server_addr;
86 struct timeval total_timeout;
87 struct timeval pertry_timeout;
91 exports exportlist, exl;
99 program_name = argv[0];
100 while ((c = getopt_long(argc, argv, "adehv", longopts, NULL)) != EOF) {
115 printf("%s\n", version);
128 switch (aflag + dflag + eflag) {
135 fprintf(stderr, "%s: only one of -a, -d or -e is allowed\n",
143 if (gethostname(hostname_buf, MAXHOSTLEN) < 0) {
144 perror("getting hostname");
147 hostname = hostname_buf;
153 fprintf(stderr, "%s: only one hostname is allowed\n",
159 if (inet_aton(hostname, &server_addr.sin_addr)) {
160 server_addr.sin_family = AF_INET;
163 if ((hp = gethostbyname(hostname)) == NULL) {
164 fprintf(stderr, "%s: can't get address for %s\n",
165 program_name, hostname);
168 server_addr.sin_family = AF_INET;
169 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
172 /* create mount deamon client */
174 server_addr.sin_port = 0;
176 if ((mclient = clnttcp_create(&server_addr,
177 MOUNTPROG, MOUNTVERS, &msock, 0, 0)) == NULL) {
178 server_addr.sin_port = 0;
180 pertry_timeout.tv_sec = 3;
181 pertry_timeout.tv_usec = 0;
182 if ((mclient = clntudp_create(&server_addr,
183 MOUNTPROG, MOUNTVERS, pertry_timeout, &msock)) == NULL) {
184 clnt_pcreateerror("mount clntudp_create");
188 mclient->cl_auth = authunix_create_default();
189 total_timeout.tv_sec = 20;
190 total_timeout.tv_usec = 0;
193 memset(&exportlist, '\0', sizeof(exportlist));
194 clnt_stat = clnt_call(mclient, MOUNTPROC_EXPORT,
195 (xdrproc_t) xdr_void, NULL,
196 (xdrproc_t) xdr_exports, (caddr_t) &exportlist,
198 if (clnt_stat != RPC_SUCCESS) {
199 clnt_perror(mclient, "rpc mount export");
203 printf("Export list for %s:\n", hostname);
205 for (exl = exportlist; exl; exl = exl->ex_next) {
206 if ((n = strlen(exl->ex_dir)) > maxlen)
210 printf("%-*s ", maxlen, exportlist->ex_dir);
211 grouplist = exportlist->ex_groups;
214 printf("%s%s", grouplist->gr_name,
215 grouplist->gr_next ? "," : "");
216 grouplist = grouplist->gr_next;
219 printf("(everyone)");
221 exportlist = exportlist->ex_next;
226 memset(&dumplist, '\0', sizeof(dumplist));
227 clnt_stat = clnt_call(mclient, MOUNTPROC_DUMP,
228 (xdrproc_t) xdr_void, NULL,
229 (xdrproc_t) xdr_mountlist, (caddr_t) &dumplist,
231 if (clnt_stat != RPC_SUCCESS) {
232 clnt_perror(mclient, "rpc mount dump");
237 for (list = dumplist; list; list = list->ml_next)
239 dumpv = (char **) calloc(n, sizeof (char *));
241 fprintf(stderr, "%s: out of memory\n", program_name);
248 printf("Hosts on %s:\n", hostname);
250 dumpv[i++] = dumplist->ml_hostname;
251 dumplist = dumplist->ml_next;
256 printf("All mount points on %s:\n", hostname);
260 t=malloc(strlen(dumplist->ml_hostname)+strlen(dumplist->ml_directory)+2);
263 fprintf(stderr, "%s: out of memory\n", program_name);
266 sprintf(t, "%s:%s", dumplist->ml_hostname, dumplist->ml_directory);
268 dumplist = dumplist->ml_next;
273 printf("Directories on %s:\n", hostname);
275 dumpv[i++] = dumplist->ml_directory;
276 dumplist = dumplist->ml_next;
280 qsort(dumpv, n, sizeof (char *), dump_cmp);
282 for (i = 0; i < n; i++) {
283 if (i == 0 || strcmp(dumpv[i], dumpv[i - 1]) != 0)
284 printf("%s\n", dumpv[i]);