Annotation of src/usr.bin/showmount/showmount.c, Revision 1.4
1.4 ! deraadt 1: /* $OpenBSD: showmount.c,v 1.7 1996/05/01 18:14:10 cgd Exp $ */
1.3 deraadt 2: /* $NetBSD: showmount.c,v 1.7 1996/05/01 18:14:10 cgd Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1989, 1993, 1995
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Rick Macklem at The University of Guelph.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: static char copyright[] =
42: "@(#) Copyright (c) 1989, 1993, 1995\n\
43: The Regents of the University of California. All rights reserved.\n";
44: #endif not lint
45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)showmount.c 8.3 (Berkeley) 3/29/95";
49: #endif
1.4 ! deraadt 50: static char rcsid[] = "$OpenBSD: showmount.c,v 1.7 1996/05/01 18:14:10 cgd Exp $";
1.1 deraadt 51: #endif not lint
52:
53: #include <sys/types.h>
54: #include <sys/file.h>
55: #include <sys/socket.h>
56: #include <sys/socketvar.h>
57:
58: #include <netdb.h>
59: #include <rpc/rpc.h>
60: #include <rpc/pmap_clnt.h>
61: #include <rpc/pmap_prot.h>
62: #include <nfs/rpcv2.h>
63:
64: #include <stdio.h>
65: #include <stdlib.h>
66: #include <string.h>
67: #include <unistd.h>
68:
69: /* Constant defs */
70: #define ALL 1
71: #define DIRS 2
72:
73: #define DODUMP 0x1
74: #define DOEXPORTS 0x2
75:
76: struct mountlist {
77: struct mountlist *ml_left;
78: struct mountlist *ml_right;
79: char ml_host[RPCMNT_NAMELEN+1];
80: char ml_dirp[RPCMNT_PATHLEN+1];
81: };
82:
83: struct grouplist {
84: struct grouplist *gr_next;
85: char gr_name[RPCMNT_NAMELEN+1];
86: };
87:
88: struct exportslist {
89: struct exportslist *ex_next;
90: struct grouplist *ex_groups;
91: char ex_dirp[RPCMNT_PATHLEN+1];
92: };
93:
94: static struct mountlist *mntdump;
95: static struct exportslist *exports;
96: static int type = 0;
97:
98: void print_dump __P((struct mountlist *));
99: void usage __P((void));
100: int xdr_mntdump __P((XDR *, struct mountlist **));
101: int xdr_exports __P((XDR *, struct exportslist **));
102:
103: /*
104: * This command queries the NFS mount daemon for it's mount list and/or
105: * it's exports list and prints them out.
106: * See "NFS: Network File System Protocol Specification, RFC1094, Appendix A"
107: * and the "Network File System Protocol XXX.."
108: * for detailed information on the protocol.
109: */
110: int
111: main(argc, argv)
112: int argc;
113: char **argv;
114: {
115: struct exportslist *exp;
116: struct grouplist *grp;
117: int estat, rpcs = 0, mntvers = 1;
1.2 deraadt 118: char *host;
119: int ch;
1.1 deraadt 120:
1.2 deraadt 121: while ((ch = getopt(argc, argv, "ade3")) != -1)
1.1 deraadt 122: switch((char)ch) {
123: case 'a':
124: if (type == 0) {
125: type = ALL;
126: rpcs |= DODUMP;
127: } else
128: usage();
129: break;
130: case 'd':
131: if (type == 0) {
132: type = DIRS;
133: rpcs |= DODUMP;
134: } else
135: usage();
136: break;
137: case 'e':
138: rpcs |= DOEXPORTS;
139: break;
140: case '3':
141: mntvers = 3;
142: break;
143: case '?':
144: default:
145: usage();
146: }
147: argc -= optind;
148: argv += optind;
149:
150: if (argc > 0)
151: host = *argv;
152: else
153: host = "localhost";
154:
155: if (rpcs == 0)
156: rpcs = DODUMP;
157:
158: if (rpcs & DODUMP)
159: if ((estat = callrpc(host, RPCPROG_MNT, mntvers,
160: RPCMNT_DUMP, xdr_void, (char *)0,
161: xdr_mntdump, (char *)&mntdump)) != 0) {
1.3 deraadt 162: fprintf(stderr, "showmount: Can't do Mountdump rpc: ");
1.1 deraadt 163: clnt_perrno(estat);
164: exit(1);
165: }
166: if (rpcs & DOEXPORTS)
167: if ((estat = callrpc(host, RPCPROG_MNT, mntvers,
168: RPCMNT_EXPORT, xdr_void, (char *)0,
169: xdr_exports, (char *)&exports)) != 0) {
1.3 deraadt 170: fprintf(stderr, "showmount: Can't do Exports rpc: ");
1.1 deraadt 171: clnt_perrno(estat);
172: exit(1);
173: }
174:
175: /* Now just print out the results */
176: if (rpcs & DODUMP) {
177: switch (type) {
178: case ALL:
179: printf("All mount points on %s:\n", host);
180: break;
181: case DIRS:
182: printf("Directories on %s:\n", host);
183: break;
184: default:
185: printf("Hosts on %s:\n", host);
186: break;
187: };
188: print_dump(mntdump);
189: }
190: if (rpcs & DOEXPORTS) {
191: printf("Exports list on %s:\n", host);
192: exp = exports;
193: while (exp) {
194: printf("%-35s", exp->ex_dirp);
195: grp = exp->ex_groups;
196: if (grp == NULL) {
197: printf("Everyone\n");
198: } else {
199: while (grp) {
200: printf("%s ", grp->gr_name);
201: grp = grp->gr_next;
202: }
203: printf("\n");
204: }
205: exp = exp->ex_next;
206: }
207: }
208:
209: exit(0);
210: }
211:
212: /*
213: * Xdr routine for retrieving the mount dump list
214: */
215: int
216: xdr_mntdump(xdrsp, mlp)
217: XDR *xdrsp;
218: struct mountlist **mlp;
219: {
220: struct mountlist *mp, **otp, *tp;
221: int bool, val, val2;
222: char *strp;
223:
224: *mlp = (struct mountlist *)0;
225: if (!xdr_bool(xdrsp, &bool))
226: return (0);
227: while (bool) {
228: mp = (struct mountlist *)malloc(sizeof(struct mountlist));
229: if (mp == NULL)
230: return (0);
231: mp->ml_left = mp->ml_right = (struct mountlist *)0;
232: strp = mp->ml_host;
233: if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
234: return (0);
235: strp = mp->ml_dirp;
236: if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
237: return (0);
238:
239: /*
240: * Build a binary tree on sorted order of either host or dirp.
241: * Drop any duplications.
242: */
243: if (*mlp == NULL) {
244: *mlp = mp;
245: } else {
246: tp = *mlp;
247: while (tp) {
248: val = strcmp(mp->ml_host, tp->ml_host);
249: val2 = strcmp(mp->ml_dirp, tp->ml_dirp);
250: switch (type) {
251: case ALL:
252: if (val == 0) {
253: if (val2 == 0) {
254: free((caddr_t)mp);
255: goto next;
256: }
257: val = val2;
258: }
259: break;
260: case DIRS:
261: if (val2 == 0) {
262: free((caddr_t)mp);
263: goto next;
264: }
265: val = val2;
266: break;
267: default:
268: if (val == 0) {
269: free((caddr_t)mp);
270: goto next;
271: }
272: break;
273: };
274: if (val < 0) {
275: otp = &tp->ml_left;
276: tp = tp->ml_left;
277: } else {
278: otp = &tp->ml_right;
279: tp = tp->ml_right;
280: }
281: }
282: *otp = mp;
283: }
284: next:
285: if (!xdr_bool(xdrsp, &bool))
286: return (0);
287: }
288: return (1);
289: }
290:
291: /*
292: * Xdr routine to retrieve exports list
293: */
294: int
295: xdr_exports(xdrsp, exp)
296: XDR *xdrsp;
297: struct exportslist **exp;
298: {
299: struct exportslist *ep;
300: struct grouplist *gp;
301: int bool, grpbool;
302: char *strp;
303:
304: *exp = (struct exportslist *)0;
305: if (!xdr_bool(xdrsp, &bool))
306: return (0);
307: while (bool) {
308: ep = (struct exportslist *)malloc(sizeof(struct exportslist));
309: if (ep == NULL)
310: return (0);
311: ep->ex_groups = (struct grouplist *)0;
312: strp = ep->ex_dirp;
313: if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
314: return (0);
315: if (!xdr_bool(xdrsp, &grpbool))
316: return (0);
317: while (grpbool) {
318: gp = (struct grouplist *)malloc(sizeof(struct grouplist));
319: if (gp == NULL)
320: return (0);
321: strp = gp->gr_name;
322: if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
323: return (0);
324: gp->gr_next = ep->ex_groups;
325: ep->ex_groups = gp;
326: if (!xdr_bool(xdrsp, &grpbool))
327: return (0);
328: }
329: ep->ex_next = *exp;
330: *exp = ep;
331: if (!xdr_bool(xdrsp, &bool))
332: return (0);
333: }
334: return (1);
335: }
336:
337: void
338: usage()
339: {
340:
1.3 deraadt 341: fprintf(stderr, "usage: showmount [-ade3] host\n");
1.1 deraadt 342: exit(1);
343: }
344:
345: /*
346: * Print the binary tree in inorder so that output is sorted.
347: */
348: void
349: print_dump(mp)
350: struct mountlist *mp;
351: {
352:
353: if (mp == NULL)
354: return;
355: if (mp->ml_left)
356: print_dump(mp->ml_left);
357: switch (type) {
358: case ALL:
359: printf("%s:%s\n", mp->ml_host, mp->ml_dirp);
360: break;
361: case DIRS:
362: printf("%s\n", mp->ml_dirp);
363: break;
364: default:
365: printf("%s\n", mp->ml_host);
366: break;
367: };
368: if (mp->ml_right)
369: print_dump(mp->ml_right);
370: }