home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
amd
/
part05
/
am.c
next >
Wrap
C/C++ Source or Header
|
1990-04-10
|
7KB
|
309 lines
/*
* $Id: am.c,v 5.1.1.1 90/01/11 16:58:29 jsp Exp Locker: jsp $
*
* Copyright (c) 1989 Jan-Simon Pendry
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Jan-Simon Pendry at Imperial College, London.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Imperial College of Science, Technology and Medicine, London, UK.
* The names of the College and University may not be used to endorse
* or promote products derived from this software without specific
* prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* %W% (Berkeley) %G%
*/
/*
* Automounter
*/
#include "am.h"
#include <sys/signal.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <setjmp.h>
char pid_fsname[16 + MAXHOSTNAMELEN]; /* "kiska.southseas.nz:(pid%d)" */
char *progname; /* "amd" */
char *auto_dir = "/a";
char *hostdomain = "unknown.domain";
char hostname[MAXHOSTNAMELEN]; /* Hostname */
char hostd[2*MAXHOSTNAMELEN]; /* Host+domain */
char *op_sys = OS_REP; /* Name of current op_sys */
char *arch = ARCH_REP; /* Name of current architecture */
char *endian = ARCH_ENDIAN; /* Big or Little endian */
int foreground = 1; /* This is the top-level server */
int mypid; /* Current process id */
int immediate_abort; /* Should close-down unmounts be retried */
struct in_addr myipaddr; /* (An) IP address of this host */
serv_state amd_state = Start;
struct amd_stats amd_stats; /* Server statistics */
time_t do_mapc_reload = 0; /* mapc_reload() call required? */
jmp_buf select_intr;
int select_intr_valid;
int orig_umask;
/*
* Signal handler:
* SIGINT - tells amd to do a full shutdown, including unmounting all filesystem.
* SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes.
*/
static void sigterm(sig)
int sig;
{
#ifdef SYS5_SIGNALS
signal(sig, sigterm);
#endif
switch (sig) {
case SIGINT:
immediate_abort = 15;
break;
case SIGTERM:
immediate_abort = -1;
/* fall through... */
default:
plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
break;
}
if (select_intr_valid)
longjmp(select_intr, sig);
}
/*
* Hook for cache reload.
* When a SIGHUP arrives it schedules a call to mapc_reload
*/
static void sighup(sig)
int sig;
{
#ifdef SYS5_SIGNALS
signal(sig, sighup);
#endif
#ifdef DEBUG
if (sig != SIGHUP)
dlog("spurious call to sighup");
#endif
/*
* Force a reload by zero'ing the timer
*/
if (amd_state == Run)
do_mapc_reload = 0;
}
static void parent_exit(sig)
int sig;
{
exit(0);
}
static int daemon_mode(P_void)
{
int bgpid = background();
if (bgpid != 0) {
if (print_pid) {
printf("%d\n", bgpid);
fflush(stdout);
}
/*
* Now wait for the automount points to
* complete.
*/
signal(SIGQUIT, parent_exit);
for (;;)
pause();
}
/*
* Pretend we are in the foreground again
*/
foreground = 1;
#ifdef TIOCNOTTY
{
int t = open("/dev/tty", O_RDWR);
if (t < 0) {
if (errno != ENXIO) /* not an error if already no controlling tty */
plog(XLOG_WARNING, "Could not open controlling tty: %m");
} else if (ioctl(t, TIOCNOTTY, 0) < 0) {
plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m");
}
}
#else
(void) setpgrp();
#endif
return getppid();
}
main(argc, argv)
int argc;
char *argv[];
{
struct hostent *hp, *gethostbyname();
char *domdot;
int ppid = 0;
int error;
/*
* Make sure some built-in assumptions are true before we start
*/
assert(sizeof(nfscookie) >= sizeof (unsigned int));
assert(sizeof(int) >= 4);
/*
* Set processing status.
*/
amd_state = Start;
/*
* Get local machine name
*/
if (gethostname(hostname, sizeof(hostname)) < 0) {
plog(XLOG_FATAL, "gethostname: %m");
going_down(1);
}
/*
* Check it makes sense
*/
if (!*hostname) {
plog(XLOG_FATAL, "host name is not set");
going_down(1);
}
/*
* Partially initialise hostd[]. This
* is completed in get_args().
*/
if (domdot = strchr(hostname, '.')) {
/*
* Hostname already contains domainname.
* Split out hostname and domainname
* components
*/
*domdot++ = '\0';
hostdomain = domdot;
}
strcpy(hostd, hostname);
/*
* Trap interrupts for shutdowns.
*/
(void) signal(SIGINT, sigterm);
/*
* Hangups tell us to reload the cache
*/
(void) signal(SIGHUP, sighup);
/*
* Trap Terminate so that we can shutdown gracefully (some chance)
*/
(void) signal(SIGTERM, sigterm);
/*
* Trap Death-of-a-child. These allow us to
* pick up the exit status of backgrounded mounts.
* See "sched.c".
*/
(void) signal(SIGCHLD, sigchld);
/*
* Initialise process id. This is kept
* cached since it is used for generating
* and using file handles.
*/
mypid = getpid();
#ifdef notdef
/*
* XXX - Doing this plugs most of a memory leak in
* gethostbyname on SunOS 4. I see no good reason
* why the host database needs to grab 1.5K of
* private data space... However, for the moment,
* I will take its word that it is a _good thing_
* (jsp)
*/
(void) sethostent(0);
#endif
/*
* Fix-up any umask problems. Most systems default
* to 002 which is not too convenient for our purposes
*/
orig_umask = umask(0);
/*
* Determine command-line arguments
*/
get_args(argc, argv);
/*
* Get our own IP address so that we
* can mount the automounter. There
* is probably a better way of doing
* this, but messing about with SIOCGCONF
* seems to be heading towards the non-portable
* arena.
*/
hp = gethostbyname(hostname);
if (!hp || hp->h_addrtype != AF_INET) {
plog(XLOG_FATAL, "Can't determine IP address of this host (%s)", hostname);
going_down(1);
}
myipaddr = *(struct in_addr *) hp->h_addr;
/*
* Now check we are root.
*/
if (geteuid() != 0) {
plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %d)", geteuid());
going_down(1);
}
#ifdef HAS_YP_MAPS
/*
* If the domain was specified then bind it here
* to circumvent any default bindings that may
* be done in the C library.
*/
if (domain && yp_bind(domain)) {
plog(XLOG_FATAL, "Can't bind to domain \"%s\"", domain);
going_down(1);
}
#endif
#ifdef DEBUG
Debug(D_DAEMON)
#endif
ppid = daemon_mode();
sprintf(pid_fsname, "%s:(pid%d)", hostname, mypid);
do_mapc_reload = clocktime() + ONE_HOUR;
/*
* Register automounter with system
*/
error = mount_automounter(ppid);
if (error && ppid)
kill(SIGALRM, ppid);
going_down(error);
abort();
}