|
|
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 - metrics - 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);
}