|
|
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.