1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 # include "sendmail.h" 10 11 #ifndef lint 12 #ifdef QUEUE 13 static char sccsid[] = "@(#)queue.c 8.15 (Berkeley) 08/23/93 (with queueing)"; 14 #else 15 static char sccsid[] = "@(#)queue.c 8.15 (Berkeley) 08/23/93 (without queueing)"; 16 #endif 17 #endif /* not lint */ 18 19 # include <errno.h> 20 # include <pwd.h> 21 # include <dirent.h> 22 23 # ifdef QUEUE 24 25 /* 26 ** Work queue. 27 */ 28 29 struct work 30 { 31 char *w_name; /* name of control file */ 32 long w_pri; /* priority of message, see below */ 33 time_t w_ctime; /* creation time of message */ 34 struct work *w_next; /* next in queue */ 35 }; 36 37 typedef struct work WORK; 38 39 WORK *WorkQ; /* queue of things to be done */ 40 /* 41 ** QUEUEUP -- queue a message up for future transmission. 42 ** 43 ** Parameters: 44 ** e -- the envelope to queue up. 45 ** queueall -- if TRUE, queue all addresses, rather than 46 ** just those with the QQUEUEUP flag set. 47 ** announce -- if TRUE, tell when you are queueing up. 48 ** 49 ** Returns: 50 ** none. 51 ** 52 ** Side Effects: 53 ** The current request are saved in a control file. 54 ** The queue file is left locked. 55 */ 56 57 queueup(e, queueall, announce) 58 register ENVELOPE *e; 59 bool queueall; 60 bool announce; 61 { 62 char *qf; 63 register FILE *tfp; 64 register HDR *h; 65 register ADDRESS *q; 66 int fd; 67 int i; 68 bool newid; 69 register char *p; 70 MAILER nullmailer; 71 char buf[MAXLINE], tf[MAXLINE]; 72 73 /* 74 ** Create control file. 75 */ 76 77 newid = (e->e_id == NULL); 78 79 /* if newid, queuename will create a locked qf file in e->lockfp */ 80 strcpy(tf, queuename(e, 't')); 81 tfp = e->e_lockfp; 82 if (tfp == NULL) 83 newid = FALSE; 84 85 /* if newid, just write the qf file directly (instead of tf file) */ 86 if (newid) 87 { 88 tfp = e->e_lockfp; 89 } 90 else 91 { 92 /* get a locked tf file */ 93 for (i = 0; i < 128; i++) 94 { 95 fd = open(tf, O_CREAT|O_WRONLY|O_EXCL, FileMode); 96 if (fd < 0) 97 { 98 if (errno != EEXIST) 99 break; 100 #ifdef LOG 101 if (LogLevel > 0 && (i % 32) == 0) 102 syslog(LOG_ALERT, "queueup: cannot create %s: %s", 103 tf, errstring(errno)); 104 #endif 105 continue; 106 } 107 108 if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB)) 109 break; 110 #ifdef LOG 111 else if (LogLevel > 0 && (i % 32) == 0) 112 syslog(LOG_ALERT, "queueup: cannot lock %s: %s", 113 tf, errstring(errno)); 114 #endif 115 116 close(fd); 117 118 if ((i % 32) == 31) 119 { 120 /* save the old temp file away */ 121 (void) rename(tf, queuename(e, 'T')); 122 } 123 else 124 sleep(i % 32); 125 } 126 if (fd < 0) 127 syserr("!queueup: cannot create temp file %s", tf); 128 129 tfp = fdopen(fd, "w"); 130 } 131 132 if (tTd(40, 1)) 133 printf("\n>>>>> queueing %s >>>>>\n", e->e_id); 134 135 /* 136 ** If there is no data file yet, create one. 137 */ 138 139 if (e->e_df == NULL) 140 { 141 register FILE *dfp; 142 extern putbody(); 143 144 e->e_df = queuename(e, 'd'); 145 e->e_df = newstr(e->e_df); 146 fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode); 147 if (fd < 0) 148 syserr("!queueup: cannot create %s", e->e_df); 149 dfp = fdopen(fd, "w"); 150 (*e->e_putbody)(dfp, FileMailer, e, NULL); 151 (void) xfclose(dfp, "queueup dfp", e->e_id); 152 e->e_putbody = putbody; 153 } 154 155 /* 156 ** Output future work requests. 157 ** Priority and creation time should be first, since 158 ** they are required by orderq. 159 */ 160 161 /* output message priority */ 162 fprintf(tfp, "P%ld\n", e->e_msgpriority); 163 164 /* output creation time */ 165 fprintf(tfp, "T%ld\n", e->e_ctime); 166 167 /* output type and name of data file */ 168 if (e->e_bodytype != NULL) 169 fprintf(tfp, "B%s\n", e->e_bodytype); 170 fprintf(tfp, "D%s\n", e->e_df); 171 172 /* message from envelope, if it exists */ 173 if (e->e_message != NULL) 174 fprintf(tfp, "M%s\n", e->e_message); 175 176 /* send various flag bits through */ 177 p = buf; 178 if (bitset(EF_WARNING, e->e_flags)) 179 *p++ = 'w'; 180 if (bitset(EF_RESPONSE, e->e_flags)) 181 *p++ = 'r'; 182 *p++ = '\0'; 183 if (buf[0] != '\0') 184 fprintf(tfp, "F%s\n", buf); 185 186 /* $r and $s and $_ macro values */ 187 if ((p = macvalue('r', e)) != NULL) 188 fprintf(tfp, "$r%s\n", p); 189 if ((p = macvalue('s', e)) != NULL) 190 fprintf(tfp, "$s%s\n", p); 191 if ((p = macvalue('_', e)) != NULL) 192 fprintf(tfp, "$_%s\n", p); 193 194 /* output name of sender */ 195 fprintf(tfp, "S%s\n", e->e_from.q_paddr); 196 197 /* output list of error recipients */ 198 printctladdr(NULL, NULL); 199 for (q = e->e_errorqueue; q != NULL; q = q->q_next) 200 { 201 if (!bitset(QDONTSEND|QBADADDR, q->q_flags)) 202 { 203 printctladdr(q, tfp); 204 fprintf(tfp, "E%s\n", q->q_paddr); 205 } 206 } 207 208 /* output list of recipient addresses */ 209 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 210 { 211 if (bitset(QQUEUEUP, q->q_flags) || 212 (queueall && !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))) 213 { 214 printctladdr(q, tfp); 215 fprintf(tfp, "R%s\n", q->q_paddr); 216 if (announce) 217 { 218 e->e_to = q->q_paddr; 219 message("queued"); 220 if (LogLevel > 8) 221 logdelivery(NULL, NULL, "queued", e); 222 e->e_to = NULL; 223 } 224 if (tTd(40, 1)) 225 { 226 printf("queueing "); 227 printaddr(q, FALSE); 228 } 229 } 230 } 231 232 /* 233 ** Output headers for this message. 234 ** Expand macros completely here. Queue run will deal with 235 ** everything as absolute headers. 236 ** All headers that must be relative to the recipient 237 ** can be cracked later. 238 ** We set up a "null mailer" -- i.e., a mailer that will have 239 ** no effect on the addresses as they are output. 240 */ 241 242 bzero((char *) &nullmailer, sizeof nullmailer); 243 nullmailer.m_re_rwset = nullmailer.m_rh_rwset = 244 nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1; 245 nullmailer.m_eol = "\n"; 246 247 define('g', "\201f", e); 248 for (h = e->e_header; h != NULL; h = h->h_link) 249 { 250 extern bool bitzerop(); 251 252 /* don't output null headers */ 253 if (h->h_value == NULL || h->h_value[0] == '\0') 254 continue; 255 256 /* don't output resent headers on non-resent messages */ 257 if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) 258 continue; 259 260 /* output this header */ 261 fprintf(tfp, "H"); 262 263 /* if conditional, output the set of conditions */ 264 if (!bitzerop(h->h_mflags) && bitset(H_CHECK|H_ACHECK, h->h_flags)) 265 { 266 int j; 267 268 (void) putc('?', tfp); 269 for (j = '\0'; j <= '\177'; j++) 270 if (bitnset(j, h->h_mflags)) 271 (void) putc(j, tfp); 272 (void) putc('?', tfp); 273 } 274 275 /* output the header: expand macros, convert addresses */ 276 if (bitset(H_DEFAULT, h->h_flags)) 277 { 278 (void) expand(h->h_value, buf, &buf[sizeof buf], e); 279 fprintf(tfp, "%s: %s\n", h->h_field, buf); 280 } 281 else if (bitset(H_FROM|H_RCPT, h->h_flags)) 282 { 283 bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags); 284 FILE *savetrace = TrafficLogFile; 285 286 TrafficLogFile = NULL; 287 288 if (bitset(H_FROM, h->h_flags)) 289 oldstyle = FALSE; 290 291 commaize(h, h->h_value, tfp, oldstyle, 292 &nullmailer, e); 293 294 TrafficLogFile = savetrace; 295 } 296 else 297 fprintf(tfp, "%s: %s\n", h->h_field, h->h_value); 298 } 299 300 /* 301 ** Clean up. 302 */ 303 304 fflush(tfp); 305 fsync(fileno(tfp)); 306 if (ferror(tfp)) 307 { 308 if (newid) 309 syserr("!552 Error writing control file %s", tf); 310 else 311 syserr("!452 Error writing control file %s", tf); 312 } 313 314 if (!newid) 315 { 316 /* rename (locked) tf to be (locked) qf */ 317 qf = queuename(e, 'q'); 318 if (rename(tf, qf) < 0) 319 syserr("cannot rename(%s, %s), df=%s", tf, qf, e->e_df); 320 321 /* close and unlock old (locked) qf */ 322 if (e->e_lockfp != NULL) 323 (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id); 324 e->e_lockfp = tfp; 325 } 326 else 327 qf = tf; 328 errno = 0; 329 330 # ifdef LOG 331 /* save log info */ 332 if (LogLevel > 79) 333 syslog(LOG_DEBUG, "%s: queueup, qf=%s, df=%s\n", e->e_id, qf, e->e_df); 334 # endif /* LOG */ 335 336 if (tTd(40, 1)) 337 printf("<<<<< done queueing %s <<<<<\n\n", e->e_id); 338 return; 339 } 340 341 printctladdr(a, tfp) 342 register ADDRESS *a; 343 FILE *tfp; 344 { 345 char *uname; 346 register struct passwd *pw; 347 register ADDRESS *q; 348 uid_t uid; 349 static ADDRESS *lastctladdr; 350 static uid_t lastuid; 351 352 /* initialization */ 353 if (a == NULL || a->q_alias == NULL || tfp == NULL) 354 { 355 if (lastctladdr != NULL && tfp != NULL) 356 fprintf(tfp, "C\n"); 357 lastctladdr = NULL; 358 lastuid = 0; 359 return; 360 } 361 362 /* find the active uid */ 363 q = getctladdr(a); 364 if (q == NULL) 365 uid = 0; 366 else 367 uid = q->q_uid; 368 a = a->q_alias; 369 370 /* check to see if this is the same as last time */ 371 if (lastctladdr != NULL && uid == lastuid && 372 strcmp(lastctladdr->q_paddr, a->q_paddr) == 0) 373 return; 374 lastuid = uid; 375 lastctladdr = a; 376 377 if (uid == 0 || (pw = getpwuid(uid)) == NULL) 378 uname = ""; 379 else 380 uname = pw->pw_name; 381 382 fprintf(tfp, "C%s:%s\n", uname, a->q_paddr); 383 } 384 385 /* 386 ** RUNQUEUE -- run the jobs in the queue. 387 ** 388 ** Gets the stuff out of the queue in some presumably logical 389 ** order and processes them. 390 ** 391 ** Parameters: 392 ** forkflag -- TRUE if the queue scanning should be done in 393 ** a child process. We double-fork so it is not our 394 ** child and we don't have to clean up after it. 395 ** 396 ** Returns: 397 ** none. 398 ** 399 ** Side Effects: 400 ** runs things in the mail queue. 401 */ 402 403 ENVELOPE QueueEnvelope; /* the queue run envelope */ 404 405 runqueue(forkflag) 406 bool forkflag; 407 { 408 register ENVELOPE *e; 409 extern ENVELOPE BlankEnvelope; 410 411 /* 412 ** If no work will ever be selected, don't even bother reading 413 ** the queue. 414 */ 415 416 CurrentLA = getla(); /* get load average */ 417 418 if (shouldqueue(0L, curtime())) 419 { 420 if (Verbose) 421 printf("Skipping queue run -- load average too high\n"); 422 if (forkflag && QueueIntvl != 0) 423 (void) setevent(QueueIntvl, runqueue, TRUE); 424 return; 425 } 426 427 /* 428 ** See if we want to go off and do other useful work. 429 */ 430 431 if (forkflag) 432 { 433 int pid; 434 435 pid = dofork(); 436 if (pid != 0) 437 { 438 extern void reapchild(); 439 440 /* parent -- pick up intermediate zombie */ 441 #ifndef SIGCHLD 442 (void) waitfor(pid); 443 #else /* SIGCHLD */ 444 (void) setsignal(SIGCHLD, reapchild); 445 #endif /* SIGCHLD */ 446 if (QueueIntvl != 0) 447 (void) setevent(QueueIntvl, runqueue, TRUE); 448 return; 449 } 450 /* child -- double fork */ 451 #ifndef SIGCHLD 452 if (fork() != 0) 453 exit(EX_OK); 454 #else /* SIGCHLD */ 455 (void) setsignal(SIGCHLD, SIG_DFL); 456 #endif /* SIGCHLD */ 457 } 458 459 setproctitle("running queue: %s", QueueDir); 460 461 # ifdef LOG 462 if (LogLevel > 69) 463 syslog(LOG_DEBUG, "runqueue %s, pid=%d, forkflag=%d", 464 QueueDir, getpid(), forkflag); 465 # endif /* LOG */ 466 467 /* 468 ** Release any resources used by the daemon code. 469 */ 470 471 # ifdef DAEMON 472 clrdaemon(); 473 # endif /* DAEMON */ 474 475 /* 476 ** Create ourselves an envelope 477 */ 478 479 CurEnv = &QueueEnvelope; 480 e = newenvelope(&QueueEnvelope, CurEnv); 481 e->e_flags = BlankEnvelope.e_flags; 482 483 /* 484 ** Make sure the alias database is open. 485 */ 486 487 initmaps(FALSE, e); 488 489 /* 490 ** Start making passes through the queue. 491 ** First, read and sort the entire queue. 492 ** Then, process the work in that order. 493 ** But if you take too long, start over. 494 */ 495 496 /* order the existing work requests */ 497 (void) orderq(FALSE); 498 499 /* process them once at a time */ 500 while (WorkQ != NULL) 501 { 502 WORK *w = WorkQ; 503 504 WorkQ = WorkQ->w_next; 505 506 /* 507 ** Ignore jobs that are too expensive for the moment. 508 */ 509 510 if (shouldqueue(w->w_pri, w->w_ctime)) 511 { 512 if (Verbose) 513 printf("\nSkipping %s\n", w->w_name + 2); 514 } 515 else 516 { 517 pid_t pid; 518 extern pid_t dowork(); 519 520 pid = dowork(w->w_name + 2, ForkQueueRuns, FALSE, e); 521 errno = 0; 522 (void) waitfor(pid); 523 } 524 free(w->w_name); 525 free((char *) w); 526 } 527 528 /* exit without the usual cleanup */ 529 e->e_id = NULL; 530 finis(); 531 } 532 /* 533 ** ORDERQ -- order the work queue. 534 ** 535 ** Parameters: 536 ** doall -- if set, include everything in the queue (even 537 ** the jobs that cannot be run because the load 538 ** average is too high). Otherwise, exclude those 539 ** jobs. 540 ** 541 ** Returns: 542 ** The number of request in the queue (not necessarily 543 ** the number of requests in WorkQ however). 544 ** 545 ** Side Effects: 546 ** Sets WorkQ to the queue of available work, in order. 547 */ 548 549 # define NEED_P 001 550 # define NEED_T 002 551 # define NEED_R 004 552 # define NEED_S 010 553 554 orderq(doall) 555 bool doall; 556 { 557 register struct dirent *d; 558 register WORK *w; 559 DIR *f; 560 register int i; 561 WORK wlist[QUEUESIZE+1]; 562 int wn = -1; 563 extern workcmpf(); 564 565 if (tTd(41, 1)) 566 { 567 printf("orderq:\n"); 568 if (QueueLimitId != NULL) 569 printf("\tQueueLimitId = %s\n", QueueLimitId); 570 if (QueueLimitSender != NULL) 571 printf("\tQueueLimitSender = %s\n", QueueLimitSender); 572 if (QueueLimitRecipient != NULL) 573 printf("\tQueueLimitRecipient = %s\n", QueueLimitRecipient); 574 } 575 576 /* clear out old WorkQ */ 577 for (w = WorkQ; w != NULL; ) 578 { 579 register WORK *nw = w->w_next; 580 581 WorkQ = nw; 582 free(w->w_name); 583 free((char *) w); 584 w = nw; 585 } 586 587 /* open the queue directory */ 588 f = opendir("."); 589 if (f == NULL) 590 { 591 syserr("orderq: cannot open \"%s\" as \".\"", QueueDir); 592 return (0); 593 } 594 595 /* 596 ** Read the work directory. 597 */ 598 599 while ((d = readdir(f)) != NULL) 600 { 601 FILE *cf; 602 char lbuf[MAXNAME]; 603 extern bool strcontainedin(); 604 605 /* is this an interesting entry? */ 606 if (d->d_name[0] != 'q' || d->d_name[1] != 'f') 607 continue; 608 609 if (QueueLimitId != NULL && 610 !strcontainedin(QueueLimitId, d->d_name)) 611 continue; 612 613 /* 614 ** Check queue name for plausibility. This handles 615 ** both old and new type ids. 616 */ 617 618 i = strlen(d->d_name); 619 if (i != 9 && i != 10) 620 { 621 if (Verbose) 622 printf("orderq: bogus qf name %s\n", d->d_name); 623 #ifdef LOG 624 if (LogLevel > 3) 625 syslog(LOG_CRIT, "orderq: bogus qf name %s", 626 d->d_name); 627 #endif 628 if (strlen(d->d_name) >= MAXNAME) 629 d->d_name[MAXNAME - 1] = '\0'; 630 strcpy(lbuf, d->d_name); 631 lbuf[0] = 'Q'; 632 (void) rename(d->d_name, lbuf); 633 continue; 634 } 635 636 /* yes -- open control file (if not too many files) */ 637 if (++wn >= QUEUESIZE) 638 continue; 639 640 cf = fopen(d->d_name, "r"); 641 if (cf == NULL) 642 { 643 /* this may be some random person sending hir msgs */ 644 /* syserr("orderq: cannot open %s", cbuf); */ 645 if (tTd(41, 2)) 646 printf("orderq: cannot open %s (%d)\n", 647 d->d_name, errno); 648 errno = 0; 649 wn--; 650 continue; 651 } 652 w = &wlist[wn]; 653 w->w_name = newstr(d->d_name); 654 655 /* make sure jobs in creation don't clog queue */ 656 w->w_pri = 0x7fffffff; 657 w->w_ctime = 0; 658 659 /* extract useful information */ 660 i = NEED_P | NEED_T; 661 if (QueueLimitSender != NULL) 662 i |= NEED_S; 663 if (QueueLimitRecipient != NULL) 664 i |= NEED_R; 665 while (i != 0 && fgets(lbuf, sizeof lbuf, cf) != NULL) 666 { 667 extern long atol(); 668 extern bool strcontainedin(); 669 670 switch (lbuf[0]) 671 { 672 case 'P': 673 w->w_pri = atol(&lbuf[1]); 674 i &= ~NEED_P; 675 break; 676 677 case 'T': 678 w->w_ctime = atol(&lbuf[1]); 679 i &= ~NEED_T; 680 break; 681 682 case 'R': 683 if (QueueLimitRecipient != NULL && 684 strcontainedin(QueueLimitRecipient, &lbuf[1])) 685 i &= ~NEED_R; 686 break; 687 688 case 'S': 689 if (QueueLimitSender != NULL && 690 strcontainedin(QueueLimitSender, &lbuf[1])) 691 i &= ~NEED_S; 692 break; 693 } 694 } 695 (void) fclose(cf); 696 697 if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) || 698 bitset(NEED_R|NEED_S, i)) 699 { 700 /* don't even bother sorting this job in */ 701 wn--; 702 } 703 } 704 (void) closedir(f); 705 wn++; 706 707 /* 708 ** Sort the work directory. 709 */ 710 711 qsort((char *) wlist, min(wn, QUEUESIZE), sizeof *wlist, workcmpf); 712 713 /* 714 ** Convert the work list into canonical form. 715 ** Should be turning it into a list of envelopes here perhaps. 716 */ 717 718 WorkQ = NULL; 719 for (i = min(wn, QUEUESIZE); --i >= 0; ) 720 { 721 w = (WORK *) xalloc(sizeof *w); 722 w->w_name = wlist[i].w_name; 723 w->w_pri = wlist[i].w_pri; 724 w->w_ctime = wlist[i].w_ctime; 725 w->w_next = WorkQ; 726 WorkQ = w; 727 } 728 729 if (tTd(40, 1)) 730 { 731 for (w = WorkQ; w != NULL; w = w->w_next) 732 printf("%32s: pri=%ld\n", w->w_name, w->w_pri); 733 } 734 735 return (wn); 736 } 737 /* 738 ** WORKCMPF -- compare function for ordering work. 739 ** 740 ** Parameters: 741 ** a -- the first argument. 742 ** b -- the second argument. 743 ** 744 ** Returns: 745 ** -1 if a < b 746 ** 0 if a == b 747 ** +1 if a > b 748 ** 749 ** Side Effects: 750 ** none. 751 */ 752 753 workcmpf(a, b) 754 register WORK *a; 755 register WORK *b; 756 { 757 long pa = a->w_pri; 758 long pb = b->w_pri; 759 760 if (pa == pb) 761 return (0); 762 else if (pa > pb) 763 return (1); 764 else 765 return (-1); 766 } 767 /* 768 ** DOWORK -- do a work request. 769 ** 770 ** Parameters: 771 ** id -- the ID of the job to run. 772 ** forkflag -- if set, run this in background. 773 ** requeueflag -- if set, reinstantiate the queue quickly. 774 ** This is used when expanding aliases in the queue. 775 ** If forkflag is also set, it doesn't wait for the 776 ** child. 777 ** e - the envelope in which to run it. 778 ** 779 ** Returns: 780 ** process id of process that is running the queue job. 781 ** 782 ** Side Effects: 783 ** The work request is satisfied if possible. 784 */ 785 786 pid_t 787 dowork(id, forkflag, requeueflag, e) 788 char *id; 789 bool forkflag; 790 bool requeueflag; 791 register ENVELOPE *e; 792 { 793 register pid_t pid; 794 extern bool readqf(); 795 796 if (tTd(40, 1)) 797 printf("dowork(%s)\n", id); 798 799 /* 800 ** Fork for work. 801 */ 802 803 if (forkflag) 804 { 805 pid = fork(); 806 if (pid < 0) 807 { 808 syserr("dowork: cannot fork"); 809 return 0; 810 } 811 } 812 else 813 { 814 pid = 0; 815 } 816 817 if (pid == 0) 818 { 819 /* 820 ** CHILD 821 ** Lock the control file to avoid duplicate deliveries. 822 ** Then run the file as though we had just read it. 823 ** We save an idea of the temporary name so we 824 ** can recover on interrupt. 825 */ 826 827 /* set basic modes, etc. */ 828 (void) alarm(0); 829 clearenvelope(e, FALSE); 830 e->e_flags |= EF_QUEUERUN; 831 e->e_errormode = EM_MAIL; 832 e->e_id = id; 833 if (forkflag) 834 disconnect(1, e); 835 # ifdef LOG 836 if (LogLevel > 76) 837 syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id, 838 getpid()); 839 # endif /* LOG */ 840 841 /* don't use the headers from sendmail.cf... */ 842 e->e_header = NULL; 843 844 /* read the queue control file -- return if locked */ 845 if (!readqf(e, !requeueflag)) 846 { 847 if (tTd(40, 4)) 848 printf("readqf(%s) failed\n", e->e_id); 849 if (forkflag) 850 exit(EX_OK); 851 else 852 return; 853 } 854 855 e->e_flags |= EF_INQUEUE; 856 eatheader(e, requeueflag); 857 858 if (requeueflag) 859 queueup(e, TRUE, FALSE); 860 861 /* do the delivery */ 862 sendall(e, SM_DELIVER); 863 864 /* finish up and exit */ 865 if (forkflag) 866 finis(); 867 else 868 dropenvelope(e); 869 } 870 e->e_id = NULL; 871 return pid; 872 } 873 /* 874 ** READQF -- read queue file and set up environment. 875 ** 876 ** Parameters: 877 ** e -- the envelope of the job to run. 878 ** announcefile -- if set, announce the name of the queue 879 ** file in error messages. 880 ** 881 ** Returns: 882 ** TRUE if it successfully read the queue file. 883 ** FALSE otherwise. 884 ** 885 ** Side Effects: 886 ** The queue file is returned locked. 887 */ 888 889 bool 890 readqf(e, announcefile) 891 register ENVELOPE *e; 892 bool announcefile; 893 { 894 register FILE *qfp; 895 ADDRESS *ctladdr; 896 struct stat st; 897 char *bp; 898 char qf[20]; 899 char buf[MAXLINE]; 900 extern long atol(); 901 extern ADDRESS *setctluser(); 902 903 /* 904 ** Read and process the file. 905 */ 906 907 strcpy(qf, queuename(e, 'q')); 908 qfp = fopen(qf, "r+"); 909 if (qfp == NULL) 910 { 911 if (tTd(40, 8)) 912 printf("readqf(%s): fopen failure (%s)\n", 913 qf, errstring(errno)); 914 if (errno != ENOENT) 915 syserr("readqf: no control file %s", qf); 916 return FALSE; 917 } 918 919 if (!lockfile(fileno(qfp), qf, NULL, LOCK_EX|LOCK_NB)) 920 { 921 /* being processed by another queuer */ 922 if (tTd(40, 8)) 923 printf("readqf(%s): locked\n", qf); 924 if (Verbose) 925 printf("%s: locked\n", e->e_id); 926 # ifdef LOG 927 if (LogLevel > 19) 928 syslog(LOG_DEBUG, "%s: locked", e->e_id); 929 # endif /* LOG */ 930 (void) fclose(qfp); 931 return FALSE; 932 } 933 934 /* 935 ** Check the queue file for plausibility to avoid attacks. 936 */ 937 938 if (fstat(fileno(qfp), &st) < 0) 939 { 940 /* must have been being processed by someone else */ 941 if (tTd(40, 8)) 942 printf("readqf(%s): fstat failure (%s)\n", 943 qf, errstring(errno)); 944 fclose(qfp); 945 return FALSE; 946 } 947 948 if (st.st_uid != geteuid()) 949 { 950 # ifdef LOG 951 if (LogLevel > 0) 952 { 953 syslog(LOG_ALERT, "%s: bogus queue file, uid=%d, mode=%o", 954 e->e_id, st.st_uid, st.st_mode); 955 } 956 # endif /* LOG */ 957 if (tTd(40, 8)) 958 printf("readqf(%s): bogus file\n", qf); 959 rename(qf, queuename(e, 'Q')); 960 fclose(qfp); 961 return FALSE; 962 } 963 964 if (st.st_size == 0) 965 { 966 /* must be a bogus file -- just remove it */ 967 (void) unlink(qf); 968 fclose(qfp); 969 return FALSE; 970 } 971 972 if (st.st_nlink == 0) 973 { 974 /* 975 ** Race condition -- we got a file just as it was being 976 ** unlinked. Just assume it is zero length. 977 */ 978 979 fclose(qfp); 980 return FALSE; 981 } 982 983 /* good file -- save this lock */ 984 e->e_lockfp = qfp; 985 986 /* do basic system initialization */ 987 initsys(e); 988 989 if (announcefile) 990 FileName = qf; 991 LineNumber = 0; 992 e->e_flags |= EF_GLOBALERRS; 993 OpMode = MD_DELIVER; 994 if (Verbose) 995 printf("\nRunning %s\n", e->e_id); 996 ctladdr = NULL; 997 while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL) 998 { 999 register char *p; 1000 struct stat st; 1001 1002 if (tTd(40, 4)) 1003 printf("+++++ %s\n", bp); 1004 switch (bp[0]) 1005 { 1006 case 'C': /* specify controlling user */ 1007 ctladdr = setctluser(&bp[1]); 1008 break; 1009 1010 case 'R': /* specify recipient */ 1011 (void) sendtolist(&bp[1], ctladdr, &e->e_sendqueue, e); 1012 break; 1013 1014 case 'E': /* specify error recipient */ 1015 (void) sendtolist(&bp[1], ctladdr, &e->e_errorqueue, e); 1016 break; 1017 1018 case 'H': /* header */ 1019 (void) chompheader(&bp[1], FALSE, e); 1020 break; 1021 1022 case 'M': /* message */ 1023 e->e_message = newstr(&bp[1]); 1024 break; 1025 1026 case 'S': /* sender */ 1027 setsender(newstr(&bp[1]), e, NULL, TRUE); 1028 break; 1029 1030 case 'B': /* body type */ 1031 e->e_bodytype = newstr(&bp[1]); 1032 break; 1033 1034 case 'D': /* data file name */ 1035 e->e_df = newstr(&bp[1]); 1036 e->e_dfp = fopen(e->e_df, "r"); 1037 if (e->e_dfp == NULL) 1038 { 1039 syserr("readqf: cannot open %s", e->e_df); 1040 e->e_msgsize = -1; 1041 } 1042 else if (fstat(fileno(e->e_dfp), &st) >= 0) 1043 e->e_msgsize = st.st_size; 1044 break; 1045 1046 case 'T': /* init time */ 1047 e->e_ctime = atol(&bp[1]); 1048 break; 1049 1050 case 'P': /* message priority */ 1051 e->e_msgpriority = atol(&bp[1]) + WkTimeFact; 1052 break; 1053 1054 case 'F': /* flag bits */ 1055 for (p = &bp[1]; *p != '\0'; p++) 1056 { 1057 switch (*p) 1058 { 1059 case 'w': /* warning sent */ 1060 e->e_flags |= EF_WARNING; 1061 break; 1062 1063 case 'r': /* response */ 1064 e->e_flags |= EF_RESPONSE; 1065 break; 1066 } 1067 } 1068 break; 1069 1070 case '$': /* define macro */ 1071 define(bp[1], newstr(&bp[2]), e); 1072 break; 1073 1074 case '\0': /* blank line; ignore */ 1075 break; 1076 1077 default: 1078 syserr("readqf: bad line \"%s\"", e->e_id, 1079 LineNumber, bp); 1080 fclose(qfp); 1081 rename(qf, queuename(e, 'Q')); 1082 return FALSE; 1083 } 1084 1085 if (bp != buf) 1086 free(bp); 1087 } 1088 1089 FileName = NULL; 1090 1091 /* 1092 ** If we haven't read any lines, this queue file is empty. 1093 ** Arrange to remove it without referencing any null pointers. 1094 */ 1095 1096 if (LineNumber == 0) 1097 { 1098 errno = 0; 1099 e->e_flags |= EF_CLRQUEUE | EF_FATALERRS | EF_RESPONSE; 1100 } 1101 return TRUE; 1102 } 1103 /* 1104 ** PRINTQUEUE -- print out a representation of the mail queue 1105 ** 1106 ** Parameters: 1107 ** none. 1108 ** 1109 ** Returns: 1110 ** none. 1111 ** 1112 ** Side Effects: 1113 ** Prints a listing of the mail queue on the standard output. 1114 */ 1115 1116 printqueue() 1117 { 1118 register WORK *w; 1119 FILE *f; 1120 int nrequests; 1121 char buf[MAXLINE]; 1122 1123 /* 1124 ** Check for permission to print the queue 1125 */ 1126 1127 if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0) 1128 { 1129 struct stat st; 1130 # ifdef NGROUPS 1131 int n; 1132 GIDSET_T gidset[NGROUPS]; 1133 # endif 1134 1135 if (stat(QueueDir, &st) < 0) 1136 { 1137 syserr("Cannot stat %s", QueueDir); 1138 return; 1139 } 1140 # ifdef NGROUPS 1141 n = getgroups(NGROUPS, gidset); 1142 while (--n >= 0) 1143 { 1144 if (gidset[n] == st.st_gid) 1145 break; 1146 } 1147 if (n < 0) 1148 # else 1149 if (RealGid != st.st_gid) 1150 # endif 1151 { 1152 usrerr("510 You are not permitted to see the queue"); 1153 setstat(EX_NOPERM); 1154 return; 1155 } 1156 } 1157 1158 /* 1159 ** Read and order the queue. 1160 */ 1161 1162 nrequests = orderq(TRUE); 1163 1164 /* 1165 ** Print the work list that we have read. 1166 */ 1167 1168 /* first see if there is anything */ 1169 if (nrequests <= 0) 1170 { 1171 printf("Mail queue is empty\n"); 1172 return; 1173 } 1174 1175 CurrentLA = getla(); /* get load average */ 1176 1177 printf("\t\tMail Queue (%d request%s", nrequests, nrequests == 1 ? "" : "s"); 1178 if (nrequests > QUEUESIZE) 1179 printf(", only %d printed", QUEUESIZE); 1180 if (Verbose) 1181 printf(")\n--Q-ID-- --Size-- -Priority- ---Q-Time--- -----------Sender/Recipient-----------\n"); 1182 else 1183 printf(")\n--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------\n"); 1184 for (w = WorkQ; w != NULL; w = w->w_next) 1185 { 1186 struct stat st; 1187 auto time_t submittime = 0; 1188 long dfsize = -1; 1189 int flags = 0; 1190 char message[MAXLINE]; 1191 char bodytype[MAXNAME]; 1192 1193 f = fopen(w->w_name, "r"); 1194 if (f == NULL) 1195 { 1196 errno = 0; 1197 continue; 1198 } 1199 printf("%8s", w->w_name + 2); 1200 if (!lockfile(fileno(f), w->w_name, NULL, LOCK_SH|LOCK_NB)) 1201 printf("*"); 1202 else if (shouldqueue(w->w_pri, w->w_ctime)) 1203 printf("X"); 1204 else 1205 printf(" "); 1206 errno = 0; 1207 1208 message[0] = bodytype[0] = '\0'; 1209 while (fgets(buf, sizeof buf, f) != NULL) 1210 { 1211 register int i; 1212 register char *p; 1213 1214 fixcrlf(buf, TRUE); 1215 switch (buf[0]) 1216 { 1217 case 'M': /* error message */ 1218 if ((i = strlen(&buf[1])) >= sizeof message) 1219 i = sizeof message - 1; 1220 bcopy(&buf[1], message, i); 1221 message[i] = '\0'; 1222 break; 1223 1224 case 'B': /* body type */ 1225 if ((i = strlen(&buf[1])) >= sizeof bodytype) 1226 i = sizeof bodytype - 1; 1227 bcopy(&buf[1], bodytype, i); 1228 bodytype[i] = '\0'; 1229 break; 1230 1231 case 'S': /* sender name */ 1232 if (Verbose) 1233 printf("%8ld %10ld%c%.12s %.38s", 1234 dfsize, 1235 w->w_pri, 1236 bitset(EF_WARNING, flags) ? '+' : ' ', 1237 ctime(&submittime) + 4, 1238 &buf[1]); 1239 else 1240 printf("%8ld %.16s %.45s", dfsize, 1241 ctime(&submittime), &buf[1]); 1242 if (message[0] != '\0' || bodytype[0] != '\0') 1243 { 1244 printf("\n %10.10s", bodytype); 1245 if (message[0] != '\0') 1246 printf(" (%.60s)", message); 1247 } 1248 break; 1249 1250 case 'C': /* controlling user */ 1251 if (Verbose) 1252 printf("\n\t\t\t\t (---%.34s---)", 1253 &buf[1]); 1254 break; 1255 1256 case 'R': /* recipient name */ 1257 if (Verbose) 1258 printf("\n\t\t\t\t\t %.38s", &buf[1]); 1259 else 1260 printf("\n\t\t\t\t %.45s", &buf[1]); 1261 break; 1262 1263 case 'T': /* creation time */ 1264 submittime = atol(&buf[1]); 1265 break; 1266 1267 case 'D': /* data file name */ 1268 if (stat(&buf[1], &st) >= 0) 1269 dfsize = st.st_size; 1270 break; 1271 1272 case 'F': /* flag bits */ 1273 for (p = &buf[1]; *p != '\0'; p++) 1274 { 1275 switch (*p) 1276 { 1277 case 'w': 1278 flags |= EF_WARNING; 1279 break; 1280 } 1281 } 1282 } 1283 } 1284 if (submittime == (time_t) 0) 1285 printf(" (no control file)"); 1286 printf("\n"); 1287 (void) fclose(f); 1288 } 1289 } 1290 1291 # endif /* QUEUE */ 1292 /* 1293 ** QUEUENAME -- build a file name in the queue directory for this envelope. 1294 ** 1295 ** Assigns an id code if one does not already exist. 1296 ** This code is very careful to avoid trashing existing files 1297 ** under any circumstances. 1298 ** 1299 ** Parameters: 1300 ** e -- envelope to build it in/from. 1301 ** type -- the file type, used as the first character 1302 ** of the file name. 1303 ** 1304 ** Returns: 1305 ** a pointer to the new file name (in a static buffer). 1306 ** 1307 ** Side Effects: 1308 ** If no id code is already assigned, queuename will 1309 ** assign an id code, create a qf file, and leave a 1310 ** locked, open-for-write file pointer in the envelope. 1311 */ 1312 1313 char * 1314 queuename(e, type) 1315 register ENVELOPE *e; 1316 int type; 1317 { 1318 static int pid = -1; 1319 static char c0; 1320 static char c1; 1321 static char c2; 1322 time_t now; 1323 struct tm *tm; 1324 static char buf[MAXNAME]; 1325 1326 if (e->e_id == NULL) 1327 { 1328 char qf[20]; 1329 1330 /* find a unique id */ 1331 if (pid != getpid()) 1332 { 1333 /* new process -- start back at "AA" */ 1334 pid = getpid(); 1335 now = curtime(); 1336 tm = localtime(&now); 1337 c0 = 'A' + tm->tm_hour; 1338 c1 = 'A'; 1339 c2 = 'A' - 1; 1340 } 1341 (void) sprintf(qf, "qf%cAA%05d", c0, pid); 1342 1343 while (c1 < '~' || c2 < 'Z') 1344 { 1345 int i; 1346 1347 if (c2 >= 'Z') 1348 { 1349 c1++; 1350 c2 = 'A' - 1; 1351 } 1352 qf[3] = c1; 1353 qf[4] = ++c2; 1354 if (tTd(7, 20)) 1355 printf("queuename: trying \"%s\"\n", qf); 1356 1357 i = open(qf, O_WRONLY|O_CREAT|O_EXCL, FileMode); 1358 if (i < 0) 1359 { 1360 if (errno == EEXIST) 1361 continue; 1362 syserr("queuename: Cannot create \"%s\" in \"%s\"", 1363 qf, QueueDir); 1364 exit(EX_UNAVAILABLE); 1365 } 1366 if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB)) 1367 { 1368 e->e_lockfp = fdopen(i, "w"); 1369 break; 1370 } 1371 1372 /* a reader got the file; abandon it and try again */ 1373 (void) close(i); 1374 } 1375 if (c1 >= '~' && c2 >= 'Z') 1376 { 1377 syserr("queuename: Cannot create \"%s\" in \"%s\"", 1378 qf, QueueDir); 1379 exit(EX_OSERR); 1380 } 1381 e->e_id = newstr(&qf[2]); 1382 define('i', e->e_id, e); 1383 if (tTd(7, 1)) 1384 printf("queuename: assigned id %s, env=%x\n", e->e_id, e); 1385 # ifdef LOG 1386 if (LogLevel > 93) 1387 syslog(LOG_DEBUG, "%s: assigned id", e->e_id); 1388 # endif /* LOG */ 1389 } 1390 1391 if (type == '\0') 1392 return (NULL); 1393 (void) sprintf(buf, "%cf%s", type, e->e_id); 1394 if (tTd(7, 2)) 1395 printf("queuename: %s\n", buf); 1396 return (buf); 1397 } 1398 /* 1399 ** UNLOCKQUEUE -- unlock the queue entry for a specified envelope 1400 ** 1401 ** Parameters: 1402 ** e -- the envelope to unlock. 1403 ** 1404 ** Returns: 1405 ** none 1406 ** 1407 ** Side Effects: 1408 ** unlocks the queue for `e'. 1409 */ 1410 1411 unlockqueue(e) 1412 ENVELOPE *e; 1413 { 1414 if (tTd(51, 4)) 1415 printf("unlockqueue(%s)\n", e->e_id); 1416 1417 /* if there is a lock file in the envelope, close it */ 1418 if (e->e_lockfp != NULL) 1419 xfclose(e->e_lockfp, "unlockqueue", e->e_id); 1420 e->e_lockfp = NULL; 1421 1422 /* don't create a queue id if we don't already have one */ 1423 if (e->e_id == NULL) 1424 return; 1425 1426 /* remove the transcript */ 1427 # ifdef LOG 1428 if (LogLevel > 87) 1429 syslog(LOG_DEBUG, "%s: unlock", e->e_id); 1430 # endif /* LOG */ 1431 if (!tTd(51, 104)) 1432 xunlink(queuename(e, 'x')); 1433 1434 } 1435 /* 1436 ** SETCTLUSER -- create a controlling address 1437 ** 1438 ** Create a fake "address" given only a local login name; this is 1439 ** used as a "controlling user" for future recipient addresses. 1440 ** 1441 ** Parameters: 1442 ** user -- the user name of the controlling user. 1443 ** 1444 ** Returns: 1445 ** An address descriptor for the controlling user. 1446 ** 1447 ** Side Effects: 1448 ** none. 1449 */ 1450 1451 ADDRESS * 1452 setctluser(user) 1453 char *user; 1454 { 1455 register ADDRESS *a; 1456 struct passwd *pw; 1457 char *p; 1458 1459 /* 1460 ** See if this clears our concept of controlling user. 1461 */ 1462 1463 if (user == NULL || *user == '\0') 1464 return NULL; 1465 1466 /* 1467 ** Set up addr fields for controlling user. 1468 */ 1469 1470 a = (ADDRESS *) xalloc(sizeof *a); 1471 bzero((char *) a, sizeof *a); 1472 1473 p = strchr(user, ':'); 1474 if (p != NULL) 1475 *p++ = '\0'; 1476 if (*user != '\0' && (pw = getpwnam(user)) != NULL) 1477 { 1478 a->q_home = newstr(pw->pw_dir); 1479 a->q_uid = pw->pw_uid; 1480 a->q_gid = pw->pw_gid; 1481 a->q_user = newstr(user); 1482 a->q_flags |= QGOODUID; 1483 } 1484 else 1485 { 1486 a->q_user = newstr(DefUser); 1487 } 1488 1489 a->q_flags |= QPRIMARY; /* flag as a "ctladdr" */ 1490 a->q_mailer = LocalMailer; 1491 if (p == NULL) 1492 a->q_paddr = a->q_user; 1493 else 1494 a->q_paddr = newstr(p); 1495 return a; 1496 } 1497