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

unix.superglobalmegacorp.com

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