main didn't exit
[unix-history] / usr / src / usr.bin / showmount / showmount.c
CommitLineData
7918c07a
KM
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
cb956e54 8 * %sccs.include.redist.c%
7918c07a
KM
9 */
10
11#ifndef lint
12char copyright[] =
13"@(#) Copyright (c) 1989 Regents of the University of California.\n\
14 All rights reserved.\n";
15#endif not lint
16
17#ifndef lint
4c529d71 18static char sccsid[] = "@(#)showmount.c 6.5 (Berkeley) %G%";
7918c07a
KM
19#endif not lint
20
7918c07a
KM
21#include <sys/types.h>
22#include <sys/file.h>
23#include <sys/socket.h>
24#include <sys/socketvar.h>
25#include <netdb.h>
26#include <rpc/rpc.h>
27#include <rpc/pmap_clnt.h>
28#include <rpc/pmap_prot.h>
29#include <nfs/rpcv2.h>
38dde0cd
KB
30#include <stdio.h>
31#include <string.h>
7918c07a
KM
32
33/* Constant defs */
34#define ALL 1
35#define DIRS 2
36
37#define DODUMP 0x1
38#define DOEXPORTS 0x2
39
40struct mountlist {
41 struct mountlist *ml_left;
42 struct mountlist *ml_right;
43 char ml_host[RPCMNT_NAMELEN+1];
44 char ml_dirp[RPCMNT_PATHLEN+1];
45};
46
47struct grouplist {
48 struct grouplist *gr_next;
49 char gr_name[RPCMNT_NAMELEN+1];
50};
51
52struct exportslist {
53 struct exportslist *ex_next;
54 struct grouplist *ex_groups;
55 char ex_dirp[RPCMNT_PATHLEN+1];
56};
57
58static struct mountlist *mntdump;
59static struct exportslist *exports;
60static int type = 0;
61int xdr_mntdump(), xdr_exports();
62
63/*
64 * This command queries the NFS mount daemon for it's mount list and/or
65 * it's exports list and prints them out.
66 * See "NFS: Network File System Protocol Specification, RFC1094, Appendix A"
67 * for detailed information on the protocol.
68 */
69main(argc, argv)
70 int argc;
71 char **argv;
72{
73 register struct mountlist *mntp;
74 register struct exportslist *exp;
75 register struct grouplist *grp;
76 extern char *optarg;
77 extern int optind;
78 register int rpcs = 0;
79 char ch;
80 char *host;
81 int estat;
82
83 while ((ch = getopt(argc, argv, "ade")) != EOF)
84 switch((char)ch) {
85 case 'a':
86 if (type == 0) {
87 type = ALL;
88 rpcs |= DODUMP;
89 } else
90 usage();
91 break;
92 case 'd':
93 if (type == 0) {
94 type = DIRS;
95 rpcs |= DODUMP;
96 } else
97 usage();
98 break;
99 case 'e':
100 rpcs |= DOEXPORTS;
101 break;
102 case '?':
103 default:
104 usage();
105 }
106 argc -= optind;
107 argv += optind;
108
109 if (argc > 0)
110 host = *argv;
111 else
112 host = "localhost";
113
114 if (rpcs == 0)
115 rpcs = DODUMP;
116
117 if (rpcs & DODUMP)
118 if ((estat = callrpc(host, RPCPROG_MNT, RPCMNT_VER1,
119 RPCMNT_DUMP, xdr_void, (char *)0,
120 xdr_mntdump, (char *)&mntdump)) != 0) {
121 clnt_perrno(estat);
122 fprintf(stderr, "Can't do Mountdump rpc\n");
123 exit(1);
124 }
125 if (rpcs & DOEXPORTS)
126 if ((estat = callrpc(host, RPCPROG_MNT, RPCMNT_VER1,
127 RPCMNT_EXPORT, xdr_void, (char *)0,
128 xdr_exports, (char *)&exports)) != 0) {
129 clnt_perrno(estat);
130 fprintf(stderr, "Can't do Exports rpc\n");
131 exit(1);
132 }
133
134 /* Now just print out the results */
135 if (rpcs & DODUMP) {
136 switch (type) {
137 case ALL:
138 printf("All mount points on %s:\n", host);
139 break;
140 case DIRS:
141 printf("Directories on %s:\n", host);
142 break;
143 default:
144 printf("Hosts on %s:\n", host);
145 break;
146 };
147 print_dump(mntdump);
148 }
149 if (rpcs & DOEXPORTS) {
150 printf("Exports list on %s:\n", host);
151 exp = exports;
152 while (exp) {
153 printf("%-35s", exp->ex_dirp);
154 grp = exp->ex_groups;
155 if (grp == NULL) {
156 printf("Everyone\n");
157 } else {
158 while (grp) {
159 printf("%s ", grp->gr_name);
160 grp = grp->gr_next;
161 }
162 printf("\n");
163 }
164 exp = exp->ex_next;
165 }
166 }
167}
168
169/*
170 * Xdr routine for retrieving the mount dump list
171 */
172xdr_mntdump(xdrsp, mlp)
173 XDR *xdrsp;
174 struct mountlist **mlp;
175{
176 register struct mountlist *mp;
177 register struct mountlist *tp;
178 register struct mountlist **otp;
179 int val, val2;
180 int bool;
181 char *strp;
182
183 *mlp = (struct mountlist *)0;
184 if (!xdr_bool(xdrsp, &bool))
185 return (0);
186 while (bool) {
187 mp = (struct mountlist *)malloc(sizeof(struct mountlist));
188 if (mp == NULL)
189 return (0);
190 mp->ml_left = mp->ml_right = (struct mountlist *)0;
191 strp = mp->ml_host;
192 if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
193 return (0);
194 strp = mp->ml_dirp;
195 if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
196 return (0);
197
198 /*
199 * Build a binary tree on sorted order of either host or dirp.
200 * Drop any duplications.
201 */
202 if (*mlp == NULL) {
203 *mlp = mp;
204 } else {
205 tp = *mlp;
206 while (tp) {
207 val = strcmp(mp->ml_host, tp->ml_host);
208 val2 = strcmp(mp->ml_dirp, tp->ml_dirp);
209 switch (type) {
210 case ALL:
211 if (val == 0) {
212 if (val2 == 0) {
213 free((caddr_t)mp);
214 goto next;
215 }
216 val = val2;
217 }
218 break;
219 case DIRS:
220 if (val2 == 0) {
221 free((caddr_t)mp);
222 goto next;
223 }
224 val = val2;
225 break;
226 default:
227 if (val == 0) {
228 free((caddr_t)mp);
229 goto next;
230 }
231 break;
232 };
233 if (val < 0) {
234 otp = &tp->ml_left;
235 tp = tp->ml_left;
236 } else {
237 otp = &tp->ml_right;
238 tp = tp->ml_right;
239 }
240 }
241 *otp = mp;
242 }
243next:
244 if (!xdr_bool(xdrsp, &bool))
245 return (0);
246 }
247 return (1);
248}
249
250/*
251 * Xdr routine to retrieve exports list
252 */
253xdr_exports(xdrsp, exp)
254 XDR *xdrsp;
255 struct exportslist **exp;
256{
257 register struct exportslist *ep;
258 register struct grouplist *gp;
259 int bool, grpbool;
260 char *strp;
261
262 *exp = (struct exportslist *)0;
263 if (!xdr_bool(xdrsp, &bool))
264 return (0);
265 while (bool) {
266 ep = (struct exportslist *)malloc(sizeof(struct exportslist));
267 if (ep == NULL)
268 return (0);
269 ep->ex_groups = (struct grouplist *)0;
270 strp = ep->ex_dirp;
271 if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
272 return (0);
273 if (!xdr_bool(xdrsp, &grpbool))
274 return (0);
275 while (grpbool) {
276 gp = (struct grouplist *)malloc(sizeof(struct grouplist));
277 if (gp == NULL)
278 return (0);
279 strp = gp->gr_name;
280 if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
281 return (0);
282 gp->gr_next = ep->ex_groups;
283 ep->ex_groups = gp;
284 if (!xdr_bool(xdrsp, &grpbool))
285 return (0);
286 }
287 ep->ex_next = *exp;
288 *exp = ep;
289 if (!xdr_bool(xdrsp, &bool))
290 return (0);
291 }
292 return (1);
293}
294
7918c07a
KM
295usage()
296{
4c529d71 297 fprintf(stderr, "usage: showmount [-ade] host\n");
7918c07a
KM
298 exit(1);
299}
300
301/*
302 * Print the binary tree in inorder so that output is sorted.
303 */
304print_dump(mp)
305 struct mountlist *mp;
306{
307
4e44e2fe
KM
308 if (mp == NULL)
309 return;
7918c07a
KM
310 if (mp->ml_left)
311 print_dump(mp->ml_left);
312 switch (type) {
313 case ALL:
314 printf("%s:%s\n", mp->ml_host, mp->ml_dirp);
315 break;
316 case DIRS:
317 printf("%s\n", mp->ml_dirp);
318 break;
319 default:
320 printf("%s\n", mp->ml_host);
321 break;
322 };
323 if (mp->ml_right)
324 print_dump(mp->ml_right);
325}