|
|
1.1 root 1: #include <sys/types.h>
2: #include <signal.h>
3: #include <ipc.h>
4: #include <stdio.h>
5: #include "faces.h"
6:
7: static fd_set cfds;
8: static int maxfd;
9: static char *pfile = "/usr/net/face/people.tab";
10: static char *mfile = "/usr/net/face/machine.tab";
11:
12: main(argc, argv)
13: int argc;
14: char **argv;
15: {
16:
17: if (argc < 2) {
18: fprintf(stderr, "usage: faces server-name ...\n");
19: exit(1);
20: }
21: maketree(pfile, mfile);
22: for (;;) {
23: listen(argc-1, argv+1);
24: log("network restart\n");
25: }
26: }
27:
28: catchalarm()
29: {
30: signal(SIGALRM, catchalarm);
31: }
32:
33: /*
34: * the main loop, listening for calls and requests
35: */
36:
37: listen(nname, namelist)
38: int nname;
39: char **namelist;
40: {
41: static int *namefd;
42: fd_set rfds;
43: register int i;
44: ipcinfo *ip;
45:
46: if (namefd == NULL)
47: namefd = (int *)emalloc(sizeof(int)*nname);
48: for (i = 0; i < nname; i++)
49: namefd[i] = -1;
50: FD_ZERO(cfds);
51: for (;;) {
52: for (i = 0; i < nname; i++) {
53: if (namefd[i] < 0) {
54: namefd[i] = ipccreat(ipcpath("", "", namelist[i]), "");
55: if (namefd[i] < 0)
56: log("can't announce %s: %s\n", namelist[i], errstr);
57: else {
58: log("fd %d: announced %s\n", namefd[i], namelist[i]);
59: FD_SET(namefd[i], cfds);
60: }
61: }
62: if (namefd[i] >= 0 && namefd[i] > maxfd)
63: maxfd = namefd[i];
64: }
65: rfds = cfds;
66: if (select(maxfd+1, &rfds, (fd_set *)0, 60*1000) < 0) {
67: log("select failed\n");
68: for (i = 0; i < maxfd; i++)
69: if (FD_ISSET(i, cfds))
70: close(i);
71: return;
72: }
73: for (i = 0; i < nname; i++) {
74: if (namefd[i] < 0)
75: continue;
76: if (FD_ISSET(namefd[i], rfds)) {
77: FD_CLR(namefd[i], rfds);
78: if ((ip = ipclisten(namefd[i])) == NULL) {
79: log("fd %d: %s: listen failed\n", namefd[i], errstr);
80: FD_CLR(namefd[i], cfds);
81: close(namefd[i]);
82: namefd[i] = -1;
83: continue;
84: }
85: newclient(ip);
86: }
87: }
88: for (i = 0; i <= maxfd; i++)
89: if (FD_ISSET(i, rfds) && FD_ISSET(i, cfds)) {
90: signal(SIGALRM, catchalarm);
91: alarm(60);
92: if (dorequest(i) == 0)
93: dropclient(i);
94: alarm(0);
95: }
96: checknew();
97: }
98: }
99:
100: /* add client to the list */
101: newclient(ip)
102: register ipcinfo *ip;
103: {
104: int fd;
105:
106: if ((fd = ipcaccept(ip)) < 0) {
107: log("ipcaccept failed\n");
108: return;
109: }
110: FD_SET(fd, cfds);
111: if (fd > maxfd)
112: maxfd = fd;
113: log("fd %d: client %s\n", fd, ip->machine);
114: }
115:
116: dropclient (fd)
117: int fd;
118: {
119: FD_CLR(fd, cfds);
120: close (fd);
121: log("fd %d: off\n", fd);
122: }
123:
124: /*
125: * check for new data, rebuild tree if necessary
126: */
127:
128: #define MINCHK 120 /* at most once in this many seconds */
129:
130: checknew()
131: {
132: static time_t lastcheck;
133: time_t now;
134:
135: now = time((time_t *)0);
136: if (now + MINCHK < lastcheck)
137: return;
138: if (newdata(pfile, mfile)) {
139: log("new data, reinitializing\n");
140: maketree(pfile, mfile);
141: now = time((time_t *)0);
142: }
143: lastcheck = now;
144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.