Commit | Line | Data |
---|---|---|
184e8823 | 1 | /* $Cambridge: exim/src/src/transport.c,v 1.19 2007/01/08 10:50:18 ph10 Exp $ */ |
059ec3d9 PH |
2 | |
3 | /************************************************* | |
4 | * Exim - an Internet mail transport agent * | |
5 | *************************************************/ | |
6 | ||
184e8823 | 7 | /* Copyright (c) University of Cambridge 1995 - 2007 */ |
059ec3d9 PH |
8 | /* See the file NOTICE for conditions of use and distribution. */ |
9 | ||
10 | /* General functions concerned with transportation, and generic options for all | |
11 | transports. */ | |
12 | ||
13 | ||
14 | #include "exim.h" | |
15 | ||
a8530a10 TK |
16 | #ifdef HAVE_LINUX_SENDFILE |
17 | #include <sys/sendfile.h> | |
18 | #endif | |
059ec3d9 PH |
19 | |
20 | /* Structure for keeping list of addresses that have been added to | |
21 | Envelope-To:, in order to avoid duplication. */ | |
22 | ||
23 | struct aci { | |
24 | struct aci *next; | |
25 | address_item *ptr; | |
26 | }; | |
27 | ||
28 | ||
29 | /* Static data for write_chunk() */ | |
30 | ||
31 | static uschar *chunk_ptr; /* chunk pointer */ | |
32 | static uschar *nl_check; /* string to look for at line start */ | |
33 | static int nl_check_length; /* length of same */ | |
34 | static uschar *nl_escape; /* string to insert */ | |
35 | static int nl_escape_length; /* length of same */ | |
36 | static int nl_partial_match; /* length matched at chunk end */ | |
37 | ||
38 | ||
39 | /* Generic options for transports, all of which live inside transport_instance | |
40 | data blocks and which therefore have the opt_public flag set. Note that there | |
41 | are other options living inside this structure which can be set only from | |
42 | certain transports. */ | |
43 | ||
44 | optionlist optionlist_transports[] = { | |
45 | { "*expand_group", opt_stringptr|opt_hidden|opt_public, | |
46 | (void *)offsetof(transport_instance, expand_gid) }, | |
47 | { "*expand_user", opt_stringptr|opt_hidden|opt_public, | |
48 | (void *)offsetof(transport_instance, expand_uid) }, | |
49 | { "*headers_rewrite_flags", opt_int|opt_public|opt_hidden, | |
50 | (void *)offsetof(transport_instance, rewrite_existflags) }, | |
51 | { "*headers_rewrite_rules", opt_void|opt_public|opt_hidden, | |
52 | (void *)offsetof(transport_instance, rewrite_rules) }, | |
53 | { "*set_group", opt_bool|opt_hidden|opt_public, | |
54 | (void *)offsetof(transport_instance, gid_set) }, | |
55 | { "*set_user", opt_bool|opt_hidden|opt_public, | |
56 | (void *)offsetof(transport_instance, uid_set) }, | |
57 | { "body_only", opt_bool|opt_public, | |
58 | (void *)offsetof(transport_instance, body_only) }, | |
59 | { "current_directory", opt_stringptr|opt_public, | |
60 | (void *)offsetof(transport_instance, current_dir) }, | |
61 | { "debug_print", opt_stringptr | opt_public, | |
62 | (void *)offsetof(transport_instance, debug_string) }, | |
63 | { "delivery_date_add", opt_bool|opt_public, | |
64 | (void *)(offsetof(transport_instance, delivery_date_add)) }, | |
65 | { "disable_logging", opt_bool|opt_public, | |
66 | (void *)(offsetof(transport_instance, disable_logging)) }, | |
67 | { "driver", opt_stringptr|opt_public, | |
68 | (void *)offsetof(transport_instance, driver_name) }, | |
69 | { "envelope_to_add", opt_bool|opt_public, | |
70 | (void *)(offsetof(transport_instance, envelope_to_add)) }, | |
71 | { "group", opt_expand_gid|opt_public, | |
72 | (void *)offsetof(transport_instance, gid) }, | |
73 | { "headers_add", opt_stringptr|opt_public, | |
74 | (void *)offsetof(transport_instance, add_headers) }, | |
75 | { "headers_only", opt_bool|opt_public, | |
76 | (void *)offsetof(transport_instance, headers_only) }, | |
77 | { "headers_remove", opt_stringptr|opt_public, | |
78 | (void *)offsetof(transport_instance, remove_headers) }, | |
79 | { "headers_rewrite", opt_rewrite|opt_public, | |
80 | (void *)offsetof(transport_instance, headers_rewrite) }, | |
81 | { "home_directory", opt_stringptr|opt_public, | |
82 | (void *)offsetof(transport_instance, home_dir) }, | |
83 | { "initgroups", opt_bool|opt_public, | |
84 | (void *)offsetof(transport_instance, initgroups) }, | |
85 | { "message_size_limit", opt_stringptr|opt_public, | |
86 | (void *)offsetof(transport_instance, message_size_limit) }, | |
87 | { "rcpt_include_affixes", opt_bool|opt_public, | |
88 | (void *)offsetof(transport_instance, rcpt_include_affixes) }, | |
89 | { "retry_use_local_part", opt_bool|opt_public, | |
90 | (void *)offsetof(transport_instance, retry_use_local_part) }, | |
91 | { "return_path", opt_stringptr|opt_public, | |
92 | (void *)(offsetof(transport_instance, return_path)) }, | |
93 | { "return_path_add", opt_bool|opt_public, | |
94 | (void *)(offsetof(transport_instance, return_path_add)) }, | |
95 | { "shadow_condition", opt_stringptr|opt_public, | |
96 | (void *)offsetof(transport_instance, shadow_condition) }, | |
97 | { "shadow_transport", opt_stringptr|opt_public, | |
98 | (void *)offsetof(transport_instance, shadow) }, | |
99 | { "transport_filter", opt_stringptr|opt_public, | |
100 | (void *)offsetof(transport_instance, filter_command) }, | |
101 | { "transport_filter_timeout", opt_time|opt_public, | |
102 | (void *)offsetof(transport_instance, filter_timeout) }, | |
103 | { "user", opt_expand_uid|opt_public, | |
104 | (void *)offsetof(transport_instance, uid) } | |
105 | }; | |
106 | ||
107 | int optionlist_transports_size = | |
108 | sizeof(optionlist_transports)/sizeof(optionlist); | |
109 | ||
110 | ||
111 | /************************************************* | |
112 | * Initialize transport list * | |
113 | *************************************************/ | |
114 | ||
115 | /* Read the transports section of the configuration file, and set up a chain of | |
116 | transport instances according to its contents. Each transport has generic | |
117 | options and may also have its own private options. This function is only ever | |
118 | called when transports == NULL. We use generic code in readconf to do most of | |
119 | the work. */ | |
120 | ||
121 | void | |
122 | transport_init(void) | |
123 | { | |
124 | transport_instance *t; | |
125 | ||
126 | readconf_driver_init(US"transport", | |
127 | (driver_instance **)(&transports), /* chain anchor */ | |
128 | (driver_info *)transports_available, /* available drivers */ | |
129 | sizeof(transport_info), /* size of info block */ | |
130 | &transport_defaults, /* default values for generic options */ | |
131 | sizeof(transport_instance), /* size of instance block */ | |
132 | optionlist_transports, /* generic options */ | |
133 | optionlist_transports_size); | |
134 | ||
135 | /* Now scan the configured transports and check inconsistencies. A shadow | |
136 | transport is permitted only for local transports. */ | |
137 | ||
138 | for (t = transports; t != NULL; t = t->next) | |
139 | { | |
140 | if (!t->info->local) | |
141 | { | |
142 | if (t->shadow != NULL) | |
143 | log_write(0, LOG_PANIC_DIE|LOG_CONFIG, | |
144 | "shadow transport not allowed on non-local transport %s", t->name); | |
145 | } | |
146 | ||
147 | if (t->body_only && t->headers_only) | |
148 | log_write(0, LOG_PANIC_DIE|LOG_CONFIG, | |
149 | "%s transport: body_only and headers_only are mutually exclusive", | |
150 | t->name); | |
151 | } | |
152 | } | |
153 | ||
154 | ||
155 | ||
156 | /************************************************* | |
157 | * Write block of data * | |
158 | *************************************************/ | |
159 | ||
160 | /* Subroutine called by write_chunk() and at the end of the message actually | |
161 | to write a data block. Also called directly by some transports to write | |
162 | additional data to the file descriptor (e.g. prefix, suffix). | |
163 | ||
164 | If a transport wants data transfers to be timed, it sets a non-zero value in | |
165 | transport_write_timeout. A non-zero transport_write_timeout causes a timer to | |
166 | be set for each block of data written from here. If time runs out, then write() | |
167 | fails and provokes an error return. The caller can then inspect sigalrm_seen to | |
168 | check for a timeout. | |
169 | ||
170 | On some systems, if a quota is exceeded during the write, the yield is the | |
171 | number of bytes written rather than an immediate error code. This also happens | |
172 | on some systems in other cases, for example a pipe that goes away because the | |
173 | other end's process terminates (Linux). On other systems, (e.g. Solaris 2) you | |
174 | get the error codes the first time. | |
175 | ||
176 | The write() function is also interruptible; the Solaris 2.6 man page says: | |
177 | ||
178 | If write() is interrupted by a signal before it writes any | |
179 | data, it will return -1 with errno set to EINTR. | |
180 | ||
181 | If write() is interrupted by a signal after it successfully | |
182 | writes some data, it will return the number of bytes written. | |
183 | ||
184 | To handle these cases, we want to restart the write() to output the remainder | |
185 | of the data after a non-negative return from write(), except after a timeout. | |
186 | In the error cases (EDQUOT, EPIPE) no bytes get written the second time, and a | |
187 | proper error then occurs. In principle, after an interruption, the second | |
188 | write() could suffer the same fate, but we do not want to continue for | |
189 | evermore, so stick a maximum repetition count on the loop to act as a | |
190 | longstop. | |
191 | ||
192 | Arguments: | |
193 | fd file descriptor to write to | |
194 | block block of bytes to write | |
195 | len number of bytes to write | |
196 | ||
197 | Returns: TRUE on success, FALSE on failure (with errno preserved); | |
198 | transport_count is incremented by the number of bytes written | |
199 | */ | |
200 | ||
201 | BOOL | |
202 | transport_write_block(int fd, uschar *block, int len) | |
203 | { | |
204 | int i, rc, save_errno; | |
958541e9 PH |
205 | int local_timeout = transport_write_timeout; |
206 | ||
207 | /* This loop is for handling incomplete writes and other retries. In most | |
208 | normal cases, it is only ever executed once. */ | |
059ec3d9 PH |
209 | |
210 | for (i = 0; i < 100; i++) | |
211 | { | |
212 | DEBUG(D_transport) | |
213 | debug_printf("writing data block fd=%d size=%d timeout=%d\n", | |
958541e9 | 214 | fd, len, local_timeout); |
059ec3d9 | 215 | |
958541e9 PH |
216 | /* This code makes use of alarm() in order to implement the timeout. This |
217 | isn't a very tidy way of doing things. Using non-blocking I/O with select() | |
218 | provides a neater approach. However, I don't know how to do this when TLS is | |
219 | in use. */ | |
059ec3d9 | 220 | |
958541e9 PH |
221 | if (transport_write_timeout <= 0) /* No timeout wanted */ |
222 | { | |
223 | #ifdef SUPPORT_TLS | |
224 | if (tls_active == fd) rc = tls_write(block, len); else | |
225 | #endif | |
226 | rc = write(fd, block, len); | |
227 | save_errno = errno; | |
228 | } | |
059ec3d9 | 229 | |
958541e9 | 230 | /* Timeout wanted. */ |
059ec3d9 | 231 | |
958541e9 | 232 | else |
059ec3d9 | 233 | { |
958541e9 PH |
234 | alarm(local_timeout); |
235 | #ifdef SUPPORT_TLS | |
236 | if (tls_active == fd) rc = tls_write(block, len); else | |
237 | #endif | |
238 | rc = write(fd, block, len); | |
239 | save_errno = errno; | |
240 | local_timeout = alarm(0); | |
059ec3d9 PH |
241 | if (sigalrm_seen) |
242 | { | |
243 | errno = ETIMEDOUT; | |
244 | return FALSE; | |
245 | } | |
246 | } | |
247 | ||
248 | /* Hopefully, the most common case is success, so test that first. */ | |
249 | ||
250 | if (rc == len) { transport_count += len; return TRUE; } | |
251 | ||
958541e9 PH |
252 | /* A non-negative return code is an incomplete write. Try again for the rest |
253 | of the block. If we have exactly hit the timeout, give up. */ | |
059ec3d9 PH |
254 | |
255 | if (rc >= 0) | |
256 | { | |
257 | len -= rc; | |
258 | block += rc; | |
259 | transport_count += rc; | |
260 | DEBUG(D_transport) debug_printf("write incomplete (%d)\n", rc); | |
958541e9 | 261 | goto CHECK_TIMEOUT; /* A few lines below */ |
059ec3d9 PH |
262 | } |
263 | ||
264 | /* A negative return code with an EINTR error is another form of | |
265 | incomplete write, zero bytes having been written */ | |
266 | ||
267 | if (save_errno == EINTR) | |
268 | { | |
269 | DEBUG(D_transport) | |
270 | debug_printf("write interrupted before anything written\n"); | |
958541e9 | 271 | goto CHECK_TIMEOUT; /* A few lines below */ |
059ec3d9 PH |
272 | } |
273 | ||
274 | /* A response of EAGAIN from write() is likely only in the case of writing | |
275 | to a FIFO that is not swallowing the data as fast as Exim is writing it. */ | |
276 | ||
277 | if (save_errno == EAGAIN) | |
278 | { | |
279 | DEBUG(D_transport) | |
280 | debug_printf("write temporarily locked out, waiting 1 sec\n"); | |
281 | sleep(1); | |
958541e9 PH |
282 | |
283 | /* Before continuing to try another write, check that we haven't run out of | |
284 | time. */ | |
285 | ||
286 | CHECK_TIMEOUT: | |
287 | if (transport_write_timeout > 0 && local_timeout <= 0) | |
288 | { | |
289 | errno = ETIMEDOUT; | |
290 | return FALSE; | |
291 | } | |
059ec3d9 PH |
292 | continue; |
293 | } | |
294 | ||
295 | /* Otherwise there's been an error */ | |
296 | ||
297 | DEBUG(D_transport) debug_printf("writing error %d: %s\n", save_errno, | |
298 | strerror(save_errno)); | |
299 | errno = save_errno; | |
300 | return FALSE; | |
301 | } | |
302 | ||
303 | /* We've tried and tried and tried but still failed */ | |
304 | ||
305 | errno = ERRNO_WRITEINCOMPLETE; | |
306 | return FALSE; | |
307 | } | |
308 | ||
309 | ||
310 | ||
311 | ||
312 | /************************************************* | |
313 | * Write formatted string * | |
314 | *************************************************/ | |
315 | ||
316 | /* This is called by various transports. It is a convenience function. | |
317 | ||
318 | Arguments: | |
319 | fd file descriptor | |
320 | format string format | |
321 | ... arguments for format | |
322 | ||
323 | Returns: the yield of transport_write_block() | |
324 | */ | |
325 | ||
326 | BOOL | |
327 | transport_write_string(int fd, char *format, ...) | |
328 | { | |
329 | va_list ap; | |
330 | va_start(ap, format); | |
331 | if (!string_vformat(big_buffer, big_buffer_size, format, ap)) | |
332 | log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong formatted string in transport"); | |
333 | va_end(ap); | |
334 | return transport_write_block(fd, big_buffer, Ustrlen(big_buffer)); | |
335 | } | |
336 | ||
337 | ||
338 | ||
339 | ||
340 | /************************************************* | |
341 | * Write character chunk * | |
342 | *************************************************/ | |
343 | ||
344 | /* Subroutine used by transport_write_message() to scan character chunks for | |
345 | newlines and act appropriately. The object is to minimise the number of writes. | |
346 | The output byte stream is buffered up in deliver_out_buffer, which is written | |
347 | only when it gets full, thus minimizing write operations and TCP packets. | |
348 | ||
349 | Static data is used to handle the case when the last character of the previous | |
350 | chunk was NL, or matched part of the data that has to be escaped. | |
351 | ||
352 | Arguments: | |
353 | fd file descript to write to | |
354 | chunk pointer to data to write | |
355 | len length of data to write | |
356 | usr_crlf TRUE if CR LF is wanted at the end of each line | |
357 | ||
358 | In addition, the static nl_xxx variables must be set as required. | |
359 | ||
360 | Returns: TRUE on success, FALSE on failure (with errno preserved) | |
361 | */ | |
362 | ||
363 | static BOOL | |
364 | write_chunk(int fd, uschar *chunk, int len, BOOL use_crlf) | |
365 | { | |
366 | uschar *start = chunk; | |
367 | uschar *end = chunk + len; | |
368 | register uschar *ptr; | |
369 | int mlen = DELIVER_OUT_BUFFER_SIZE - nl_escape_length - 2; | |
370 | ||
371 | /* The assumption is made that the check string will never stretch over move | |
372 | than one chunk since the only time there are partial matches is when copying | |
373 | the body in large buffers. There is always enough room in the buffer for an | |
374 | escape string, since the loop below ensures this for each character it | |
375 | processes, and it won't have stuck in the escape string if it left a partial | |
376 | match. */ | |
377 | ||
378 | if (nl_partial_match >= 0) | |
379 | { | |
380 | if (nl_check_length > 0 && len >= nl_check_length && | |
381 | Ustrncmp(start, nl_check + nl_partial_match, | |
382 | nl_check_length - nl_partial_match) == 0) | |
383 | { | |
384 | Ustrncpy(chunk_ptr, nl_escape, nl_escape_length); | |
385 | chunk_ptr += nl_escape_length; | |
386 | start += nl_check_length - nl_partial_match; | |
387 | } | |
388 | ||
389 | /* The partial match was a false one. Insert the characters carried over | |
390 | from the previous chunk. */ | |
391 | ||
392 | else if (nl_partial_match > 0) | |
393 | { | |
394 | Ustrncpy(chunk_ptr, nl_check, nl_partial_match); | |
395 | chunk_ptr += nl_partial_match; | |
396 | } | |
397 | ||
398 | nl_partial_match = -1; | |
399 | } | |
400 | ||
401 | /* Now process the characters in the chunk. Whenever we hit a newline we check | |
402 | for possible escaping. The code for the non-NL route should be as fast as | |
403 | possible. */ | |
404 | ||
405 | for (ptr = start; ptr < end; ptr++) | |
406 | { | |
407 | register int ch; | |
408 | ||
409 | /* Flush the buffer if it has reached the threshold - we want to leave enough | |
410 | room for the next uschar, plus a possible extra CR for an LF, plus the escape | |
411 | string. */ | |
412 | ||
413 | if (chunk_ptr - deliver_out_buffer > mlen) | |
414 | { | |
415 | if (!transport_write_block(fd, deliver_out_buffer, | |
416 | chunk_ptr - deliver_out_buffer)) | |
417 | return FALSE; | |
418 | chunk_ptr = deliver_out_buffer; | |
419 | } | |
420 | ||
421 | if ((ch = *ptr) == '\n') | |
422 | { | |
423 | int left = end - ptr - 1; /* count of chars left after NL */ | |
424 | ||
425 | /* Insert CR before NL if required */ | |
426 | ||
427 | if (use_crlf) *chunk_ptr++ = '\r'; | |
428 | *chunk_ptr++ = '\n'; | |
429 | ||
430 | /* The check_string test (formerly "from hack") replaces the specific | |
431 | string at the start of a line with an escape string (e.g. "From " becomes | |
432 | ">From " or "." becomes "..". It is a case-sensitive test. The length | |
433 | check above ensures there is always enough room to insert this string. */ | |
434 | ||
435 | if (nl_check_length > 0) | |
436 | { | |
437 | if (left >= nl_check_length && | |
438 | Ustrncmp(ptr+1, nl_check, nl_check_length) == 0) | |
439 | { | |
440 | Ustrncpy(chunk_ptr, nl_escape, nl_escape_length); | |
441 | chunk_ptr += nl_escape_length; | |
442 | ptr += nl_check_length; | |
443 | } | |
444 | ||
445 | /* Handle the case when there isn't enough left to match the whole | |
446 | check string, but there may be a partial match. We remember how many | |
447 | characters matched, and finish processing this chunk. */ | |
448 | ||
449 | else if (left <= 0) nl_partial_match = 0; | |
450 | ||
451 | else if (Ustrncmp(ptr+1, nl_check, left) == 0) | |
452 | { | |
453 | nl_partial_match = left; | |
454 | ptr = end; | |
455 | } | |
456 | } | |
457 | } | |
458 | ||
459 | /* Not a NL character */ | |
460 | ||
461 | else *chunk_ptr++ = ch; | |
462 | } | |
463 | ||
464 | return TRUE; | |
465 | } | |
466 | ||
467 | ||
468 | ||
469 | ||
470 | /************************************************* | |
471 | * Generate address for RCPT TO * | |
472 | *************************************************/ | |
473 | ||
474 | /* This function puts together an address for RCPT to, using the caseful | |
475 | version of the local part and the caseful version of the domain. If there is no | |
476 | prefix or suffix, or if affixes are to be retained, we can just use the | |
477 | original address. Otherwise, if there is a prefix but no suffix we can use a | |
478 | pointer into the original address. If there is a suffix, however, we have to | |
479 | build a new string. | |
480 | ||
481 | Arguments: | |
482 | addr the address item | |
483 | include_affixes TRUE if affixes are to be included | |
484 | ||
485 | Returns: a string | |
486 | */ | |
487 | ||
488 | uschar * | |
489 | transport_rcpt_address(address_item *addr, BOOL include_affixes) | |
490 | { | |
491 | uschar *at; | |
492 | int plen, slen; | |
493 | ||
494 | if (include_affixes) | |
495 | { | |
496 | setflag(addr, af_include_affixes); /* Affects logged => line */ | |
497 | return addr->address; | |
498 | } | |
499 | ||
500 | if (addr->suffix == NULL) | |
501 | { | |
502 | if (addr->prefix == NULL) return addr->address; | |
503 | return addr->address + Ustrlen(addr->prefix); | |
504 | } | |
505 | ||
506 | at = Ustrrchr(addr->address, '@'); | |
507 | plen = (addr->prefix == NULL)? 0 : Ustrlen(addr->prefix); | |
508 | slen = Ustrlen(addr->suffix); | |
509 | ||
510 | return string_sprintf("%.*s@%s", (at - addr->address - plen - slen), | |
511 | addr->address + plen, at + 1); | |
512 | } | |
513 | ||
514 | ||
515 | /************************************************* | |
516 | * Output Envelope-To: address & scan duplicates * | |
517 | *************************************************/ | |
518 | ||
519 | /* This function is called from internal_transport_write_message() below, when | |
520 | generating an Envelope-To: header line. It checks for duplicates of the given | |
521 | address and its ancestors. When one is found, this function calls itself | |
522 | recursively, to output the envelope address of the duplicate. | |
523 | ||
524 | We want to avoid duplication in the list, which can arise for example when | |
525 | A->B,C and then both B and C alias to D. This can also happen when there are | |
526 | unseen drivers in use. So a list of addresses that have been output is kept in | |
527 | the plist variable. | |
528 | ||
529 | It is also possible to have loops in the address ancestry/duplication graph, | |
530 | for example if there are two top level addresses A and B and we have A->B,C and | |
531 | B->A. To break the loop, we use a list of processed addresses in the dlist | |
532 | variable. | |
533 | ||
534 | After handling duplication, this function outputs the progenitor of the given | |
535 | address. | |
536 | ||
537 | Arguments: | |
538 | p the address we are interested in | |
539 | pplist address of anchor of the list of addresses not to output | |
540 | pdlist address of anchor of the list of processed addresses | |
541 | first TRUE if this is the first address; set it FALSE afterwards | |
542 | fd the file descriptor to write to | |
543 | use_crlf to be passed on to write_chunk() | |
544 | ||
545 | Returns: FALSE if writing failed | |
546 | */ | |
547 | ||
548 | static BOOL | |
549 | write_env_to(address_item *p, struct aci **pplist, struct aci **pdlist, | |
550 | BOOL *first, int fd, BOOL use_crlf) | |
551 | { | |
552 | address_item *pp; | |
553 | struct aci *ppp; | |
554 | ||
555 | /* Do nothing if we have already handled this address. If not, remember it | |
556 | so that we don't handle it again. */ | |
557 | ||
558 | for (ppp = *pdlist; ppp != NULL; ppp = ppp->next) | |
559 | { if (p == ppp->ptr) return TRUE; } | |
560 | ||
561 | ppp = store_get(sizeof(struct aci)); | |
562 | ppp->next = *pdlist; | |
563 | *pdlist = ppp; | |
564 | ppp->ptr = p; | |
565 | ||
566 | /* Now scan up the ancestry, checking for duplicates at each generation. */ | |
567 | ||
568 | for (pp = p;; pp = pp->parent) | |
569 | { | |
570 | address_item *dup; | |
571 | for (dup = addr_duplicate; dup != NULL; dup = dup->next) | |
572 | { | |
573 | if (dup->dupof != pp) continue; /* Not a dup of our address */ | |
574 | if (!write_env_to(dup, pplist, pdlist, first, fd, use_crlf)) return FALSE; | |
575 | } | |
576 | if (pp->parent == NULL) break; | |
577 | } | |
578 | ||
579 | /* Check to see if we have already output the progenitor. */ | |
580 | ||
581 | for (ppp = *pplist; ppp != NULL; ppp = ppp->next) | |
582 | { if (pp == ppp->ptr) break; } | |
583 | if (ppp != NULL) return TRUE; | |
584 | ||
585 | /* Remember what we have output, and output it. */ | |
586 | ||
587 | ppp = store_get(sizeof(struct aci)); | |
588 | ppp->next = *pplist; | |
589 | *pplist = ppp; | |
590 | ppp->ptr = pp; | |
591 | ||
592 | if (!(*first) && !write_chunk(fd, US",\n ", 3, use_crlf)) return FALSE; | |
593 | *first = FALSE; | |
594 | return write_chunk(fd, pp->address, Ustrlen(pp->address), use_crlf); | |
595 | } | |
596 | ||
597 | ||
598 | ||
599 | ||
600 | /************************************************* | |
601 | * Write the message * | |
602 | *************************************************/ | |
603 | ||
604 | /* This function writes the message to the given file descriptor. The headers | |
605 | are in the in-store data structure, and the rest of the message is in the open | |
606 | file descriptor deliver_datafile. Make sure we start it at the beginning. | |
607 | ||
608 | . If add_return_path is TRUE, a "return-path:" header is added to the message, | |
609 | containing the envelope sender's address. | |
610 | ||
611 | . If add_envelope_to is TRUE, a "envelope-to:" header is added to the message, | |
612 | giving the top-level envelope address that caused this delivery to happen. | |
613 | ||
614 | . If add_delivery_date is TRUE, a "delivery-date:" header is added to the | |
615 | message. It gives the time and date that delivery took place. | |
616 | ||
617 | . If check_string is not null, the start of each line is checked for that | |
618 | string. If it is found, it is replaced by escape_string. This used to be | |
619 | the "from hack" for files, and "smtp_dots" for escaping SMTP dots. | |
620 | ||
621 | . If use_crlf is true, newlines are turned into CRLF (SMTP output). | |
622 | ||
623 | The yield is TRUE if all went well, and FALSE if not. Exit *immediately* after | |
624 | any writing or reading error, leaving the code in errno intact. Error exits | |
625 | can include timeouts for certain transports, which are requested by setting | |
626 | transport_write_timeout non-zero. | |
627 | ||
628 | Arguments: | |
629 | addr (chain of) addresses (for extra headers), or NULL; | |
630 | only the first address is used | |
631 | fd file descriptor to write the message to | |
632 | options bit-wise options: | |
633 | add_return_path if TRUE, add a "return-path" header | |
634 | add_envelope_to if TRUE, add a "envelope-to" header | |
635 | add_delivery_date if TRUE, add a "delivery-date" header | |
636 | use_crlf if TRUE, turn NL into CR LF | |
637 | end_dot if TRUE, send a terminating "." line at the end | |
638 | no_headers if TRUE, omit the headers | |
639 | no_body if TRUE, omit the body | |
640 | size_limit if > 0, this is a limit to the size of message written; | |
641 | it is used when returning messages to their senders, | |
642 | and is approximate rather than exact, owing to chunk | |
643 | buffering | |
644 | add_headers a string containing one or more headers to add; it is | |
645 | expanded, and must be in correct RFC 822 format as | |
646 | it is transmitted verbatim; NULL => no additions, | |
647 | and so does empty string or forced expansion fail | |
648 | remove_headers a colon-separated list of headers to remove, or NULL | |
649 | check_string a string to check for at the start of lines, or NULL | |
650 | escape_string a string to insert in front of any check string | |
651 | rewrite_rules chain of header rewriting rules | |
652 | rewrite_existflags flags for the rewriting rules | |
653 | ||
654 | Returns: TRUE on success; FALSE (with errno) on failure. | |
655 | In addition, the global variable transport_count | |
656 | is incremented by the number of bytes written. | |
657 | */ | |
658 | ||
659 | static BOOL | |
660 | internal_transport_write_message(address_item *addr, int fd, int options, | |
661 | int size_limit, uschar *add_headers, uschar *remove_headers, uschar *check_string, | |
662 | uschar *escape_string, rewrite_rule *rewrite_rules, int rewrite_existflags) | |
663 | { | |
664 | int written = 0; | |
665 | int len; | |
666 | header_line *h; | |
667 | BOOL use_crlf = (options & topt_use_crlf) != 0; | |
668 | ||
669 | /* Initialize pointer in output buffer. */ | |
670 | ||
671 | chunk_ptr = deliver_out_buffer; | |
672 | ||
673 | /* Set up the data for start-of-line data checking and escaping */ | |
674 | ||
675 | nl_partial_match = -1; | |
676 | if (check_string != NULL && escape_string != NULL) | |
677 | { | |
678 | nl_check = check_string; | |
679 | nl_check_length = Ustrlen(nl_check); | |
680 | nl_escape = escape_string; | |
681 | nl_escape_length = Ustrlen(nl_escape); | |
682 | } | |
683 | else nl_check_length = nl_escape_length = 0; | |
684 | ||
685 | /* Whether the escaping mechanism is applied to headers or not is controlled by | |
686 | an option (set for SMTP, not otherwise). Negate the length if not wanted till | |
687 | after the headers. */ | |
688 | ||
689 | if ((options & topt_escape_headers) == 0) nl_check_length = -nl_check_length; | |
690 | ||
691 | /* Write the headers if required, including any that have to be added. If there | |
692 | are header rewriting rules, apply them. */ | |
693 | ||
694 | if ((options & topt_no_headers) == 0) | |
695 | { | |
696 | /* Add return-path: if requested. */ | |
697 | ||
698 | if ((options & topt_add_return_path) != 0) | |
699 | { | |
700 | uschar buffer[ADDRESS_MAXLENGTH + 20]; | |
701 | sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH, | |
702 | return_path); | |
703 | if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE; | |
704 | } | |
705 | ||
706 | /* Add envelope-to: if requested */ | |
707 | ||
708 | if ((options & topt_add_envelope_to) != 0) | |
709 | { | |
710 | BOOL first = TRUE; | |
711 | address_item *p; | |
712 | struct aci *plist = NULL; | |
713 | struct aci *dlist = NULL; | |
714 | void *reset_point = store_get(0); | |
715 | ||
716 | if (!write_chunk(fd, US"Envelope-to: ", 13, use_crlf)) return FALSE; | |
717 | ||
718 | /* Pick up from all the addresses. The plist and dlist variables are | |
719 | anchors for lists of addresses already handled; they have to be defined at | |
720 | this level becuase write_env_to() calls itself recursively. */ | |
721 | ||
722 | for (p = addr; p != NULL; p = p->next) | |
723 | { | |
724 | if (!write_env_to(p, &plist, &dlist, &first, fd, use_crlf)) return FALSE; | |
725 | } | |
726 | ||
727 | /* Add a final newline and reset the store used for tracking duplicates */ | |
728 | ||
729 | if (!write_chunk(fd, US"\n", 1, use_crlf)) return FALSE; | |
730 | store_reset(reset_point); | |
731 | } | |
732 | ||
733 | /* Add delivery-date: if requested. */ | |
734 | ||
735 | if ((options & topt_add_delivery_date) != 0) | |
736 | { | |
737 | uschar buffer[100]; | |
738 | sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full)); | |
739 | if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE; | |
740 | } | |
741 | ||
742 | /* Then the message's headers. Don't write any that are flagged as "old"; | |
743 | that means they were rewritten, or are a record of envelope rewriting, or | |
744 | were removed (e.g. Bcc). If remove_headers is not null, skip any headers that | |
745 | match any entries therein. Then check addr->p.remove_headers too, provided that | |
746 | addr is not NULL. */ | |
747 | ||
748 | if (remove_headers != NULL) | |
749 | { | |
750 | uschar *s = expand_string(remove_headers); | |
751 | if (s == NULL && !expand_string_forcedfail) | |
752 | { | |
753 | errno = ERRNO_CHHEADER_FAIL; | |
754 | return FALSE; | |
755 | } | |
756 | remove_headers = s; | |
757 | } | |
758 | ||
759 | for (h = header_list; h != NULL; h = h->next) | |
760 | { | |
761 | int i; | |
762 | uschar *list = NULL; | |
763 | BOOL include_header; | |
764 | ||
765 | if (h->type == htype_old) continue; | |
766 | ||
767 | include_header = TRUE; | |
768 | list = remove_headers; | |
769 | ||
770 | for (i = 0; i < 2; i++) /* For remove_headers && addr->p.remove_headers */ | |
771 | { | |
772 | if (list != NULL) | |
773 | { | |
774 | int sep = ':'; /* This is specified as a colon-separated list */ | |
775 | uschar *s, *ss; | |
776 | uschar buffer[128]; | |
777 | while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) | |
778 | != NULL) | |
779 | { | |
780 | int len = Ustrlen(s); | |
781 | if (strncmpic(h->text, s, len) != 0) continue; | |
782 | ss = h->text + len; | |
783 | while (*ss == ' ' || *ss == '\t') ss++; | |
784 | if (*ss == ':') break; | |
785 | } | |
786 | if (s != NULL) { include_header = FALSE; break; } | |
787 | } | |
788 | if (addr != NULL) list = addr->p.remove_headers; | |
789 | } | |
790 | ||
791 | /* If this header is to be output, try to rewrite it if there are rewriting | |
792 | rules. */ | |
793 | ||
794 | if (include_header) | |
795 | { | |
796 | if (rewrite_rules != NULL) | |
797 | { | |
798 | void *reset_point = store_get(0); | |
799 | header_line *hh = | |
800 | rewrite_header(h, NULL, NULL, rewrite_rules, rewrite_existflags, | |
801 | FALSE); | |
802 | if (hh != NULL) | |
803 | { | |
804 | if (!write_chunk(fd, hh->text, hh->slen, use_crlf)) return FALSE; | |
805 | store_reset(reset_point); | |
806 | continue; /* With the next header line */ | |
807 | } | |
808 | } | |
809 | ||
810 | /* Either no rewriting rules, or it didn't get rewritten */ | |
811 | ||
812 | if (!write_chunk(fd, h->text, h->slen, use_crlf)) return FALSE; | |
813 | } | |
814 | ||
815 | /* Header removed */ | |
816 | ||
817 | else | |
818 | { | |
819 | DEBUG(D_transport) debug_printf("removed header line:\n%s---\n", | |
820 | h->text); | |
821 | } | |
822 | } | |
823 | ||
824 | /* Add on any address-specific headers. If there are multiple addresses, | |
825 | they will all have the same headers in order to be batched. The headers | |
826 | are chained in reverse order of adding (so several addresses from the | |
827 | same alias might share some of them) but we want to output them in the | |
828 | opposite order. This is a bit tedious, but there shouldn't be very many | |
829 | of them. We just walk the list twice, reversing the pointers each time, | |
7999bbd7 PH |
830 | but on the second time, write out the items. |
831 | ||
832 | Headers added to an address by a router are guaranteed to end with a newline. | |
833 | */ | |
059ec3d9 PH |
834 | |
835 | if (addr != NULL) | |
836 | { | |
837 | int i; | |
838 | header_line *hprev = addr->p.extra_headers; | |
839 | header_line *hnext; | |
840 | for (i = 0; i < 2; i++) | |
841 | { | |
842 | for (h = hprev, hprev = NULL; h != NULL; h = hnext) | |
843 | { | |
844 | hnext = h->next; | |
845 | h->next = hprev; | |
846 | hprev = h; | |
847 | if (i == 1) | |
848 | { | |
849 | if (!write_chunk(fd, h->text, h->slen, use_crlf)) return FALSE; | |
850 | DEBUG(D_transport) | |
851 | debug_printf("added header line(s):\n%s---\n", h->text); | |
852 | } | |
853 | } | |
854 | } | |
855 | } | |
856 | ||
857 | /* If a string containing additional headers exists, expand it and write | |
858 | out the result. This is done last so that if it (deliberately or accidentally) | |
859 | isn't in header format, it won't mess up any other headers. An empty string | |
7999bbd7 PH |
860 | or a forced expansion failure are noops. An added header string from a |
861 | transport may not end with a newline; add one if it does not. */ | |
059ec3d9 PH |
862 | |
863 | if (add_headers != NULL) | |
864 | { | |
865 | uschar *s = expand_string(add_headers); | |
866 | if (s == NULL) | |
867 | { | |
868 | if (!expand_string_forcedfail) | |
869 | { | |
870 | errno = ERRNO_CHHEADER_FAIL; | |
871 | return FALSE; | |
872 | } | |
873 | } | |
874 | else | |
875 | { | |
876 | int len = Ustrlen(s); | |
877 | if (len > 0) | |
878 | { | |
879 | if (!write_chunk(fd, s, len, use_crlf)) return FALSE; | |
880 | if (s[len-1] != '\n' && !write_chunk(fd, US"\n", 1, use_crlf)) | |
881 | return FALSE; | |
882 | DEBUG(D_transport) | |
7999bbd7 PH |
883 | { |
884 | debug_printf("added header line(s):\n%s", s); | |
885 | if (s[len-1] != '\n') debug_printf("\n"); | |
886 | debug_printf("---\n"); | |
887 | } | |
059ec3d9 PH |
888 | } |
889 | } | |
890 | } | |
891 | ||
892 | /* Separate headers from body with a blank line */ | |
893 | ||
894 | if (!write_chunk(fd, US"\n", 1, use_crlf)) return FALSE; | |
895 | } | |
896 | ||
897 | /* If the body is required, ensure that the data for check strings (formerly | |
898 | the "from hack") is enabled by negating the length if necessary. (It will be | |
899 | negative in cases where it isn't to apply to the headers). Then ensure the body | |
900 | is positioned at the start of its file (following the message id), then write | |
901 | it, applying the size limit if required. */ | |
902 | ||
903 | if ((options & topt_no_body) == 0) | |
904 | { | |
905 | nl_check_length = abs(nl_check_length); | |
906 | nl_partial_match = 0; | |
907 | lseek(deliver_datafile, SPOOL_DATA_START_OFFSET, SEEK_SET); | |
908 | while ((len = read(deliver_datafile, deliver_in_buffer, | |
909 | DELIVER_IN_BUFFER_SIZE)) > 0) | |
910 | { | |
911 | if (!write_chunk(fd, deliver_in_buffer, len, use_crlf)) return FALSE; | |
912 | if (size_limit > 0) | |
913 | { | |
914 | written += len; | |
915 | if (written > size_limit) | |
916 | { | |
917 | len = 0; /* Pretend EOF */ | |
918 | break; | |
919 | } | |
920 | } | |
921 | } | |
922 | ||
923 | /* Finished with the check string */ | |
924 | ||
925 | nl_check_length = nl_escape_length = 0; | |
926 | ||
927 | /* A read error on the body will have left len == -1 and errno set. */ | |
928 | ||
929 | if (len != 0) return FALSE; | |
930 | ||
931 | /* If requested, add a terminating "." line (SMTP output). */ | |
932 | ||
933 | if ((options & topt_end_dot) != 0 && !write_chunk(fd, US".\n", 2, use_crlf)) | |
934 | return FALSE; | |
935 | } | |
936 | ||
937 | /* Write out any remaining data in the buffer before returning. */ | |
938 | ||
939 | return (len = chunk_ptr - deliver_out_buffer) <= 0 || | |
940 | transport_write_block(fd, deliver_out_buffer, len); | |
941 | } | |
942 | ||
943 | ||
fb2274d4 TK |
944 | #ifdef EXPERIMENTAL_DOMAINKEYS |
945 | ||
946 | /********************************************************************************** | |
947 | * External interface to write the message, while signing it with domainkeys * | |
948 | **********************************************************************************/ | |
949 | ||
950 | /* This function is a wrapper around transport_write_message(). It is only called | |
951 | from the smtp transport if | |
952 | (1) Domainkeys support is compiled in. | |
953 | (2) The dk_private_key option on the smtp transport is set. | |
954 | The function sets up a replacement fd into a -K file, then calls the normal | |
955 | function. This way, the exact bits that exim would have put "on the wire" will | |
956 | end up in the file (except for TLS encapsulation, which is the very | |
957 | very last thing). When we are done signing the file, send the | |
958 | signed message down the original fd (or TLS fd). | |
959 | ||
960 | Arguments: as for internal_transport_write_message() above, with additional | |
84330b7b | 961 | arguments: |
fb2274d4 TK |
962 | uschar *dk_private_key The private key to use (filename or plain data) |
963 | uschar *dk_domain Override domain (normally NULL) | |
964 | uschar *dk_selector The selector to use. | |
965 | uschar *dk_canon The canonalization scheme to use, "simple" or "nofws" | |
966 | uschar *dk_headers Colon-separated header list to include in the signing | |
967 | process. | |
968 | uschar *dk_strict What to do if signing fails: 1/true => throw error | |
969 | 0/false => send anyway | |
970 | ||
971 | Returns: TRUE on success; FALSE (with errno) for any failure | |
972 | */ | |
973 | ||
974 | BOOL | |
975 | dk_transport_write_message(address_item *addr, int fd, int options, | |
976 | int size_limit, uschar *add_headers, uschar *remove_headers, | |
977 | uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules, | |
978 | int rewrite_existflags, uschar *dk_private_key, uschar *dk_domain, | |
979 | uschar *dk_selector, uschar *dk_canon, uschar *dk_headers, uschar *dk_strict) | |
980 | { | |
981 | int dk_fd; | |
982 | int save_errno = 0; | |
983 | BOOL rc; | |
984 | uschar dk_spool_name[256]; | |
985 | char sbuf[2048]; | |
986 | int sread = 0; | |
987 | int wwritten = 0; | |
988 | uschar *dk_signature = NULL; | |
a8530a10 | 989 | off_t size = 0; |
84330b7b | 990 | |
a8530a10 TK |
991 | (void)string_format(dk_spool_name, 256, "%s/input/%s/%s-%d-K", |
992 | spool_directory, message_subdir, message_id, (int)getpid()); | |
993 | dk_fd = Uopen(dk_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE); | |
fb2274d4 TK |
994 | if (dk_fd < 0) |
995 | { | |
996 | /* Can't create spool file. Ugh. */ | |
997 | rc = FALSE; | |
998 | save_errno = errno; | |
999 | goto CLEANUP; | |
1000 | } | |
84330b7b | 1001 | |
fb2274d4 TK |
1002 | /* Call original function */ |
1003 | rc = transport_write_message(addr, dk_fd, options, | |
1004 | size_limit, add_headers, remove_headers, | |
1005 | check_string, escape_string, rewrite_rules, | |
1006 | rewrite_existflags); | |
84330b7b | 1007 | |
fb2274d4 TK |
1008 | /* Save error state. We must clean up before returning. */ |
1009 | if (!rc) | |
1010 | { | |
1011 | save_errno = errno; | |
1012 | goto CLEANUP; | |
1013 | } | |
1014 | ||
1015 | /* Rewind file and feed it to the goats^W DK lib */ | |
1016 | lseek(dk_fd, 0, SEEK_SET); | |
1017 | dk_signature = dk_exim_sign(dk_fd, | |
1018 | dk_private_key, | |
1019 | dk_domain, | |
1020 | dk_selector, | |
1021 | dk_canon); | |
84330b7b | 1022 | |
fb2274d4 TK |
1023 | if (dk_signature != NULL) |
1024 | { | |
1025 | /* Send the signature first */ | |
1026 | int siglen = Ustrlen(dk_signature); | |
1027 | while(siglen > 0) | |
1028 | { | |
1029 | #ifdef SUPPORT_TLS | |
1030 | if (tls_active == fd) wwritten = tls_write(dk_signature, siglen); else | |
1031 | #endif | |
1032 | wwritten = write(fd,dk_signature,siglen); | |
1033 | if (wwritten == -1) | |
1034 | { | |
1035 | /* error, bail out */ | |
1036 | save_errno = errno; | |
1037 | rc = FALSE; | |
1038 | goto CLEANUP; | |
1039 | } | |
1040 | siglen -= wwritten; | |
1041 | dk_signature += wwritten; | |
1042 | } | |
1043 | } | |
1044 | else if (dk_strict != NULL) | |
1045 | { | |
1046 | uschar *dk_strict_result = expand_string(dk_strict); | |
1047 | if (dk_strict_result != NULL) | |
1048 | { | |
a8d97c8a PH |
1049 | if ( (strcmpic(dk_strict,US"1") == 0) || |
1050 | (strcmpic(dk_strict,US"true") == 0) ) | |
fb2274d4 TK |
1051 | { |
1052 | save_errno = errno; | |
1053 | rc = FALSE; | |
1054 | goto CLEANUP; | |
1055 | } | |
1056 | } | |
1057 | } | |
1058 | ||
a8530a10 TK |
1059 | /* Fetch file positition (the size) */ |
1060 | size = lseek(dk_fd,0,SEEK_CUR); | |
1061 | ||
1062 | /* Rewind file */ | |
fb2274d4 | 1063 | lseek(dk_fd, 0, SEEK_SET); |
84330b7b | 1064 | |
a8530a10 TK |
1065 | #ifdef HAVE_LINUX_SENDFILE |
1066 | /* We can use sendfile() to shove the file contents | |
1067 | to the socket. However only if we don't use TLS, | |
1068 | in which case theres another layer of indirection | |
1069 | before the data finally hits the socket. */ | |
1070 | if (tls_active != fd) | |
1071 | { | |
1072 | ssize_t copied = 0; | |
1073 | off_t offset = 0; | |
1074 | while((copied >= 0) && (offset<size)) | |
1075 | { | |
1076 | copied = sendfile(fd, dk_fd, &offset, (size - offset)); | |
1077 | } | |
1078 | if (copied < 0) | |
1079 | { | |
1080 | save_errno = errno; | |
1081 | rc = FALSE; | |
1082 | } | |
1083 | goto CLEANUP; | |
1084 | } | |
1085 | #endif | |
1086 | ||
1087 | /* Send file down the original fd */ | |
fb2274d4 TK |
1088 | while((sread = read(dk_fd,sbuf,2048)) > 0) |
1089 | { | |
1090 | char *p = sbuf; | |
1091 | /* write the chunk */ | |
1092 | DK_WRITE: | |
1093 | #ifdef SUPPORT_TLS | |
a8d97c8a | 1094 | if (tls_active == fd) wwritten = tls_write(US p, sread); else |
fb2274d4 TK |
1095 | #endif |
1096 | wwritten = write(fd,p,sread); | |
1097 | if (wwritten == -1) | |
1098 | { | |
1099 | /* error, bail out */ | |
1100 | save_errno = errno; | |
1101 | rc = FALSE; | |
1102 | goto CLEANUP; | |
1103 | } | |
1104 | if (wwritten < sread) | |
1105 | { | |
1106 | /* short write, try again */ | |
1107 | p += wwritten; | |
1108 | sread -= wwritten; | |
1109 | goto DK_WRITE; | |
1110 | } | |
1111 | } | |
84330b7b | 1112 | |
fb2274d4 TK |
1113 | if (sread == -1) |
1114 | { | |
1115 | save_errno = errno; | |
1116 | rc = FALSE; | |
1117 | goto CLEANUP; | |
1118 | } | |
1119 | ||
fb2274d4 TK |
1120 | CLEANUP: |
1121 | /* unlink -K file */ | |
f1e894f3 | 1122 | (void)close(dk_fd); |
fb2274d4 TK |
1123 | Uunlink(dk_spool_name); |
1124 | errno = save_errno; | |
1125 | return rc; | |
1126 | } | |
1127 | #endif | |
059ec3d9 PH |
1128 | |
1129 | ||
1130 | /************************************************* | |
1131 | * External interface to write the message * | |
1132 | *************************************************/ | |
1133 | ||
1134 | /* If there is no filtering required, call the internal function above to do | |
1135 | the real work, passing over all the arguments from this function. Otherwise, | |
1136 | set up a filtering process, fork another process to call the internal function | |
1137 | to write to the filter, and in this process just suck from the filter and write | |
1138 | down the given fd. At the end, tidy up the pipes and the processes. | |
1139 | ||
1140 | Arguments: as for internal_transport_write_message() above | |
1141 | ||
1142 | Returns: TRUE on success; FALSE (with errno) for any failure | |
1143 | transport_count is incremented by the number of bytes written | |
1144 | */ | |
1145 | ||
1146 | BOOL | |
1147 | transport_write_message(address_item *addr, int fd, int options, | |
1148 | int size_limit, uschar *add_headers, uschar *remove_headers, | |
1149 | uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules, | |
1150 | int rewrite_existflags) | |
1151 | { | |
1152 | BOOL use_crlf; | |
1153 | BOOL last_filter_was_NL = TRUE; | |
1154 | int rc, len, yield, fd_read, fd_write, save_errno; | |
1155 | int pfd[2]; | |
1156 | pid_t filter_pid, write_pid; | |
1157 | ||
2e2a30b4 PH |
1158 | transport_filter_timed_out = FALSE; |
1159 | ||
059ec3d9 PH |
1160 | /* If there is no filter command set up, call the internal function that does |
1161 | the actual work, passing it the incoming fd, and return its result. */ | |
1162 | ||
1163 | if (transport_filter_argv == NULL) | |
1164 | return internal_transport_write_message(addr, fd, options, size_limit, | |
1165 | add_headers, remove_headers, check_string, escape_string, | |
1166 | rewrite_rules, rewrite_existflags); | |
1167 | ||
1168 | /* Otherwise the message must be written to a filter process and read back | |
1169 | before being written to the incoming fd. First set up the special processing to | |
1170 | be done during the copying. */ | |
1171 | ||
1172 | use_crlf = (options & topt_use_crlf) != 0; | |
1173 | nl_partial_match = -1; | |
1174 | ||
1175 | if (check_string != NULL && escape_string != NULL) | |
1176 | { | |
1177 | nl_check = check_string; | |
1178 | nl_check_length = Ustrlen(nl_check); | |
1179 | nl_escape = escape_string; | |
1180 | nl_escape_length = Ustrlen(nl_escape); | |
1181 | } | |
1182 | else nl_check_length = nl_escape_length = 0; | |
1183 | ||
1184 | /* Start up a subprocess to run the command. Ensure that our main fd will | |
1185 | be closed when the subprocess execs, but remove the flag afterwards. | |
1186 | (Otherwise, if this is a TCP/IP socket, it can't get passed on to another | |
1187 | process to deliver another message.) We get back stdin/stdout file descriptors. | |
1188 | If the process creation failed, give an error return. */ | |
1189 | ||
1190 | fd_read = -1; | |
1191 | fd_write = -1; | |
1192 | save_errno = 0; | |
1193 | yield = FALSE; | |
1194 | write_pid = (pid_t)(-1); | |
1195 | ||
ff790e47 | 1196 | (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); |
059ec3d9 PH |
1197 | filter_pid = child_open(transport_filter_argv, NULL, 077, &fd_write, &fd_read, |
1198 | FALSE); | |
ff790e47 | 1199 | (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC); |
059ec3d9 PH |
1200 | if (filter_pid < 0) goto TIDY_UP; /* errno set */ |
1201 | ||
1202 | DEBUG(D_transport) | |
1203 | debug_printf("process %d running as transport filter: write=%d read=%d\n", | |
1204 | (int)filter_pid, fd_write, fd_read); | |
1205 | ||
1206 | /* Fork subprocess to write the message to the filter, and return the result | |
1207 | via a(nother) pipe. While writing to the filter, we do not do the CRLF, | |
1208 | smtp dots, or check string processing. */ | |
1209 | ||
1210 | if (pipe(pfd) != 0) goto TIDY_UP; /* errno set */ | |
1211 | if ((write_pid = fork()) == 0) | |
1212 | { | |
1213 | BOOL rc; | |
f1e894f3 PH |
1214 | (void)close(fd_read); |
1215 | (void)close(pfd[pipe_read]); | |
059ec3d9 PH |
1216 | nl_check_length = nl_escape_length = 0; |
1217 | rc = internal_transport_write_message(addr, fd_write, | |
1218 | (options & ~(topt_use_crlf | topt_end_dot)), | |
1219 | size_limit, add_headers, remove_headers, NULL, NULL, | |
1220 | rewrite_rules, rewrite_existflags); | |
1221 | save_errno = errno; | |
f1e894f3 PH |
1222 | (void)write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)); |
1223 | (void)write(pfd[pipe_write], (void *)&save_errno, sizeof(int)); | |
1224 | (void)write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int)); | |
059ec3d9 PH |
1225 | _exit(0); |
1226 | } | |
1227 | save_errno = errno; | |
1228 | ||
1229 | /* Parent process: close our copy of the writing subprocess' pipes. */ | |
1230 | ||
f1e894f3 PH |
1231 | (void)close(pfd[pipe_write]); |
1232 | (void)close(fd_write); | |
059ec3d9 PH |
1233 | fd_write = -1; |
1234 | ||
1235 | /* Writing process creation failed */ | |
1236 | ||
1237 | if (write_pid < 0) | |
1238 | { | |
1239 | errno = save_errno; /* restore */ | |
1240 | goto TIDY_UP; | |
1241 | } | |
1242 | ||
1243 | /* When testing, let the subprocess get going */ | |
1244 | ||
1245 | if (running_in_test_harness) millisleep(250); | |
1246 | ||
1247 | DEBUG(D_transport) | |
1248 | debug_printf("process %d writing to transport filter\n", (int)write_pid); | |
1249 | ||
1250 | /* Copy the message from the filter to the output fd. A read error leaves len | |
1251 | == -1 and errno set. We need to apply a timeout to the read, to cope with | |
1252 | the case when the filter gets stuck, but it can be quite a long one. The | |
1253 | default is 5m, but this is now configurable. */ | |
1254 | ||
1255 | DEBUG(D_transport) debug_printf("copying from the filter\n"); | |
1256 | ||
1257 | /* Copy the output of the filter, remembering if the last character was NL. If | |
1258 | no data is returned, that counts as "ended with NL" (default setting of the | |
1259 | variable is TRUE). */ | |
1260 | ||
1261 | chunk_ptr = deliver_out_buffer; | |
1262 | ||
1263 | for (;;) | |
1264 | { | |
1265 | sigalrm_seen = FALSE; | |
1266 | alarm(transport_filter_timeout); | |
1267 | len = read(fd_read, deliver_in_buffer, DELIVER_IN_BUFFER_SIZE); | |
1268 | alarm(0); | |
1269 | if (sigalrm_seen) | |
1270 | { | |
1271 | errno = ETIMEDOUT; | |
2e2a30b4 | 1272 | transport_filter_timed_out = TRUE; |
059ec3d9 PH |
1273 | goto TIDY_UP; |
1274 | } | |
1275 | ||
1276 | /* If the read was successful, write the block down the original fd, | |
1277 | remembering whether it ends in \n or not. */ | |
1278 | ||
1279 | if (len > 0) | |
1280 | { | |
1281 | if (!write_chunk(fd, deliver_in_buffer, len, use_crlf)) goto TIDY_UP; | |
1282 | last_filter_was_NL = (deliver_in_buffer[len-1] == '\n'); | |
1283 | } | |
1284 | ||
1285 | /* Otherwise, break the loop. If we have hit EOF, set yield = TRUE. */ | |
1286 | ||
1287 | else | |
1288 | { | |
1289 | if (len == 0) yield = TRUE; | |
1290 | break; | |
1291 | } | |
1292 | } | |
1293 | ||
1294 | /* Tidying up code. If yield = FALSE there has been an error and errno is set | |
1295 | to something. Ensure the pipes are all closed and the processes are removed. If | |
1296 | there has been an error, kill the processes before waiting for them, just to be | |
1297 | sure. Also apply a paranoia timeout. */ | |
1298 | ||
1299 | TIDY_UP: | |
1300 | save_errno = errno; | |
1301 | ||
f1e894f3 PH |
1302 | (void)close(fd_read); |
1303 | if (fd_write > 0) (void)close(fd_write); | |
059ec3d9 PH |
1304 | |
1305 | if (!yield) | |
1306 | { | |
1307 | if (filter_pid > 0) kill(filter_pid, SIGKILL); | |
1308 | if (write_pid > 0) kill(write_pid, SIGKILL); | |
1309 | } | |
1310 | ||
1311 | /* Wait for the filter process to complete. */ | |
1312 | ||
1313 | DEBUG(D_transport) debug_printf("waiting for filter process\n"); | |
1314 | if (filter_pid > 0 && (rc = child_close(filter_pid, 30)) != 0 && yield) | |
1315 | { | |
1316 | yield = FALSE; | |
1317 | save_errno = ERRNO_FILTER_FAIL; | |
1318 | addr->more_errno = rc; | |
1319 | DEBUG(D_transport) debug_printf("filter process returned %d\n", rc); | |
1320 | } | |
1321 | ||
1322 | /* Wait for the writing process to complete. If it ends successfully, | |
8e669ac1 | 1323 | read the results from its pipe, provided we haven't already had a filter |
35af9f61 | 1324 | process failure. */ |
059ec3d9 PH |
1325 | |
1326 | DEBUG(D_transport) debug_printf("waiting for writing process\n"); | |
1327 | if (write_pid > 0) | |
1328 | { | |
35af9f61 PH |
1329 | rc = child_close(write_pid, 30); |
1330 | if (yield) | |
059ec3d9 | 1331 | { |
8e669ac1 | 1332 | if (rc == 0) |
35af9f61 PH |
1333 | { |
1334 | BOOL ok; | |
f1e894f3 | 1335 | (void)read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)); |
35af9f61 PH |
1336 | if (!ok) |
1337 | { | |
f1e894f3 PH |
1338 | (void)read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); |
1339 | (void)read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int)); | |
35af9f61 PH |
1340 | yield = FALSE; |
1341 | } | |
1342 | } | |
1343 | else | |
059ec3d9 | 1344 | { |
059ec3d9 | 1345 | yield = FALSE; |
35af9f61 PH |
1346 | save_errno = ERRNO_FILTER_FAIL; |
1347 | addr->more_errno = rc; | |
1348 | DEBUG(D_transport) debug_printf("writing process returned %d\n", rc); | |
059ec3d9 | 1349 | } |
8e669ac1 | 1350 | } |
059ec3d9 | 1351 | } |
f1e894f3 | 1352 | (void)close(pfd[pipe_read]); |
059ec3d9 PH |
1353 | |
1354 | /* If there have been no problems we can now add the terminating "." if this is | |
1355 | SMTP output, turning off escaping beforehand. If the last character from the | |
1356 | filter was not NL, insert a NL to make the SMTP protocol work. */ | |
1357 | ||
1358 | if (yield) | |
1359 | { | |
1360 | nl_check_length = nl_escape_length = 0; | |
1361 | if ((options & topt_end_dot) != 0 && (last_filter_was_NL? | |
1362 | !write_chunk(fd, US".\n", 2, use_crlf) : | |
1363 | !write_chunk(fd, US"\n.\n", 3, use_crlf))) | |
1364 | { | |
1365 | yield = FALSE; | |
1366 | } | |
1367 | ||
1368 | /* Write out any remaining data in the buffer. */ | |
1369 | ||
1370 | else | |
1371 | { | |
1372 | yield = (len = chunk_ptr - deliver_out_buffer) <= 0 || | |
1373 | transport_write_block(fd, deliver_out_buffer, len); | |
1374 | } | |
1375 | } | |
1376 | else errno = save_errno; /* From some earlier error */ | |
1377 | ||
1378 | DEBUG(D_transport) | |
1379 | { | |
1380 | debug_printf("end of filtering transport writing: yield=%d\n", yield); | |
1381 | if (!yield) | |
1382 | debug_printf("errno=%d more_errno=%d\n", errno, addr->more_errno); | |
1383 | } | |
1384 | ||
1385 | return yield; | |
1386 | } | |
1387 | ||
1388 | ||
1389 | ||
1390 | ||
1391 | ||
1392 | /************************************************* | |
1393 | * Update waiting database * | |
1394 | *************************************************/ | |
1395 | ||
1396 | /* This is called when an address is deferred by remote transports that are | |
1397 | capable of sending more than one message over one connection. A database is | |
1398 | maintained for each transport, keeping track of which messages are waiting for | |
1399 | which hosts. The transport can then consult this when eventually a successful | |
1400 | delivery happens, and if it finds that another message is waiting for the same | |
1401 | host, it can fire up a new process to deal with it using the same connection. | |
1402 | ||
1403 | The database records are keyed by host name. They can get full if there are | |
1404 | lots of messages waiting, and so there is a continuation mechanism for them. | |
1405 | ||
1406 | Each record contains a list of message ids, packed end to end without any | |
1407 | zeros. Each one is MESSAGE_ID_LENGTH bytes long. The count field says how many | |
1408 | in this record, and the sequence field says if there are any other records for | |
1409 | this host. If the sequence field is 0, there are none. If it is 1, then another | |
1410 | record with the name <hostname>:0 exists; if it is 2, then two other records | |
1411 | with sequence numbers 0 and 1 exist, and so on. | |
1412 | ||
1413 | Currently, an exhaustive search of all continuation records has to be done to | |
1414 | determine whether to add a message id to a given record. This shouldn't be | |
1415 | too bad except in extreme cases. I can't figure out a *simple* way of doing | |
1416 | better. | |
1417 | ||
1418 | Old records should eventually get swept up by the exim_tidydb utility. | |
1419 | ||
1420 | Arguments: | |
f6c332bd | 1421 | hostlist list of hosts that this message could be sent to |
059ec3d9 PH |
1422 | tpname name of the transport |
1423 | ||
1424 | Returns: nothing | |
1425 | */ | |
1426 | ||
1427 | void | |
1428 | transport_update_waiting(host_item *hostlist, uschar *tpname) | |
1429 | { | |
1430 | uschar buffer[256]; | |
1431 | uschar *prevname = US""; | |
1432 | host_item *host; | |
1433 | open_db dbblock; | |
1434 | open_db *dbm_file; | |
1435 | ||
7a0743eb PH |
1436 | DEBUG(D_transport) debug_printf("updating wait-%s database\n", tpname); |
1437 | ||
059ec3d9 PH |
1438 | /* Open the database for this transport */ |
1439 | ||
1440 | sprintf(CS buffer, "wait-%.200s", tpname); | |
1441 | dbm_file = dbfn_open(buffer, O_RDWR, &dbblock, TRUE); | |
1442 | if (dbm_file == NULL) return; | |
1443 | ||
1444 | /* Scan the list of hosts for which this message is waiting, and ensure | |
f6c332bd | 1445 | that the message id is in each host record. */ |
059ec3d9 PH |
1446 | |
1447 | for (host = hostlist; host!= NULL; host = host->next) | |
1448 | { | |
1449 | BOOL already = FALSE; | |
1450 | dbdata_wait *host_record; | |
1451 | uschar *s; | |
1452 | int i, host_length; | |
1453 | ||
059ec3d9 PH |
1454 | /* Skip if this is the same host as we just processed; otherwise remember |
1455 | the name for next time. */ | |
1456 | ||
1457 | if (Ustrcmp(prevname, host->name) == 0) continue; | |
1458 | prevname = host->name; | |
1459 | ||
1460 | /* Look up the host record; if there isn't one, make an empty one. */ | |
1461 | ||
1462 | host_record = dbfn_read(dbm_file, host->name); | |
1463 | if (host_record == NULL) | |
1464 | { | |
1465 | host_record = store_get(sizeof(dbdata_wait) + MESSAGE_ID_LENGTH); | |
1466 | host_record->count = host_record->sequence = 0; | |
1467 | } | |
1468 | ||
1469 | /* Compute the current length */ | |
1470 | ||
1471 | host_length = host_record->count * MESSAGE_ID_LENGTH; | |
1472 | ||
1473 | /* Search the record to see if the current message is already in it. */ | |
1474 | ||
1475 | for (s = host_record->text; s < host_record->text + host_length; | |
1476 | s += MESSAGE_ID_LENGTH) | |
1477 | { | |
1478 | if (Ustrncmp(s, message_id, MESSAGE_ID_LENGTH) == 0) | |
1479 | { already = TRUE; break; } | |
1480 | } | |
1481 | ||
1482 | /* If we haven't found this message in the main record, search any | |
1483 | continuation records that exist. */ | |
1484 | ||
1485 | for (i = host_record->sequence - 1; i >= 0 && !already; i--) | |
1486 | { | |
1487 | dbdata_wait *cont; | |
1488 | sprintf(CS buffer, "%.200s:%d", host->name, i); | |
1489 | cont = dbfn_read(dbm_file, buffer); | |
1490 | if (cont != NULL) | |
1491 | { | |
1492 | int clen = cont->count * MESSAGE_ID_LENGTH; | |
1493 | for (s = cont->text; s < cont->text + clen; s += MESSAGE_ID_LENGTH) | |
1494 | { | |
1495 | if (Ustrncmp(s, message_id, MESSAGE_ID_LENGTH) == 0) | |
1496 | { already = TRUE; break; } | |
1497 | } | |
1498 | } | |
1499 | } | |
1500 | ||
1501 | /* If this message is already in a record, no need to update. */ | |
1502 | ||
7a0743eb PH |
1503 | if (already) |
1504 | { | |
1505 | DEBUG(D_transport) debug_printf("already listed for %s\n", host->name); | |
1506 | continue; | |
1507 | } | |
059ec3d9 PH |
1508 | |
1509 | ||
1510 | /* If this record is full, write it out with a new name constructed | |
1511 | from the sequence number, increase the sequence number, and empty | |
1512 | the record. */ | |
1513 | ||
1514 | if (host_record->count >= WAIT_NAME_MAX) | |
1515 | { | |
1516 | sprintf(CS buffer, "%.200s:%d", host->name, host_record->sequence); | |
1517 | dbfn_write(dbm_file, buffer, host_record, sizeof(dbdata_wait) + host_length); | |
1518 | host_record->sequence++; | |
1519 | host_record->count = 0; | |
1520 | host_length = 0; | |
1521 | } | |
1522 | ||
1523 | /* If this record is not full, increase the size of the record to | |
1524 | allow for one new message id. */ | |
1525 | ||
1526 | else | |
1527 | { | |
1528 | dbdata_wait *newr = | |
1529 | store_get(sizeof(dbdata_wait) + host_length + MESSAGE_ID_LENGTH); | |
1530 | memcpy(newr, host_record, sizeof(dbdata_wait) + host_length); | |
1531 | host_record = newr; | |
1532 | } | |
1533 | ||
1534 | /* Now add the new name on the end */ | |
1535 | ||
1536 | memcpy(host_record->text + host_length, message_id, MESSAGE_ID_LENGTH); | |
1537 | host_record->count++; | |
1538 | host_length += MESSAGE_ID_LENGTH; | |
1539 | ||
1540 | /* Update the database */ | |
1541 | ||
1542 | dbfn_write(dbm_file, host->name, host_record, sizeof(dbdata_wait) + host_length); | |
7a0743eb | 1543 | DEBUG(D_transport) debug_printf("added to list for %s\n", host->name); |
059ec3d9 PH |
1544 | } |
1545 | ||
1546 | /* All now done */ | |
1547 | ||
1548 | dbfn_close(dbm_file); | |
1549 | } | |
1550 | ||
1551 | ||
1552 | ||
1553 | ||
1554 | /************************************************* | |
1555 | * Test for waiting messages * | |
1556 | *************************************************/ | |
1557 | ||
1558 | /* This function is called by a remote transport which uses the previous | |
1559 | function to remember which messages are waiting for which remote hosts. It's | |
1560 | called after a successful delivery and its job is to check whether there is | |
1561 | another message waiting for the same host. However, it doesn't do this if the | |
1562 | current continue sequence is greater than the maximum supplied as an argument, | |
1563 | or greater than the global connection_max_messages, which, if set, overrides. | |
1564 | ||
1565 | Arguments: | |
1566 | transport_name name of the transport | |
1567 | hostname name of the host | |
1568 | local_message_max maximum number of messages down one connection | |
1569 | as set by the caller transport | |
1570 | new_message_id set to the message id of a waiting message | |
1571 | more set TRUE if there are yet more messages waiting | |
1572 | ||
1573 | Returns: TRUE if new_message_id set; FALSE otherwise | |
1574 | */ | |
1575 | ||
1576 | BOOL | |
1577 | transport_check_waiting(uschar *transport_name, uschar *hostname, | |
1578 | int local_message_max, uschar *new_message_id, BOOL *more) | |
1579 | { | |
1580 | dbdata_wait *host_record; | |
1581 | int host_length, path_len; | |
1582 | open_db dbblock; | |
1583 | open_db *dbm_file; | |
1584 | uschar buffer[256]; | |
1585 | ||
1586 | *more = FALSE; | |
1587 | ||
1588 | DEBUG(D_transport) | |
1589 | { | |
1590 | debug_printf("transport_check_waiting entered\n"); | |
1591 | debug_printf(" sequence=%d local_max=%d global_max=%d\n", | |
1592 | continue_sequence, local_message_max, connection_max_messages); | |
1593 | } | |
1594 | ||
1595 | /* Do nothing if we have hit the maximum number that can be send down one | |
1596 | connection. */ | |
1597 | ||
1598 | if (connection_max_messages >= 0) local_message_max = connection_max_messages; | |
1599 | if (local_message_max > 0 && continue_sequence >= local_message_max) | |
1600 | { | |
1601 | DEBUG(D_transport) | |
1602 | debug_printf("max messages for one connection reached: returning\n"); | |
1603 | return FALSE; | |
1604 | } | |
1605 | ||
1606 | /* Open the waiting information database. */ | |
1607 | ||
1608 | sprintf(CS buffer, "wait-%.200s", transport_name); | |
1609 | dbm_file = dbfn_open(buffer, O_RDWR, &dbblock, TRUE); | |
1610 | if (dbm_file == NULL) return FALSE; | |
1611 | ||
1612 | /* See if there is a record for this host; if not, there's nothing to do. */ | |
1613 | ||
1614 | host_record = dbfn_read(dbm_file, hostname); | |
1615 | if (host_record == NULL) | |
1616 | { | |
1617 | dbfn_close(dbm_file); | |
1618 | DEBUG(D_transport) debug_printf("no messages waiting for %s\n", hostname); | |
1619 | return FALSE; | |
1620 | } | |
1621 | ||
1622 | /* If the data in the record looks corrupt, just log something and | |
1623 | don't try to use it. */ | |
1624 | ||
1625 | if (host_record->count > WAIT_NAME_MAX) | |
1626 | { | |
1627 | dbfn_close(dbm_file); | |
1628 | log_write(0, LOG_MAIN|LOG_PANIC, "smtp-wait database entry for %s has bad " | |
1629 | "count=%d (max=%d)", hostname, host_record->count, WAIT_NAME_MAX); | |
1630 | return FALSE; | |
1631 | } | |
1632 | ||
1633 | /* Scan the message ids in the record from the end towards the beginning, | |
1634 | until one is found for which a spool file actually exists. If the record gets | |
1635 | emptied, delete it and continue with any continuation records that may exist. | |
1636 | */ | |
1637 | ||
1638 | host_length = host_record->count * MESSAGE_ID_LENGTH; | |
1639 | ||
1640 | /* Loop to handle continuation host records in the database */ | |
1641 | ||
1642 | for (;;) | |
1643 | { | |
1644 | BOOL found = FALSE; | |
1645 | ||
1646 | sprintf(CS buffer, "%s/input/", spool_directory); | |
1647 | path_len = Ustrlen(buffer); | |
1648 | ||
1649 | for (host_length -= MESSAGE_ID_LENGTH; host_length >= 0; | |
1650 | host_length -= MESSAGE_ID_LENGTH) | |
1651 | { | |
1652 | struct stat statbuf; | |
1653 | Ustrncpy(new_message_id, host_record->text + host_length, | |
1654 | MESSAGE_ID_LENGTH); | |
1655 | new_message_id[MESSAGE_ID_LENGTH] = 0; | |
1656 | ||
1657 | if (split_spool_directory) | |
1658 | sprintf(CS(buffer + path_len), "%c/%s-D", new_message_id[5], new_message_id); | |
1659 | else | |
1660 | sprintf(CS(buffer + path_len), "%s-D", new_message_id); | |
1661 | ||
1662 | /* The listed message may be the one we are currently processing. If | |
1663 | so, we want to remove it from the list without doing anything else. | |
1664 | If not, do a stat to see if it is an existing message. If it is, break | |
1665 | the loop to handle it. No need to bother about locks; as this is all | |
1666 | "hint" processing, it won't matter if it doesn't exist by the time exim | |
1667 | actually tries to deliver it. */ | |
1668 | ||
1669 | if (Ustrcmp(new_message_id, message_id) != 0 && | |
1670 | Ustat(buffer, &statbuf) == 0) | |
1671 | { | |
1672 | found = TRUE; | |
1673 | break; | |
1674 | } | |
1675 | } | |
1676 | ||
1677 | /* If we have removed all the message ids from the record delete the record. | |
1678 | If there is a continuation record, fetch it and remove it from the file, | |
1679 | as it will be rewritten as the main record. Repeat in the case of an | |
1680 | empty continuation. */ | |
1681 | ||
1682 | while (host_length <= 0) | |
1683 | { | |
1684 | int i; | |
1685 | dbdata_wait *newr = NULL; | |
1686 | ||
1687 | /* Search for a continuation */ | |
1688 | ||
1689 | for (i = host_record->sequence - 1; i >= 0 && newr == NULL; i--) | |
1690 | { | |
1691 | sprintf(CS buffer, "%.200s:%d", hostname, i); | |
1692 | newr = dbfn_read(dbm_file, buffer); | |
1693 | } | |
1694 | ||
1695 | /* If no continuation, delete the current and break the loop */ | |
1696 | ||
1697 | if (newr == NULL) | |
1698 | { | |
1699 | dbfn_delete(dbm_file, hostname); | |
1700 | break; | |
1701 | } | |
1702 | ||
1703 | /* Else replace the current with the continuation */ | |
1704 | ||
1705 | dbfn_delete(dbm_file, buffer); | |
1706 | host_record = newr; | |
1707 | host_length = host_record->count * MESSAGE_ID_LENGTH; | |
1708 | } | |
1709 | ||
1710 | /* If we found an existing message, break the continuation loop. */ | |
1711 | ||
1712 | if (found) break; | |
1713 | ||
1714 | /* If host_length <= 0 we have emptied a record and not found a good message, | |
1715 | and there are no continuation records. Otherwise there is a continuation | |
1716 | record to process. */ | |
1717 | ||
1718 | if (host_length <= 0) | |
1719 | { | |
1720 | dbfn_close(dbm_file); | |
1721 | DEBUG(D_transport) debug_printf("waiting messages already delivered\n"); | |
1722 | return FALSE; | |
1723 | } | |
1724 | } | |
1725 | ||
1726 | /* Control gets here when an existing message has been encountered; its | |
1727 | id is in new_message_id, and host_length is the revised length of the | |
1728 | host record. If it is zero, the record has been removed. Update the | |
1729 | record if required, close the database, and return TRUE. */ | |
1730 | ||
1731 | if (host_length > 0) | |
1732 | { | |
1733 | host_record->count = host_length/MESSAGE_ID_LENGTH; | |
1734 | dbfn_write(dbm_file, hostname, host_record, (int)sizeof(dbdata_wait) + host_length); | |
1735 | *more = TRUE; | |
1736 | } | |
1737 | ||
1738 | dbfn_close(dbm_file); | |
1739 | return TRUE; | |
1740 | } | |
1741 | ||
1742 | ||
1743 | ||
1744 | /************************************************* | |
1745 | * Deliver waiting message down same socket * | |
1746 | *************************************************/ | |
1747 | ||
1748 | /* Fork a new exim process to deliver the message, and do a re-exec, both to | |
1749 | get a clean delivery process, and to regain root privilege in cases where it | |
1750 | has been given away. | |
1751 | ||
1752 | Arguments: | |
1753 | transport_name to pass to the new process | |
1754 | hostname ditto | |
1755 | hostaddress ditto | |
1756 | id the new message to process | |
1757 | socket_fd the connected socket | |
1758 | ||
1759 | Returns: FALSE if fork fails; TRUE otherwise | |
1760 | */ | |
1761 | ||
1762 | BOOL | |
1763 | transport_pass_socket(uschar *transport_name, uschar *hostname, | |
1764 | uschar *hostaddress, uschar *id, int socket_fd) | |
1765 | { | |
1766 | pid_t pid; | |
1767 | int status; | |
1768 | ||
1769 | DEBUG(D_transport) debug_printf("transport_pass_socket entered\n"); | |
1770 | ||
1771 | if ((pid = fork()) == 0) | |
1772 | { | |
1773 | int i = 16; | |
1774 | uschar **argv; | |
1775 | ||
1776 | /* Disconnect entirely from the parent process. If we are running in the | |
1777 | test harness, wait for a bit to allow the previous process time to finish, | |
1778 | write the log, etc., so that the output is always in the same order for | |
1779 | automatic comparison. */ | |
1780 | ||
1781 | if ((pid = fork()) != 0) _exit(EXIT_SUCCESS); | |
ed0e9820 | 1782 | if (running_in_test_harness) sleep(1); |
059ec3d9 PH |
1783 | |
1784 | /* Set up the calling arguments; use the standard function for the basics, | |
1785 | but we have a number of extras that may be added. */ | |
1786 | ||
1787 | argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0); | |
1788 | ||
1789 | if (smtp_authenticated) argv[i++] = US"-MCA"; | |
1790 | ||
1791 | #ifdef SUPPORT_TLS | |
1792 | if (tls_offered) argv[i++] = US"-MCT"; | |
1793 | #endif | |
1794 | ||
1795 | if (smtp_use_size) argv[i++] = US"-MCS"; | |
1796 | if (smtp_use_pipelining) argv[i++] = US"-MCP"; | |
1797 | ||
1798 | if (queue_run_pid != (pid_t)0) | |
1799 | { | |
1800 | argv[i++] = US"-MCQ"; | |
1801 | argv[i++] = string_sprintf("%d", queue_run_pid); | |
1802 | argv[i++] = string_sprintf("%d", queue_run_pipe); | |
1803 | } | |
1804 | ||
1805 | argv[i++] = US"-MC"; | |
1806 | argv[i++] = transport_name; | |
1807 | argv[i++] = hostname; | |
1808 | argv[i++] = hostaddress; | |
1809 | argv[i++] = string_sprintf("%d", continue_sequence + 1); | |
1810 | argv[i++] = id; | |
1811 | argv[i++] = NULL; | |
1812 | ||
1813 | /* Arrange for the channel to be on stdin. */ | |
1814 | ||
1815 | if (socket_fd != 0) | |
1816 | { | |
f1e894f3 PH |
1817 | (void)dup2(socket_fd, 0); |
1818 | (void)close(socket_fd); | |
059ec3d9 PH |
1819 | } |
1820 | ||
1821 | DEBUG(D_exec) debug_print_argv(argv); | |
1822 | exim_nullstd(); /* Ensure std{out,err} exist */ | |
1823 | execv(CS argv[0], (char *const *)argv); | |
1824 | ||
1825 | DEBUG(D_any) debug_printf("execv failed: %s\n", strerror(errno)); | |
1826 | _exit(errno); /* Note: must be _exit(), NOT exit() */ | |
1827 | } | |
1828 | ||
1829 | /* If the process creation succeeded, wait for the first-level child, which | |
1830 | immediately exits, leaving the second level process entirely disconnected from | |
1831 | this one. */ | |
1832 | ||
1833 | if (pid > 0) | |
1834 | { | |
1835 | int rc; | |
1836 | while ((rc = wait(&status)) != pid && (rc >= 0 || errno != ECHILD)); | |
1837 | DEBUG(D_transport) debug_printf("transport_pass_socket succeeded\n"); | |
1838 | return TRUE; | |
1839 | } | |
1840 | else | |
1841 | { | |
1842 | DEBUG(D_transport) debug_printf("transport_pass_socket failed to fork: %s\n", | |
1843 | strerror(errno)); | |
1844 | return FALSE; | |
1845 | } | |
1846 | } | |
1847 | ||
1848 | ||
1849 | ||
1850 | /************************************************* | |
1851 | * Set up direct (non-shell) command * | |
1852 | *************************************************/ | |
1853 | ||
1854 | /* This function is called when a command line is to be parsed and executed | |
1855 | directly, without the use of /bin/sh. It is called by the pipe transport, | |
1856 | the queryprogram router, and also from the main delivery code when setting up a | |
1857 | transport filter process. The code for ETRN also makes use of this; in that | |
1858 | case, no addresses are passed. | |
1859 | ||
1860 | Arguments: | |
1861 | argvptr pointer to anchor for argv vector | |
1862 | cmd points to the command string | |
1863 | expand_arguments true if expansion is to occur | |
1864 | expand_failed error value to set if expansion fails; not relevant if | |
1865 | addr == NULL | |
1866 | addr chain of addresses, or NULL | |
1867 | etext text for use in error messages | |
1868 | errptr where to put error message if addr is NULL; | |
1869 | otherwise it is put in the first address | |
1870 | ||
1871 | Returns: TRUE if all went well; otherwise an error will be | |
1872 | set in the first address and FALSE returned | |
1873 | */ | |
1874 | ||
1875 | BOOL | |
1876 | transport_set_up_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments, | |
1877 | int expand_failed, address_item *addr, uschar *etext, uschar **errptr) | |
1878 | { | |
1879 | address_item *ad; | |
1880 | uschar **argv; | |
1881 | uschar *s, *ss; | |
1882 | int address_count = 0; | |
1883 | int argcount = 0; | |
1884 | int i, max_args; | |
1885 | ||
1886 | /* Get store in which to build an argument list. Count the number of addresses | |
1887 | supplied, and allow for that many arguments, plus an additional 60, which | |
1888 | should be enough for anybody. Multiple addresses happen only when the local | |
1889 | delivery batch option is set. */ | |
1890 | ||
1891 | for (ad = addr; ad != NULL; ad = ad->next) address_count++; | |
1892 | max_args = address_count + 60; | |
1893 | *argvptr = argv = store_get((max_args+1)*sizeof(uschar *)); | |
1894 | ||
1895 | /* Split the command up into arguments terminated by white space. Lose | |
1896 | trailing space at the start and end. Double-quoted arguments can contain \\ and | |
1897 | \" escapes and so can be handled by the standard function; single-quoted | |
1898 | arguments are verbatim. Copy each argument into a new string. */ | |
1899 | ||
1900 | s = cmd; | |
1901 | while (isspace(*s)) s++; | |
1902 | ||
1903 | while (*s != 0 && argcount < max_args) | |
1904 | { | |
1905 | if (*s == '\'') | |
1906 | { | |
1907 | ss = s + 1; | |
1908 | while (*ss != 0 && *ss != '\'') ss++; | |
1909 | argv[argcount++] = ss = store_get(ss - s++); | |
1910 | while (*s != 0 && *s != '\'') *ss++ = *s++; | |
1911 | if (*s != 0) s++; | |
1912 | *ss++ = 0; | |
1913 | } | |
1914 | else argv[argcount++] = string_dequote(&s); | |
1915 | while (isspace(*s)) s++; | |
1916 | } | |
1917 | ||
1918 | argv[argcount] = (uschar *)0; | |
1919 | ||
1920 | /* If *s != 0 we have run out of argument slots. */ | |
1921 | ||
1922 | if (*s != 0) | |
1923 | { | |
1924 | uschar *msg = string_sprintf("Too many arguments in command \"%s\" in " | |
1925 | "%s", cmd, etext); | |
1926 | if (addr != NULL) | |
1927 | { | |
1928 | addr->transport_return = FAIL; | |
1929 | addr->message = msg; | |
1930 | } | |
1931 | else *errptr = msg; | |
1932 | return FALSE; | |
1933 | } | |
1934 | ||
1935 | /* Expand each individual argument if required. Expansion happens for pipes set | |
1936 | up in filter files and with directly-supplied commands. It does not happen if | |
1937 | the pipe comes from a traditional .forward file. A failing expansion is a big | |
1938 | disaster if the command came from Exim's configuration; if it came from a user | |
1939 | it is just a normal failure. The expand_failed value is used as the error value | |
1940 | to cater for these two cases. | |
1941 | ||
1942 | An argument consisting just of the text "$pipe_addresses" is treated specially. | |
1943 | It is not passed to the general expansion function. Instead, it is replaced by | |
1944 | a number of arguments, one for each address. This avoids problems with shell | |
1945 | metacharacters and spaces in addresses. | |
1946 | ||
1947 | If the parent of the top address has an original part of "system-filter", this | |
1948 | pipe was set up by the system filter, and we can permit the expansion of | |
1949 | $recipients. */ | |
1950 | ||
1951 | DEBUG(D_transport) | |
1952 | { | |
1953 | debug_printf("direct command:\n"); | |
1954 | for (i = 0; argv[i] != (uschar *)0; i++) | |
1955 | debug_printf(" argv[%d] = %s\n", i, string_printing(argv[i])); | |
1956 | } | |
1957 | ||
1958 | if (expand_arguments) | |
1959 | { | |
1960 | BOOL allow_dollar_recipients = addr != NULL && | |
1961 | addr->parent != NULL && | |
1962 | Ustrcmp(addr->parent->address, "system-filter") == 0; | |
1963 | ||
1964 | for (i = 0; argv[i] != (uschar *)0; i++) | |
1965 | { | |
1966 | ||
1967 | /* Handle special fudge for passing an address list */ | |
1968 | ||
1969 | if (addr != NULL && | |
1970 | (Ustrcmp(argv[i], "$pipe_addresses") == 0 || | |
1971 | Ustrcmp(argv[i], "${pipe_addresses}") == 0)) | |
1972 | { | |
1973 | int additional; | |
1974 | ||
1975 | if (argcount + address_count - 1 > max_args) | |
1976 | { | |
1977 | addr->transport_return = FAIL; | |
1978 | addr->message = string_sprintf("Too many arguments to command \"%s\" " | |
1979 | "in %s", cmd, etext); | |
1980 | return FALSE; | |
1981 | } | |
1982 | ||
1983 | additional = address_count - 1; | |
1984 | if (additional > 0) | |
1985 | memmove(argv + i + 1 + additional, argv + i + 1, | |
1986 | (argcount - i)*sizeof(uschar *)); | |
1987 | ||
1988 | for (ad = addr; ad != NULL; ad = ad->next) argv[i++] = ad->address; | |
1989 | i--; | |
1990 | } | |
1991 | ||
1992 | /* Handle normal expansion string */ | |
1993 | ||
1994 | else | |
1995 | { | |
1996 | uschar *expanded_arg; | |
1997 | enable_dollar_recipients = allow_dollar_recipients; | |
1998 | expanded_arg = expand_string(argv[i]); | |
1999 | enable_dollar_recipients = FALSE; | |
2000 | ||
2001 | if (expanded_arg == NULL) | |
2002 | { | |
2003 | uschar *msg = string_sprintf("Expansion of \"%s\" " | |
2004 | "from command \"%s\" in %s failed: %s", | |
2005 | argv[i], cmd, etext, expand_string_message); | |
2006 | if (addr != NULL) | |
2007 | { | |
2008 | addr->transport_return = expand_failed; | |
2009 | addr->message = msg; | |
2010 | } | |
2011 | else *errptr = msg; | |
2012 | return FALSE; | |
2013 | } | |
2014 | argv[i] = expanded_arg; | |
2015 | } | |
2016 | } | |
2017 | ||
2018 | DEBUG(D_transport) | |
2019 | { | |
2020 | debug_printf("direct command after expansion:\n"); | |
2021 | for (i = 0; argv[i] != (uschar *)0; i++) | |
2022 | debug_printf(" argv[%d] = %s\n", i, string_printing(argv[i])); | |
2023 | } | |
2024 | } | |
2025 | ||
2026 | return TRUE; | |
2027 | } | |
2028 | ||
2029 | /* End of transport.c */ |