]> git.decadent.org.uk Git - nfs-utils.git/blob - utils/showmount/showmount.c
Initial revision
[nfs-utils.git] / utils / showmount / showmount.c
1 /*
2  * showmount.c -- show mount information for an NFS server
3  * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
4  *
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)
8  * any later version.
9  *
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.
14  */
15
16 #include "config.h"
17
18 #include <stdio.h>
19 #include <rpc/rpc.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <sys/time.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <memory.h>
27 #include <stdlib.h>
28
29 #include <netdb.h>
30 #include <arpa/inet.h>
31 #include <errno.h>
32 #include <getopt.h>
33 #include <mount.h>
34 #include <unistd.h>
35
36 static char *   version = "showmount for " VERSION;
37 static char *   program_name;
38 static int      headers = 1;
39 static int      hflag = 0;
40 static int      aflag = 0;
41 static int      dflag = 0;
42 static int      eflag = 0;
43
44 static struct option longopts[] =
45 {
46         { "all", 0, 0, 'a' },
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' },
52         { NULL, 0, 0, 0 }
53 };
54
55 #define MAXHOSTLEN 256
56
57 int dump_cmp(p, q)
58 char **p;
59 char **q;
60 {
61         return strcmp(*p, *q);
62 }
63
64 static void usage(fp, n)
65 FILE *fp;
66 int n;
67 {
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");
71         exit(n);
72 }
73
74 int main(argc, argv)
75 int argc;
76 char **argv;
77 {
78         char hostname_buf[MAXHOSTLEN];
79         char *hostname;
80         enum clnt_stat clnt_stat;
81         struct hostent *hp;
82         struct sockaddr_in server_addr;
83         int msock;
84         struct timeval total_timeout;
85         struct timeval pertry_timeout;
86         int c;
87         CLIENT *mclient;
88         groups grouplist;
89         exports exportlist, exl;
90         mountlist dumplist;
91         mountlist list;
92         int i;
93         int n;
94         int maxlen;
95         char **dumpv;
96
97         program_name = argv[0];
98         while ((c = getopt_long(argc, argv, "adehv", longopts, NULL)) != EOF) {
99                 switch (c) {
100                 case 'a':
101                         aflag = 1;
102                         break;
103                 case 'd':
104                         dflag = 1;
105                         break;
106                 case 'e':
107                         eflag = 1;
108                         break;
109                 case 'h':
110                         usage(stdout, 0);
111                         break;
112                 case 'v':
113                         printf("%s\n", version);
114                         exit(0);
115                 case 0:
116                         break;
117                 case '?':
118                 default:
119                         usage(stderr, 1);
120                         break;
121                 }
122         }
123         argc -= optind;
124         argv += optind;
125
126         switch (aflag + dflag + eflag) {
127         case 0:
128                 hflag = 1;
129                 break;
130         case 1:
131                 break;
132         default:
133                 fprintf(stderr, "%s: only one of -a, -d or -e is allowed\n",
134                         program_name);
135                 exit(1);
136                 break;
137         }
138
139         switch (argc) {
140         case 0:
141                 if (gethostname(hostname_buf, MAXHOSTLEN) < 0) {
142                         perror("getting hostname");
143                         exit(1);
144                 }
145                 hostname = hostname_buf;
146                 break;
147         case 1:
148                 hostname = argv[0];
149                 break;
150         default:
151                 fprintf(stderr, "%s: only one hostname is allowed\n",
152                         program_name);
153                 exit(1);
154                 break;
155         }
156
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);
160         }
161         else {
162                 if ((hp = gethostbyname(hostname)) == NULL) {
163                         fprintf(stderr, "%s: can't get address for %s\n",
164                                 program_name, hostname);
165                         exit(1);
166                 }
167                 server_addr.sin_family = AF_INET;
168                 memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
169         }
170
171         /* create mount deamon client */
172
173         server_addr.sin_port = 0;
174         msock = RPC_ANYSOCK;
175         if ((mclient = clnttcp_create(&server_addr,
176             MOUNTPROG, MOUNTVERS, &msock, 0, 0)) == NULL) {
177                 server_addr.sin_port = 0;
178                 msock = RPC_ANYSOCK;
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");
184                         exit(1);
185                 }
186         }
187         mclient->cl_auth = authunix_create_default();
188         total_timeout.tv_sec = 20;
189         total_timeout.tv_usec = 0;
190
191         if (eflag) {
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,
196                         total_timeout);
197                 if (clnt_stat != RPC_SUCCESS) {
198                         clnt_perror(mclient, "rpc mount export");
199                         exit(1);
200                 }
201                 if (headers)
202                         printf("Export list for %s:\n", hostname);
203                 maxlen = 0;
204                 for (exl = exportlist; exl; exl = exl->ex_next) {
205                         if ((n = strlen(exl->ex_dir)) > maxlen)
206                                 maxlen = n;
207                 }
208                 while (exportlist) {
209                         printf("%-*s ", maxlen, exportlist->ex_dir);
210                         grouplist = exportlist->ex_groups;
211                         if (grouplist)
212                                 while (grouplist) {
213                                         printf("%s%s", grouplist->gr_name,
214                                                 grouplist->gr_next ? "," : "");
215                                         grouplist = grouplist->gr_next;
216                                 }
217                         else
218                                 printf("(everyone)");
219                         printf("\n");
220                         exportlist = exportlist->ex_next;
221                 }
222                 exit(0);
223         }
224
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,
229                 total_timeout);
230         if (clnt_stat != RPC_SUCCESS) {
231                 clnt_perror(mclient, "rpc mount dump");
232                 exit(1);
233         }
234
235         n = 0;
236         for (list = dumplist; list; list = list->ml_next)
237                 n++;
238         dumpv = (char **) calloc(n, sizeof (char *));
239         if (n && !dumpv) {
240                 fprintf(stderr, "%s: out of memory\n", program_name);
241                 exit(1);
242         }
243         i = 0;
244
245         if (hflag) {
246                 if (headers)
247                         printf("Hosts on %s:\n", hostname);
248                 while (dumplist) {
249                         dumpv[i++] = dumplist->ml_hostname;
250                         dumplist = dumplist->ml_next;
251                 }
252         }
253         else if (aflag) {
254                 if (headers)
255                         printf("All mount points on %s:\n", hostname);
256                 while (dumplist) {
257                         char *t;
258
259                         t=malloc(strlen(dumplist->ml_hostname)+strlen(dumplist->ml_directory)+2);
260                         if (!t)
261                         {
262                                 fprintf(stderr, "%s: out of memory\n", program_name);
263                                 exit(1);
264                         }
265                         sprintf(t, "%s:%s", dumplist->ml_hostname, dumplist->ml_directory);
266                         dumpv[i++] = t;
267                         dumplist = dumplist->ml_next;
268                 }
269         }
270         else if (dflag) {
271                 if (headers)
272                         printf("Directories on %s:\n", hostname);
273                 while (dumplist) {
274                         dumpv[i++] = dumplist->ml_directory;
275                         dumplist = dumplist->ml_next;
276                 }
277         }
278
279         qsort(dumpv, n, sizeof (char *), dump_cmp);
280         
281         for (i = 0; i < n; i++) {
282                 if (i == 0 || strcmp(dumpv[i], dumpv[i - 1]) != 0)
283                         printf("%s\n", dumpv[i]);
284         }
285         exit(0);
286 }
287