#ifndef lint static char sccsid[] = "@(#)showmount.c 1.1 94/10/31 Copyr 1987 Sun Micro"; #endif /* * Copyright (c) 1987 Sun Microsystems, Inc. */ /* * showmount */ #include #include #include #include #include #include #include #include struct timeval TIMEOUT = { 25, 0 }; int sorthost(); int sortpath(); #define NTABLEENTRIES 2048 struct mountlist *table[NTABLEENTRIES]; main(argc, argv) int argc; char **argv; { int aflg = 0, dflg = 0, eflg = 0; int err, addr; struct mountlist *ml = NULL; struct mountlist **tb, **endtb; struct hostent *hp; char *host = NULL, hostbuf[256]; char *last; CLIENT *cl; while(--argc) { if (argv[1][0] == '-') { switch(argv[1][1]) { case 'a': aflg++; break; case 'd': dflg++; break; case 'e': eflg++; break; default: usage(); exit(1); } } else if (host) { usage(); exit(1); } else host = argv[1]; argv++; } if (host == NULL) { if (gethostname(hostbuf, sizeof(hostbuf)) < 0) { perror("showmount: gethostname"); exit(1); } host = hostbuf; } /* * First try tcp, then drop back to udp if * tcp is unavailable (an old version of mountd perhaps) * Using tcp is preferred because it can handle * arbitrarily long export lists. */ cl = clnt_create(host, MOUNTPROG, MOUNTVERS, "tcp"); if (cl == NULL) { cl = clnt_create(host, MOUNTPROG, MOUNTVERS, "udp"); if (cl == NULL) { clnt_pcreateerror(host); exit(1); } } if (eflg) { printex(cl, host); if (aflg + dflg == 0) { exit(0); } } if (err = clnt_call(cl, MOUNTPROC_DUMP, xdr_void, 0, xdr_mountlist, &ml, TIMEOUT)) { fprintf(stderr, "showmount: %s\n", clnt_sperrno(err)); exit(1); } tb = table; for (; ml != NULL && tb < &table[NTABLEENTRIES]; ml = ml->ml_nxt) *tb++ = ml; if (ml != NULL && tb == &table[NTABLEENTRIES]) printf("showmount: table overflow: only %d entries shown\n", NTABLEENTRIES); endtb = tb; if (dflg) qsort(table, endtb - table, sizeof(struct mountlist *), sortpath); else qsort(table, endtb - table, sizeof(struct mountlist *), sorthost); if (aflg) { for (tb = table; tb < endtb; tb++) printf("%s:%s\n", (*tb)->ml_name, (*tb)->ml_path); } else if (dflg) { last = ""; for (tb = table; tb < endtb; tb++) { if (strcmp(last, (*tb)->ml_path)) printf("%s\n", (*tb)->ml_path); last = (*tb)->ml_path; } } else { last = ""; for (tb = table; tb < endtb; tb++) { if (strcmp(last, (*tb)->ml_name)) printf("%s\n", (*tb)->ml_name); last = (*tb)->ml_name; } } exit(0); /* NOTREACHED */ } sorthost(a, b) struct mountlist **a,**b; { return strcmp((*a)->ml_name, (*b)->ml_name); } sortpath(a, b) struct mountlist **a,**b; { return strcmp((*a)->ml_path, (*b)->ml_path); } usage() { fprintf(stderr, "showmount [-a] [-d] [-e] [host]\n"); } printex(cl, host) CLIENT *cl; char *host; { struct exports *ex = NULL; struct exports *e; struct groups *gr; enum clnt_stat err; int max; if (err = clnt_call(cl, MOUNTPROC_EXPORT, xdr_void, 0, xdr_exports, &ex, TIMEOUT)) { fprintf(stderr, "showmount: %s\n", clnt_sperrno(err)); exit(1); } if (ex == NULL) { fprintf(stdout, "no exported file systems for %s\n", host); } else { fprintf(stdout, "export list for %s:\n", host); } max = 0; for (e = ex; e != NULL; e = e->ex_next) { if (strlen(e->ex_name) > max) { max = strlen(e->ex_name); } } while (ex) { fprintf(stdout, "%-*s ", max, ex->ex_name); gr = ex->ex_groups; if (gr == NULL) { fprintf(stdout, "(everyone)"); } while (gr) { fprintf(stdout, "%s", gr->g_name); gr = gr->g_next; if (gr) { fprintf(stdout, ","); } } fprintf(stdout, "\n"); ex = ex->ex_next; } }