Annotation of researchv9/ipc/src/mgrs/svcmgr/service.c, revision 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.