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