Annotation of 43BSDReno/usr.bin/uucp/uuxqt.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)uuxqt.c    5.13    (Berkeley) 6/29/90";
                      3: #endif
                      4: 
                      5: #include "uucp.h"
                      6: #include <sys/stat.h>
                      7: #ifdef NDIR
                      8: #include "ndir.h"
                      9: #else
                     10: #include <sys/dir.h>
                     11: #endif
                     12: #include <signal.h>
                     13: 
                     14: #define BADCHARS       "&^|(`\\<>;\"{}\n'"
                     15: #define RECHECKTIME    60*10   /* 10 minutes */
                     16: 
                     17: #define APPCMD(d) {\
                     18: char *p;\
                     19: for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';}
                     20: 
                     21: extern char Filent[LLEN][NAMESIZE];
                     22: 
                     23: /*
                     24:  *     uuxqt will execute commands set up by a uux command,
                     25:  *     usually from a remote machine - set by uucp.
                     26:  */
                     27: 
                     28: #define        NCMDS   50
                     29: char *Cmds[NCMDS+1];
                     30: int Notify[NCMDS+1];
                     31: #define        NT_YES  0       /* if should notify on execution */
                     32: #define        NT_ERR  1       /* if should notify if non-zero exit status (-z equivalent) */
                     33: #define        NT_NO   2       /* if should not notify ever (-n equivalent) */
                     34: 
                     35: extern int Nfiles;
                     36: 
                     37: int TransferSucceeded = 1;
                     38: int notiok = 1;
                     39: int nonzero = 0;
                     40: 
                     41: struct timeb Now;
                     42: 
                     43: char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin";
                     44: char UU_MACHINE[MAXFULLNAME];
                     45: char Shell[MAXFULLNAME];
                     46: char HOME[MAXFULLNAME];
                     47: 
                     48: extern char **environ;
                     49: char *nenv[] = {
                     50:        PATH,
                     51:        Shell,
                     52:        HOME,
                     53:        UU_MACHINE,
                     54:        0
                     55: };
                     56: 
                     57: /*  to remove restrictions from uuxqt
                     58:  *  define ALLOK 1
                     59:  *
                     60:  *  to add allowable commands, add to the file CMDFILE
                     61:  *  A line of form "PATH=..." changes the search path
                     62:  */
                     63: main(argc, argv)
                     64: char *argv[];
                     65: {
                     66:        char xcmd[BUFSIZ*2];
                     67:        int argnok;
                     68:        int notiflg;
                     69:        char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ*2];
                     70:        char lbuf[MAXFULLNAME];
                     71:        char cfile[NAMESIZE], dfile[MAXFULLNAME];
                     72:        char file[NAMESIZE];
                     73:        char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME];
                     74:        register FILE *xfp, *fp;
                     75:        FILE *dfp;
                     76:        char path[MAXFULLNAME];
                     77:        char cmd[BUFSIZ*2];
                     78:        char *cmdp, prm[1000], *ptr;
                     79:        char *getprm(), *lastpart();
                     80:        int uid, ret, badfiles;
                     81:        register int i;
                     82:        int stcico = 0;
                     83:        time_t xstart, xnow;
                     84:        char retstat[30];
                     85:        extern char *optarg;
                     86:        extern int optind;
                     87: 
                     88:        strcpy(Progname, "uuxqt");
                     89:        uucpname(Myname);
                     90:        strcpy(Rmtname, Myname);
                     91: 
                     92:        umask(WFMASK);
                     93:        Ofn = 1;
                     94:        Ifn = 0;
                     95:        while ((i = getopt(argc, argv, "x:S:")) != EOF) 
                     96:                switch(i) {
                     97:                case 'x':
                     98:                        chkdebug();
                     99:                        Debug = atoi(optarg);
                    100:                        if (Debug <= 0)
                    101:                                Debug = 1;
                    102:                        break;
                    103:                case 'S':
                    104:                        Spool = optarg;
                    105:                        DEBUG(1, "Spool set to %s", Spool);
                    106:                        break;
                    107:                case '?':
                    108:                default:
                    109:                        fprintf(stderr, "unknown flag %s\n", argv[optind-1]);
                    110:                                break;
                    111:                }
                    112: 
                    113:        DEBUG(4, "\n\n** START **\n", CNULL);
                    114:        if (subchdir(Spool) < 0) {
                    115:                syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool);
                    116:                cleanup(1);
                    117:        }
                    118:        strcpy(Wrkdir, Spool);
                    119:        uid = getuid();
                    120:        if (guinfo(uid, User, path) != SUCCESS) {
                    121:                syslog(LOG_WARNING, "Can't find username for uid %d", uid);
                    122:                DEBUG(1, "Using username", "uucp");
                    123:                strcpy(User, "uucp");
                    124:        }
                    125:        setgid(getegid());
                    126:        setuid(geteuid());
                    127: 
                    128:        DEBUG(4, "User - %s\n", User);
                    129:        if (ulockf(X_LOCK, X_LOCKTIME) != 0)
                    130:                exit(0);
                    131: 
                    132:        fp = fopen(CMDFILE, "r");
                    133:        if (fp == NULL) {
                    134:                logent(CANTOPEN, CMDFILE);
                    135:                Cmds[0] = "rmail";
                    136:                Cmds[1] = "rnews";
                    137:                Cmds[2] = "ruusend";
                    138:                Cmds[3] = NULL;
                    139:                goto doprocess;
                    140:        }
                    141:        DEBUG(5, "%s opened\n", CMDFILE);
                    142:        for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) {
                    143:                int j;
                    144:                /* strip trailing whitespace */
                    145:                for (j = strlen(xcmd)-1; j >= 0; --j)
                    146:                        if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t')
                    147:                                xcmd[j] = '\0';
                    148:                        else
                    149:                                break;
                    150:                /* look for imbedded whitespace */
                    151:                for (; j >= 0; --j)
                    152:                        if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t')
                    153:                                break;
                    154:                /* skip this entry if it has embedded whitespace */
                    155:                /* This defends against a bad PATH=, for example */
                    156:                if (j >= 0) {
                    157:                        logent(xcmd, "BAD WHITESPACE");
                    158:                        continue;
                    159:                }
                    160:                if (strncmp(xcmd, "PATH=", 5) == 0) {
                    161:                        strcpy(PATH, xcmd);
                    162:                        i--;    /*kludge */
                    163:                        continue;
                    164:                }
                    165:                DEBUG(5, "xcmd = %s\n", xcmd);
                    166: 
                    167:                if ((ptr = index(xcmd, ',')) != NULL) {
                    168:                        *ptr++ = '\0';
                    169:                        if (strncmp(ptr, "Err", 3) == SAME)
                    170:                                Notify[i] = NT_ERR;
                    171:                        else if (strcmp(ptr, "No") == SAME)
                    172:                                Notify[i] = NT_NO;
                    173:                        else
                    174:                                Notify[i] = NT_YES;
                    175:                } else
                    176:                        Notify[i] = NT_YES;
                    177:                if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) {
                    178:                        DEBUG(1, "MALLOC FAILED", CNULL);
                    179:                        break;
                    180:                }
                    181:                strcpy(Cmds[i], xcmd);
                    182:        }
                    183:        Cmds[i] = CNULL;
                    184:        fclose(fp);
                    185: 
                    186: doprocess:
                    187: 
                    188:        (void) sprintf(HOME, "HOME=%s", Spool);
                    189:        (void) sprintf(Shell, "SHELL=%s", SHELL);
                    190:        environ = nenv; /* force use if our environment */
                    191: 
                    192:        DEBUG(11,"path = %s\n", getenv("PATH"));
                    193: 
                    194:        DEBUG(4, "process %s\n", CNULL);
                    195: 
                    196:        time(&xstart);
                    197:        while (gtxfile(xfile) > 0) {
                    198:                /* if /etc/nologin exists, exit cleanly */
                    199: #if defined(BSD4_2) || defined(USG)
                    200:                if (access(NOLOGIN) == 0) {
                    201: #else !BSD4_2 && ! USG
                    202:                ultouch();
                    203:                if (nologinflag) {
                    204: #endif !BSD4_2 && !USG
                    205:                        logent(NOLOGIN, "UUXQT SHUTDOWN");
                    206:                        if (Debug)
                    207:                                logent("debugging", "continuing anyway");
                    208:                        else
                    209:                                break;
                    210:                }
                    211:                DEBUG(4, "xfile - %s\n", xfile);
                    212: 
                    213:                xfp = fopen(subfile(xfile), "r");
                    214:                if (xfp == NULL) {
                    215:                        syslog(LOG_ERR, "fopen(%s) failed: %m", subfile(xfile));
                    216:                        cleanup(1);
                    217:                }
                    218: 
                    219:                /*  initialize to default  */
                    220:                strcpy(user, User);
                    221:                strcpy(fin, DEVNULL);
                    222:                strcpy(fout, DEVNULL);
                    223:                strcpy(sysout, Myname);
                    224:                badfiles = 0;
                    225:                while (fgets(buf, BUFSIZ, xfp) != NULL) {
                    226:                        if(buf[0] != '\0' && buf[0] != '#' &&
                    227:                            buf[1] != ' ' && buf[1] != '\0' && buf[1] != '\n') {
                    228:                                char *bnp, cfilename[BUFSIZ];
                    229:                                DEBUG(4, "uuxqt: buf = %s\n", buf);
                    230:                                bnp = rindex(xfile, '/');
                    231:                                sprintf(cfilename, "%s/%s", CORRUPT,
                    232:                                        bnp ? bnp + 1 : xfile);
                    233:                                DEBUG(4, "uuxqt: move %s to ", xfile);
                    234:                                DEBUG(4, "%s\n", cfilename);
                    235:                                xmv(xfile, cfilename);
                    236:                                syslog(LOG_WARNING, "%s: X. FILE CORRUPTED",
                    237:                                        xfile);
                    238:                                fclose(xfp);
                    239:                                goto doprocess;
                    240:                        }
                    241:                        switch (buf[0]) {
                    242:                        case X_USER: {
                    243:                                char ORmtname[MAXFULLNAME];
                    244:                                strcpy(ORmtname, Rmtname);
                    245:                                sscanf(&buf[1], "%s %s", user, Rmtname);
                    246:                                sprintf(UU_MACHINE, "UU_MACHINE=%s", Rmtname);
                    247:                                if (strcmp(ORmtname, Rmtname) != 0)
                    248:                                        logcls();
                    249:                                break;}
                    250:                        case X_RETURNTO:
                    251:                                sscanf(&buf[1], "%s", user);
                    252:                                break;
                    253:                        case X_STDIN:
                    254:                                sscanf(&buf[1], "%s", fin);
                    255:                                i = expfile(fin);
                    256:                                /* rti!trt: do not check permissions of
                    257:                                 * vanilla spool file */
                    258:                                if (i != 0
                    259:                                 && (chkpth("", "", fin) || anyread(fin) != 0))
                    260:                                        badfiles = 1;
                    261:                                break;
                    262:                        case X_STDOUT:
                    263:                                sscanf(&buf[1], "%s%s", fout, sysout);
                    264:                                sysout[MAXBASENAME] = '\0';
                    265:                                /* rti!trt: do not check permissions of
                    266:                                 * vanilla spool file.  DO check permissions
                    267:                                 * of writing on a non-vanilla file */
                    268:                                i = 1;
                    269:                                if (fout[0] != '~' || prefix(sysout, Myname))
                    270:                                        i = expfile(fout);
                    271:                                if (i != 0
                    272:                                 && (chkpth("", "", fout)
                    273:                                        || chkperm(fout, (char *)1)))
                    274:                                        badfiles = 1;
                    275:                                break;
                    276:                        case X_CMD:
                    277:                                strcpy(cmd, &buf[2]);
                    278:                                if (*(cmd + strlen(cmd) - 1) == '\n')
                    279:                                        *(cmd + strlen(cmd) - 1) = '\0';
                    280:                                break;
                    281:                        case X_NONOTI:
                    282:                                notiok = 0;
                    283:                                break;
                    284:                        case X_NONZERO:
                    285:                                nonzero = 1;
                    286:                                break;
                    287:                        default:
                    288:                                break;
                    289:                        }
                    290:                }
                    291: 
                    292:                fclose(xfp);
                    293:                DEBUG(4, "fin - %s, ", fin);
                    294:                DEBUG(4, "fout - %s, ", fout);
                    295:                DEBUG(4, "sysout - %s, ", sysout);
                    296:                DEBUG(4, "user - %s\n", user);
                    297:                DEBUG(4, "cmd - %s\n", cmd);
                    298: 
                    299:                /*  command execution  */
                    300:                if (strcmp(fout, DEVNULL) == SAME)
                    301:                        strcpy(dfile,DEVNULL);
                    302:                else
                    303:                        gename(DATAPRE, sysout, 'O', dfile);
                    304: 
                    305:                /* expand file names where necessary */
                    306:                expfile(dfile);
                    307:                cmdp = buf;
                    308:                ptr = cmd;
                    309:                xcmd[0] = '\0';
                    310:                argnok = 0;
                    311:                while ((ptr = getprm(ptr, prm)) != NULL) {
                    312:                        if (prm[0] == ';' || prm[0] == '^'
                    313:                          || prm[0] == '&'  || prm[0] == '|') {
                    314:                                xcmd[0] = '\0';
                    315:                                APPCMD(prm);
                    316:                                continue;
                    317:                        }
                    318: 
                    319:                        if ((argnok = argok(xcmd, prm)) != SUCCESS)
                    320:                                /*  command not valid  */
                    321:                                break;
                    322: 
                    323:                        if (prm[0] == '~')
                    324:                                expfile(prm);
                    325:                        APPCMD(prm);
                    326:                }
                    327:                /*
                    328:                 * clean up trailing ' ' in command.
                    329:                 */
                    330:                if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ')
                    331:                        *--cmdp = '\0';
                    332:                if (argnok || badfiles) {
                    333:                        sprintf(lbuf, "%s XQT DENIED", user);
                    334:                        logent(cmd, lbuf);
                    335:                        DEBUG(4, "bad command %s\n", prm);
                    336:                        notify(user, Rmtname, cmd, "DENIED");
                    337:                        goto rmfiles;
                    338:                }
                    339:                sprintf(lbuf, "%s XQT", user);
                    340:                logent(buf, lbuf);
                    341:                DEBUG(4, "cmd %s\n", buf);
                    342: 
                    343:                mvxfiles(xfile);
                    344:                if (subchdir(XQTDIR) < 0) {
                    345:                        syslog(LOG_ERR, "chdir(%s) failed: %m", XQTDIR);
                    346:                        cleanup(1);
                    347:                }
                    348:                ret = shio(buf, fin, dfile);
                    349:                sprintf(retstat, "signal %d, exit %d", ret & 0377,
                    350:                  (ret>>8) & 0377);
                    351:                if (strcmp(xcmd, "rmail") == SAME)
                    352:                        notiok = 0;
                    353:                if (strcmp(xcmd, "rnews") == SAME)
                    354:                        nonzero = 1;
                    355:                notiflg = chknotify(xcmd);
                    356:                if (notiok && notiflg != NT_NO &&
                    357:                   (ret != 0 || (!nonzero && notiflg == NT_YES)))
                    358:                        notify(user, Rmtname, cmd, retstat);
                    359:                else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
                    360:                        /* mail failed - return letter to sender  */
                    361: #ifdef DANGEROUS
                    362:                        /* NOT GUARANTEED SAFE!!! */
                    363:                        if (!nonzero)
                    364:                                retosndr(user, Rmtname, fin);
                    365: #else
                    366:                        notify(user, Rmtname, cmd, retstat);
                    367: #endif
                    368:                        sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user);
                    369:                        logent("MAIL FAIL", buf);
                    370:                }
                    371:                DEBUG(4, "exit cmd - %d\n", ret);
                    372:                if (subchdir(Spool) < 0) {
                    373:                        syslog(LOG_ERR, "chdir(%s) failed: %m", Spool);
                    374:                        cleanup(1);
                    375:                }
                    376:                rmxfiles(xfile);
                    377:                if (ret != 0) {
                    378:                        /*  exit status not zero */
                    379:                        dfp = fopen(subfile(dfile), "a");
                    380:                        if (dfp == NULL) {
                    381:                                syslog(LOG_ERR, "fopen(%s) failed: %m",
                    382:                                        subfile(dfile));
                    383:                                cleanup(1);
                    384:                        }
                    385:                        fprintf(dfp, "exit status %d", ret);
                    386:                        fclose(dfp);
                    387:                }
                    388:                if (strcmp(fout, DEVNULL) != SAME) {
                    389:                        if (prefix(sysout, Myname)) {
                    390:                                xmv(dfile, fout);
                    391:                                chmod(fout, BASEMODE);
                    392:                        } else {
                    393:                                char *cp = rindex(user, '!');
                    394:                                gename(CMDPRE, sysout, 'O', cfile);
                    395:                                fp = fopen(subfile(cfile), "w");
                    396:                                if (fp == NULL) {
                    397:                                        syslog(LOG_ERR, "fopen(%s) failed: %m",
                    398:                                                subfile(cfile));
                    399:                                        cleanup(1);
                    400:                                }
                    401:                                fprintf(fp, "S %s %s %s - %s 0666\n", dfile,
                    402:                                        fout, cp ? cp : user, lastpart(dfile));
                    403:                                fclose(fp);
                    404:                        }
                    405:                }
                    406:        rmfiles:
                    407:                xfp = fopen(subfile(xfile), "r");
                    408:                if (xfp == NULL) {
                    409:                        syslog(LOG_ERR, "fopen(%s) failed: %m",
                    410:                                subfile(xfile));
                    411:                        cleanup(1);
                    412:                }
                    413:                while (fgets(buf, BUFSIZ, xfp) != NULL) {
                    414:                        if (buf[0] != X_RQDFILE)
                    415:                                continue;
                    416:                        sscanf(&buf[1], "%s", file);
                    417:                        unlink(subfile(file));
                    418:                }
                    419:                unlink(subfile(xfile));
                    420:                fclose(xfp);
                    421: 
                    422:                /* rescan X. for new work every RECHECKTIME seconds */
                    423:                time(&xnow);
                    424:                if (xnow > (xstart + RECHECKTIME)) {
                    425:                        extern int Nfiles;
                    426:                        Nfiles = 0;     /*force rescan for new work */
                    427:                }
                    428:                xstart = xnow;
                    429:        }
                    430: 
                    431:        if (stcico)
                    432:                xuucico("");
                    433:        cleanup(0);
                    434: }
                    435: 
                    436: 
                    437: cleanup(code)
                    438: int code;
                    439: {
                    440:        logcls();
                    441:        rmlock(CNULL);
                    442: #ifdef VMS
                    443:        /*
                    444:         *      Since we run as a BATCH job we must wait for all processes to
                    445:         *      to finish
                    446:         */
                    447:        while(wait(0) != -1)
                    448:                ;
                    449: #endif VMS
                    450:        exit(code);
                    451: }
                    452: 
                    453: 
                    454: /*
                    455:  *     get a file to execute
                    456:  *
                    457:  *     return codes:  0 - no file  |  1 - file to execute
                    458:  */
                    459: 
                    460: gtxfile(file)
                    461: register char *file;
                    462: {
                    463:        char pre[3];
                    464:        register int rechecked, i;
                    465:        time_t ystrdy;          /* yesterday */
                    466:        struct stat stbuf;      /* for X file age */
                    467: 
                    468:        pre[0] = XQTPRE;
                    469:        pre[1] = '.';
                    470:        pre[2] = '\0';
                    471:        rechecked = 0;
                    472: retry:
                    473:        if (Nfiles-- <= 0) {
                    474:                Nfiles = 0;
                    475:                if (rechecked)
                    476:                        return 0;
                    477:                rechecked = 1;
                    478:                DEBUG(4, "iswrk\n", CNULL);
                    479:                return iswrk(file, "get", Spool, pre);
                    480:        }
                    481:        sprintf(file, "%s/%s", Spool, Filent[0]);
                    482:        for (i=0; i<Nfiles;i++)
                    483:                strcpy(Filent[i], Filent[i+1]);
                    484: 
                    485:        DEBUG(4, "file - %s\n", file);
                    486:        /* skip spurious subdirectories */
                    487:        if (strcmp(pre, file) == SAME)
                    488:                goto retry;
                    489:        if (gotfiles(file))
                    490:                return 1;
                    491:        /* check for old X. file with no work files and remove them. */
                    492:        if (Nfiles > LLEN/2) {
                    493:            time(&ystrdy);
                    494:            ystrdy -= (4 * 3600L);              /* 4 hours ago */
                    495:            DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL);
                    496:            while (Nfiles-- > 0) {
                    497:                sprintf(file, "%s/%s", Spool, Filent[0]);
                    498:                for (i=0; i<Nfiles; i++)
                    499:                        strcpy(Filent[i], Filent[i+1]);
                    500: 
                    501:                if (gotfiles(file))
                    502:                        return 1;
                    503:                if (stat(subfile(file), &stbuf) == 0)
                    504:                    if (stbuf.st_mtime <= ystrdy) {
                    505:                        char *bnp, cfilename[NAMESIZE];
                    506:                        DEBUG(4, "gtxfile: move %s to CORRUPT \n", file);
                    507:                        bnp = rindex(file, '/');
                    508:                        sprintf(cfilename, "%s/%s", CORRUPT,
                    509:                                bnp ? bnp + 1 : file);
                    510:                        xmv(file, cfilename);
                    511:                        syslog(LOG_WARNING, "%s: X. FILE MISSING FILES", file);
                    512:                    }
                    513:            }
                    514:            Nfiles = 0;
                    515:            DEBUG(4, "iswrk\n", CNULL);
                    516:            if (!iswrk(file, "get", Spool, pre))
                    517:                return 0;
                    518:        }
                    519:        goto retry;
                    520: }
                    521: 
                    522: /*
                    523:  *     check for needed files
                    524:  *
                    525:  *     return codes:  0 - not ready  |  1 - all files ready
                    526:  */
                    527: 
                    528: gotfiles(file)
                    529: register char *file;
                    530: {
                    531:        struct stat stbuf;
                    532:        register FILE *fp;
                    533:        char buf[BUFSIZ], rqfile[MAXFULLNAME];
                    534: 
                    535:        fp = fopen(subfile(file), "r");
                    536:        if (fp == NULL)
                    537:                return 0;
                    538: 
                    539:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    540:                DEBUG(4, "%s\n", buf);
                    541:                if (buf[0] != X_RQDFILE)
                    542:                        continue;
                    543:                sscanf(&buf[1], "%s", rqfile);
                    544:                expfile(rqfile);
                    545:                if (stat(subfile(rqfile), &stbuf) == -1) {
                    546:                        fclose(fp);
                    547:                        return 0;
                    548:                }
                    549:        }
                    550: 
                    551:        fclose(fp);
                    552:        return 1;
                    553: }
                    554: 
                    555: 
                    556: /*
                    557:  *     remove execute files to x-directory
                    558:  */
                    559: 
                    560: rmxfiles(xfile)
                    561: register char *xfile;
                    562: {
                    563:        register FILE *fp;
                    564:        char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE];
                    565:        char tfull[MAXFULLNAME];
                    566: 
                    567:        if((fp = fopen(subfile(xfile), "r")) == NULL)
                    568:                return;
                    569: 
                    570:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    571:                if (buf[0] != X_RQDFILE)
                    572:                        continue;
                    573:                if (sscanf(&buf[1], "%s%s", file, tfile) < 2)
                    574:                        continue;
                    575:                sprintf(tfull, "%s/%s", XQTDIR, tfile);
                    576:                unlink(subfile(tfull));
                    577:        }
                    578:        fclose(fp);
                    579:        return;
                    580: }
                    581: 
                    582: 
                    583: /*
                    584:  *     move execute files to x-directory
                    585:  */
                    586: 
                    587: mvxfiles(xfile)
                    588: char *xfile;
                    589: {
                    590:        register FILE *fp;
                    591:        char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE];
                    592:        char tfull[MAXFULLNAME];
                    593: 
                    594:        if((fp = fopen(subfile(xfile), "r")) == NULL)
                    595:                return;
                    596: 
                    597:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    598:                if (buf[0] != X_RQDFILE)
                    599:                        continue;
                    600:                if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2)
                    601:                        continue;
                    602:                expfile(ffile);
                    603:                sprintf(tfull, "%s/%s", XQTDIR, tfile);
                    604:                unlink(subfile(tfull));
                    605:                if (xmv(ffile, tfull) != 0) {
                    606:                        syslog(LOG_WARNING, "xmv(%s,%s) failed: %m",
                    607:                                ffile, tfull);
                    608:                        cleanup(1);
                    609:                }
                    610:        }
                    611:        fclose(fp);
                    612: }
                    613: 
                    614: /*
                    615:  *     check for valid command/argument        
                    616:  *     *NOTE - side effect is to set xc to the command to be executed.
                    617:  *
                    618:  *     return 0 - ok | 1 nok
                    619:  */
                    620: 
                    621: argok(xc, cmd)
                    622: register char *xc, *cmd;
                    623: {
                    624:        register char **ptr;
                    625: 
                    626: #ifndef ALLOK
                    627:        if (strpbrk(cmd, BADCHARS) != NULL) {
                    628:                DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL);
                    629:                logent(cmd, "NASTY MAGIC CHARACTER FOUND");
                    630:                return FAIL;
                    631:        }
                    632: #endif !ALLOK
                    633: 
                    634:        if (xc[0] != '\0')
                    635:                return SUCCESS;
                    636: 
                    637: #ifndef ALLOK
                    638:        ptr = Cmds;
                    639:        DEBUG(9, "Compare %s and\n", cmd);
                    640:        while(*ptr != NULL) {
                    641:                DEBUG(9, "\t%s\n", *ptr);
                    642:                if (strcmp(cmd, *ptr) == SAME)
                    643:                        break;
                    644:                ptr++;
                    645:        }
                    646:        if (*ptr == NULL) {
                    647:                DEBUG(1,"COMMAND NOT FOUND\n", CNULL);
                    648:                return FAIL;
                    649:        }
                    650: #endif
                    651:        strcpy(xc, cmd);
                    652:        DEBUG(9, "MATCHED %s\n", xc);
                    653:        return SUCCESS;
                    654: }
                    655: 
                    656: 
                    657: /*
                    658:  *     if notification should be sent for successful execution of cmd
                    659:  *
                    660:  *     return NT_YES - do notification
                    661:  *            NT_ERR - do notification if exit status != 0
                    662:  *            NT_NO  - don't do notification ever
                    663:  */
                    664: 
                    665: chknotify(cmd)
                    666: char *cmd;
                    667: {
                    668:        register char **ptr;
                    669:        register int *nptr;
                    670: 
                    671:        ptr = Cmds;
                    672:        nptr = Notify;
                    673:        while (*ptr != NULL) {
                    674:                if (strcmp(cmd, *ptr) == SAME)
                    675:                        return *nptr;
                    676:                ptr++;
                    677:                nptr++;
                    678:        }
                    679:        return NT_YES;          /* "shouldn't happen" */
                    680: }
                    681: 
                    682: 
                    683: 
                    684: /*
                    685:  *     send mail to user giving execution results
                    686:  */
                    687: 
                    688: notify(user, rmt, cmd, str)
                    689: char *user, *rmt, *cmd, *str;
                    690: {
                    691:        char text[BUFSIZ*2];
                    692:        char ruser[MAXFULLNAME];
                    693: 
                    694:        if (strpbrk(user, BADCHARS) != NULL) {
                    695:                char lbuf[MAXFULLNAME];
                    696:                sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user);
                    697:                logent(cmd, lbuf);
                    698:                strcpy(user, "postmaster");
                    699:        }
                    700:        sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str);
                    701:        if (prefix(rmt, Myname))
                    702:                strcpy(ruser, user);
                    703:        else
                    704:                sprintf(ruser, "%s!%s", rmt, user);
                    705:        mailst(ruser, text, CNULL);
                    706: }
                    707: 
                    708: /*
                    709:  *     return mail to sender
                    710:  *
                    711:  */
                    712: retosndr(user, rmt, file)
                    713: char *user, *rmt, *file;
                    714: {
                    715:        char ruser[MAXFULLNAME];
                    716: 
                    717:        if (strpbrk(user, BADCHARS) != NULL) {
                    718:                char lbuf[MAXFULLNAME];
                    719:                sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user);
                    720:                logent(file, lbuf);
                    721:                strcpy(user, "postmaster");
                    722:        }
                    723:        if (strcmp(rmt, Myname) == SAME)
                    724:                strcpy(ruser, user);
                    725:        else
                    726:                sprintf(ruser, "%s!%s", rmt, user);
                    727: 
                    728:        if (anyread(file) == 0)
                    729:                mailst(ruser, "Mail failed.  Letter returned to sender.\n", file);
                    730:        else
                    731:                mailst(ruser, "Mail failed.  Letter returned to sender.\n", CNULL);
                    732:        return;
                    733: }
                    734: 
                    735: /*
                    736:  *     execute shell of command with fi and fo as standard input/output
                    737:  */
                    738: 
                    739: shio(cmd, fi, fo)
                    740: char *cmd, *fi, *fo;
                    741: {
                    742:        int status, f;
                    743:        int pid, ret;
                    744:        char *args[256];
                    745:        extern int errno;
                    746: 
                    747:        if (fi == NULL)
                    748:                fi = DEVNULL;
                    749:        if (fo == NULL)
                    750:                fo = DEVNULL;
                    751: 
                    752:        getargs(cmd, args, 256);
                    753:        DEBUG(3, "shio - %s\n", cmd);
                    754: #ifdef SIGCHLD
                    755:        signal(SIGCHLD, SIG_IGN);
                    756: #endif SIGCHLD
                    757:        if ((pid = fork()) == 0) {
                    758:                signal(SIGINT, SIG_IGN);
                    759:                signal(SIGHUP, SIG_IGN);
                    760:                signal(SIGQUIT, SIG_IGN);
                    761:                close(Ifn);
                    762:                close(Ofn);
                    763:                close(0);
                    764:                setuid(getuid());
                    765:                f = open(subfile(fi), 0);
                    766:                if (f != 0) {
                    767:                        logent(fi, "CAN'T READ");
                    768:                        exit(-errno);
                    769:                }
                    770:                close(1);
                    771:                f = creat(subfile(fo), 0666);
                    772:                if (f != 1) {
                    773:                        logent(fo, "CAN'T WRITE");
                    774:                        exit(-errno);
                    775:                }
                    776:                execvp(args[0], args);
                    777:                exit(100+errno);
                    778:        }
                    779:        while ((ret = wait(&status)) != pid && ret != -1)
                    780:                ;
                    781:        DEBUG(3, "status %d\n", status);
                    782:        return status;
                    783: }

unix.superglobalmegacorp.com

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