Annotation of researchv9/ipc/src/mgrs/svcmgr/service.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.