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.17 (Berkeley) 09/18/93 (with queueing)"; 14 #else 15 static char sccsid[] = "@(#)queue.c 8.17 (Berkeley) 09/18/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 register char *p; 603 char lbuf[MAXNAME]; 604 extern bool strcontainedin(); 605 606 /* is this an interesting entry? */ 607 if (d->d_name[0] != 'q' || d->d_name[1] != 'f') 608 continue; 609 610 if (QueueLimitId != NULL && 611 !strcontainedin(QueueLimitId, d->d_name)) 612 continue; 613 614 /* 615 ** Check queue name for plausibility. This handles 616 ** both old and new type ids. 617 */ 618 619 p = d->d_name + 2; 620 if (isupper(p[0]) && isupper(p[2])) 621 p += 3; 622 else if (isupper(p[1])) 623 p += 2; 624 else 625 p = d->d_name; 626 for (i = 0; isdigit(*p); p++) 627 i++; 628 if (i < 5 || *p != '\0') 629 { 630 if (Verbose) 631 printf("orderq: bogus qf name %s\n", d->d_name); 632 #ifdef LOG 633 if (LogLevel > 3) 634 syslog(LOG_CRIT, "orderq: bogus qf name %s", 635 d->d_name); 636 #endif 637 if (strlen(d->d_name) >= MAXNAME) 638 d->d_name[MAXNAME - 1] = '\0'; 639 strcpy(lbuf, d->d_name); 640 lbuf[0] = 'Q'; 641 (void) rename(d->d_name, lbuf); 642 continue; 643 } 644 645 /* yes -- open control file (if not too many files) */ 646 if (++wn >= QUEUESIZE) 647 continue; 648 649 cf = fopen(d->d_name, "r"); 650 if (cf == NULL) 651 { 652 /* this may be some random person sending hir msgs */ 653 /* syserr("orderq: cannot open %s", cbuf); */ 654 if (tTd(41, 2)) 655 printf("orderq: cannot open %s (%d)\n", 656 d->d_name, errno); 657 errno = 0; 658 wn--; 659 continue; 660 } 661 w = &wlist[wn]; 662 w->w_name = newstr(d->d_name); 663 664 /* make sure jobs in creation don't clog queue */ 665 w->w_pri = 0x7fffffff; 666 w->w_ctime = 0; 667 668 /* extract useful information */ 669 i = NEED_P | NEED_T; 670 if (QueueLimitSender != NULL) 671 i |= NEED_S; 672 if (QueueLimitRecipient != NULL) 673 i |= NEED_R; 674 while (i != 0 && fgets(lbuf, sizeof lbuf, cf) != NULL) 675 { 676 extern long atol(); 677 extern bool strcontainedin(); 678 679 switch (lbuf[0]) 680 { 681 case 'P': 682 w->w_pri = atol(&lbuf[1]); 683 i &= ~NEED_P; 684 break; 685 686 case 'T': 687 w->w_ctime = atol(&lbuf[1]); 688 i &= ~NEED_T; 689 break; 690 691 case 'R': 692 if (QueueLimitRecipient != NULL && 693 strcontainedin(QueueLimitRecipient, &lbuf[1])) 694 i &= ~NEED_R; 695 break; 696 697 case 'S': 698 if (QueueLimitSender != NULL && 699 strcontainedin(QueueLimitSender, &lbuf[1])) 700 i &= ~NEED_S; 701 break; 702 } 703 } 704 (void) fclose(cf); 705 706 if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) || 707 bitset(NEED_R|NEED_S, i)) 708 { 709 /* don't even bother sorting this job in */ 710 wn--; 711 } 712 } 713 (void) closedir(f); 714 wn++; 715 716 /* 717 ** Sort the work directory. 718 */ 719 720 qsort((char *) wlist, min(wn, QUEUESIZE), sizeof *wlist, workcmpf); 721 722 /* 723 ** Convert the work list into canonical form. 724 ** Should be turning it into a list of envelopes here perhaps. 725 */ 726 727 WorkQ = NULL; 728 for (i = min(wn, QUEUESIZE); --i >= 0; ) 729 { 730 w = (WORK *) xalloc(sizeof *w); 731 w->w_name = wlist[i].w_name; 732 w->w_pri = wlist[i].w_pri; 733 w->w_ctime = wlist[i].w_ctime; 734 w->w_next = WorkQ; 735 WorkQ = w; 736 } 737 738 if (tTd(40, 1)) 739 { 740 for (w = WorkQ; w != NULL; w = w->w_next) 741 printf("%32s: pri=%ld\n", w->w_name, w->w_pri); 742 } 743 744 return (wn); 745 } 746 /* 747 ** WORKCMPF -- compare function for ordering work. 748 ** 749 ** Parameters: 750 ** a -- the first argument. 751 ** b -- the second argument. 752 ** 753 ** Returns: 754 ** -1 if a < b 755 ** 0 if a == b 756 ** +1 if a > b 757 ** 758 ** Side Effects: 759 ** none. 760 */ 761 762 workcmpf(a, b) 763 register WORK *a; 764 register WORK *b; 765 { 766 long pa = a->w_pri; 767 long pb = b->w_pri; 768 769 if (pa == pb) 770 return (0); 771 else if (pa > pb) 772 return (1); 773 else 774 return (-1); 775 } 776 /* 777 ** DOWORK -- do a work request. 778 ** 779 ** Parameters: 780 ** id -- the ID of the job to run. 781 ** forkflag -- if set, run this in background. 782 ** requeueflag -- if set, reinstantiate the queue quickly. 783 ** This is used when expanding aliases in the queue. 784 ** If forkflag is also set, it doesn't wait for the 785 ** child. 786 ** e - the envelope in which to run it. 787 ** 788 ** Returns: 789 ** process id of process that is running the queue job. 790 ** 791 ** Side Effects: 792 ** The work request is satisfied if possible. 793 */ 794 795 pid_t 796 dowork(id, forkflag, requeueflag, e) 797 char *id; 798 bool forkflag; 799 bool requeueflag; 800 register ENVELOPE *e; 801 { 802 register pid_t pid; 803 extern bool readqf(); 804 805 if (tTd(40, 1)) 806 printf("dowork(%s)\n", id); 807 808 /* 809 ** Fork for work. 810 */ 811 812 if (forkflag) 813 { 814 pid = fork(); 815 if (pid < 0) 816 { 817 syserr("dowork: cannot fork"); 818 return 0; 819 } 820 } 821 else 822 { 823 pid = 0; 824 } 825 826 if (pid == 0) 827 { 828 /* 829 ** CHILD 830 ** Lock the control file to avoid duplicate deliveries. 831 ** Then run the file as though we had just read it. 832 ** We save an idea of the temporary name so we 833 ** can recover on interrupt. 834 */ 835 836 /* set basic modes, etc. */ 837 (void) alarm(0); 838 clearenvelope(e, FALSE); 839 e->e_flags |= EF_QUEUERUN; 840 e->e_errormode = EM_MAIL; 841 e->e_id = id; 842 if (forkflag) 843 disconnect(1, e); 844 # ifdef LOG 845 if (LogLevel > 76) 846 syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id, 847 getpid()); 848 # endif /* LOG */ 849 850 /* don't use the headers from sendmail.cf... */ 851 e->e_header = NULL; 852 853 /* read the queue control file -- return if locked */ 854 if (!readqf(e, !requeueflag)) 855 { 856 if (tTd(40, 4)) 857 printf("readqf(%s) failed\n", e->e_id); 858 if (forkflag) 859 exit(EX_OK); 860 else 861 return; 862 } 863 864 e->e_flags |= EF_INQUEUE; 865 eatheader(e, requeueflag); 866 867 if (requeueflag) 868 queueup(e, TRUE, FALSE); 869 870 /* do the delivery */ 871 sendall(e, SM_DELIVER); 872 873 /* finish up and exit */ 874 if (forkflag) 875 finis(); 876 else 877 dropenvelope(e); 878 } 879 e->e_id = NULL; 880 return pid; 881 } 882 /* 883 ** READQF -- read queue file and set up environment. 884 ** 885 ** Parameters: 886 ** e -- the envelope of the job to run. 887 ** announcefile -- if set, announce the name of the queue 888 ** file in error messages. 889 ** 890 ** Returns: 891 ** TRUE if it successfully read the queue file. 892 ** FALSE otherwise. 893 ** 894 ** Side Effects: 895 ** The queue file is returned locked. 896 */ 897 898 bool 899 readqf(e, announcefile) 900 register ENVELOPE *e; 901 bool announcefile; 902 { 903 register FILE *qfp; 904 ADDRESS *ctladdr; 905 struct stat st; 906 char *bp; 907 char qf[20]; 908 char buf[MAXLINE]; 909 extern long atol(); 910 extern ADDRESS *setctluser(); 911 912 /* 913 ** Read and process the file. 914 */ 915 916 strcpy(qf, queuename(e, 'q')); 917 qfp = fopen(qf, "r+"); 918 if (qfp == NULL) 919 { 920 if (tTd(40, 8)) 921 printf("readqf(%s): fopen failure (%s)\n", 922 qf, errstring(errno)); 923 if (errno != ENOENT) 924 syserr("readqf: no control file %s", qf); 925 return FALSE; 926 } 927 928 if (!lockfile(fileno(qfp), qf, NULL, LOCK_EX|LOCK_NB)) 929 { 930 /* being processed by another queuer */ 931 if (tTd(40, 8)) 932 printf("readqf(%s): locked\n", qf); 933 if (Verbose) 934 printf("%s: locked\n", e->e_id); 935 # ifdef LOG 936 if (LogLevel > 19) 937 syslog(LOG_DEBUG, "%s: locked", e->e_id); 938 # endif /* LOG */ 939 (void) fclose(qfp); 940 return FALSE; 941 } 942 943 /* 944 ** Check the queue file for plausibility to avoid attacks. 945 */ 946 947 if (fstat(fileno(qfp), &st) < 0) 948 { 949 /* must have been being processed by someone else */ 950 if (tTd(40, 8)) 951 printf("readqf(%s): fstat failure (%s)\n", 952 qf, errstring(errno)); 953 fclose(qfp); 954 return FALSE; 955 } 956 957 if (st.st_uid != geteuid()) 958 { 959 # ifdef LOG 960 if (LogLevel > 0) 961 { 962 syslog(LOG_ALERT, "%s: bogus queue file, uid=%d, mode=%o", 963 e->e_id, st.st_uid, st.st_mode); 964 } 965 # endif /* LOG */ 966 if (tTd(40, 8)) 967 printf("readqf(%s): bogus file\n", qf); 968 rename(qf, queuename(e, 'Q')); 969 fclose(qfp); 970 return FALSE; 971 } 972 973 if (st.st_size == 0) 974 { 975 /* must be a bogus file -- just remove it */ 976 (void) unlink(qf); 977 fclose(qfp); 978 return FALSE; 979 } 980 981 if (st.st_nlink == 0) 982 { 983 /* 984 ** Race condition -- we got a file just as it was being 985 ** unlinked. Just assume it is zero length. 986 */ 987 988 fclose(qfp); 989 return FALSE; 990 } 991 992 /* good file -- save this lock */ 993 e->e_lockfp = qfp; 994 995 /* do basic system initialization */ 996 initsys(e); 997 998 if (announcefile) 999 FileName = qf; 1000 LineNumber = 0; 1001 e->e_flags |= EF_GLOBALERRS; 1002 OpMode = MD_DELIVER; 1003 if (Verbose) 1004 printf("\nRunning %s\n", e->e_id); 1005 ctladdr = NULL; 1006 while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL) 1007 { 1008 register char *p; 1009 struct stat st; 1010 1011 if (tTd(40, 4)) 1012 printf("+++++ %s\n", bp); 1013 switch (bp[0]) 1014 { 1015 case 'C': /* specify controlling user */ 1016 ctladdr = setctluser(&bp[1]); 1017 break; 1018 1019 case 'R': /* specify recipient */ 1020 (void) sendtolist(&bp[1], ctladdr, &e->e_sendqueue, e); 1021 break; 1022 1023 case 'E': /* specify error recipient */ 1024 (void) sendtolist(&bp[1], ctladdr, &e->e_errorqueue, e); 1025 break; 1026 1027 case 'H': /* header */ 1028 (void) chompheader(&bp[1], FALSE, e); 1029 break; 1030 1031 case 'M': /* message */ 1032 e->e_message = newstr(&bp[1]); 1033 break; 1034 1035 case 'S': /* sender */ 1036 setsender(newstr(&bp[1]), e, NULL, TRUE); 1037 break; 1038 1039 case 'B': /* body type */ 1040 e->e_bodytype = newstr(&bp[1]); 1041 break; 1042 1043 case 'D': /* data file name */ 1044 e->e_df = newstr(&bp[1]); 1045 e->e_dfp = fopen(e->e_df, "r"); 1046 if (e->e_dfp == NULL) 1047 { 1048 syserr("readqf: cannot open %s", e->e_df); 1049 e->e_msgsize = -1; 1050 } 1051 else if (fstat(fileno(e->e_dfp), &st) >= 0) 1052 e->e_msgsize = st.st_size; 1053 break; 1054 1055 case 'T': /* init time */ 1056 e->e_ctime = atol(&bp[1]); 1057 break; 1058 1059 case 'P': /* message priority */ 1060 e->e_msgpriority = atol(&bp[1]) + WkTimeFact; 1061 break; 1062 1063 case 'F': /* flag bits */ 1064 for (p = &bp[1]; *p != '\0'; p++) 1065 { 1066 switch (*p) 1067 { 1068 case 'w': /* warning sent */ 1069 e->e_flags |= EF_WARNING; 1070 break; 1071 1072 case 'r': /* response */ 1073 e->e_flags |= EF_RESPONSE; 1074 break; 1075 } 1076 } 1077 break; 1078 1079 case '$': /* define macro */ 1080 define(bp[1], newstr(&bp[2]), e); 1081 break; 1082 1083 case '\0': /* blank line; ignore */ 1084 break; 1085 1086 default: 1087 syserr("readqf: bad line \"%s\"", e->e_id, 1088 LineNumber, bp); 1089 fclose(qfp); 1090 rename(qf, queuename(e, 'Q')); 1091 return FALSE; 1092 } 1093 1094 if (bp != buf) 1095 free(bp); 1096 } 1097 1098 FileName = NULL; 1099 1100 /* 1101 ** If we haven't read any lines, this queue file is empty. 1102 ** Arrange to remove it without referencing any null pointers. 1103 */ 1104 1105 if (LineNumber == 0) 1106 { 1107 errno = 0; 1108 e->e_flags |= EF_CLRQUEUE | EF_FATALERRS | EF_RESPONSE; 1109 } 1110 return TRUE; 1111 } 1112 /* 1113 ** PRINTQUEUE -- print out a representation of the mail queue 1114 ** 1115 ** Parameters: 1116 ** none. 1117 ** 1118 ** Returns: 1119 ** none. 1120 ** 1121 ** Side Effects: 1122 ** Prints a listing of the mail queue on the standard output. 1123 */ 1124 1125 printqueue() 1126 { 1127 register WORK *w; 1128 FILE *f; 1129 int nrequests; 1130 char buf[MAXLINE]; 1131 1132 /* 1133 ** Check for permission to print the queue 1134 */ 1135 1136 if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0) 1137 { 1138 struct stat st; 1139 # ifdef NGROUPS 1140 int n; 1141 GIDSET_T gidset[NGROUPS]; 1142 # endif 1143 1144 if (stat(QueueDir, &st) < 0) 1145 { 1146 syserr("Cannot stat %s", QueueDir); 1147 return; 1148 } 1149 # ifdef NGROUPS 1150 n = getgroups(NGROUPS, gidset); 1151 while (--n >= 0) 1152 { 1153 if (gidset[n] == st.st_gid) 1154 break; 1155 } 1156 if (n < 0) 1157 # else 1158 if (RealGid != st.st_gid) 1159 # endif 1160 { 1161 usrerr("510 You are not permitted to see the queue"); 1162 setstat(EX_NOPERM); 1163 return; 1164 } 1165 } 1166 1167 /* 1168 ** Read and order the queue. 1169 */ 1170 1171 nrequests = orderq(TRUE); 1172 1173 /* 1174 ** Print the work list that we have read. 1175 */ 1176 1177 /* first see if there is anything */ 1178 if (nrequests <= 0) 1179 { 1180 printf("Mail queue is empty\n"); 1181 return; 1182 } 1183 1184 CurrentLA = getla(); /* get load average */ 1185 1186 printf("\t\tMail Queue (%d request%s", nrequests, nrequests == 1 ? "" : "s"); 1187 if (nrequests > QUEUESIZE) 1188 printf(", only %d printed", QUEUESIZE); 1189 if (Verbose) 1190 printf(")\n--Q-ID-- --Size-- -Priority- ---Q-Time--- -----------Sender/Recipient-----------\n"); 1191 else 1192 printf(")\n--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------\n"); 1193 for (w = WorkQ; w != NULL; w = w->w_next) 1194 { 1195 struct stat st; 1196 auto time_t submittime = 0; 1197 long dfsize = -1; 1198 int flags = 0; 1199 char message[MAXLINE]; 1200 char bodytype[MAXNAME]; 1201 1202 printf("%8s", w->w_name + 2); 1203 f = fopen(w->w_name, "r"); 1204 if (f == NULL) 1205 { 1206 printf(" (job completed)\n"); 1207 errno = 0; 1208 continue; 1209 } 1210 if (!lockfile(fileno(f), w->w_name, NULL, LOCK_SH|LOCK_NB)) 1211 printf("*"); 1212 else if (shouldqueue(w->w_pri, w->w_ctime)) 1213 printf("X"); 1214 else 1215 printf(" "); 1216 errno = 0; 1217 1218 message[0] = bodytype[0] = '\0'; 1219 while (fgets(buf, sizeof buf, f) != NULL) 1220 { 1221 register int i; 1222 register char *p; 1223 1224 fixcrlf(buf, TRUE); 1225 switch (buf[0]) 1226 { 1227 case 'M': /* error message */ 1228 if ((i = strlen(&buf[1])) >= sizeof message) 1229 i = sizeof message - 1; 1230 bcopy(&buf[1], message, i); 1231 message[i] = '\0'; 1232 break; 1233 1234 case 'B': /* body type */ 1235 if ((i = strlen(&buf[1])) >= sizeof bodytype) 1236 i = sizeof bodytype - 1; 1237 bcopy(&buf[1], bodytype, i); 1238 bodytype[i] = '\0'; 1239 break; 1240 1241 case 'S': /* sender name */ 1242 if (Verbose) 1243 printf("%8ld %10ld%c%.12s %.38s", 1244 dfsize, 1245 w->w_pri, 1246 bitset(EF_WARNING, flags) ? '+' : ' ', 1247 ctime(&submittime) + 4, 1248 &buf[1]); 1249 else 1250 printf("%8ld %.16s %.45s", dfsize, 1251 ctime(&submittime), &buf[1]); 1252 if (message[0] != '\0' || bodytype[0] != '\0') 1253 { 1254 printf("\n %10.10s", bodytype); 1255 if (message[0] != '\0') 1256 printf(" (%.60s)", message); 1257 } 1258 break; 1259 1260 case 'C': /* controlling user */ 1261 if (Verbose) 1262 printf("\n\t\t\t\t (---%.34s---)", 1263 &buf[1]); 1264 break; 1265 1266 case 'R': /* recipient name */ 1267 if (Verbose) 1268 printf("\n\t\t\t\t\t %.38s", &buf[1]); 1269 else 1270 printf("\n\t\t\t\t %.45s", &buf[1]); 1271 break; 1272 1273 case 'T': /* creation time */ 1274 submittime = atol(&buf[1]); 1275 break; 1276 1277 case 'D': /* data file name */ 1278 if (stat(&buf[1], &st) >= 0) 1279 dfsize = st.st_size; 1280 break; 1281 1282 case 'F': /* flag bits */ 1283 for (p = &buf[1]; *p != '\0'; p++) 1284 { 1285 switch (*p) 1286 { 1287 case 'w': 1288 flags |= EF_WARNING; 1289 break; 1290 } 1291 } 1292 } 1293 } 1294 if (submittime == (time_t) 0) 1295 printf(" (no control file)"); 1296 printf("\n"); 1297 (void) fclose(f); 1298 } 1299 } 1300 1301 # endif /* QUEUE */ 1302 /* 1303 ** QUEUENAME -- build a file name in the queue directory for this envelope. 1304 ** 1305 ** Assigns an id code if one does not already exist. 1306 ** This code is very careful to avoid trashing existing files 1307 ** under any circumstances. 1308 ** 1309 ** Parameters: 1310 ** e -- envelope to build it in/from. 1311 ** type -- the file type, used as the first character 1312 ** of the file name. 1313 ** 1314 ** Returns: 1315 ** a pointer to the new file name (in a static buffer). 1316 ** 1317 ** Side Effects: 1318 ** If no id code is already assigned, queuename will 1319 ** assign an id code, create a qf file, and leave a 1320 ** locked, open-for-write file pointer in the envelope. 1321 */ 1322 1323 char * 1324 queuename(e, type) 1325 register ENVELOPE *e; 1326 int type; 1327 { 1328 static int pid = -1; 1329 static char c0; 1330 static char c1; 1331 static char c2; 1332 time_t now; 1333 struct tm *tm; 1334 static char buf[MAXNAME]; 1335 1336 if (e->e_id == NULL) 1337 { 1338 char qf[20]; 1339 1340 /* find a unique id */ 1341 if (pid != getpid()) 1342 { 1343 /* new process -- start back at "AA" */ 1344 pid = getpid(); 1345 now = curtime(); 1346 tm = localtime(&now); 1347 c0 = 'A' + tm->tm_hour; 1348 c1 = 'A'; 1349 c2 = 'A' - 1; 1350 } 1351 (void) sprintf(qf, "qf%cAA%05d", c0, pid); 1352 1353 while (c1 < '~' || c2 < 'Z') 1354 { 1355 int i; 1356 1357 if (c2 >= 'Z') 1358 { 1359 c1++; 1360 c2 = 'A' - 1; 1361 } 1362 qf[3] = c1; 1363 qf[4] = ++c2; 1364 if (tTd(7, 20)) 1365 printf("queuename: trying \"%s\"\n", qf); 1366 1367 i = open(qf, O_WRONLY|O_CREAT|O_EXCL, FileMode); 1368 if (i < 0) 1369 { 1370 if (errno == EEXIST) 1371 continue; 1372 syserr("queuename: Cannot create \"%s\" in \"%s\"", 1373 qf, QueueDir); 1374 exit(EX_UNAVAILABLE); 1375 } 1376 if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB)) 1377 { 1378 e->e_lockfp = fdopen(i, "w"); 1379 break; 1380 } 1381 1382 /* a reader got the file; abandon it and try again */ 1383 (void) close(i); 1384 } 1385 if (c1 >= '~' && c2 >= 'Z') 1386 { 1387 syserr("queuename: Cannot create \"%s\" in \"%s\"", 1388 qf, QueueDir); 1389 exit(EX_OSERR); 1390 } 1391 e->e_id = newstr(&qf[2]); 1392 define('i', e->e_id, e); 1393 if (tTd(7, 1)) 1394 printf("queuename: assigned id %s, env=%x\n", e->e_id, e); 1395 # ifdef LOG 1396 if (LogLevel > 93) 1397 syslog(LOG_DEBUG, "%s: assigned id", e->e_id); 1398 # endif /* LOG */ 1399 } 1400 1401 if (type == '\0') 1402 return (NULL); 1403 (void) sprintf(buf, "%cf%s", type, e->e_id); 1404 if (tTd(7, 2)) 1405 printf("queuename: %s\n", buf); 1406 return (buf); 1407 } 1408 /* 1409 ** UNLOCKQUEUE -- unlock the queue entry for a specified envelope 1410 ** 1411 ** Parameters: 1412 ** e -- the envelope to unlock. 1413 ** 1414 ** Returns: 1415 ** none 1416 ** 1417 ** Side Effects: 1418 ** unlocks the queue for `e'. 1419 */ 1420 1421 unlockqueue(e) 1422 ENVELOPE *e; 1423 { 1424 if (tTd(51, 4)) 1425 printf("unlockqueue(%s)\n", e->e_id); 1426 1427 /* if there is a lock file in the envelope, close it */ 1428 if (e->e_lockfp != NULL) 1429 xfclose(e->e_lockfp, "unlockqueue", e->e_id); 1430 e->e_lockfp = NULL; 1431 1432 /* don't create a queue id if we don't already have one */ 1433 if (e->e_id == NULL) 1434 return; 1435 1436 /* remove the transcript */ 1437 # ifdef LOG 1438 if (LogLevel > 87) 1439 syslog(LOG_DEBUG, "%s: unlock", e->e_id); 1440 # endif /* LOG */ 1441 if (!tTd(51, 104)) 1442 xunlink(queuename(e, 'x')); 1443 1444 } 1445 /* 1446 ** SETCTLUSER -- create a controlling address 1447 ** 1448 ** Create a fake "address" given only a local login name; this is 1449 ** used as a "controlling user" for future recipient addresses. 1450 ** 1451 ** Parameters: 1452 ** user -- the user name of the controlling user. 1453 ** 1454 ** Returns: 1455 ** An address descriptor for the controlling user. 1456 ** 1457 ** Side Effects: 1458 ** none. 1459 */ 1460 1461 ADDRESS * 1462 setctluser(user) 1463 char *user; 1464 { 1465 register ADDRESS *a; 1466 struct passwd *pw; 1467 char *p; 1468 1469 /* 1470 ** See if this clears our concept of controlling user. 1471 */ 1472 1473 if (user == NULL || *user == '\0') 1474 return NULL; 1475 1476 /* 1477 ** Set up addr fields for controlling user. 1478 */ 1479 1480 a = (ADDRESS *) xalloc(sizeof *a); 1481 bzero((char *) a, sizeof *a); 1482 1483 p = strchr(user, ':'); 1484 if (p != NULL) 1485 *p++ = '\0'; 1486 if (*user != '\0' && (pw = getpwnam(user)) != NULL) 1487 { 1488 a->q_home = newstr(pw->pw_dir); 1489 a->q_uid = pw->pw_uid; 1490 a->q_gid = pw->pw_gid; 1491 a->q_user = newstr(user); 1492 a->q_flags |= QGOODUID; 1493 } 1494 else 1495 { 1496 a->q_user = newstr(DefUser); 1497 } 1498 1499 a->q_flags |= QPRIMARY; /* flag as a "ctladdr" */ 1500 a->q_mailer = LocalMailer; 1501 if (p == NULL) 1502 a->q_paddr = a->q_user; 1503 else 1504 a->q_paddr = newstr(p); 1505 return a; 1506 } 1507