Postfix3.3.1
qmgr_defer.c
[詳解]
1 /*++
2 /* NAME
3 /* qmgr_defer
4 /* SUMMARY
5 /* deal with mail that must be delivered later
6 /* SYNOPSIS
7 /* #include "qmgr.h"
8 /*
9 /* void qmgr_defer_recipient(message, recipient, dsn)
10 /* QMGR_MESSAGE *message;
11 /* RECIPIENT *recipient;
12 /* DSN *dsn;
13 /*
14 /* void qmgr_defer_todo(queue, dsn)
15 /* QMGR_QUEUE *queue;
16 /* DSN *dsn;
17 /*
18 /* void qmgr_defer_transport(transport, dsn)
19 /* QMGR_TRANSPORT *transport;
20 /* DSN *dsn;
21 /* DESCRIPTION
22 /* qmgr_defer_recipient() defers delivery of the named message to
23 /* the named recipient. It updates the message structure and writes
24 /* a log entry.
25 /*
26 /* qmgr_defer_todo() iterates over all "todo" deliveries queued for
27 /* the named site, and calls qmgr_defer_recipient() for each recipient
28 /* found. Side effects caused by qmgr_entry_done(), qmgr_queue_done(),
29 /* and by qmgr_active_done(): in-core queue entries will disappear,
30 /* in-core queues may disappear, in-core and on-disk messages may
31 /* disappear, bounces may be sent, new in-core queues, queue entries
32 /* and recipients may appear.
33 /*
34 /* qmgr_defer_transport() calls qmgr_defer_todo() for each queue
35 /* that depends on the named transport. See there for side effects.
36 /*
37 /* Arguments:
38 /* .IP recipient
39 /* A recipient address; used for logging purposes, and for updating
40 /* the message-specific \fIdefer\fR log.
41 /* .IP queue
42 /* Specifies a queue with delivery requests for a specific next-hop
43 /* host (or local user).
44 /* .IP transport
45 /* Specifies a message delivery transport.
46 /* .IP dsn
47 /* See dsn(3).
48 /* BUGS
49 /* The side effects of calling this routine are quite dramatic.
50 /* DIAGNOSTICS
51 /* Panic: consistency check failure. Fatal: out of memory.
52 /* LICENSE
53 /* .ad
54 /* .fi
55 /* The Secure Mailer license must be distributed with this software.
56 /* AUTHOR(S)
57 /* Wietse Venema
58 /* IBM T.J. Watson Research
59 /* P.O. Box 704
60 /* Yorktown Heights, NY 10598, USA
61 /*--*/
62 
63 /* System library. */
64 
65 #include <sys_defs.h>
66 
67 /* Utility library. */
68 
69 #include <msg.h>
70 #include <vstream.h>
71 
72 /* Global library. */
73 
74 #include <mail_proto.h>
75 #include <defer.h>
76 
77 /* Application-specific. */
78 
79 #include "qmgr.h"
80 
81 /* qmgr_defer_transport - defer todo entries for named transport */
82 
83 void qmgr_defer_transport(QMGR_TRANSPORT *transport, DSN *dsn)
84 {
85  QMGR_QUEUE *queue;
86  QMGR_QUEUE *next;
87 
88  if (msg_verbose)
89  msg_info("defer transport %s: %s %s",
90  transport->name, dsn->status, dsn->reason);
91 
92  /*
93  * Proceed carefully. Queues may disappear as a side effect.
94  */
95  for (queue = transport->queue_list.next; queue; queue = next) {
96  next = queue->peers.next;
97  qmgr_defer_todo(queue, dsn);
98  }
99 }
100 
101 /* qmgr_defer_todo - defer all todo queue entries for specific site */
102 
103 void qmgr_defer_todo(QMGR_QUEUE *queue, DSN *dsn)
104 {
105  QMGR_ENTRY *entry;
106  QMGR_ENTRY *next;
107  QMGR_MESSAGE *message;
108  RECIPIENT *recipient;
109  int nrcpt;
110  QMGR_QUEUE *retry_queue;
111 
112  /*
113  * Sanity checks.
114  */
115  if (msg_verbose)
116  msg_info("defer site %s: %s %s",
117  queue->name, dsn->status, dsn->reason);
118 
119  /*
120  * See if we can redirect the deliveries to the retry(8) delivery agent,
121  * so that they can be handled asynchronously. If the retry(8) service is
122  * unavailable, use the synchronous defer(8) server. With a large todo
123  * queue, this blocks the queue manager for a significant time.
124  */
125  retry_queue = qmgr_error_queue(MAIL_SERVICE_RETRY, dsn);
126 
127  /*
128  * Proceed carefully. Queue entries may disappear as a side effect.
129  */
130  for (entry = queue->todo.next; entry != 0; entry = next) {
131  next = entry->peers.next;
132  if (retry_queue != 0) {
133  qmgr_entry_move_todo(retry_queue, entry);
134  continue;
135  }
136  message = entry->message;
137  for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) {
138  recipient = entry->rcpt_list.info + nrcpt;
139  qmgr_defer_recipient(message, recipient, dsn);
140  }
142  }
143 }
144 
145 /* qmgr_defer_recipient - defer delivery of specific recipient */
146 
147 void qmgr_defer_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient,
148  DSN *dsn)
149 {
150  MSG_STATS stats;
151 
152  /*
153  * Update the message structure and log the message disposition.
154  */
155  message->flags |= defer_append(message->tflags, message->queue_id,
156  QMGR_MSG_STATS(&stats, message), recipient,
157  "none", dsn);
158 }
int msg_verbose
Definition: msg.c:177
QMGR_QUEUE * qmgr_error_queue(const char *, DSN *)
Definition: qmgr_error.c:85
QMGR_ENTRY * next
Definition: qmgr.h:193
char * queue_id
Definition: qmgr.h:298
const char * reason
Definition: dsn.h:20
void qmgr_defer_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient, DSN *dsn)
Definition: qmgr_defer.c:147
void qmgr_entry_move_todo(QMGR_QUEUE *, QMGR_ENTRY *)
Definition: qmgr_entry.c:180
void qmgr_defer_transport(QMGR_TRANSPORT *transport, DSN *dsn)
Definition: qmgr_defer.c:83
QMGR_QUEUE * next
Definition: qmgr.h:148
void qmgr_defer_todo(QMGR_QUEUE *queue, DSN *dsn)
Definition: qmgr_defer.c:103
#define QMGR_QUEUE_TODO
Definition: qmgr.h:216
int flags
Definition: qmgr.h:283
QMGR_QUEUE_LIST peers
Definition: qmgr.h:211
char * name
Definition: qmgr.h:200
QMGR_ENTRY_LIST todo
Definition: qmgr.h:209
QMGR_ENTRY_LIST peers
Definition: qmgr.h:267
void qmgr_entry_done(QMGR_ENTRY *, int)
Definition: qmgr_entry.c:212
char * name
Definition: qmgr.h:155
#define QMGR_MSG_STATS(stats, message)
Definition: qmgr.h:341
QMGR_MESSAGE * message
Definition: qmgr.h:264
const char * status
Definition: dsn.h:18
#define MAIL_SERVICE_RETRY
Definition: mail_proto.h:53
QMGR_QUEUE_LIST queue_list
Definition: qmgr.h:160
Definition: dsn.h:17
RECIPIENT * info
RECIPIENT_LIST rcpt_list
Definition: qmgr.h:265
int tflags
Definition: qmgr.h:285
int defer_append(int flags, const char *id, MSG_STATS *stats, RECIPIENT *rcpt, const char *relay, DSN *dsn)
Definition: defer.c:187
void msg_info(const char *fmt,...)
Definition: msg.c:199