Postfix3.3.1
qmgr_scan.c
[詳解]
1 /*++
2 /* NAME
3 /* qmgr_scan 3
4 /* SUMMARY
5 /* queue scanning
6 /* SYNOPSIS
7 /* #include "qmgr.h"
8 /*
9 /* QMGR_SCAN *qmgr_scan_create(queue_name)
10 /* const char *queue_name;
11 /*
12 /* char *qmgr_scan_next(scan_info)
13 /* QMGR_SCAN *scan_info;
14 /*
15 /* void qmgr_scan_request(scan_info, flags)
16 /* QMGR_SCAN *scan_info;
17 /* int flags;
18 /* DESCRIPTION
19 /* This module implements queue scans. A queue scan always runs
20 /* to completion, so that all files get a fair chance. The caller
21 /* can request that a queue scan be restarted once it completes.
22 /*
23 /* qmgr_scan_create() creates a context for scanning the named queue,
24 /* but does not start a queue scan.
25 /*
26 /* qmgr_scan_next() returns the base name of the next queue file.
27 /* A null pointer means that no file was found. qmgr_scan_next()
28 /* automagically restarts a queue scan when a scan request had
29 /* arrived while the scan was in progress.
30 /*
31 /* qmgr_scan_request() records a request for the next queue scan. The
32 /* flags argument is the bit-wise OR of zero or more of the following,
33 /* unrecognized flags being ignored:
34 /* .IP QMGR_FLUSH_ONCE
35 /* Forget state information about dead hosts or transports.
36 /* This request takes effect immediately.
37 /* .IP QMGR_FLUSH_DFXP
38 /* Override the defer_transports setting. This takes effect
39 /* immediately when a queue scan is in progress, and affects
40 /* the next queue scan.
41 /* .IP QMGR_SCAN_ALL
42 /* Ignore queue file time stamps. This takes effect immediately
43 /* when a queue scan is in progress, and affects the next queue
44 /* scan.
45 /* .IP QMGR_SCAN_START
46 /* Start a queue scan when none is in progress, or restart the
47 /* current scan upon completion.
48 /* DIAGNOSTICS
49 /* Fatal: out of memory.
50 /* Panic: interface violations, internal consistency errors.
51 /* LICENSE
52 /* .ad
53 /* .fi
54 /* The Secure Mailer license must be distributed with this software.
55 /* AUTHOR(S)
56 /* Wietse Venema
57 /* IBM T.J. Watson Research
58 /* P.O. Box 704
59 /* Yorktown Heights, NY 10598, USA
60 /*--*/
61 
62 /* System library. */
63 
64 #include <sys_defs.h>
65 
66 /* Utility library. */
67 
68 #include <msg.h>
69 #include <mymalloc.h>
70 #include <scan_dir.h>
71 
72 /* Global library. */
73 
74 #include <mail_scan_dir.h>
75 
76 /* Application-specific. */
77 
78 #include "qmgr.h"
79 
80 /* qmgr_scan_start - start queue scan */
81 
82 static void qmgr_scan_start(QMGR_SCAN *scan_info)
83 {
84  const char *myname = "qmgr_scan_start";
85 
86  /*
87  * Sanity check.
88  */
89  if (scan_info->handle)
90  msg_panic("%s: %s queue scan in progress",
91  myname, scan_info->queue);
92 
93  /*
94  * Give the poor tester a clue.
95  */
96  if (msg_verbose)
97  msg_info("%s: %sstart %s queue scan",
98  myname,
99  scan_info->nflags & QMGR_SCAN_START ? "re" : "",
100  scan_info->queue);
101 
102  /*
103  * Start or restart the scan.
104  */
105  scan_info->flags = scan_info->nflags;
106  scan_info->nflags = 0;
107  scan_info->handle = scan_dir_open(scan_info->queue);
108 }
109 
110 /* qmgr_scan_request - request for future scan */
111 
112 void qmgr_scan_request(QMGR_SCAN *scan_info, int flags)
113 {
114 
115  /*
116  * Apply "forget all dead destinations" requests immediately. Throttle
117  * dead transports and queues at the earliest opportunity: preferably
118  * during an already ongoing queue scan, otherwise the throttling will
119  * have to wait until a "start scan" trigger arrives.
120  *
121  * The QMGR_FLUSH_ONCE request always comes with QMGR_FLUSH_DFXP, and
122  * sometimes it also comes with QMGR_SCAN_ALL. It becomes a completely
123  * different story when a flush request is encoded in file permissions.
124  */
125  if (flags & QMGR_FLUSH_ONCE)
126  qmgr_enable_all();
127 
128  /*
129  * Apply "ignore time stamp" requests also towards the scan that is
130  * already in progress.
131  */
132  if (scan_info->handle != 0 && (flags & QMGR_SCAN_ALL))
133  scan_info->flags |= QMGR_SCAN_ALL;
134 
135  /*
136  * Apply "override defer_transports" requests also towards the scan that
137  * is already in progress.
138  */
139  if (scan_info->handle != 0 && (flags & QMGR_FLUSH_DFXP))
140  scan_info->flags |= QMGR_FLUSH_DFXP;
141 
142  /*
143  * If a scan is in progress, just record the request.
144  */
145  scan_info->nflags |= flags;
146  if (scan_info->handle == 0 && (flags & QMGR_SCAN_START) != 0) {
147  scan_info->nflags &= ~QMGR_SCAN_START;
148  qmgr_scan_start(scan_info);
149  }
150 }
151 
152 /* qmgr_scan_next - look for next queue file */
153 
154 char *qmgr_scan_next(QMGR_SCAN *scan_info)
155 {
156  char *path = 0;
157 
158  /*
159  * Restart the scan if we reach the end and a queue scan request has
160  * arrived in the mean time.
161  */
162  if (scan_info->handle && (path = mail_scan_dir_next(scan_info->handle)) == 0) {
163  scan_info->handle = scan_dir_close(scan_info->handle);
164  if (msg_verbose && (scan_info->nflags & QMGR_SCAN_START) == 0)
165  msg_info("done %s queue scan", scan_info->queue);
166  }
167  if (!scan_info->handle && (scan_info->nflags & QMGR_SCAN_START)) {
168  qmgr_scan_start(scan_info);
169  path = mail_scan_dir_next(scan_info->handle);
170  }
171  return (path);
172 }
173 
174 /* qmgr_scan_create - create queue scan context */
175 
176 QMGR_SCAN *qmgr_scan_create(const char *queue)
177 {
178  QMGR_SCAN *scan_info;
179 
180  scan_info = (QMGR_SCAN *) mymalloc(sizeof(*scan_info));
181  scan_info->queue = mystrdup(queue);
182  scan_info->flags = scan_info->nflags = 0;
183  scan_info->handle = 0;
184  return (scan_info);
185 }
int msg_verbose
Definition: msg.c:177
char * mystrdup(const char *str)
Definition: mymalloc.c:225
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define QMGR_SCAN_ALL
Definition: qmgr.h:398
SCAN_DIR * scan_dir_open(const char *path)
Definition: scan_dir.c:165
QMGR_SCAN * qmgr_scan_create(const char *queue)
Definition: qmgr_scan.c:176
SCAN_DIR * scan_dir_close(SCAN_DIR *scan)
Definition: scan_dir.c:210
void qmgr_scan_request(QMGR_SCAN *scan_info, int flags)
Definition: qmgr_scan.c:112
#define QMGR_FLUSH_DFXP
Definition: qmgr.h:400
void qmgr_enable_all(void)
Definition: qmgr_enable.c:60
int flags
Definition: qmgr.h:388
char * qmgr_scan_next(QMGR_SCAN *scan_info)
Definition: qmgr_scan.c:154
char * queue
Definition: qmgr.h:387
struct SCAN_DIR * handle
Definition: qmgr.h:390
#define QMGR_FLUSH_ONCE
Definition: qmgr.h:399
#define QMGR_SCAN_START
Definition: qmgr.h:397
char * mail_scan_dir_next(SCAN_DIR *scan)
Definition: mail_scan_dir.c:43
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void msg_info(const char *fmt,...)
Definition: msg.c:199
int nflags
Definition: qmgr.h:389