|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T m ┃
Length: 7761 (0x1e51) Types: TextFile Names: »main.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen └─ ⟦this⟧ »cph85dist/rman/daemon/main.c«
/* * Copyright (c) 1985 Jonathan C. Broome and The Regents of the * University of California. * * This software may be freely redistributed without licensing * provided that this copyright notice remains intact and no profit * is gained through any redistribution. * * Please report any bug fixes or modifications to the author at: * * broome@ucb-vax.berkeley.edu * or: * ...!ucbvax!broome * * The author and the Regents assume no liability for any damages * or loss of revenue caused directly or indirectly by the use of * this software. */ #ifndef lint static char *RCSid = "$Header: main.c,v 1.9 85/08/27 18:45:47 broome Exp $"; #endif /* * $Log: main.c,v $ * Revision 1.9 85/08/27 15:16:47 broome * Last cleanup before release. * * Revision 1.8 85/08/05 08:53:38 broome * Fixed missing argument to error printf ... * * Revision 1.7 85/08/04 16:33:06 broome * Added new command line options: * -f - to specify a configuration file besides the default. * -l - sets load cutoff so that we won't answer pings if load is higher. * -p - specify alternate port number to listen on. * * Revision 1.6 85/07/24 10:38:57 broome * * Revision 1.5 85/07/16 11:09:56 broome * Tuned the new "ping" stuff a bit. * * Revision 1.4 85/07/06 16:55:57 broome * Added new ping routines to help improve response times, * also makes it easier to cope with dead hosts. * * Revision 1.3 85/07/03 17:34:30 broome * [ RCS screwed up again! ] * * Revision 1.2 85/07/02 21:05:52 broome * * Revision 1.1 85/06/25 11:23:38 broome * Initial revision */ #include "response.h" #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <signal.h> #include <errno.h> #include <stdio.h> #ifdef SERVICES #include <netdb.h> #endif SERVICES #ifndef STRICT /* hang up on unknown hosts ??? */ #define STRICT 0 #endif #ifndef TIMEOUT /* timeout interval on a connection */ #define TIMEOUT 2 #endif extern int errno; char hostname[32]; main (ac, av) int ac; char **av; { #ifdef SERVICES struct servent *sp, *getservbyname(); #endif char **argv; char *ctime(); char *config_file = CONFIG; long now; char line[128]; int argc, len, psock, ssock, new, mask, tty; int reaper(), hup(), timeout(); int port = 0; int secure = STRICT; /* hang up on unidentified hosts??? */ extern double cutoff; struct sockaddr_in sin; /* * usage: mand [ -s ] [ -f config_file ] [ -p service_port ] [ -l load_cutoff ] */ while (*++av) { if (**av != '-') usage (); switch (*++*av) { case 'f': if (*++av) /* next arg is configuration file */ config_file = *av; else usage (); break; case 'p': if (*++av) /* next arg is service port to use */ port = htons (atoi (*av)); else usage (); break; case 'l': if (*++av) /* next arg is load cutoff point */ cutoff = (double) atoi (*av); else usage (); break; case 's': secure = !secure; printf ("Secure = O%s\n", secure ? "N" : "FF"); break; default: usage (); } } if (port == 0) { #ifndef SERVICES fprintf (stderr, "Have to specify a service port!\n"); usage (); #else if ((sp = getservbyname ("man", "tcp")) == NULL) { fprintf (stderr, "mand: \"man/tcp\": unknown service.\n"); exit (1); } port = sp->s_port; #endif SERVICES } if ((ssock = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); exit (-1); } sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = port; if (bind (ssock, (char *)&sin, sizeof (sin)) < 0) { perror ("bind"); exit (-2); } (void) listen (ssock, 5); if ((psock = open_ping (port)) < 0) /* start up datagram socket */ exit (1); if (fork ()) /* fork off into background */ exit (0); signal (SIGCHLD, reaper); signal (SIGPIPE, SIG_IGN); signal (SIGHUP, hup); tty = open ("/dev/tty", 0, 0); /* disassociate from terminal */ if (tty != -1) { ioctl (tty, TIOCNOTTY, (struct sgttyb *)0); (void) close (tty); } else if (setpgrp (0, 0)) perror ("setpgrp"); (void) chdir ("/usr/man"); (void) umask (0); /* may not want this when root */ config (config_file); gethostname (hostname, 32); for ( ;; ) { mask = (1 << psock) | (1 << ssock); if (select (20, &mask, 0, 0, 0) <= 0) continue; if (mask & (1 << psock)) /* `ping' */ ping (); if (mask & (1 << ssock)) { len = sizeof (sin); if ((new = accept (ssock, &sin, &len)) < 0) { if (errno != EINTR) { perror ("accept"); exit (-1); } else continue; } if (fork ()) { /* parent */ close (new); } else { /* child */ close (ssock); close (psock); signal (SIGCHLD, SIG_IGN); signal (SIGALRM, timeout); alarm (TIMEOUT * 60); /* close conn after TIMEOUT mins */ if (new != 0) /* set up stdin, stdout, stderr */ dup2 (new, 0); if (new != 1) dup2 (new, 1); if (new != 2) dup2 (new, 2); if (identify (sin) && secure) { printf ("%d %s manual server: your host does not have man access\r\n", ERR_HELLO, hostname); exit (1); } time (&now); printf ("%d %s manual page server ready at %19.19s\r\n", OK_HELLO, hostname, ctime (&now)); (void) fflush (stdout); while (gets (line)) { /* read a line */ argc = parse (line, &argv); /* parse it */ if (argc == 0) /* blank line --- */ continue; /* just ignore it */ funcall (argc, argv); /* do the command */ } quit(); } } } } /* * Take care of all the dead children, avoiding zombie processes. */ reaper() { union wait status; while (wait3 (&status, WNOHANG, 0) > 0) ; } /* * Bye bye ... */ quit () { long now; time (&now); printf ("%d %s closing connection at %19.19s\r\n", OK_GOODBYE, hostname, ctime (&now)); exit (0); } /* * Exit nicely on SIGHUP. */ hup () { exit (0); } /* * Timed out after TIMEOUT minutes --- close down the connection. */ timeout () { printf ("%d %s manual server: connection timed out after %d minutes.\r\n", ERR_TIMEOUT, hostname, TIMEOUT); exit (1); } /* * Print a usage message and go away. */ usage () { fprintf (stderr, "Usage: mand [ -s ] [ -f config_file ] [ -p port ] [ -l load_cutoff ]\n"); exit (1); }