Annotation of coherent/a/usr/bob/uusrc/src/uuxqt.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  uuxqt.c
        !             3:  *
        !             4:  *  Execute local commands spooled by remote sites.
        !             5:  *
        !             6:  *  copyright (x) richard h. lamb 1985, 1986, 1987
        !             7:  *  changes (massive) copyright (c) 1989-1991 by Mark Williams Company
        !             8:  */
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <signal.h>
        !            12: #include <access.h>
        !            13: #include <sys/param.h>
        !            14: #include <sys/stat.h>
        !            15: #include "dirent.h"
        !            16: #include "dcp.h"
        !            17: #include "perm.h"
        !            18: 
        !            19: /*
        !            20:  *  Global Variables Definitions
        !            21:  */
        !            22: 
        !            23: char   directory[CTLFLEN];             /* directory for control files  */
        !            24: char   xfile[CTLFLEN];                 /* "X.*" control file name      */
        !            25: FILE   *xfp = NULL;                    /* Opened "X.*" FILE pointer    */
        !            26: int    processid;                      /* process id of this uuxqt     */
        !            27: char   line[BUFSIZ];                   /* Reading a text line          */
        !            28: 
        !            29: static char    command[BUFSIZ], input[60], output[60];
        !            30: static char    orig_user[128];
        !            31: static char    orig_system[SITELEN+1];
        !            32: static char    notifywho[BUFSIZ];
        !            33: static char    *allowed;
        !            34: 
        !            35: static int     failstatus_req;
        !            36: static int     succstatus_req;
        !            37: static char    errbuf1[BUFSIZ];
        !            38: static char    errbuf2[BUFSIZ];
        !            39: static char    errbuf3[BUFSIZ];
        !            40: static char    reason[80];
        !            41: 
        !            42: static char    *sep = " \t\n";
        !            43: 
        !            44: char   *rmtname = NULL;
        !            45: char   **zenvp;                        /* Globally Available envp      */
        !            46: 
        !            47: extern int optind;
        !            48: extern int optopt;
        !            49: extern char *optarg;
        !            50: 
        !            51: /*
        !            52:  *  Extern Function Declarations
        !            53:  */
        !            54: 
        !            55: extern char    *strtok();
        !            56: extern char    *index();
        !            57: 
        !            58: catchsegv()
        !            59: {
        !            60:        fatal("Segmentation violation -- uuxqt aborted");
        !            61: }
        !            62: 
        !            63: catchterm()
        !            64: {
        !            65:        fatal("Local signal -- uuxqt aborted");
        !            66: }
        !            67: 
        !            68: main(argc, argv, envp)
        !            69: int argc;
        !            70: char *argv[], *envp[];
        !            71: {
        !            72:        char xqtdir[LOGFLEN];
        !            73:        char ch;
        !            74: 
        !            75:        while ( (ch=getopt(argc, argv, "x:vV")) != EOF ) {
        !            76:                switch (ch) {
        !            77:                case 'x':
        !            78:                        debuglevel = atoi(optarg);
        !            79:                        break;
        !            80:                case 'v':
        !            81:                case 'V':
        !            82:                        fatal("uuxqt: Version %s", VERSION);
        !            83:                case '?':
        !            84:                default:
        !            85:                        fatal("Improper option usage: %c", optopt);
        !            86:                }
        !            87:        }
        !            88: 
        !            89:        bedaemon();     /* detach from controlling terminal */
        !            90: 
        !            91:        zenvp = envp;
        !            92:        processid = getpid();
        !            93:        signal(SIGINT,  SIG_IGN);
        !            94:        signal(SIGHUP,  SIG_IGN);
        !            95:        signal(SIGQUIT, SIG_IGN);
        !            96:        signal(SIGTERM, catchterm);
        !            97:        signal(SIGSEGV, catchsegv);
        !            98:        open_debug("uuxqt", 0);
        !            99:        sprintf(xqtdir, "%s/.Xqtdir", SPOOLDIR);
        !           100:        if (chdir(xqtdir) != 0)
        !           101:                fatal("can't chdir to: %s", xqtdir);
        !           102:        dcxqt();
        !           103:        close_debug();
        !           104:        exit(0);
        !           105: }
        !           106: 
        !           107: dcxqt()
        !           108: {
        !           109:        if ( lockexist("uuxqt") )
        !           110:                return;
        !           111: 
        !           112:        if ( lockit("uuxqt") < 0 )
        !           113:                fatal("Can't lock uuxqt");
        !           114: 
        !           115:        if ( dscan_start() ) {
        !           116:                while ( dscan() ) {
        !           117:                        if ( xscan_start() ) {
        !           118:                                while ( xscan() )
        !           119:                                        dcxqt_work();
        !           120:                                xscan_done();
        !           121:                        }
        !           122:                }
        !           123:                dscan_done();
        !           124:        }
        !           125:        if ( lockrm("uuxqt") < 0 )
        !           126:                printmsg(M_LOG, "error unlocking uuxqt");
        !           127: }
        !           128: 
        !           129: /*
        !           130:  * Perform the work specified in the "X.*" control file: "xfile"
        !           131:  */
        !           132: 
        !           133: dcxqt_work()
        !           134: {
        !           135:        static  char lastsite[SITELEN] = "\0";
        !           136:        int     filewait = 0;
        !           137:        int     removethis = 0;
        !           138:        int     did_work = 0;
        !           139:        int     fnd;
        !           140:        int     execval;
        !           141:        char    *sp, *osp;
        !           142: 
        !           143:        if ( (xfp=fopen(xfile, "r")) == NULL )
        !           144:                return;
        !           145: 
        !           146:        reason[0] = input[0] = output[0] = command[0] =
        !           147:        notifywho[0] = orig_user[0] = orig_system[0] =
        !           148:        errbuf1[0] = errbuf2[0] = errbuf3[0] = '\0';
        !           149:        failstatus_req = succstatus_req = fnd = 0;
        !           150: 
        !           151:        while ( fgets(line, BUFSIZ, xfp) != NULL ) {
        !           152:                sp = strtok(line, sep);
        !           153:                switch(line[0]) {
        !           154:                case 'C':
        !           155:                        sp = strtok(NULL, "#\n");
        !           156:                        strcpy(command, sp);
        !           157:                        break;
        !           158:                case 'F':
        !           159:                        sp = strtok(NULL, sep);
        !           160:                        osp = strtok(NULL, sep);
        !           161:                        sprintf(input,"%s/%s", directory, sp);
        !           162:                        filewait |= isfileabsent(input);
        !           163:                        
        !           164:                        if (filewait == 0 && osp != NULL) {
        !           165:                                if (link(input, osp) == -1) {
        !           166:                                        sprintf(errbuf1,
        !           167:                                                "Cannot link %s to %s.\n",
        !           168:                                                input, osp);
        !           169:                                        removethis = 1;
        !           170:                                }
        !           171:                                ul(input);
        !           172:                                input[0] = '\0';
        !           173:                        }
        !           174:                        break;
        !           175:                case 'I':
        !           176:                        sp = strtok(NULL, sep);
        !           177:                        sprintf(input, "%s/%s", directory, sp);
        !           178:                        break;
        !           179:                case 'M':
        !           180:                        strcpy(errbuf2,
        !           181:                                "Execute M record not supported");
        !           182:                        break;
        !           183:                case 'O':
        !           184:                        sp = strtok(NULL, sep);
        !           185:                        sprintf(output, "%s/%s", directory, sp);
        !           186:                        break;
        !           187:                case 'R':
        !           188:                        strcpy (notifywho, sp = strtok(NULL, sep));
        !           189:                        break;
        !           190:                case 'U':
        !           191:                        strcpy(orig_user, sp = strtok(NULL, sep));
        !           192:                        strncpy(orig_system,sp=strtok(NULL, sep), SITELEN);
        !           193:                        if ( strncmp(orig_system, lastsite, SITELEN) != 0) {
        !           194:                                strncpy(lastsite, orig_system, SITELEN);
        !           195:                                rmtname = &lastsite[0];
        !           196:                                open_the_logfile("uuxqt");
        !           197:                                plog(M_INFO, "Starting Xqt {%d} (V%s)",
        !           198:                                                         processid, VERSION);
        !           199:                                perm_get(orig_system, NULL);
        !           200:                                allowed = perm_value(commands_e);
        !           201:                        }
        !           202:                        break;
        !           203:                case 'Z':
        !           204:                        failstatus_req = 1;
        !           205:                        break;
        !           206:                case 'n':
        !           207:                        succstatus_req = 1;
        !           208:                        break;
        !           209:                case '#':
        !           210:                        break;
        !           211:                default:
        !           212:                        sprintf(errbuf3, "Unknown command %s", sp);
        !           213:                        break;
        !           214:                }
        !           215:        }
        !           216: 
        !           217:        if (strlen(notifywho) < 1)
        !           218:                strcpy (notifywho, orig_user);
        !           219:        if (strlen(errbuf1) > 0)
        !           220:                plog(M_INFO, errbuf1);
        !           221:        if (strlen(errbuf2) > 0)
        !           222:                plog(M_INFO, errbuf2);
        !           223:        if (strlen(errbuf3) > 0)
        !           224:                plog(M_INFO, errbuf3);
        !           225: 
        !           226:        plog(M_INFO, "%s (<%s >%s)", command, input, output);
        !           227:        if (removethis) {
        !           228:                unlinkfiles();
        !           229:        } else if (filewait)
        !           230:                plog(M_INFO, "Waiting for files");
        !           231:        else {
        !           232:                did_work ++;
        !           233:                if ( (execval=shell2(command, input, output)) != 0 ) {
        !           234:                        plog(M_INFO, "Command failed, status %d (0x%04x)",
        !           235:                                                execval, execval);
        !           236:                        strcpy(reason, "Exit status not zero");
        !           237:                }
        !           238:                if (succstatus_req || (failstatus_req && (execval != 0))) 
        !           239:                        remote_status(execval);
        !           240:                unlinkfiles();
        !           241:        }
        !           242:        if (did_work > 0) {
        !           243:                plog(M_INFO, "Finished {%d}", processid);
        !           244:        }
        !           245:        fclose(xfp);
        !           246: }
        !           247: 
        !           248: unlinkfiles()
        !           249: {
        !           250:        char    *osp, *sp;
        !           251: 
        !           252:        rewind(xfp);
        !           253:        while(fgets(line, BUFSIZ, xfp) != NULL) {
        !           254:                sp = strtok(line, sep);
        !           255:                switch(line[0]) {
        !           256:                case 'C':
        !           257:                        break;
        !           258:                case 'F':
        !           259:                        sp = strtok(NULL, sep);
        !           260:                        osp = strtok(NULL, sep);
        !           261:                        ul(sp);
        !           262:                        if (osp != NULL) 
        !           263:                                ul(osp);
        !           264:                        break;
        !           265:                case 'I':case 'M':case 'O':
        !           266:                case 'U':case 'Z':case 'n':
        !           267:                default:
        !           268:                        break;
        !           269:                
        !           270:                }
        !           271:        }
        !           272:        ul(xfile);
        !           273:        ul(input);
        !           274:        ul(output);
        !           275: }
        !           276: 
        !           277: static
        !           278: ul(fn)
        !           279: char   *fn;
        !           280: {
        !           281:        int     status;
        !           282:        if (strlen(fn) < 1)
        !           283:                return;
        !           284:        status = unlink(fn);    
        !           285: }
        !           286: 
        !           287: remote_status(val)
        !           288: int val;
        !           289: {
        !           290:        static char pbuf[BUFSIZ];
        !           291: 
        !           292:        FILE    *fmp;
        !           293:        (void) signal(SIGPIPE, SIG_IGN);
        !           294:        sprintf(pbuf, "mail -auucp %s!%s ", orig_system, notifywho);
        !           295:        if ((fmp = popen(pbuf, "w")) == NULL)
        !           296:                plog(M_INFO, "Cannot send remote status mail");
        !           297:        else {
        !           298:                fprintf(fmp, "From: UUXQT V%s\n", VERSION);
        !           299:                fprintf(fmp, "Subject: UUXQT remote execution status\n\n");
        !           300:                fprintf(fmp,
        !           301:                        "Command \"%s\" %s.\n\tStatus %d (0x%04x)",
        !           302:                        command, val ? "failed" : "succeeded", val, val);
        !           303:                if (strlen(reason) > 0)
        !           304:                        fprintf(fmp, "\nReason: %s", reason);
        !           305:                fprintf(fmp, "\n");
        !           306:                if (pclose(fmp) != 0)
        !           307:                        plog(M_INFO, "Remote status mail failed");
        !           308:                plog(M_INFO, "Remote status mail posted to %s!%s",
        !           309:                        orig_system, notifywho);
        !           310:        }
        !           311: }
        !           312: 
        !           313: isfileabsent(fn)
        !           314: char   *fn;
        !           315: {
        !           316:        return access(fn, AREAD);
        !           317: }
        !           318: 
        !           319: #define        MAXENVS 200
        !           320: static char *uuenvp[MAXENVS];
        !           321: static char uu_user[BUFSIZ];
        !           322: static char uu_mach[BUFSIZ];
        !           323: 
        !           324: shell2(command, inname, outname)
        !           325: char *command;
        !           326: char *inname;
        !           327: char *outname;
        !           328: {
        !           329:        int     waitstat;
        !           330:        int     fd, i;
        !           331:        int     waitpid, cpid;
        !           332: 
        !           333:        if ( !permission(command) ) {
        !           334:                strcpy(reason, "No permission to execute command");
        !           335:                plog(M_INFO, "No permission to execute: %s", command);
        !           336:                if (failstatus_req)
        !           337:                        remote_status(-1);
        !           338:                return 0;
        !           339:        }
        !           340: 
        !           341:        sprintf(uu_user, "UU_USER=%s", notifywho);
        !           342:        sprintf(uu_mach, "UU_MACHINE=%s", orig_system);
        !           343:        uuenvp[0] = uu_user;
        !           344:        uuenvp[1] = uu_mach;
        !           345:        for (i=2; (zenvp[i]!=NULL) && (i<MAXENVS); i++)
        !           346:                uuenvp[i] = zenvp[i-2];
        !           347:                if ((cpid = fork()) < 0) {
        !           348:                plog(M_INFO, "couldn't fork");
        !           349:                return -1;
        !           350:        }
        !           351:        if (cpid == 0) {
        !           352:                if (strlen(inname) != 0) {
        !           353:                        fd = open(inname, 0);
        !           354:                        dup2(fd, 0);
        !           355:                        if (fd > 0)
        !           356:                                close(fd);
        !           357:                }
        !           358:                if (strlen(outname) != 0) {
        !           359:                        fd = creat(outname, 0644);
        !           360:                        dup2(fd, 1);
        !           361:                        if (fd > 1)
        !           362:                                close(fd);
        !           363:                }
        !           364:                execle("/bin/sh", "sh", "-c", command, (char *)0, uuenvp);
        !           365:                plog(M_INFO, "Could not exec /bin/sh");
        !           366:                exit(0177);
        !           367:        }
        !           368:        while (((waitpid = wait(&waitstat)) != cpid) && (waitpid > 0))
        !           369:                ;
        !           370:        return waitstat;
        !           371: }
        !           372: 
        !           373: permission(command)
        !           374: char *command;
        !           375: {
        !           376:        char *sp, *cp, *spcp;
        !           377:        int ok;
        !           378: 
        !           379:        if ( (spcp=index(command, ' ')) != NULL ) 
        !           380:                *spcp = '\0';
        !           381: 
        !           382:        sp = allowed;
        !           383:        ok = 0;
        !           384:        do {
        !           385:                if ( (cp=index(sp, ':')) != NULL )
        !           386:                        *cp = '\0';
        !           387:                if ( strcmp(command, sp) == 0 )
        !           388:                        ok = 1;
        !           389:                if ( cp != NULL )
        !           390:                        *cp++ = ':';
        !           391:        } while ( !ok && ((sp=cp) != NULL) );
        !           392: 
        !           393:        if ( spcp != NULL )
        !           394:                *spcp = ' ';
        !           395:        return(ok);
        !           396: }
        !           397: 
        !           398: /*
        !           399:  * Directory Scan Functions:
        !           400:  *
        !           401:  * dscan_start()  :  Opens SPOOLDIR to scan for sitename subdirectories
        !           402:  *               :  Returns: (1) opened ok, (0) error
        !           403:  * dscan()       :  Sets variable "directory" to next directory
        !           404:  *               :  Returns: (1) found directory, (0) no directory
        !           405:  * dscan_done()          :  Done scanning SPOOLDIR for directories
        !           406:  *
        !           407:  * xscan_start()  :  Opens "directory" to scan for "X.*" control files
        !           408:  *               :  Returns: (1) opened ok, (0) error
        !           409:  * xscan()       :  Sets variable "xfile" to next such "X.*" control file
        !           410:  *               :  Returns: (1) found file, (0) no file
        !           411:  * xscan_done()          :  Done scanning "directory" for "X.*" control files
        !           412:  */
        !           413: 
        !           414: static DIR *sdirp, *xdirp;
        !           415: extern DIR *opendir();
        !           416: extern struct direct *readdir();
        !           417: 
        !           418: dscan_start()
        !           419: {
        !           420:        if ( (sdirp=opendir(SPOOLDIR)) == NULL ) {
        !           421:                printmsg(M_LOG, "Cannot open spool directory: %s", SPOOLDIR);
        !           422:                return(0);
        !           423:        }
        !           424:        return(1);
        !           425: }
        !           426: 
        !           427: dscan()
        !           428: {
        !           429:        struct stat statbuf;
        !           430:        struct dirent *mdp;
        !           431: 
        !           432:        while( (mdp=readdir(sdirp)) != NULL ) {
        !           433:                if ( mdp->d_name[0] == '.' )
        !           434:                        continue;
        !           435:                sprintf(directory, "%s/%s", SPOOLDIR, mdp->d_name);
        !           436:                stat(directory, &statbuf);
        !           437:                if ( statbuf.st_mode & S_IFDIR )
        !           438:                        return(1);
        !           439:        }
        !           440:        return(0);
        !           441: }
        !           442: 
        !           443: dscan_done()
        !           444: {
        !           445:        closedir(sdirp);
        !           446: }
        !           447: 
        !           448: xscan_start()
        !           449: {
        !           450:        if ( (xdirp=opendir(directory)) == NULL ) {
        !           451:                printmsg(M_LOG, "Cannot open spool directory: %s", directory);
        !           452:                return(0);
        !           453:        }
        !           454:        return(1);
        !           455: }
        !           456: 
        !           457: xscan()
        !           458: {
        !           459:        struct stat statbuf;
        !           460:        struct dirent *xdp;
        !           461: 
        !           462:        while( (xdp=readdir(xdirp)) != NULL ) {
        !           463:                if ( strncmp(xdp->d_name, "X.", 2) == 0 ) {
        !           464:                        sprintf(xfile, "%s/%s", directory, xdp->d_name);
        !           465:                        stat(xfile, &statbuf);
        !           466:                        if ( statbuf.st_mode & S_IFDIR )
        !           467:                                continue;
        !           468:                        return(1);
        !           469:                }
        !           470:        }
        !           471:        return(0);
        !           472: }
        !           473: 
        !           474: xscan_done()
        !           475: {
        !           476:        closedir(xdirp);
        !           477: }
        !           478: 
        !           479: fatal(x)
        !           480: {
        !           481:        printmsg(M_FATAL, "%r", &x);
        !           482:        if ( lockexist("uuxqt") )
        !           483:                lockrm("uuxqt");
        !           484:        close_logfile();
        !           485:        close_debug();
        !           486:        exit(1);
        !           487: }      

unix.superglobalmegacorp.com

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