V9/jerq/src/sysmon/daemon.ok.c

Compare this file to the similar file:
Show the results in this format:

#include <stdio.h>
/*
 *	The following code implements a daemon that "feeds" information to
 *	other processes over datakit.  	It handles the multiplexing
 *	and expects the following routines to perform the data collection
 *	and distribution:
 *		init() - initialize data collectin
 *		generate() - generate a new set of data
 *		sendinfo(fd) - send the information on the given fd
 *		myname() - return the name this daemon should use
 *		add(fd, who) - tell application that a new cleint exists
 *		drop(fd) - tell it that that client has disappeared
 */		
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dkmgr.h>
#include <ctype.h>
#include <sys/stat.h>
#include <signal.h>
#include "defs.h"

/* globals */
#define LIFETIME 24*60*60	/* secs to live since first started */
#define LIFESECS 1800		/* secs of lifetime while no clients exist */
#define RESENDSECS  5		/* secs between resends */
#define RESTART 20		/* minutes between restarts */
#define DEBUG ;
#define LOGDIR "/tmp/"

char *sysname;			/* name of system */
char *oursrv;			/* name of this server */
int cfd_owait[NOFILE];		/* TRUE if waiting for output to complete */
fd_set cfds;			/* set of client fd's */
char errbuf[128];
bool solo;			/* TRUE if started by a shell */
int clients;			/* number of clients */

/* imports */
extern int errno;
extern int dkp_ld;
extern int dkmgropen;
extern int dkmgrreply;
char * malloc();
char * realloc();
char * strcpy();

/* predefined */
char * ealloc();
char * sname();
char * getsysname();
int    ding();

/* specific to generator */
int generate();			/* generate information */
int sendinfo();
char *myname();
int init();
void add();
void drop();

paranoia()
{
	exit(1);
}

main (argc, argv)
int argc;
char *argv[];
{
	struct mgrmsg *dkmgr(), *mp;
	fd_set rfds, wfds;
	int fds, fd, mask;
	long deathtime, lonelytime, now;
	int (*sigfunc)();

	FD_ZERO(rfds); FD_ZERO(wfds);
	doargs(argc, argv);
	detach();
	init();			/* application dependent init */
	lonelytime = time((long *)0) + 2*LIFESECS;
	deathtime = time((long *)0) + LIFETIME;

	while (1) {

		/* generate the new information */
		generate();

		/* only read if there is a request waiting */
		if (FD_ISSET(dkmgropen, rfds)) {
			mp = dkmgr(oursrv, 0);
			if (mp != NULL)
				newclient (mp->m_chan, mp->m_uid);
		}

		/* send information to clients (if any) */
		sigfunc = signal(SIGALRM, paranoia);
		alarm(60);
		for (fd = 0; fd < NOFILE; fd++) {
			if (FD_ISSET(fd, wfds))
				cfd_owait[fd] = FALSE;
			if (FD_ISSET(fd, cfds) && !cfd_owait[fd]) {
				if (sendinfo (fd) < 0)
					dropclient (fd);
				else
					cfd_owait[fd] = TRUE;
			}
		}
		now = time((long *)0);
		alarm(0);
		signal(SIGALRM, sigfunc);

		/* is anyone out there? */
		if (clients != 0)
				lonelytime = time((long *)0) + LIFESECS;
		else if (now > lonelytime)
				die("life ain't worth livin");

		/* time to reset? */
		if (now > deathtime)
			die("reached retirement age");

		/* scan for request from dk or child termination */
		FD_SET(dkmgropen, rfds);
		if (mp != NULL) {
			wfds = cfds;
			fds = select (20, &rfds, &wfds, 0);
		} else {
			FD_ZERO(wfds);
		}

		/* don't hog the CPU */
		sleep (RESENDSECS);
	}
}

/* scan the arguments and pick a service name */
doargs (argc, argv)
	int argc;
	char *argv[];
{
	int fd;

	if (argc > 1) {
		solo = FALSE;
		oursrv = argv[1];
	} else if ((sysname = getsysname()) != NULL) {
		solo = TRUE;
		oursrv = sname(sysname, myname());
		oursrv = strcpy (ealloc (strlen (oursrv) + 1), oursrv);
	} else {
		sprintf (errbuf, "%s: cant's find /etc/whoami", oursrv);
		perror (errbuf);
		exit (-1);
	}
}

/* detach from our environment */
detach ()
{
	int i;
	char logfile[64];

	/* detach from the process group */	
	setpgrp (0, 0);

	/* ignore some signals */
	signal(SIGPIPE, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	/* detach from old i/o */
	switch (fork()) {
	case -1:
		perror ("gen: couldn't fork");
		exit (-1);
	case 0:
		for (i = 0; i < NOFILE; i++)
			close (i);
		i = open ("/dev/null", 0);
		strcpy (logfile, LOGDIR);
		strcat (logfile, myname());
		strcat (logfile, ".log");
		i = creat (logfile, 0666);
		i = dup (1);
		break;
	default:
		_exit (0);
	}
}

/* add client to the list */
newclient(chan, who)
int chan;		/* dkchannel */
char * who;		/* client */
{
	int fd, i, rv;
	char *devname, *dkfilename();

	/* open the line to the client */
	devname = dkfilename(chan);
	fd = open (devname, 2);
	if (fd < 0) {
		perror (oursrv);
		dkmgrnak (chan);
		return;
	}
	if (dkproto(fd, dkp_ld) < 0) {
		(void)close (fd);
		perror (oursrv);
		dkmgrnak (chan);
		return;
	}
	dkmgrack(chan);

	/* channel is open, add client to fdlist */
	FD_SET(fd, cfds);

	/* tell application about it */
	add (fd, who);
	clients++;

	log("new client %s %d", who, fd);
}


dropclient (fd)
int fd;
{
	/* do our bookkeeping */
	FD_CLR(fd, cfds);
	close (fd);

	/* tell application about it */
	drop (fd);
	clients--;

	log("drop client %d", fd);
}

die(s)
char *s;
{
	log(s);
	exit(0);
}

log(p1, p2, p3, p4, p5)
int p1, p2, p3, p4, p5;
{
	fprintf(stderr, "[%d] ", time((long *)0));
	fprintf(stderr, p1, p2, p3, p4, p5);
	fprintf(stderr, "\n");
}