# 2.11BSD#431 - /usr/src/usr.bin/uucp/uuxqt.c

##### Functions

    argok             X
    chknotify         X
    cleanup           X
    gotfiles          X
    gtxfile           X
    main              X
    mvxfiles          X
    notify            X
    retosndr          X
    rmxfiles          X
    shio              X

##### Variables

    Cmds              X
    HOME              X
    Notify            X
    Now               X
    PATH              X
    Shell             X
    TransferSucceeded X
    nenv              X
    nonzero           X
    notiok            X

##### Macros

    APPCMD            X
    BADCHARS          X
    NCMDS             X
    NT_ERR            X
    NT_NO             X
    NT_YES            X
    RECHECKTIME       X

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

#### Defined functions

argok defined in line 554; used 1 times

- in line 280

chknotify defined in line 598; used 1 times

- in line 314

cleanup defined in line 382; used 1 times

- in line 378

gotfiles defined in line 463; used 2 times

- in line 430, 437

gtxfile defined in line 405; used 1 times

- in line 181

main defined in line 59; never used
mvxfiles defined in line 522; used 1 times

- in line 304

notify defined in line 621; used 3 times

- in line 297, 317, 325

retosndr defined in line 645; used 1 times

- in line 323

rmxfiles defined in line 495; used 1 times

- in line 333

shio defined in line 672; used 1 times

- in line 307

#### Defined variables

Cmds defined in line 27; used 9 times

- in line 120-123(4), 162-168(3), 571, 604

HOME defined in line 43; used 2 times

- in line 49, 173

Notify defined in line 28; used 5 times

- in line 155-161(4), 605

Now defined in line 39; never used
PATH defined in line 41; used 2 times

- in line 47, 146

Shell defined in line 42; used 2 times

- in line 48, 174

TransferSucceeded defined in line 35; never used
nenv defined in line 46; used 1 times

- in line 175

nonzero defined in line 37; used 4 times

- in line 246, 313-316(2), 322

notiok defined in line 36; used 3 times

- in line 243, 311-315(2)

sccsid defined in line 2; never used

#### Defined macros

APPCMD defined in line 17; used 2 times

- in line 276, 286

BADCHARS defined in line 14; used 3 times

- in line 560, 627, 650

NCMDS defined in line 26; used 3 times

- in line 27-28(2), 127

NT_ERR defined in line 30; used 1 times

- in line 155

NT_NO defined in line 31; used 2 times

- in line 157, 315

NT_YES defined in line 29; used 4 times

- in line 159-161(2), 316, 612

RECHECKTIME defined in line 15; used 1 times

- in line 369

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1846 |