|
|
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, 0); ! 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.