15
15
/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id,
16
/* encoding, dsn_envid, template)
17
17
/* const char *service;
18
18
/* const char *queue_name;
19
19
/* const char *queue_id;
20
20
/* const char *encoding;
21
/* const char *dsn_envid;
22
/* const BOUNCE_TEMPLATE *template;
23
/* BOUNCE_INFO *bounce_mail_one_init(queue_name, queue_id,
24
/* encoding, orig_recipient,
25
/* recipient, dsn_status,
24
/* BOUNCE_INFO *bounce_mail_one_init(queue_name, queue_id, encoding,
25
/* dsn_envid, dsn_notify, rcpt_buf,
27
27
/* const char *queue_name;
28
28
/* const char *queue_id;
29
29
/* const char *encoding;
30
/* const char *orig_recipient;
31
/* const char *recipient;
32
/* const char *status;
31
/* const char *dsn_envid;
32
/* RCPT_BUF *rcpt_buf;
34
/* const BOUNCE_TEMPLATE *template;
35
36
/* void bounce_mail_free(bounce_info)
36
37
/* BOUNCE_INFO *bounce_info;
38
/* int bounce_header(fp, bounce_info, recipient)
39
/* int bounce_header(fp, bounce_info, recipient, postmaster_copy)
40
41
/* BOUNCE_INFO *bounce_info;
41
42
/* const char *recipient;
43
/* int postmaster_copy;
43
45
/* int bounce_boilerplate(fp, bounce_info)
102
107
/* and with the text why the recipient was undeliverable.
104
109
/* bounce_diagnostic_log() sends a human-readable representation of
105
/* logfile information for all undeliverable recipients. This routine
106
/* will become obsolete when individual recipients of the same message
107
/* can have different sender addresses to bounce to.
110
/* logfile information for all undeliverable recipients. The
111
/* notify_filter specifies what recipient status records should be
112
/* reported: DSN_NOTIFY_SUCCESS, DSN_NOTIFY_FAILURE, DSN_NOTIFY_DELAY.
113
/* In the absence of DSN NOTIFY information all records are reported.
114
/* The result value is -1 in case of error, the number of reported
115
/* recipients in case of success.
109
117
/* bounce_header_dsn() starts a message/delivery-status message
110
118
/* segment and sends the machine-readable information that identifies
115
123
/* and with the text why the recipient was undeliverable.
117
125
/* bounce_diagnostic_dsn() sends a machine-readable representation of
118
/* logfile information for all undeliverable recipients. This routine
119
/* will become obsolete when individual recipients of the same message
120
/* can have different sender addresses to bounce to.
126
/* logfile information for all undeliverable recipients. The
127
/* notify_filter specifies what recipient status records should be
128
/* reported: DSN_NOTIFY_SUCCESS, DSN_NOTIFY_FAILURE, DSN_NOTIFY_DELAY.
129
/* In the absence of DSN NOTIFY information all records are reported.
130
/* The result value is -1 in case of error, the number of reported
131
/* recipients in case of success.
122
/* bounce_original() starts a message/rfc822 or headers/rfc822
123
/* message segment and sends the original message, either full or
124
/* message headers only.
133
/* bounce_original() starts a message/rfc822 or text/rfc822-headers
134
/* message segment and sends the original message, either full
135
/* (DSN_RET_FULL) or message headers only (DSN_RET_HDRS).
126
137
/* bounce_delrcpt() deletes recipients in the logfile from the original
224
238
bounce_info->queue_id, encoding);
225
239
bounce_info->mime_encoding = 0;
227
bounce_info->flush = flush;
241
if (dsn_envid && *dsn_envid)
242
bounce_info->dsn_envid = dsn_envid;
244
bounce_info->dsn_envid = 0;
245
bounce_info->template = template;
228
246
bounce_info->buf = vstring_alloc(100);
229
247
bounce_info->sender = vstring_alloc(100);
230
248
bounce_info->arrival_time = 0;
231
249
bounce_info->orig_offs = 0;
250
bounce_info->message_size = 0;
251
bounce_info->rcpt_buf = rcpt_buf;
252
bounce_info->dsn_buf = dsn_buf;
232
253
bounce_info->log_handle = log_handle;
262
283
msg_fatal("open %s %s: %m", service, queue_id);
265
* Skip over the original message envelope records. If the envelope is
266
* corrupted just send whatever we can (remember this is a best effort,
267
* it does not have to be perfect).
286
* Get time/size/sender information from the original message envelope
287
* records. If the envelope is corrupted just send whatever we can
288
* (remember this is a best effort, it does not have to be perfect).
269
290
* Lock the file for shared use, so that queue manager leaves it alone after
278
299
VSTREAM_PATH(bounce_info->orig_fp));
279
300
while ((rec_type = rec_get(bounce_info->orig_fp,
280
301
bounce_info->buf, 0)) > 0) {
281
if (rec_type == REC_TYPE_TIME && bounce_info->arrival_time == 0) {
282
if ((bounce_info->arrival_time = atol(STR(bounce_info->buf))) < 0)
304
* Postfix version dependent: data offset in SIZE record.
306
if (rec_type == REC_TYPE_SIZE) {
307
if (bounce_info->message_size == 0)
308
sscanf(STR(bounce_info->buf), "%ld %ld",
309
&bounce_info->message_size,
310
&bounce_info->orig_offs);
311
if (bounce_info->message_size < 0)
312
bounce_info->message_size = 0;
313
if (bounce_info->orig_offs < 0)
314
bounce_info->orig_offs = 0;
318
* Information for the Arrival-Date: attribute.
320
else if (rec_type == REC_TYPE_TIME) {
321
if (bounce_info->arrival_time == 0
322
&& (bounce_info->arrival_time = atol(STR(bounce_info->buf))) < 0)
283
323
bounce_info->arrival_time = 0;
284
} else if (rec_type == REC_TYPE_FROM) {
327
* Information for the X-Postfix-Sender: attribute.
329
else if (rec_type == REC_TYPE_FROM) {
285
330
quote_822_local_flags(bounce_info->sender,
286
331
VSTRING_LEN(bounce_info->buf) ?
287
332
STR(bounce_info->buf) :
288
333
mail_addr_mail_daemon(), 0);
289
} else if (rec_type == REC_TYPE_MESG) {
337
* Backwards compatibility: no data offset in SIZE record.
339
else if (rec_type == REC_TYPE_MESG) {
290
340
/* XXX Future: sender+recipient after message content. */
291
341
if (VSTRING_LEN(bounce_info->sender) == 0)
292
342
msg_warn("%s: no sender before message content record",
318
375
* job. But if the system IS running out of resources, raise a fatal
319
376
* run-time error and force a backoff.
321
if ((log_handle = bounce_log_open(service, queue_id, O_RDONLY, 0)) == 0
323
msg_fatal("open %s %s: %m", service, queue_id);
324
bounce_info = bounce_mail_alloc(service, queue_name, queue_id,
325
encoding, flush, log_handle);
378
if ((log_handle = bounce_log_open(service, queue_id, O_RDONLY, 0)) == 0) {
380
msg_fatal("open %s %s: %m", service, queue_id);
384
rcpt_buf = rcpb_create();
385
dsn_buf = dsb_create();
387
bounce_info = bounce_mail_alloc(service, queue_name, queue_id, encoding,
388
dsn_envid, rcpt_buf, dsn_buf,
389
template, log_handle);
326
390
return (bounce_info);
331
395
BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
332
396
const char *queue_id,
333
397
const char *encoding,
334
const char *orig_recipient,
335
const char *recipient,
337
const char *dsn_status,
338
const char *dsn_action,
398
const char *dsn_envid,
401
BOUNCE_TEMPLATE *template)
341
403
BOUNCE_INFO *bounce_info;
342
BOUNCE_LOG *log_handle;
345
* Initialize the bounce_info structure. Forge a logfile record for just
406
* Initialize the bounce_info structure for just one recipient.
348
log_handle = bounce_log_forge(orig_recipient, recipient, offset, dsn_status,
350
bounce_info = bounce_mail_alloc("none", queue_name, queue_id,
351
encoding, BOUNCE_MSG_FAIL, log_handle);
408
bounce_info = bounce_mail_alloc("none", queue_name, queue_id, encoding,
409
dsn_envid, rcpt_buf, dsn_buf, template,
352
411
return (bounce_info);
357
416
void bounce_mail_free(BOUNCE_INFO *bounce_info)
359
if (bounce_info->log_handle && bounce_log_close(bounce_info->log_handle))
360
msg_warn("%s: read bounce log %s: %m",
361
bounce_info->queue_id, bounce_info->queue_id);
418
if (bounce_info->log_handle) {
419
if (bounce_log_close(bounce_info->log_handle))
420
msg_warn("%s: read bounce log %s: %m",
421
bounce_info->queue_id, bounce_info->queue_id);
422
rcpb_free(bounce_info->rcpt_buf);
423
dsb_free(bounce_info->dsn_buf);
362
425
if (bounce_info->orig_fp && vstream_fclose(bounce_info->orig_fp))
363
426
msg_warn("%s: read message file %s %s: %m",
364
427
bounce_info->queue_id, bounce_info->queue_name,
383
447
#define STREQ(a, b) (strcasecmp((a), (b)) == 0)
385
post_mail_fprintf(bounce, "From: %s (Mail Delivery System)",
386
MAIL_ADDR_MAIL_DAEMON);
389
* Non-delivery subject line.
391
if (bounce_info->flush == BOUNCE_MSG_FAIL) {
392
post_mail_fputs(bounce, dest == var_bounce_rcpt
393
|| dest == var_2bounce_rcpt || dest == var_delay_rcpt ?
394
"Subject: Postmaster Copy: Undelivered Mail" :
395
"Subject: Undelivered Mail Returned to Sender");
399
* Delayed mail subject line.
401
else if (bounce_info->flush == BOUNCE_MSG_WARN) {
402
post_mail_fputs(bounce, dest == var_bounce_rcpt
403
|| dest == var_2bounce_rcpt || dest == var_delay_rcpt ?
404
"Subject: Postmaster Warning: Delayed Mail" :
405
"Subject: Delayed Mail (still being retried)");
409
* Address verification or delivery report.
412
post_mail_fputs(bounce, "Subject: Mail Delivery Status Report");
415
post_mail_fprintf(bounce, "To: %s",
416
STR(quote_822_local(bounce_info->buf, dest)));
452
bounce_template_headers(post_mail_fprintf, bounce, template,
453
STR(quote_822_local(bounce_info->buf, dest)),
457
* Auto-Submitted header, as per RFC 3834.
459
post_mail_fprintf(bounce, "Auto-Submitted: %s", postmaster_copy ?
460
"auto-generated" : "auto-replied");
463
* MIME header. Use 8bit encoding when either the bounced message or the
464
* template requires it.
421
466
post_mail_fprintf(bounce, "MIME-Version: 1.0");
422
467
post_mail_fprintf(bounce, "Content-Type: %s; report-type=%s;",
424
469
post_mail_fprintf(bounce, "\tboundary=\"%s\"", bounce_info->mime_boundary);
425
470
if (bounce_info->mime_encoding)
426
471
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
472
STREQ(bounce_info->mime_encoding, MAIL_ATTR_ENC_7BIT) ?
473
bounce_template_encoding(template) :
427
474
bounce_info->mime_encoding);
428
475
post_mail_fputs(bounce, "");
429
476
post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
434
481
post_mail_fputs(bounce, "");
435
482
post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
436
483
post_mail_fprintf(bounce, "Content-Description: %s", "Notification");
437
post_mail_fprintf(bounce, "Content-Type: %s", "text/plain");
484
post_mail_fprintf(bounce, "Content-Type: %s; charset=%s",
485
"text/plain", bounce_template_charset(template));
438
486
post_mail_fputs(bounce, "");
440
488
return (vstream_ferror(bounce));
449
* Print the message body with the problem report. XXX For now, we use a
450
* fixed bounce template. We could use a site-specific parametrized
451
* template with ${name} macros and we could do wonderful things such as
452
* word wrapping to make the text look nicer. No matter how hard we would
453
* try, receiving bounced mail will always suck.
497
* Print the boiler-plate text.
455
#define UNDELIVERED(flush) \
456
((flush) == BOUNCE_MSG_FAIL || (flush) == BOUNCE_MSG_WARN)
458
post_mail_fprintf(bounce, "This is the %s program at host %s.",
459
var_mail_name, var_myhostname);
460
post_mail_fputs(bounce, "");
461
if (bounce_info->flush == BOUNCE_MSG_FAIL) {
462
post_mail_fputs(bounce,
463
"I'm sorry to have to inform you that your message could not");
464
post_mail_fputs(bounce,
465
"be delivered to one or more recipients. It's attached below.");
466
} else if (bounce_info->flush == BOUNCE_MSG_WARN) {
467
post_mail_fputs(bounce,
468
"####################################################################");
469
post_mail_fputs(bounce,
470
"# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #");
471
post_mail_fputs(bounce,
472
"####################################################################");
473
post_mail_fputs(bounce, "");
474
post_mail_fprintf(bounce,
475
"Your message could not be delivered for %.1f hours.",
476
var_delay_warn_time / 3600.0);
477
post_mail_fprintf(bounce,
478
"It will be retried until it is %.1f days old.",
479
var_max_queue_time / 86400.0);
481
post_mail_fputs(bounce,
482
"Enclosed is the mail delivery report that you requested.");
484
if (UNDELIVERED(bounce_info->flush)) {
485
post_mail_fputs(bounce, "");
486
post_mail_fprintf(bounce,
487
"For further assistance, please send mail to <%s>",
488
MAIL_ADDR_POSTMASTER);
489
post_mail_fputs(bounce, "");
490
post_mail_fprintf(bounce,
491
"If you do so, please include this problem report. You can");
492
post_mail_fprintf(bounce,
493
"delete your own text from the attached returned message.");
495
post_mail_fputs(bounce, "");
496
post_mail_fprintf(bounce, "\t\t\tThe %s program", var_mail_name);
499
bounce_template_expand(post_mail_fputs, bounce, bounce_info->template);
497
500
return (vstream_ferror(bounce));
534
539
* piped into other programs. Sort of like TCP Wrapper's safe_finger
542
#define NON_NULL_EMPTY(s) ((s) && *(s))
537
544
post_mail_fputs(bounce, "");
538
if (bounce_info->log_handle->orig_rcpt) {
545
if (NON_NULL_EMPTY(rcpt->orig_addr)) {
539
546
bounce_print_wrap(bounce, bounce_info, "<%s> (expanded from <%s>): %s",
540
bounce_info->log_handle->recipient,
541
bounce_info->log_handle->orig_rcpt,
542
bounce_info->log_handle->text);
547
rcpt->address, rcpt->orig_addr, dsn->reason);
544
549
bounce_print_wrap(bounce, bounce_info, "<%s>: %s",
545
bounce_info->log_handle->recipient,
546
bounce_info->log_handle->text);
550
rcpt->address, dsn->reason);
548
552
return (vstream_ferror(bounce));
551
555
/* bounce_diagnostic_log - send bounce log report */
553
int bounce_diagnostic_log(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
557
int bounce_diagnostic_log(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
560
RECIPIENT *rcpt = &bounce_info->rcpt_buf->rcpt;
557
* Append a copy of the delivery error log. We're doing a best effort, so
558
* there is no point raising a fatal run-time error in case of a logfile
564
* Append a human-readable copy of the delivery error log. We're doing a
565
* best effort, so there is no point raising a fatal run-time error in
566
* case of a logfile read error.
568
* XXX DSN If the logfile with failed recipients is unavailable, pretend
569
* that we found something anyway, so that this notification will not be
561
572
if (bounce_info->log_handle == 0
562
573
|| bounce_log_rewind(bounce_info->log_handle)) {
563
post_mail_fputs(bounce, "\t--- Delivery report unavailable ---");
574
if (IS_FAILURE_TEMPLATE(bounce_info->template)) {
575
post_mail_fputs(bounce, "");
576
post_mail_fputs(bounce, "\t--- Delivery report unavailable ---");
577
count = 1; /* XXX don't abort */
565
while (bounce_log_read(bounce_info->log_handle) != 0)
566
if (bounce_recipient_log(bounce, bounce_info) != 0)
580
while (bounce_log_read(bounce_info->log_handle, bounce_info->rcpt_buf,
581
bounce_info->dsn_buf) != 0) {
582
if (rcpt->dsn_notify == 0 /* compat */
583
|| (rcpt->dsn_notify & notify_filter)) {
585
if (bounce_recipient_log(bounce, bounce_info) != 0)
569
return (vstream_ferror(bounce));
590
return (vstream_ferror(bounce) ? -1 : count);
572
593
/* bounce_header_dsn - send per-MTA bounce DSN records */
610
635
int bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
637
RECIPIENT *rcpt = &bounce_info->rcpt_buf->rcpt;
638
DSN *dsn = &bounce_info->dsn_buf->dsn;
612
640
post_mail_fputs(bounce, "");
613
post_mail_fprintf(bounce, "Final-Recipient: rfc822; %s",
614
bounce_info->log_handle->recipient);
615
if (bounce_info->log_handle->orig_rcpt) {
641
post_mail_fprintf(bounce, "Final-Recipient: rfc822; %s", rcpt->address);
646
* RFC 3464 section 6.3.d: "If no ORCPT parameter was provided for this
647
* recipient, the Original-Recipient field MUST NOT appear."
649
* This is inconsistent with section 5.2.1.d: "If no ORCPT parameter was
650
* present in the RCPT command when the message was received, an ORCPT
651
* parameter MAY be added to the RCPT command when the message is
652
* relayed.". Postfix adds an ORCPT parameter under these conditions.
654
* Therefore, all down-stream MTAs will send DSNs with Original-Recipient
655
* field ontaining this same ORCPT value. When a down-stream MTA can use
656
* that information in their DSNs, it makes no sense that an up-stream
657
* MTA can't use that same information in its own DSNs.
659
* Postfix always reports an Original-Recipient field, because it is more
660
* more useful and more consistent.
662
if (NON_NULL_EMPTY(rcpt->dsn_orcpt)) {
663
post_mail_fprintf(bounce, "Original-Recipient: %s", rcpt->dsn_orcpt);
664
} else if (NON_NULL_EMPTY(rcpt->orig_addr)) {
616
665
post_mail_fprintf(bounce, "Original-Recipient: rfc822; %s",
617
bounce_info->log_handle->orig_rcpt);
619
668
post_mail_fprintf(bounce, "Action: %s",
620
bounce_info->flush == BOUNCE_MSG_FAIL ?
621
"failed" : bounce_info->log_handle->dsn_action);
622
post_mail_fprintf(bounce, "Status: %s",
623
bounce_info->log_handle->dsn_status);
624
bounce_print_wrap(bounce, bounce_info, "Diagnostic-Code: X-%s; %s",
625
bounce_info->mail_name, bounce_info->log_handle->text);
669
IS_FAILURE_TEMPLATE(bounce_info->template) ?
670
"failed" : dsn->action);
671
post_mail_fprintf(bounce, "Status: %s", dsn->status);
672
if (NON_NULL_EMPTY(dsn->mtype) && NON_NULL_EMPTY(dsn->mname))
673
bounce_print_wrap(bounce, bounce_info, "Remote-MTA: %s; %s",
674
dsn->mtype, dsn->mname);
675
if (NON_NULL_EMPTY(dsn->dtype) && NON_NULL_EMPTY(dsn->dtext))
676
bounce_print_wrap(bounce, bounce_info, "Diagnostic-Code: %s; %s",
677
dsn->dtype, dsn->dtext);
679
bounce_print_wrap(bounce, bounce_info, "Diagnostic-Code: X-%s; %s",
680
bounce_info->mail_name, dsn->reason);
627
post_mail_fprintf(bounce, "Last-Attempt-Date: %s",
628
bounce_info->log_handle->log_time);
683
post_mail_fprintf(bounce, "Last-Attempt-Date: %s",
684
mail_date(dsn->time));
630
if (bounce_info->flush == BOUNCE_MSG_WARN)
686
if (IS_DELAY_TEMPLATE(bounce_info->template))
631
687
post_mail_fprintf(bounce, "Will-Retry-Until: %s",
632
688
mail_date(bounce_info->arrival_time + var_max_queue_time));
633
689
return (vstream_ferror(bounce));
636
692
/* bounce_diagnostic_dsn - send bounce log report, machine readable form */
638
int bounce_diagnostic_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info)
694
int bounce_diagnostic_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
697
RECIPIENT *rcpt = &bounce_info->rcpt_buf->rcpt;
642
* Append a copy of the delivery error log. We're doing a best effort, so
643
* there is no point raising a fatal run-time error in case of a logfile
701
* Append a machine-readable copy of the delivery error log. We're doing
702
* a best effort, so there is no point raising a fatal run-time error in
703
* case of a logfile read error.
705
* XXX DSN If the logfile with failed recipients is unavailable, pretend
706
* that we found something anyway, so that this notification will not be
646
if (bounce_info->log_handle != 0
647
&& bounce_log_rewind(bounce_info->log_handle) == 0) {
648
while (bounce_log_read(bounce_info->log_handle) != 0)
649
if (bounce_recipient_dsn(bounce, bounce_info) != 0)
709
if (bounce_info->log_handle == 0
710
|| bounce_log_rewind(bounce_info->log_handle)) {
711
if (IS_FAILURE_TEMPLATE(bounce_info->template))
712
count = 1; /* XXX don't abort */
714
while (bounce_log_read(bounce_info->log_handle, bounce_info->rcpt_buf,
715
bounce_info->dsn_buf) != 0) {
716
if (rcpt->dsn_notify == 0 /* compat */
717
|| (rcpt->dsn_notify & notify_filter)) {
719
if (bounce_recipient_dsn(bounce, bounce_info) != 0)
652
return (vstream_ferror(bounce));
724
return (vstream_ferror(bounce) ? -1 : count);
655
727
/* bounce_original - send a copy of the original to the victim */
661
733
int rec_type = 0;
736
* When truncating a large message, don't damage the MIME structure: send
737
* the message headers only.
739
if (var_bounce_limit > 0
740
&& bounce_info->orig_fp
741
&& (bounce_info->message_size <= 0
742
|| bounce_info->message_size > var_bounce_limit))
743
headers_only = DSN_RET_HDRS;
748
#define IS_UNDELIVERED_TEMPLATE(template) \
749
(IS_FAILURE_TEMPLATE(template) || IS_DELAY_TEMPLATE(template))
667
751
post_mail_fputs(bounce, "");
668
752
post_mail_fprintf(bounce, "--%s", bounce_info->mime_boundary);
669
753
post_mail_fprintf(bounce, "Content-Description: %s%s",
670
UNDELIVERED(bounce_info->flush) ? "Undelivered " : "",
671
headers_only ? "Message Headers" : "Message");
672
post_mail_fprintf(bounce, "Content-Type: %s", headers_only ?
754
IS_UNDELIVERED_TEMPLATE(bounce_info->template) ?
756
headers_only == DSN_RET_HDRS ?
757
"Message Headers" : "Message");
758
post_mail_fprintf(bounce, "Content-Type: %s",
759
headers_only == DSN_RET_HDRS ?
673
760
"text/rfc822-headers" : "message/rfc822");
674
761
if (bounce_info->mime_encoding)
675
762
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
689
* Copy the original message contents. Limit the amount of bounced text
690
* so there is a better chance of the bounce making it back. We're doing
691
* raw record output here so that we don't throw away binary transparency
776
* Copy the original message contents. We're doing raw record output here
777
* so that we don't throw away binary transparency yet.
694
779
#define IS_HEADER(s) (IS_SPACE_TAB(*(s)) || is_header(s))
697
781
while (status == 0 && (rec_type = rec_get(bounce_info->orig_fp, bounce_info->buf, 0)) > 0) {
698
782
if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
700
if (headers_only && !IS_HEADER(vstring_str(bounce_info->buf)))
702
if (var_bounce_limit == 0 || bounce_length < var_bounce_limit) {
703
bounce_length += VSTRING_LEN(bounce_info->buf) + 2;
704
status = (REC_PUT_BUF(bounce, rec_type, bounce_info->buf) != rec_type);
784
if (headers_only == DSN_RET_HDRS
785
&& !IS_HEADER(vstring_str(bounce_info->buf)))
787
status = (REC_PUT_BUF(bounce, rec_type, bounce_info->buf) != rec_type);
724
805
void bounce_delrcpt(BOUNCE_INFO *bounce_info)
807
RECIPIENT *rcpt = &bounce_info->rcpt_buf->rcpt;
726
809
if (bounce_info->orig_fp != 0
727
810
&& bounce_info->log_handle != 0
728
811
&& bounce_log_rewind(bounce_info->log_handle) == 0)
729
while (bounce_log_read(bounce_info->log_handle) != 0)
730
if (bounce_info->log_handle->rcpt_offset > 0)
731
deliver_completed(bounce_info->orig_fp,
732
bounce_info->log_handle->rcpt_offset);
812
while (bounce_log_read(bounce_info->log_handle, bounce_info->rcpt_buf,
813
bounce_info->dsn_buf) != 0)
814
if (rcpt->offset > 0)
815
deliver_completed(bounce_info->orig_fp, rcpt->offset);
735
818
/* bounce_delrcpt_one - delete one recipient from original queue file */
737
820
void bounce_delrcpt_one(BOUNCE_INFO *bounce_info)
739
if (bounce_info->orig_fp != 0
740
&& bounce_info->log_handle != 0
741
&& bounce_info->log_handle->rcpt_offset > 0)
742
deliver_completed(bounce_info->orig_fp,
743
bounce_info->log_handle->rcpt_offset);
822
RECIPIENT *rcpt = &bounce_info->rcpt_buf->rcpt;
824
if (bounce_info->orig_fp != 0 && rcpt->offset > 0)
825
deliver_completed(bounce_info->orig_fp, rcpt->offset);