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 (inet_aton(hostname, &server_addr.sin_addr.s_addr)) {
158 server_addr.sin_family = AF_INET;
161 if ((hp = gethostbyname(hostname)) == NULL) {
162 fprintf(stderr, "%s: can't get address for %s\n",
163 program_name, hostname);
166 server_addr.sin_family = AF_INET;
167 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
170 /* create mount deamon client */
172 server_addr.sin_port = 0;
174 if ((mclient = clnttcp_create(&server_addr,
175 MOUNTPROG, MOUNTVERS, &msock, 0, 0)) == NULL) {
176 server_addr.sin_port = 0;
178 pertry_timeout.tv_sec = 3;
179 pertry_timeout.tv_usec = 0;
180 if ((mclient = clntudp_create(&server_addr,
181 MOUNTPROG, MOUNTVERS, pertry_timeout, &msock)) == NULL) {
182 clnt_pcreateerror("mount clntudp_create");
186 mclient->cl_auth = authunix_create_default();
187 total_timeout.tv_sec = 20;
188 total_timeout.tv_usec = 0;
191 memset(&exportlist, '\0', sizeof(exportlist));
192 clnt_stat = clnt_call(mclient, MOUNTPROC_EXPORT,
193 (xdrproc_t) xdr_void, NULL,
194 (xdrproc_t) xdr_exports, (caddr_t) &exportlist,
196 if (clnt_stat != RPC_SUCCESS) {
197 clnt_perror(mclient, "rpc mount export");
201 printf("Export list for %s:\n", hostname);
203 for (exl = exportlist; exl; exl = exl->ex_next) {
204 if ((n = strlen(exl->ex_dir)) > maxlen)
208 printf("%-*s ", maxlen, exportlist->ex_dir);
209 grouplist = exportlist->ex_groups;
212 printf("%s%s", grouplist->gr_name,
213 grouplist->gr_next ? "," : "");
214 grouplist = grouplist->gr_next;
217 printf("(everyone)");
219 exportlist = exportlist->ex_next;
224 memset(&dumplist, '\0', sizeof(dumplist));
225 clnt_stat = clnt_call(mclient, MOUNTPROC_DUMP,
226 (xdrproc_t) xdr_void, NULL,
227 (xdrproc_t) xdr_mountlist, (caddr_t) &dumplist,
229 if (clnt_stat != RPC_SUCCESS) {
230 clnt_perror(mclient, "rpc mount dump");
235 for (list = dumplist; list; list = list->ml_next)
237 dumpv = (char **) calloc(n, sizeof (char *));
239 fprintf(stderr, "%s: out of memory\n", program_name);
246 printf("Hosts on %s:\n", hostname);
248 dumpv[i++] = dumplist->ml_hostname;
249 dumplist = dumplist->ml_next;
254 printf("All mount points on %s:\n", hostname);
258 t=malloc(strlen(dumplist->ml_hostname)+strlen(dumplist->ml_directory)+2);
261 fprintf(stderr, "%s: out of memory\n", program_name);
264 sprintf(t, "%s:%s", dumplist->ml_hostname, dumplist->ml_directory);
266 dumplist = dumplist->ml_next;
271 printf("Directories on %s:\n", hostname);
273 dumpv[i++] = dumplist->ml_directory;
274 dumplist = dumplist->ml_next;
278 qsort(dumpv, n, sizeof (char *), dump_cmp);
280 for (i = 0; i < n; i++) {
281 if (i == 0 || strcmp(dumpv[i], dumpv[i - 1]) != 0)
282 printf("%s\n", dumpv[i]);