/* * Display a mount tree. */ static void show_mt(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *pwid) { while (mt) { show_mti(mt, e, mwid, dwid, pwid); show_mt(mt->mt_next, e, mwid, dwid, pwid); mt = mt->mt_child; } }
/* * MAIN */ int main(int argc, char *argv[]) { int opt_ch; int errs = 0; char *server; struct sockaddr_in server_addr; CLIENT *clnt = NULL; struct hostent *hp; int nodefault = 0; struct timeval tv; char *progname = NULL; /* * Compute program name */ if (argv[0]) { progname = strrchr(argv[0], '/'); if (progname && progname[1]) progname++; else progname = argv[0]; } if (!progname) progname = "amq"; am_set_progname(progname); /* * Parse arguments */ while ((opt_ch = getopt(argc, argv, "Hfh:l:msuvx:D:pP:TUw")) != -1) switch (opt_ch) { case 'H': goto show_usage; break; case 'f': flush_flag = 1; nodefault = 1; break; case 'h': def_server = optarg; break; case 'l': amq_logfile = optarg; nodefault = 1; break; case 'm': minfo_flag = 1; nodefault = 1; break; case 'p': getpid_flag = 1; nodefault = 1; break; case 's': stats_flag = 1; nodefault = 1; break; case 'u': unmount_flag = 1; nodefault = 1; break; case 'v': getvers_flag = 1; nodefault = 1; break; case 'x': xlog_optstr = optarg; nodefault = 1; break; case 'D': debug_opts = optarg; nodefault = 1; break; case 'P': amd_program_number = atoi(optarg); break; case 'T': use_tcp_flag = 1; break; case 'U': use_udp_flag = 1; break; case 'w': getpwd_flag = 1; break; default: errs = 1; break; } if (optind == argc) { if (unmount_flag) errs = 1; } if (errs) { show_usage: fprintf(stderr, "\ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\ \t[-x log_options] [-D debug_options]\n\ \t[-P program_number] [[-u] directory ...]\n", am_get_progname() ); exit(1); } /* set use_udp and use_tcp flags both to on if none are defined */ if (!use_tcp_flag && !use_udp_flag) use_tcp_flag = use_udp_flag = 1; #if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) /* * Figure out root server of cluster */ if (def_server == localhost) server = cluster_server(); else #endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */ server = def_server; /* * Get address of server */ if ((hp = gethostbyname(server)) == 0 && !STREQ(server, localhost)) { fprintf(stderr, "%s: Can't get address of %s\n", am_get_progname(), server); exit(1); } memset(&server_addr, 0, sizeof(server_addr)); /* as per POSIX, sin_len need not be set (used internally by kernel) */ server_addr.sin_family = AF_INET; if (hp) { memmove((voidp) &server_addr.sin_addr, (voidp) hp->h_addr, sizeof(server_addr.sin_addr)); } else { /* fake "localhost" */ server_addr.sin_addr.s_addr = htonl(0x7f000001); } /* * Create RPC endpoint */ tv.tv_sec = 5; /* 5 seconds for timeout or per retry */ tv.tv_usec = 0; if (use_tcp_flag) /* try tcp first */ clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "tcp"); if (!clnt && use_udp_flag) { /* try udp next */ clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "udp"); /* if ok, set timeout (valid for connectionless transports only) */ if (clnt) clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tv); } if (!clnt) { fprintf(stderr, "%s: ", am_get_progname()); clnt_pcreateerror(server); exit(1); } /* * Control debugging */ if (debug_opts) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_DEBUG; opt.as_str = debug_opts; rc = amqproc_setopt_1(&opt, clnt); if (rc && *rc < 0) { fprintf(stderr, "%s: daemon not compiled for debug\n", am_get_progname()); errs = 1; } else if (!rc || *rc > 0) { fprintf(stderr, "%s: debug setting for \"%s\" failed\n", am_get_progname(), debug_opts); errs = 1; } } /* * Control logging */ if (xlog_optstr) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_XLOG; opt.as_str = xlog_optstr; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: setting log level to \"%s\" failed\n", am_get_progname(), xlog_optstr); errs = 1; } } /* * Control log file */ if (amq_logfile) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_LOGFILE; opt.as_str = amq_logfile; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", am_get_progname(), amq_logfile); errs = 1; } } /* * Flush map cache */ if (flush_flag) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_FLUSHMAPC; opt.as_str = ""; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", am_get_progname(), server); errs = 1; } } /* * getpwd info */ if (getpwd_flag) { char path[MAXPATHLEN+1]; char *wd = getcwd(path, MAXPATHLEN+1); amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); amq_mount_tree_p mt; u_int i; int flag; if (!wd) { perror("getcwd"); exit(1); } for (i = 0; mlp && i < mlp->amq_mount_tree_list_len; i++) { mt = mlp->amq_mount_tree_list_val[i]; while (1) { flag = 0; show_pwd(mt, path, sizeof(path), &flag); if (!flag) { printf("%s\n", path); break; } } } exit(0); } /* * Mount info */ if (minfo_flag) { int dummy; amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); if (ml) { int mwid = 0, dwid = 0, twid = 0; show_mi(ml, Calc, &mwid, &dwid, &twid); mwid++; dwid++; twid++; show_mi(ml, Full, &mwid, &dwid, &twid); } else { fprintf(stderr, "%s: amd on %s cannot provide mount info\n", am_get_progname(), server); } } /* * Get Version */ if (getvers_flag) { amq_string *spp = amqproc_getvers_1((voidp) 0, clnt); if (spp && *spp) { fputs(*spp, stdout); XFREE(*spp); } else { fprintf(stderr, "%s: failed to get version information\n", am_get_progname()); errs = 1; } } /* * Get PID of amd */ if (getpid_flag) { int *ip = amqproc_getpid_1((voidp) 0, clnt); if (ip && *ip) { printf("%d\n", *ip); } else { fprintf(stderr, "%s: failed to get PID of amd\n", am_get_progname()); errs = 1; } } /* * Apply required operation to all remaining arguments */ if (optind < argc) { do { char *fs = argv[optind++]; if (unmount_flag) { /* * Unmount request */ amqproc_umnt_1(&fs, clnt); } else { /* * Stats request */ amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt); if (mtp) { amq_mount_tree *mt = *mtp; if (mt) { int mwid = 0, dwid = 0, twid = 0; show_mt(mt, Calc, &mwid, &dwid, &twid); mwid++; dwid++, twid++; printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n", dwid, dwid, "What"); show_mt(mt, Stats, &mwid, &dwid, &twid); } else { fprintf(stderr, "%s: %s not automounted\n", am_get_progname(), fs); } xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp); } else { fprintf(stderr, "%s: ", am_get_progname()); clnt_perror(clnt, server); errs = 1; } } } while (optind < argc); } else if (unmount_flag) { goto show_usage; } else if (stats_flag) { amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt); if (ms) { show_ms(ms); } else { fprintf(stderr, "%s: ", am_get_progname()); clnt_perror(clnt, server); errs = 1; } } else if (!nodefault) { amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); if (mlp) { enum show_opt e = Calc; int mwid = 0, dwid = 0, pwid = 0; while (e != ShowDone) { u_int i; for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { show_mt(mlp->amq_mount_tree_list_val[i], e, &mwid, &dwid, &pwid); } mwid++; dwid++, pwid++; if (e == Calc) e = Short; else if (e == Short) e = ShowDone; } } else { fprintf(stderr, "%s: ", am_get_progname()); clnt_perror(clnt, server); errs = 1; } } exit(errs); return errs; /* should never reach here */ }
/* * MAIN */ int main(int argc, char *argv[]) { int nodefault = 0, opt_ch, errs = 0, s; struct sockaddr_in server_addr; struct hostent *hp; CLIENT *clnt; char *server; /* * Parse arguments */ while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != -1) switch (opt_ch) { case 'f': flush_flag = 1; nodefault = 1; break; case 'h': def_server = optarg; break; case 'l': logfile = optarg; nodefault = 1; break; case 'm': minfo_flag = 1; nodefault = 1; break; case 's': stats_flag = 1; nodefault = 1; break; case 'u': unmount_flag = 1; nodefault = 1; break; case 'v': getvers_flag = 1; nodefault = 1; break; case 'x': xlog_optstr = optarg; nodefault = 1; break; case 'D': debug_opts = optarg; nodefault = 1; break; case 'M': mount_map = optarg; nodefault = 1; break; default: errs = 1; break; } if (optind == argc) { if (unmount_flag) errs = 1; } if (errs) { show_usage: fprintf(stderr, "usage: %s [-fmsuv] [-h hostname] " "[directory ...]\n", __progname); exit(1); } server = def_server; /* * Get address of server */ if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) { fprintf(stderr, "%s: Can't get address of %s\n", __progname, server); exit(1); } bzero(&server_addr, sizeof server_addr); server_addr.sin_family = AF_INET; if (hp) { bcopy((void *)hp->h_addr, (void *)&server_addr.sin_addr, sizeof(server_addr.sin_addr)); } else { /* fake "localhost" */ server_addr.sin_addr.s_addr = htonl(0x7f000001); } /* * Create RPC endpoint */ s = privsock(SOCK_STREAM); clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); if (clnt == 0) { close(s); s = privsock(SOCK_DGRAM); clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s); } if (clnt == 0) { fprintf(stderr, "%s: ", __progname); clnt_pcreateerror(server); exit(1); } /* * Control debugging */ if (debug_opts) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_DEBUG; opt.as_str = debug_opts; rc = amqproc_setopt_1(&opt, clnt); if (rc && *rc < 0) { fprintf(stderr, "%s: daemon not compiled for debug", __progname); errs = 1; } else if (!rc || *rc > 0) { fprintf(stderr, "%s: debug setting for \"%s\" failed\n", __progname, debug_opts); errs = 1; } } /* * Control logging */ if (xlog_optstr) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_XLOG; opt.as_str = xlog_optstr; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: setting log level to \"%s\" failed\n", __progname, xlog_optstr); errs = 1; } } /* * Control log file */ if (logfile) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_LOGFILE; opt.as_str = logfile; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", __progname, logfile); errs = 1; } } /* * Flush map cache */ if (flush_flag) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_FLUSHMAPC; opt.as_str = ""; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", __progname, server); errs = 1; } } /* * Mount info */ if (minfo_flag) { int dummy; amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); if (ml) { int mwid = 0, dwid = 0, twid = 0; show_mi(ml, Calc, &mwid, &dwid, &twid); mwid++; dwid++; twid++; show_mi(ml, Full, &mwid, &dwid, &twid); } else { fprintf(stderr, "%s: amd on %s cannot provide mount info\n", __progname, server); } } /* * Mount map */ if (mount_map) { int *rc; do { rc = amqproc_mount_1(&mount_map, clnt); } while (rc && *rc < 0); if (!rc || *rc > 0) { if (rc) errno = *rc; else errno = ETIMEDOUT; fprintf(stderr, "%s: could not start new ", __progname); perror("autmount point"); } } /* * Get Version */ if (getvers_flag) { amq_string *spp = amqproc_getvers_1((void *)0, clnt); if (spp && *spp) { printf("%s.\n", *spp); free(*spp); } else { fprintf(stderr, "%s: failed to get version information\n", __progname); errs = 1; } } /* * Apply required operation to all remaining arguments */ if (optind < argc) { do { char *fs = argv[optind++]; if (unmount_flag) { /* * Unmount request */ amqproc_umnt_1(&fs, clnt); } else { /* * Stats request */ amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt); if (mtp) { amq_mount_tree *mt = *mtp; if (mt) { int mwid = 0, dwid = 0, twid = 0; show_mt(mt, Calc, &mwid, &dwid, &twid); mwid++; dwid++; twid++; printf("%-*.*s Uid Getattr " "Lookup RdDir RdLnk " "Statfs Mounted@\n", dwid, dwid, "What"); show_mt(mt, Stats, &mwid, &dwid, &twid); } else { fprintf(stderr, "%s: %s not automounted\n", __progname, fs); } xdr_pri_free(xdr_amq_mount_tree_p, mtp); } else { fprintf(stderr, "%s: ", __progname); clnt_perror(clnt, server); errs = 1; } } } while (optind < argc); } else if (unmount_flag) { goto show_usage; } else if (stats_flag) { amq_mount_stats *ms = amqproc_stats_1((void *)0, clnt); if (ms) { show_ms(ms); } else { fprintf(stderr, "%s: ", __progname); clnt_perror(clnt, server); errs = 1; } } else if (!nodefault) { amq_mount_tree_list *mlp = amqproc_export_1((void *)0, clnt); if (mlp) { enum show_opt e = Calc; int mwid = 0, dwid = 0, pwid = 0; while (e != ShowDone) { int i; for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { show_mt(mlp->amq_mount_tree_list_val[i], e, &mwid, &dwid, &pwid); } mwid++; dwid++; pwid++; if (e == Calc) e = Short; else if (e == Short) e = ShowDone; } } else { fprintf(stderr, "%s: ", __progname); clnt_perror(clnt, server); errs = 1; } } exit(errs); }