|
|
1.1 root 1: #include <stdio.h>
2: /*
3: * The following code implements a daemon that "feeds" information to
4: * other processes over datakit. It handles the multiplexing
5: * and expects the following routines to perform the data collection
6: * and distribution:
7: * init() - initialize data collectin
8: * generate() - generate a new set of data
9: * sendinfo(fd) - send the information on the given fd
10: * myname() - return the name this daemon should use
11: * add(fd, who) - tell application that a new cleint exists
12: * drop(fd) - tell it that that client has disappeared
13: */
14: #include <errno.h>
15: #include <sys/param.h>
16: #include <sys/types.h>
17: #include <sys/ioctl.h>
18: #include <dkmgr.h>
19: #include <ctype.h>
20: #include <sys/stat.h>
21: #include <signal.h>
22: #include "defs.h"
23:
24: /* globals */
25: #define LIFETIME 24*60*60 /* secs to live since first started */
26: #define LIFESECS 1800 /* secs of lifetime while no clients exist */
27: #define RESENDSECS 5 /* secs between resends */
28: #define RESTART 20 /* minutes between restarts */
29: #define DEBUG ;
30: #define LOGDIR "/tmp/"
31:
32: char *sysname; /* name of system */
33: char *oursrv; /* name of this server */
34: int cfd_owait[NOFILE]; /* TRUE if waiting for output to complete */
35: fd_set cfds; /* set of client fd's */
36: char errbuf[128];
37: bool solo; /* TRUE if started by a shell */
38: int clients; /* number of clients */
39:
40: /* imports */
41: extern int errno;
42: extern int dkp_ld;
43: extern int dkmgropen;
44: extern int dkmgrreply;
45: char * malloc();
46: char * realloc();
47: char * strcpy();
48:
49: /* predefined */
50: char * ealloc();
51: char * sname();
52: char * getsysname();
53: int ding();
54:
55: /* specific to generator */
56: int generate(); /* generate information */
57: int sendinfo();
58: char *myname();
59: int init();
60: void add();
61: void drop();
62:
63: paranoia()
64: {
65: exit(1);
66: }
67:
68: main (argc, argv)
69: int argc;
70: char *argv[];
71: {
72: struct mgrmsg *dkmgr(), *mp;
73: fd_set rfds, wfds;
74: int fds, fd, mask;
75: long deathtime, lonelytime, now;
76: int (*sigfunc)();
77:
78: FD_ZERO(rfds); FD_ZERO(wfds);
79: doargs(argc, argv);
80: detach();
81: init(); /* application dependent init */
82: lonelytime = time((long *)0) + 2*LIFESECS;
83: deathtime = time((long *)0) + LIFETIME;
84:
85: while (1) {
86:
87: /* generate the new information */
88: generate();
89:
90: /* only read if there is a request waiting */
91: if (FD_ISSET(dkmgropen, rfds)) {
92: mp = dkmgr(oursrv, 2);
93: if (mp != NULL)
94: newclient (mp->m_chan, mp->m_uid);
95: }
96:
97: /* send information to clients (if any) */
98: sigfunc = signal(SIGALRM, paranoia);
99: alarm(60);
100: for (fd = 0; fd < NOFILE; fd++) {
101: if (FD_ISSET(fd, wfds))
102: cfd_owait[fd] = FALSE;
103: if (FD_ISSET(fd, cfds) && !cfd_owait[fd]) {
104: if (sendinfo (fd) < 0)
105: dropclient (fd);
106: else
107: cfd_owait[fd] = TRUE;
108: }
109: }
110: now = time((long *)0);
111: alarm(0);
112: signal(SIGALRM, sigfunc);
113:
114: /* is anyone out there? */
115: if (clients != 0)
116: lonelytime = time((long *)0) + LIFESECS;
117: else if (now > lonelytime)
118: die("life ain't worth livin");
119:
120: /* time to reset? */
121: if (now > deathtime)
122: die("reached retirement age");
123:
124: /* scan for request from dk or child termination */
125: FD_SET(dkmgropen, rfds);
126: if (mp != NULL) {
127: wfds = cfds;
128: fds = select (20, &rfds, &wfds, 0);
129: } else {
130: FD_ZERO(wfds);
131: }
132:
133: /* don't hog the CPU */
134: sleep (RESENDSECS);
135: }
136: }
137:
138: /* scan the arguments and pick a service name */
139: doargs (argc, argv)
140: int argc;
141: char *argv[];
142: {
143: int fd;
144:
145: if (argc > 1) {
146: solo = FALSE;
147: oursrv = argv[1];
148: } else if ((sysname = getsysname()) != NULL) {
149: solo = TRUE;
150: oursrv = sname(sysname, myname());
151: oursrv = strcpy (ealloc (strlen (oursrv) + 1), oursrv);
152: } else {
153: sprintf (errbuf, "%s: cant's find /etc/whoami", oursrv);
154: perror (errbuf);
155: exit (-1);
156: }
157: }
158:
159: /* detach from our environment */
160: detach ()
161: {
162: int i;
163: char logfile[64];
164:
165: /* detach from the process group */
166: setpgrp (0, 0);
167:
168: /* ignore some signals */
169: signal(SIGPIPE, SIG_IGN);
170: signal(SIGHUP, SIG_IGN);
171: signal(SIGTERM, SIG_IGN);
172:
173: /* detach from old i/o */
174: switch (fork()) {
175: case -1:
176: perror ("gen: couldn't fork");
177: exit (-1);
178: case 0:
179: for (i = 0; i < NOFILE; i++)
180: close (i);
181: i = open ("/dev/null", 0);
182: strcpy (logfile, LOGDIR);
183: strcat (logfile, myname());
184: strcat (logfile, ".log");
185: i = creat (logfile, 0666);
186: i = dup (1);
187: break;
188: default:
189: _exit (0);
190: }
191: }
192:
193: /* add client to the list */
194: newclient(chan, who)
195: int chan; /* dkchannel */
196: char * who; /* client */
197: {
198: int fd, i, rv;
199: char *devname, *dkfilename();
200:
201: /* open the line to the client */
202: devname = dkfilename(chan);
203: fd = open (devname, 2);
204: if (fd < 0) {
205: perror (oursrv);
206: dkmgrnak (chan);
207: return;
208: }
209: if (dkproto(fd, dkp_ld) < 0) {
210: (void)close (fd);
211: perror (oursrv);
212: dkmgrnak (chan);
213: return;
214: }
215: dkmgrack(chan);
216:
217: /* channel is open, add client to fdlist */
218: FD_SET(fd, cfds);
219:
220: /* tell application about it */
221: add (fd, who);
222: clients++;
223:
224: log("new client %s %d", who, fd);
225: }
226:
227:
228: dropclient (fd)
229: int fd;
230: {
231: /* do our bookkeeping */
232: FD_CLR(fd, cfds);
233: close (fd);
234:
235: /* tell application about it */
236: drop (fd);
237: clients--;
238:
239: log("drop client %d", fd);
240: }
241:
242: die(s)
243: char *s;
244: {
245: log(s);
246: exit(0);
247: }
248:
249: log(p1, p2, p3, p4, p5)
250: int p1, p2, p3, p4, p5;
251: {
252: fprintf(stderr, "[%d] ", time((long *)0));
253: fprintf(stderr, p1, p2, p3, p4, p5);
254: fprintf(stderr, "\n");
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.