1/* 2 * Copyright (c) 1997-1998 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 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 acknowledgment: |
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 --- 4 unchanged lines hidden (view full) --- 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 * %W% (Berkeley) %G% 40 * |
41 * $Id: amq.c,v 1.2 1998/08/23 22:52:08 obrien Exp $ |
42 * 43 */ 44 45/* 46 * Automounter query tool 47 */ 48 49#ifndef lint 50char copyright[] = "\ 51@(#)Copyright (c) 1997-1998 Erez Zadok\n\ 52@(#)Copyright (c) 1990 Jan-Simon Pendry\n\ 53@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 54@(#)Copyright (c) 1990 The Regents of the University of California.\n\ 55@(#)All rights reserved.\n"; 56#if __GNUC__ < 2 |
57static char rcsid[] = "$Id: amq.c,v 1.2 1998/08/23 22:52:08 obrien Exp $"; |
58static char sccsid[] = "%W% (Berkeley) %G%"; 59#endif /* __GNUC__ < 2 */ 60#endif /* not lint */ 61 62#ifdef HAVE_CONFIG_H 63# include <config.h> 64#endif /* HAVE_CONFIG_H */ 65#include <am_defs.h> 66#include <amq.h> 67 68/* locals */ |
69#if 0 |
70char *progname; |
71#endif |
72static int flush_flag; 73static int minfo_flag; 74static int getpid_flag; 75static int unmount_flag; 76static int stats_flag; 77static int getvers_flag; 78static int amd_program_number = AMQ_PROGRAM; 79static int use_tcp_flag, use_udp_flag; 80static char *debug_opts; 81static char *amq_logfile; 82static char *mount_map; 83static char *xlog_optstr; 84static char localhost[] = "localhost"; 85static char *def_server = localhost; 86 87/* externals */ 88extern int optind; 89extern char *optarg; 90 |
91/* forward declarations */ |
92#ifdef HAVE_TRANSPORT_TYPE_TLI 93static CLIENT *get_secure_amd_client(char *host, struct timeval *tv, int *sock); 94static int amq_bind_resv_port(int td, u_short *pp); 95#else /* not HAVE_TRANSPORT_TYPE_TLI */ 96static int privsock(int ty); 97#endif /* not HAVE_TRANSPORT_TYPE_TLI */ 98 99/* dummy variables */ |
100#if 0 |
101char hostname[MAXHOSTNAMELEN]; |
102pid_t mypid; 103serv_state amd_state; |
104int foreground, orig_umask; 105int debug_flags; 106#endif |
107 108/* structures */ 109enum show_opt { 110 Full, Stats, Calc, Short, ShowDone 111}; 112 113 114/* --- 194 unchanged lines hidden (view full) --- 309 int errs = 0; 310 char *server; 311 struct sockaddr_in server_addr; 312 int s; /* to pass the Amd security check, we must use a priv port */ 313 CLIENT *clnt = NULL; 314 struct hostent *hp; 315 int nodefault = 0; 316 struct timeval tv; |
317 char *progname = NULL; |
318#ifndef HAVE_TRANSPORT_TYPE_TLI 319 enum clnt_stat cs; 320#endif /* not HAVE_TRANSPORT_TYPE_TLI */ 321 322 323 /* 324 * Compute program name 325 */ 326 if (argv[0]) { 327 progname = strrchr(argv[0], '/'); 328 if (progname && progname[1]) 329 progname++; 330 else 331 progname = argv[0]; 332 } 333 if (!progname) 334 progname = "amq"; |
335 am_set_progname(progname); |
336 337 /* 338 * Parse arguments 339 */ 340 while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:pP:TU")) != -1) 341 switch (opt_ch) { 342 case 'f': 343 flush_flag = 1; --- 70 unchanged lines hidden (view full) --- 414 if (unmount_flag) 415 errs = 1; 416 } 417 if (errs) { 418 show_usage: 419 fprintf(stderr, "\ 420Usage: %s [-h host] [[-f] [-m] [-p] [-v] [-s]] | [[-u] directory ...]]\n\ 421\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n\ |
422\t[-P prognum] [-T] [-U]\n", am_get_progname()); |
423 exit(1); 424 } 425 426 /* set use_udp and use_tcp flags both to on if none are defined */ 427 if (!use_tcp_flag && !use_udp_flag) 428 use_tcp_flag = use_udp_flag = 1; 429 430#if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) --- 5 unchanged lines hidden (view full) --- 436 else 437#endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */ 438 server = def_server; 439 440 /* 441 * Get address of server 442 */ 443 if ((hp = gethostbyname(server)) == 0 && !STREQ(server, localhost)) { |
444 fprintf(stderr, "%s: Can't get address of %s\n", 445 am_get_progname(), server); |
446 exit(1); 447 } 448 memset(&server_addr, 0, sizeof server_addr); 449 server_addr.sin_family = AF_INET; 450 if (hp) { 451 memmove((voidp) &server_addr.sin_addr, (voidp) hp->h_addr, 452 sizeof(server_addr.sin_addr)); 453 } else { --- 18 unchanged lines hidden (view full) --- 472 clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tv); 473 } 474#else /* not HAVE_TRANSPORT_TYPE_TLI */ 475 476 /* first check if remote portmapper is up */ 477 cs = pmap_ping(&server_addr); 478 if (cs == RPC_TIMEDOUT) { 479 fprintf(stderr, "%s: failed to contact portmapper on host \"%s\". %s\n", |
480 am_get_progname(), server, clnt_sperrno(cs)); |
481 exit(1); 482 } 483 484 /* portmapper exists: get remote amd info from it */ 485 if (!clnt && use_tcp_flag) { /* try tcp first */ 486 s = RPC_ANYSOCK; 487 clnt = clnttcp_create(&server_addr, amd_program_number, 488 AMQ_VERSION, &s, 0, 0); 489 } 490 if (!clnt && use_udp_flag) { /* try udp next */ 491 /* XXX: do we need to close(s) ? */ 492 s = privsock(SOCK_DGRAM); 493 clnt = clntudp_create(&server_addr, amd_program_number, 494 AMQ_VERSION, tv, &s); 495 } 496#endif /* not HAVE_TRANSPORT_TYPE_TLI */ 497 if (!clnt) { |
498 fprintf(stderr, "%s: ", am_get_progname()); |
499 clnt_pcreateerror(server); 500 exit(1); 501 } 502 503 /* 504 * Control debugging 505 */ 506 if (debug_opts) { 507 int *rc; 508 amq_setopt opt; 509 opt.as_opt = AMOPT_DEBUG; 510 opt.as_str = debug_opts; 511 rc = amqproc_setopt_1(&opt, clnt); 512 if (rc && *rc < 0) { |
513 fprintf(stderr, "%s: daemon not compiled for debug\n", 514 am_get_progname()); |
515 errs = 1; 516 } else if (!rc || *rc > 0) { |
517 fprintf(stderr, "%s: debug setting for \"%s\" failed\n", 518 am_get_progname(), debug_opts); |
519 errs = 1; 520 } 521 } 522 523 /* 524 * Control logging 525 */ 526 if (xlog_optstr) { 527 int *rc; 528 amq_setopt opt; 529 opt.as_opt = AMOPT_XLOG; 530 opt.as_str = xlog_optstr; 531 rc = amqproc_setopt_1(&opt, clnt); 532 if (!rc || *rc) { |
533 fprintf(stderr, "%s: setting log level to \"%s\" failed\n", 534 am_get_progname(), xlog_optstr); |
535 errs = 1; 536 } 537 } 538 539 /* 540 * Control log file 541 */ 542 if (amq_logfile) { 543 int *rc; 544 amq_setopt opt; 545 opt.as_opt = AMOPT_LOGFILE; 546 opt.as_str = amq_logfile; 547 rc = amqproc_setopt_1(&opt, clnt); 548 if (!rc || *rc) { |
549 fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", 550 am_get_progname(), amq_logfile); |
551 errs = 1; 552 } 553 } 554 555 /* 556 * Flush map cache 557 */ 558 if (flush_flag) { 559 int *rc; 560 amq_setopt opt; 561 opt.as_opt = AMOPT_FLUSHMAPC; 562 opt.as_str = ""; 563 rc = amqproc_setopt_1(&opt, clnt); 564 if (!rc || *rc) { |
565 fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", 566 am_get_progname(), server); |
567 errs = 1; 568 } 569 } 570 571 /* 572 * Mount info 573 */ 574 if (minfo_flag) { 575 int dummy; 576 amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); 577 if (ml) { 578 int mwid = 0, dwid = 0, twid = 0; 579 show_mi(ml, Calc, &mwid, &dwid, &twid); 580 mwid++; 581 dwid++; 582 twid++; 583 show_mi(ml, Full, &mwid, &dwid, &twid); 584 585 } else { |
586 fprintf(stderr, "%s: amd on %s cannot provide mount info\n", 587 am_get_progname(), server); |
588 } 589 } 590 591 /* 592 * Mount map 593 */ 594 if (mount_map) { 595 int *rc; 596 do { 597 rc = amqproc_mount_1(&mount_map, clnt); 598 } while (rc && *rc < 0); 599 if (!rc || *rc > 0) { 600 if (rc) 601 errno = *rc; 602 else 603 errno = ETIMEDOUT; |
604 fprintf(stderr, "%s: could not start new ", am_get_progname()); 605 perror("automount point"); |
606 } 607 } 608 609 /* 610 * Get Version 611 */ 612 if (getvers_flag) { 613 amq_string *spp = amqproc_getvers_1((voidp) 0, clnt); 614 if (spp && *spp) { 615 fputs(*spp, stdout); 616 XFREE(*spp); 617 } else { |
618 fprintf(stderr, "%s: failed to get version information\n", 619 am_get_progname()); |
620 errs = 1; 621 } 622 } 623 624 /* 625 * Get PID of amd 626 */ 627 if (getpid_flag) { 628 int *ip = amqproc_getpid_1((voidp) 0, clnt); 629 if (ip && *ip) { 630 printf("%d\n", *ip); 631 } else { |
632 fprintf(stderr, "%s: failed to get PID of amd\n", am_get_progname()); |
633 errs = 1; 634 } 635 } 636 637 /* 638 * Apply required operation to all remaining arguments 639 */ 640 if (optind < argc) { --- 15 unchanged lines hidden (view full) --- 656 int mwid = 0, dwid = 0, twid = 0; 657 show_mt(mt, Calc, &mwid, &dwid, &twid); 658 mwid++; 659 dwid++, twid++; 660 printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n", 661 dwid, dwid, "What"); 662 show_mt(mt, Stats, &mwid, &dwid, &twid); 663 } else { |
664 fprintf(stderr, "%s: %s not automounted\n", am_get_progname(), fs); |
665 } 666 xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp); 667 } else { |
668 fprintf(stderr, "%s: ", am_get_progname()); |
669 clnt_perror(clnt, server); 670 errs = 1; 671 } 672 } 673 } while (optind < argc); 674 675 } else if (unmount_flag) { 676 goto show_usage; 677 678 } else if (stats_flag) { 679 amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt); 680 if (ms) { 681 show_ms(ms); 682 } else { |
683 fprintf(stderr, "%s: ", am_get_progname()); |
684 clnt_perror(clnt, server); 685 errs = 1; 686 } 687 688 } else if (!nodefault) { 689 amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); 690 if (mlp) { 691 enum show_opt e = Calc; --- 8 unchanged lines hidden (view full) --- 700 dwid++, pwid++; 701 if (e == Calc) 702 e = Short; 703 else if (e == Short) 704 e = ShowDone; 705 } 706 707 } else { |
708 fprintf(stderr, "%s: ", am_get_progname()); |
709 clnt_perror(clnt, server); 710 errs = 1; 711 } 712 } 713 exit(errs); |
714 return errs; /* should never reach here */ |
715} 716 717 718#ifdef HAVE_TRANSPORT_TYPE_TLI 719 720/* 721 * How to bind to reserved ports. 722 * TLI handle (socket) and port version. --- 80 unchanged lines hidden (view full) --- 803 (XDRPROC_T_TYPE) xdr_void, 804 NULL, 805 (XDRPROC_T_TYPE) xdr_void, 806 NULL, 807 *tv, 808 NULL); 809 if (cs == RPC_TIMEDOUT) { 810 fprintf(stderr, "%s: failed to contact portmapper on host \"%s\". %s\n", |
811 am_get_progname(), host, clnt_sperrno(cs)); |
812 exit(1); 813 } 814 } 815 816 /* 817 * First transport type to try: TCP 818 */ 819 if (use_tcp_flag) { 820 /* Find amd address on TCP */ 821 nc = getnetconfigent(NC_TCP); 822 if (!nc) { 823 fprintf(stderr, "getnetconfig for tcp failed: %s\n", nc_sperror()); 824 goto tryudp; 825 } 826 827 if (!rpcb_getaddr(amd_program_number, AMQ_VERSION, nc, &nb, host)) { 828 /* |
829 * don't print error messages here, since amd might legitimately |
830 * serve udp only 831 */ 832 goto tryudp; 833 } |
834 /* Create privileged TCP socket */ |
835 *sock = t_open(nc->nc_device, O_RDWR, 0); 836 837 if (*sock < 0) { 838 fprintf(stderr, "t_open %s: %m\n", nc->nc_device); 839 goto tryudp; 840 } 841 if (amq_bind_resv_port(*sock, (u_short *) 0) < 0) 842 goto tryudp; --- 19 unchanged lines hidden (view full) --- 862 fprintf(stderr, "getnetconfig for udp failed: %s\n", nc_sperror()); 863 return NULL; 864 } 865 if (!rpcb_getaddr(amd_program_number, AMQ_VERSION, nc, &nb, host)) { 866 fprintf(stderr, "%s\n", 867 clnt_spcreateerror("couldn't get amd address on udp")); 868 return NULL; 869 } |
870 /* create privileged UDP socket */ |
871 *sock = t_open(nc->nc_device, O_RDWR, 0); 872 873 if (*sock < 0) { 874 fprintf(stderr, "t_open %s: %m\n", nc->nc_device); 875 return NULL; /* neither tcp not udp succeeded */ 876 } 877 if (amq_bind_resv_port(*sock, (u_short *) 0) < 0) 878 return NULL; --- 75 unchanged lines hidden --- |