home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / amd / part05 / am.c next >
C/C++ Source or Header  |  1990-04-10  |  7KB  |  309 lines

  1. /*
  2.  * $Id: am.c,v 5.1.1.1 90/01/11 16:58:29 jsp Exp Locker: jsp $
  3.  *
  4.  * Copyright (c) 1989 Jan-Simon Pendry
  5.  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  6.  * Copyright (c) 1989 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * This code is derived from software contributed to Berkeley by
  10.  * Jan-Simon Pendry at Imperial College, London.
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted
  13.  * provided that the above copyright notice and this paragraph are
  14.  * duplicated in all such forms and that any documentation,
  15.  * advertising materials, and other materials related to such
  16.  * distribution and use acknowledge that the software was developed
  17.  * by Imperial College of Science, Technology and Medicine, London, UK.
  18.  * The names of the College and University may not be used to endorse
  19.  * or promote products derived from this software without specific
  20.  * prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  *
  25.  *    %W% (Berkeley) %G%
  26.  */
  27.  
  28. /*
  29.  * Automounter
  30.  */
  31.  
  32. #include "am.h"
  33. #include <sys/signal.h>
  34. #include <netdb.h>
  35. #include <sys/ioctl.h>
  36. #include <fcntl.h>
  37. #include <setjmp.h>
  38.  
  39. char pid_fsname[16 + MAXHOSTNAMELEN];    /* "kiska.southseas.nz:(pid%d)" */
  40. char *progname;                /* "amd" */
  41. char *auto_dir = "/a";
  42. char *hostdomain = "unknown.domain";
  43. char hostname[MAXHOSTNAMELEN];        /* Hostname */
  44. char hostd[2*MAXHOSTNAMELEN];        /* Host+domain */
  45. char *op_sys = OS_REP;            /* Name of current op_sys */
  46. char *arch = ARCH_REP;            /* Name of current architecture */
  47. char *endian = ARCH_ENDIAN;        /* Big or Little endian */
  48. int foreground = 1;            /* This is the top-level server */
  49. int mypid;                /* Current process id */
  50. int immediate_abort;            /* Should close-down unmounts be retried */
  51. struct in_addr myipaddr;        /* (An) IP address of this host */
  52. serv_state amd_state = Start;
  53. struct amd_stats amd_stats;        /* Server statistics */
  54. time_t do_mapc_reload = 0;        /* mapc_reload() call required? */
  55. jmp_buf select_intr;
  56. int select_intr_valid;
  57. int orig_umask;
  58.  
  59. /*
  60.  * Signal handler:
  61.  * SIGINT - tells amd to do a full shutdown, including unmounting all filesystem.
  62.  * SIGTERM - tells amd to shutdown now.  Just unmounts the automount nodes.
  63.  */
  64. static void sigterm(sig)
  65. int sig;
  66. {
  67. #ifdef SYS5_SIGNALS
  68.     signal(sig, sigterm);
  69. #endif
  70.  
  71.     switch (sig) {
  72.     case SIGINT:
  73.         immediate_abort = 15;
  74.         break;
  75.  
  76.     case SIGTERM:
  77.         immediate_abort = -1;
  78.         /* fall through... */
  79.  
  80.     default:
  81.         plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
  82.         break;
  83.     }
  84.     if (select_intr_valid)
  85.         longjmp(select_intr, sig);
  86. }
  87.  
  88. /*
  89.  * Hook for cache reload.
  90.  * When a SIGHUP arrives it schedules a call to mapc_reload
  91.  */
  92. static void sighup(sig)
  93. int sig;
  94. {
  95. #ifdef SYS5_SIGNALS
  96.     signal(sig, sighup);
  97. #endif
  98.  
  99. #ifdef DEBUG
  100.     if (sig != SIGHUP)
  101.         dlog("spurious call to sighup");
  102. #endif
  103.     /*
  104.      * Force a reload by zero'ing the timer
  105.      */
  106.     if (amd_state == Run)
  107.         do_mapc_reload = 0;
  108. }
  109.  
  110. static void parent_exit(sig)
  111. int sig;
  112. {
  113.     exit(0);
  114. }
  115.  
  116. static int daemon_mode(P_void)
  117. {
  118.     int bgpid = background();
  119.  
  120.     if (bgpid != 0) {
  121.         if (print_pid) {
  122.             printf("%d\n", bgpid);
  123.             fflush(stdout);
  124.         }
  125.         /*
  126.          * Now wait for the automount points to
  127.          * complete.
  128.          */
  129.         signal(SIGQUIT, parent_exit);
  130.         for (;;)
  131.             pause();
  132.     }
  133.  
  134.     /*
  135.      * Pretend we are in the foreground again
  136.      */
  137.     foreground = 1;
  138. #ifdef TIOCNOTTY
  139.     {
  140.         int t = open("/dev/tty", O_RDWR);
  141.         if (t < 0) {
  142.             if (errno != ENXIO)    /* not an error if already no controlling tty */
  143.                 plog(XLOG_WARNING, "Could not open controlling tty: %m");
  144.         } else if (ioctl(t, TIOCNOTTY, 0) < 0) {
  145.             plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m");
  146.         }
  147.     }
  148. #else
  149.     (void) setpgrp();
  150. #endif
  151.  
  152.     return getppid();
  153. }
  154.  
  155. main(argc, argv)
  156. int argc;
  157. char *argv[];
  158. {
  159.     struct hostent *hp, *gethostbyname();
  160.     char *domdot;
  161.     int ppid = 0;
  162.     int error;
  163.  
  164.     /*
  165.      * Make sure some built-in assumptions are true before we start
  166.      */
  167.     assert(sizeof(nfscookie) >= sizeof (unsigned int));
  168.     assert(sizeof(int) >= 4);
  169.  
  170.     /*
  171.      * Set processing status.
  172.      */
  173.     amd_state = Start;
  174.  
  175.     /*
  176.      * Get local machine name
  177.      */
  178.     if (gethostname(hostname, sizeof(hostname)) < 0) {
  179.         plog(XLOG_FATAL, "gethostname: %m");
  180.         going_down(1);
  181.     }
  182.     /*
  183.      * Check it makes sense
  184.      */
  185.     if (!*hostname) {
  186.         plog(XLOG_FATAL, "host name is not set");
  187.         going_down(1);
  188.     }
  189.     /*
  190.      * Partially initialise hostd[].  This
  191.      * is completed in get_args().
  192.      */
  193.     if (domdot = strchr(hostname, '.')) {
  194.         /*
  195.          * Hostname already contains domainname.
  196.          * Split out hostname and domainname
  197.          * components
  198.          */
  199.         *domdot++ = '\0';
  200.         hostdomain = domdot;
  201.     }
  202.     strcpy(hostd, hostname);
  203.  
  204.     /*
  205.      * Trap interrupts for shutdowns.
  206.      */
  207.     (void) signal(SIGINT, sigterm);
  208.  
  209.     /*
  210.      * Hangups tell us to reload the cache
  211.      */
  212.     (void) signal(SIGHUP, sighup);
  213.  
  214.     /*
  215.      * Trap Terminate so that we can shutdown gracefully (some chance)
  216.      */
  217.     (void) signal(SIGTERM, sigterm);
  218.     /*
  219.      * Trap Death-of-a-child.  These allow us to
  220.      * pick up the exit status of backgrounded mounts.
  221.      * See "sched.c".
  222.      */
  223.     (void) signal(SIGCHLD, sigchld);
  224.  
  225.     /*
  226.      * Initialise process id.  This is kept
  227.      * cached since it is used for generating
  228.      * and using file handles.
  229.      */
  230.     mypid = getpid();
  231.  
  232. #ifdef notdef
  233. /*
  234.  * XXX - Doing this plugs most of a memory leak in
  235.  * gethostbyname on SunOS 4.  I see no good reason
  236.  * why the host database needs to grab 1.5K of
  237.  * private data space...  However, for the moment,
  238.  * I will take its word that it is a _good thing_
  239.  * (jsp)
  240.  */
  241.     (void) sethostent(0);
  242. #endif
  243.  
  244.     /*
  245.      * Fix-up any umask problems.  Most systems default
  246.      * to 002 which is not too convenient for our purposes
  247.      */
  248.     orig_umask = umask(0);
  249.  
  250.     /*
  251.      * Determine command-line arguments
  252.      */
  253.     get_args(argc, argv);
  254.  
  255.     /*
  256.      * Get our own IP address so that we
  257.      * can mount the automounter.  There
  258.      * is probably a better way of doing
  259.      * this, but messing about with SIOCGCONF
  260.      * seems to be heading towards the non-portable
  261.      * arena.
  262.      */
  263.     hp = gethostbyname(hostname);
  264.     if (!hp || hp->h_addrtype != AF_INET) {
  265.         plog(XLOG_FATAL, "Can't determine IP address of this host (%s)", hostname);
  266.         going_down(1);
  267.     }
  268.     myipaddr = *(struct in_addr *) hp->h_addr;
  269.  
  270.     /*
  271.      * Now check we are root.
  272.      */
  273.     if (geteuid() != 0) {
  274.         plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %d)", geteuid());
  275.         going_down(1);
  276.     }
  277.  
  278. #ifdef HAS_YP_MAPS
  279.     /*
  280.      * If the domain was specified then bind it here
  281.      * to circumvent any default bindings that may
  282.      * be done in the C library.
  283.      */
  284.     if (domain && yp_bind(domain)) {
  285.         plog(XLOG_FATAL, "Can't bind to domain \"%s\"", domain);
  286.         going_down(1);
  287.     }
  288. #endif
  289.  
  290. #ifdef DEBUG
  291.     Debug(D_DAEMON)
  292. #endif
  293.     ppid = daemon_mode();
  294.  
  295.     sprintf(pid_fsname, "%s:(pid%d)", hostname, mypid);
  296.  
  297.     do_mapc_reload = clocktime() + ONE_HOUR;
  298.  
  299.     /*
  300.      * Register automounter with system
  301.      */
  302.     error = mount_automounter(ppid);
  303.     if (error && ppid)
  304.         kill(SIGALRM, ppid);
  305.     going_down(error);
  306.  
  307.     abort();
  308. }
  309.