1: #ifndef lint
   2: static char sccsid[] = "@(#)uuxqt.c	5.8 (Berkeley) 1/24/86";
   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] = 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
chknotify defined in line 598; used 1 times
cleanup defined in line 382; used 1 times
gotfiles defined in line 463; used 2 times
gtxfile defined in line 405; used 1 times
main defined in line 59; never used
mvxfiles defined in line 522; used 1 times
notify defined in line 621; used 3 times
retosndr defined in line 645; used 1 times
rmxfiles defined in line 495; used 1 times
shio defined in line 672; used 1 times

Defined variables

Cmds defined in line 27; used 9 times
HOME defined in line 43; used 2 times
Notify defined in line 28; used 5 times
Now defined in line 39; never used
PATH defined in line 41; used 2 times
Shell defined in line 42; used 2 times
TransferSucceeded defined in line 35; never used
nenv defined in line 46; used 1 times
nonzero defined in line 37; used 4 times
notiok defined in line 36; used 3 times
sccsid defined in line 2; never used

Defined macros

APPCMD defined in line 17; used 2 times
BADCHARS defined in line 14; used 3 times
NCMDS defined in line 26; used 3 times
NT_ERR defined in line 30; used 1 times
NT_NO defined in line 31; used 2 times
NT_YES defined in line 29; used 4 times
RECHECKTIME defined in line 15; used 1 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2809
Valid CSS Valid XHTML 1.0 Strict