diff options
Diffstat (limited to 'server/main.c.old')
-rw-r--r-- | server/main.c.old | 803 |
1 files changed, 0 insertions, 803 deletions
diff --git a/server/main.c.old b/server/main.c.old deleted file mode 100644 index b3ec4e4..0000000 --- a/server/main.c.old +++ /dev/null @@ -1,803 +0,0 @@ -/* This file is part of the Project Athena Zephyr Notification System. - * It contains the main loop of the Zephyr server - * - * Created by: John T. Kohl - * - * $Source$ - * $Author$ - * - * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - */ - -#include <zephyr/mit-copyright.h> - -#ifndef lint -#ifndef SABER -static char rcsid_main_c[] = - "$Id$"; -#endif -#endif - -/* - * Server loop for Zephyr. - */ - -/* - The Zephyr server maintains several linked lists of information. - - There is an array of servers (otherservers) initialized and maintained - by server_s.c. - - Each server descriptor contains a pointer to a linked list of hosts - which are ``owned'' by that server. The first server is the ``limbo'' - server which owns any host which was formerly owned by a dead server. - - Each of these host list entries has an IP address and a pointer to a - linked list of clients on that host. - - Each client has a sockaddr_in, a list of subscriptions, and possibly - a session key. - - In addition, the class manager has copies of the pointers to the - clients which are registered with a particular class, the - not-yet-acknowledged list has copies of pointers to some clients, - and the hostm manager may have copies of pointers to some clients - (if the client has not acknowledged a packet after a given timeout). -*/ - -#include "zserver.h" -/* which includes - zephyr/zephyr.h - <errno.h> - <sys/types.h> - <netinet/in.h> - <sys/time.h> - <stdio.h> - <sys/file.h> - <syslog.h> - <strings.h> - <signal.h> - timer.h - zsrv_err.h - */ - -#include <netdb.h> -#include <sys/socket.h> -#include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/resource.h> -#include <sys/wait.h> -#ifdef POSIX -#include <termios.h> -#endif - -#ifdef POSIX -#define SIGNAL_RETURN_TYPE void -#define SIG_RETURN return -#else -#define SIGNAL_RETURN_TYPE int -#define SIG_RETURN return(0) -#endif - -#if !defined(__SABER__) && (defined (vax) || defined (ibm032)) -#define MONCONTROL moncontrol -#else -#define MONCONTROL (void) -#endif - -#define EVER (;;) /* don't stop looping */ - -#ifdef __STDC__ -# define P(s) s -#else -# define P(s) () -#endif - -static int do_net_setup P((void)), initialize P((void)); -static void usage P((void)), do_reset P((void)); -static SIGNAL_RETURN_TYPE bye P((int)), - dbug_on P((int)), dbug_off P((int)), - sig_dump_db P((int)), sig_dump_strings P((int)), - reset P((int)), reap P((int)); -static void read_from_dump P((char *dumpfile)); -static void dump_db P((void)), dump_strings P((void)); - -#ifndef DEBUG -static void detach P((void)); -#endif - -extern void perror P((Zconst char *)); - -#undef P - -static short doreset = 0; /* if it becomes 1, perform - reset functions */ - -int srv_socket; /* dgram socket for clients - and other servers */ -int bdump_socket = -1; /* brain dump socket fd - (closed most of the time) */ -fd_set interesting; /* the file descrips we are listening - to right now */ -int nfildes; /* number to look at in select() */ -struct sockaddr_in sock_sin; /* address of the socket */ -struct timeval nexthost_tv; /* time till next timeout for select */ - -ZNotAcked_t *nacklist; /* list of packets waiting for ack's */ - -u_short hm_port; /* the port # of the host manager */ - -char *programname; /* set to the basename of argv[0] */ -char myname[MAXHOSTNAMELEN]; /* my host name */ - -int zdebug; -#ifdef DEBUG_MALLOC -int dump_malloc_stats = 0; -unsigned long m_size; -#endif -#ifdef DEBUG -int zalone; -#endif - -struct timeval t_local; /* store current time for other uses */ - -static int dump_db_flag = 0; -static int dump_strings_flag = 0; - -u_long npackets; /* number of packets processed */ -long uptime; /* when we started operations */ -static int nofork; -struct in_addr my_addr; -char *bdump_version = "1.1"; - -int -main(argc, argv) - int argc; - char **argv; -{ - int nfound; /* #fildes ready on select */ - fd_set readable; - struct timeval *tvp; - int init_from_dump = 0; - char *dumpfile; -#ifdef POSIX - struct sigaction action; -#endif - - - int optchar; /* option processing */ - extern char *optarg; - extern int optind; - - /* set name */ - if (programname = strrchr(argv[0],'/')) - programname++; - else programname = argv[0]; - - /* process arguments */ - - while ((optchar = getopt(argc, argv, "dsnv:f:")) != EOF) { - switch(optchar) { - case 'd': - zdebug = 1; - break; -#ifdef DEBUG - case 's': - zalone = 1; - break; -#endif - case 'n': - nofork = 1; - break; - case 'v': - bdump_version = optarg; - break; - case 'f': - init_from_dump = 0; - dumpfile = optarg; - break; - case '?': - default: - usage(); - /*NOTREACHED*/ - } - } - -#ifdef KERBEROS - /* if there is no readable srvtab and we are not standalone, there - is no possible way we can succeed, so we exit */ - - if (access(ZEPHYR_SRVTAB, R_OK) -#ifdef DEBUG - && !zalone -#endif /* DEBUG */ - ) { - fprintf(stderr, "NO ZEPHYR SRVTAB (%s) available; exiting\n", - ZEPHYR_SRVTAB); - exit(1); - } -#endif /* KERBEROS */ - -#ifndef DEBUG - if (!nofork) - detach(); -#endif /* DEBUG */ - - /* open log */ - OPENLOG(programname, LOG_PID, LOG_LOCAL6); - -#if defined (DEBUG) && 0 - if (zalone) - syslog(LOG_DEBUG, "standalone operation"); -#endif -#if 0 - if (zdebug) - syslog(LOG_DEBUG, "debugging on"); -#endif - - /* set up sockets & my_addr and myname, - find other servers and set up server table, initialize queues - for retransmits, initialize error tables, - set up restricted classes */ - - if (initialize()) - exit(1); - - if (init_from_dump) - read_from_dump(dumpfile); - - /* Seed random number set. */ - srandom (getpid () ^ time (0)); - -#ifndef __SABER__ - /* chdir to somewhere where a core dump will survive */ - if (chdir("/usr/tmp") != 0) - syslog(LOG_ERR,"chdir failed (%m) (execution continuing)"); - -#if 0 - /* - * Many systems don't implement setpriority() as is done under BSD, - * and the kernel scheduler will appropriately swap in the processes - * that are needed. - */ - if (setpriority(PRIO_PROCESS, getpid(), -10)) - syslog(LOG_ERR,"setpriority failed (%m)"); -#endif -#endif - - FD_ZERO(&interesting); - FD_SET(srv_socket, &interesting); - - nfildes = srv_socket + 1; - - -#ifdef POSIX - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - - action.sa_handler = bye; - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); - - action.sa_handler = dbug_on; - sigaction(SIGUSR1, &action, NULL); - - action.sa_handler = dbug_off; - sigaction(SIGUSR2, &action, NULL); - - action.sa_handler = reap; - sigaction(SIGCHLD, &action, NULL); - - action.sa_handler = sig_dump_db; - sigaction(SIGFPE, &action, NULL); - sigaction(SIGXCPU, &action, NULL); - - action.sa_handler = sig_dump_strings; - sigaction(SIGEMT, &action, NULL); - - action.sa_handler = reset; - sigaction(SIGHUP, &action, NULL); -#else /* !posix */ - (void) signal(SIGINT, bye); - (void) signal(SIGTERM, bye); - (void) signal(SIGUSR1, dbug_on); - (void) signal(SIGUSR2, dbug_off); - (void) signal(SIGCHLD, reap); - (void) signal(SIGFPE, sig_dump_db); - (void) signal(SIGXCPU, sig_dump_db); - (void) signal(SIGEMT, sig_dump_strings); - (void) signal(SIGHUP, reset); -#endif /* POSIX */ - - syslog(LOG_NOTICE, "Ready for action"); - - /* Initialize t_local for other uses */ - (void) gettimeofday(&t_local, (struct timezone *)0); - /* GO! */ - uptime = NOW; - -#ifdef DEBUG_MALLOC - malloc_inuse(&m_size); -#endif - for EVER { - if (doreset) - do_reset(); - - if (dump_db_flag) - dump_db(); - if (dump_strings_flag) - dump_strings(); - - nexthost_tv.tv_usec = 0; - tvp = &nexthost_tv; - - if (nexttimo != 0L) { - nexthost_tv.tv_sec = nexttimo - NOW; - if (nexthost_tv.tv_sec <= 0) { - /* timeout has passed! */ - /* so we process one timeout, then pop to - select, polling for input. This way we get - work done even if swamped with many - timeouts */ - /* this will reset nexttimo */ - (void) timer_process(); - nexthost_tv.tv_sec = 0; - } - } else { /* no timeouts to process */ - nexthost_tv.tv_sec = 15; - } - readable = interesting; - if (msgs_queued()) { - /* when there is input in the queue, we - artificially set up to pick up the input */ - nfound = 1; - FD_ZERO(&readable); - } else - nfound = select(nfildes, &readable, (fd_set *) 0, - (fd_set *) 0, tvp); - - /* Initialize t_local for other uses */ - (void) gettimeofday(&t_local, (struct timezone *)0); - - /* don't flame about EINTR, since a SIGUSR1 or SIGUSR2 - can generate it by interrupting the select */ - if (nfound < 0) { - if (errno != EINTR) - syslog(LOG_WARNING, "select error: %m"); -#ifdef DEBUG_MALLOC - if (dump_malloc_stats) { - unsigned long foo,histid2; - dump_malloc_stats = 0; - foo = malloc_inuse(&histid2); - printf("Total inuse: %d\n",foo); - malloc_list(2,m_size,histid2); - } -#endif - continue; - } - if (nfound == 0) - /* either we timed out or we were just - polling for input. Either way we want to continue - the loop, and process the next timeout */ - continue; - else { - if ((bdump_socket >= 0) && - FD_ISSET(bdump_socket,&readable)) - bdump_send(); - else if (msgs_queued() || - FD_ISSET(srv_socket, &readable)) { - handle_packet(); - } else - syslog(LOG_ERR, "select weird?!?!"); - } - } -} - -/* Initialize net stuff. - Set up the server array. - Initialize the packet ack queues to be empty. - Initialize the error tables. - Restrict certain classes. - */ - -static int -initialize() -{ - if (do_net_setup()) - return(1); - - server_init(); - -#if 0 - if (!(nacklist = (ZNotAcked_t *) xmalloc(sizeof(ZNotAcked_t)))) { - /* unrecoverable */ - syslog(LOG_CRIT, "nacklist malloc"); - abort(); - } -#else - { - static ZNotAcked_t not_acked_head; - nacklist = ¬_acked_head; - } -#endif - (void) memset((caddr_t) nacklist, 0, sizeof(ZNotAcked_t)); - nacklist->q_forw = nacklist->q_back = nacklist; - - nexttimo = 1L; /* trigger the timers when we hit - the FOR loop */ - - (void) ZInitialize(); /* set up the library */ - (void) init_zsrv_err_tbl(); /* set up err table */ - - (void) ZSetServerState(1); - (void) ZSetFD(srv_socket); /* set up the socket as the - input fildes */ - - /* set up default strings */ - - class_control = make_zstring(ZEPHYR_CTL_CLASS, 1); - class_admin = make_zstring(ZEPHYR_ADMIN_CLASS, 1); - class_hm = make_zstring(HM_CTL_CLASS, 1); - class_ulogin = make_zstring(LOGIN_CLASS, 1); - class_ulocate = make_zstring(LOCATE_CLASS, 1); - wildcard_class = make_zstring(MATCHALL_CLASS, 1); - wildcard_instance = make_zstring(WILDCARD_INSTANCE, 1); - empty = make_zstring("", 0); - - matchall_sub.q_forw = &matchall_sub; - matchall_sub.q_back = &matchall_sub; - matchall_sub.zst_dest.classname = wildcard_class; - matchall_sub.zst_dest.inst = dup_zstring(empty); - matchall_sub.zst_dest.recip = dup_zstring(empty); - - set_ZDestination_hash(&matchall_sub.zst_dest); - /* restrict certain classes */ - access_init(); - return(0); -} - -/* - * Set up the server and client sockets, and initialize my_addr and myname - */ - -static int -do_net_setup() -{ - struct servent *sp; - struct hostent *hp; - char hostname[MAXHOSTNAMELEN+1]; - int flags; - - if (gethostname(hostname, MAXHOSTNAMELEN+1)) { - syslog(LOG_ERR, "no hostname: %m"); - return(1); - } - if (!(hp = gethostbyname(hostname))) { - syslog(LOG_ERR, "no gethostbyname repsonse"); - (void) strncpy(myname, hostname, MAXHOSTNAMELEN); - return(1); - } - (void) strncpy(myname, hp->h_name, MAXHOSTNAMELEN); - (void) memcpy((caddr_t) &my_addr, (caddr_t) hp->h_addr, - sizeof(hp->h_addr)); - - (void) setservent(1); /* keep file/connection open */ - - if (!(sp = getservbyname(SERVER_SVCNAME, "udp"))) { - syslog(LOG_ERR, "%s/udp unknown",SERVER_SVCNAME); - return(1); - } - (void) memset((caddr_t) &sock_sin, 0, sizeof(sock_sin)); - sock_sin.sin_port = sp->s_port; - - if (!(sp = getservbyname(HM_SVCNAME, "udp"))) { - syslog(LOG_ERR, "%s/udp unknown", HM_SVCNAME); - return(1); - } - hm_port = sp->s_port; - - (void) endservent(); - - if ((srv_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "client_sock failed: %m"); - return(1); - } - if (bind(srv_socket, (struct sockaddr *) &sock_sin, - sizeof(sock_sin)) < 0) { - syslog(LOG_ERR, "client bind failed: %m"); - return(1); - } - - /* set not-blocking */ -#ifdef POSIX - flags = fcntl(srv_socket, F_GETFL); - flags |= O_NONBLOCK; - (void) fcntl(srv_socket, F_SETFL, flags); -#else - flags = 1; - (void) ioctl(srv_socket, FIONBIO, (caddr_t) &flags); -#endif - - return(0); -} - - -/* - * print out a usage message. - */ - -static void -usage() -{ -#ifdef DEBUG - fprintf(stderr,"Usage: %s [-d] [-s] [-n] [-f dumpfile]\n",programname); -#else - fprintf(stderr,"Usage: %s [-d] [-n] [-f dumpfile]\n",programname); -#endif /* DEBUG */ - exit(2); -} - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -bye(int sig) -#else -bye(sig) - int sig; -#endif -{ - server_shutdown(); /* tell other servers */ - hostm_shutdown(); /* tell our hosts */ -#ifdef KERBEROS - (void) dest_tkt(); -#endif - syslog(LOG_NOTICE, "goodbye (sig %d)",sig); - exit(0); - /*NOTREACHED*/ -} - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -dbug_on(int sig) -#else -dbug_on(sig) - int sig; -#endif -{ - syslog(LOG_DEBUG, "debugging turned on"); -#ifdef DEBUG_MALLOC - dump_malloc_stats = 1; -#endif - zdebug = 1; - SIG_RETURN; -} - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -dbug_off(int sig) -#else -dbug_off(sig) - int sig; -#endif -{ - syslog(LOG_DEBUG, "debugging turned off"); -#ifdef DEBUG_MALLOC - malloc_inuse(&m_size); -#endif - zdebug = 0; - SIG_RETURN; -} - -int fork_for_dump = 0; - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -sig_dump_strings (int sig) -#else -sig_dump_strings(sig) - int sig; -#endif -{ - dump_strings_flag = 1; - SIG_RETURN; -} - -static void dump_strings() -{ - FILE *fp; - int oerrno = errno; - fp = fopen ("/usr/tmp/zephyr.strings", "w"); - if (!fp) { - syslog (LOG_ERR, "can't open strings dump file: %m"); - errno = oerrno; - dump_strings_flag = 0; - return; - } - syslog (LOG_INFO, "dumping strings to disk"); - print_zstring_table(fp); - if (fclose (fp) == EOF) - syslog (LOG_ERR, "error writing strings dump file"); - else - syslog (LOG_INFO, "dump done"); - oerrno = errno; - dump_strings_flag = 0; - return; -} - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -sig_dump_db(int sig) -#else -sig_dump_db(sig) - int sig; -#endif -{ - dump_db_flag = 1; - SIG_RETURN; -} - -static void dump_db() -{ - /* dump the in-core database to human-readable form on disk */ - FILE *fp; - int oerrno = errno; - int pid; - -#ifdef __SABER__ - pid = -1; -#else - if (fork_for_dump) { - MONCONTROL (0); - pid = fork (); - MONCONTROL (1); - } - else - pid = -1; -#endif - if (pid > 0) - { - dump_db_flag = 0; - return; - } - if ((fp = fopen("/usr/tmp/zephyr.db", "w")) == (FILE *)0) { - syslog(LOG_ERR, "can't open dump database"); - errno = oerrno; - dump_db_flag = 0; - return; - } - syslog(LOG_INFO, "dumping to disk"); - server_dump_servers(fp); - uloc_dump_locs(fp); - hostm_dump_hosts(fp); - syslog(LOG_INFO, "dump done"); - if (fclose(fp) == EOF) { - syslog(LOG_ERR, "can't close dump db"); - } - if (pid == 0) - exit (0); - errno = oerrno; - dump_db_flag = 0; - return; -} - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -reset(int sig) -#else -reset(sig) - int sig; -#endif -{ -#if 1 - zdbug((LOG_DEBUG,"reset()")); -#endif - doreset = 1; - SIG_RETURN; -} - -#ifdef __GNUG__ -#define wait WaitStatus -#endif - -static SIGNAL_RETURN_TYPE -#ifdef __STDC__ -reap(int sig) -#else -reap(sig) - int sig; -#endif -{ - int oerrno = errno; - -#ifdef POSIX - int waitb; - while (waitpid(-1, &waitb, WNOHANG) == 0) ; -#else - union wait waitb; - while (wait3 (&waitb, WNOHANG, (struct rusage*) 0) == 0) ; -#endif - - errno = oerrno; - SIG_RETURN; -} - -static void -do_reset() -{ - int oerrno = errno; -#ifdef POSIX - sigset_t mask, omask; -#else - int omask; -#endif -#if 0 - zdbug((LOG_DEBUG,"do_reset()")); -#endif -#ifdef POSIX - sigemptyset(&mask); - sigaddset(&mask, SIGHUP); - sigprocmask(SIG_BLOCK, &mask, &omask); -#else - omask = sigblock(sigmask(SIGHUP)); -#endif - - /* reset various things in the server's state */ - subscr_reset(); - server_reset(); - access_reinit(); - syslog (LOG_INFO, "restart completed"); - doreset = 0; - errno = oerrno; -#ifdef POSIX - sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); -#else - sigsetmask(omask); -#endif -} - -#ifndef DEBUG -/* - * detach from the terminal - */ - -static void -detach() -{ - /* detach from terminal and fork. */ - register int i; - register long size; - -#ifdef POSIX - size = sysconf(_SC_OPEN_MAX); -#else - size = getdtablesize(); -#endif - /* profiling seems to get confused by fork() */ - MONCONTROL (0); - i = fork (); - MONCONTROL (1); - if (i) { - if (i < 0) - perror("fork"); - exit(0); - } - - for (i = 0; i < size; i++) { - (void) close(i); - } - i = open("/dev/tty", O_RDWR, 666); - (void) ioctl(i, TIOCNOTTY, (caddr_t) 0); - (void) close(i); -#ifdef POSIX - (void) setsid(); -#endif -} -#endif - -static void -read_from_dump(dumpfile) - char *dumpfile; -{ - return; -} |