|
|
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.