|
|
1.1 root 1: #include "mgr.h"
2: #include <sys/types.h>
3: #include <errno.h>
4: #include <ctype.h>
5:
6: fd_set listenset; /* set of fd's on which we are listening */
7: Service *svchead; /* head of services */
8: Service *nsvchead; /* new head of services */
9:
10: /*
11: * Parse a service definition line. The line is of the form:
12: * `service action+action+action+...'
13: */
14: Service *
15: newservice(cp)
16: char *cp;
17: {
18: # define MAXACTS 32
19: char *arg;
20: char *acts[MAXACTS];
21: Service *sp=(Service *)malloc(sizeof(Service));
22: int i, n;
23: Action *lap;
24:
25: if(sp==NULL) {
26: logevent("out of memory parsing service\n");
27: return NULL;
28: }
29: sp->ap = NULL;
30: sp->listen = -1;
31: sp->name = NULL;
32: sp->next = (Service *)NULL;
33: sp->accept = 0;
34: sp->lasttime = 1;
35:
36: /* find service name */
37: for(; isspace(*cp); cp++)
38: ;
39: for(arg=cp; *arg && !isspace(*arg); arg++)
40: ;
41: if(isspace(*arg))
42: *arg++ = '\0';
43: sp->name = strdup(cp);
44:
45: /* separate actions */
46: for(; isspace(*arg); arg++)
47: ;
48: for(n=0; n<MAXACTS; n++) {
49: if(*arg=='\0')
50: break;
51: acts[n] = arg;
52: for(;;arg++)
53: if(*arg=='\\' && *(arg+1)=='+') {
54: arg++;
55: } else if(*arg=='+') {
56: *arg++ = '\0';
57: break;
58: } else if(*arg=='\0')
59: break;
60: for(; isspace(*arg)||*arg=='+'; arg++)
61: ;
62: }
63: if (n <= 0) {
64: logevent("service with no action `%s'\n", cp);
65: freeservice(sp);
66: return NULL;
67: }
68:
69: /* parse actions */
70: for(lap=NULL, i=0; i<n; i++) {
71: if (lap==NULL)
72: sp->ap = lap = newaction(acts[i]);
73: else
74: lap = lap->next = newaction(acts[i]);
75: if (lap==NULL) {
76: freeservice(sp);
77: return NULL;
78: }
79: lap->next = NULL;
80: sp->accept |= lap->accept;
81: }
82: logevent("newservice(%s)\n", sp->name);
83: return sp;
84: }
85:
86: freeservice(sp)
87: Service *sp;
88: {
89: if(sp==NULL)
90: return;
91: if(sp->listen>=0) {
92: logevent("denouncing %s\n", sp->name);
93: close(sp->listen);
94: FD_CLR(sp->listen, listenset);
95: }
96: if(sp->name!=NULL)
97: free(sp->name);
98: for(; sp->ap!=NULL; sp->ap=sp->ap->next)
99: freeaction(sp->ap);
100: free((char *)sp);
101: }
102:
103: /*
104: * Add a service to the ones for which we are listening
105: */
106: addservice(sp)
107: Service *sp;
108: {
109: Service *p;
110:
111: /* look for an announced version of the service */
112: for(p=svchead; p; p=p->next)
113: if (strcmp(sp->name, p->name)==0)
114: break;
115:
116: /* inherit fd from old service */
117: if (p) {
118: sp->listen = p->listen;
119: p->listen = -1;
120: }
121:
122: /* add the new service */
123: sp->next = nsvchead;
124: nsvchead = sp;
125: return 0;
126: }
127:
128: /*
129: * Start the listening process on any services not already listening.
130: */
131: startsvcs()
132: {
133: Service *p, *np;
134:
135: /* denounce old services */
136: for(p=svchead; p; p=np) {
137: np = p->next;
138: freeservice(p);
139: }
140:
141: /* install new services */
142: svchead = nsvchead;
143: nsvchead = (Service *)NULL;
144:
145: announcesvcs();
146: }
147:
148: /*
149: * Announce any services not already listening
150: */
151: announcesvcs()
152: {
153: Service *p;
154:
155: /* announce new services */
156: for(p=svchead; p; p=p->next) {
157: if (p->listen>=0)
158: continue;
159: logevent("announcing %s\n", p->name);
160: p->listen = ipccreat(p->name, "light");
161: if (p->listen<0) {
162: logevent("failed\n");
163: continue;
164: }
165: chmod(p->name, 0666);
166: FD_SET(p->listen, listenset);
167: }
168: }
169:
170: /*
171: * Reset all services
172: */
173: resetsvcs()
174: {
175: Service *p, *np;
176:
177: /* shut down all listeners */
178: logevent("resetsrvcs()\n");
179: for(p=svchead; p; p=np) {
180: logevent("retracting %s\n", p->name);
181: np = p->next;
182: freeservice(p);
183: }
184: svchead = (Service *)NULL;
185: readfiles();
186: }
187:
188: /*
189: * Get a request and vector to the appropriate service
190: */
191: Request *
192: listen()
193: {
194: fd_set readset;
195: Service *sp;
196: static Request rp;
197: ipcinfo *ip;
198: int n;
199:
200: for(;;) {
201: readset = listenset;
202: if((n=select(NOFILE, &readset, (fd_set *)NULL, 30*1000))<0) {
203: if (errno!=EINTR) {
204: logevent("select failed: %d\n", errno);
205: resetsvcs();
206: }
207: continue;
208: }
209: if(checkfiles())
210: readfiles();
211: announcesvcs();
212: if(n==0)
213: continue;
214: for(sp=svchead; sp; sp=sp->next)
215: if (FD_ISSET(sp->listen, readset))
216: break;
217: if (!sp) {
218: logevent("listen on bad fd\n");
219: resetsvcs();
220: continue;
221: }
222: if ((ip = ipclisten(sp->listen)) == NULL) {
223: logevent("bad listen: fd %d\n", sp->listen);
224: close(sp->listen);
225: FD_CLR(sp->listen, listenset);
226: sp->listen = -1;
227: continue;
228: }
229: logevent("call for %s\n", ip->name);
230: if (ip->machine==NULL || ip->user==NULL) {
231: logevent("null machine/user called %s!\n", sp->name);
232: ipcreject(ip, EACCES, "no machine or user name");
233: continue;
234: }
235: logevent("call from %s!%s\n", ip->machine, ip->user);
236: if ((!sp->accept) && ipcaccept(ip)<0) {
237: logevent("can't accept %s from %s!%s\n", sp->name, ip->machine, ip->user);
238: continue;
239: }
240: logevent("accept %s from %s %s\n", sp->name, ip->machine, ip->user);
241: return(newrequest(ip, sp));
242: }
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.