Merge branch 'CHUNKING'
[exim.git] / src / src / spool_in.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2016 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for reading spool files. When compiling for a utility (eximon),
9 not all are needed, and some functionality can be cut out. */
10
11
12 #include "exim.h"
13
14
15
16 #ifndef COMPILE_UTILITY
17 /*************************************************
18 * Open and lock data file *
19 *************************************************/
20
21 /* The data file is the one that is used for locking, because the header file
22 can get replaced during delivery because of header rewriting. The file has
23 to opened with write access so that we can get an exclusive lock, but in
24 fact it won't be written to. Just in case there's a major disaster (e.g.
25 overwriting some other file descriptor with the value of this one), open it
26 with append.
27
28 Argument: the id of the message
29 Returns: fd if file successfully opened and locked, else -1
30
31 Side effect: message_subdir is set for the (possibly split) spool directory
32 */
33
34 int
35 spool_open_datafile(uschar *id)
36 {
37 int i;
38 struct stat statbuf;
39 flock_t lock_data;
40 int fd;
41
42 /* If split_spool_directory is set, first look for the file in the appropriate
43 sub-directory of the input directory. If it is not found there, try the input
44 directory itself, to pick up leftovers from before the splitting. If split_
45 spool_directory is not set, first look in the main input directory. If it is
46 not found there, try the split sub-directory, in case it is left over from a
47 splitting state. */
48
49 for (i = 0; i < 2; i++)
50 {
51 uschar * fname;
52 int save_errno;
53
54 message_subdir[0] = split_spool_directory == i == 0 ? id[5] : 0;
55 fname = spool_fname(US"input", message_subdir, id, US"-D");
56 DEBUG(D_deliver) debug_printf("Trying spool file %s\n", fname);
57
58 if ((fd = Uopen(fname, O_RDWR | O_APPEND, 0)) >= 0)
59 break;
60 save_errno = errno;
61 if (errno == ENOENT)
62 {
63 if (i == 0) continue;
64 if (!queue_running)
65 log_write(0, LOG_MAIN, "Spool%s%s file %s-D not found",
66 *queue_name ? US" Q=" : US"",
67 *queue_name ? queue_name : US"",
68 id);
69 }
70 else
71 log_write(0, LOG_MAIN, "Spool error for %s: %s", fname, strerror(errno));
72 errno = save_errno;
73 return -1;
74 }
75
76 /* File is open and message_subdir is set. Set the close-on-exec flag, and lock
77 the file. We lock only the first line of the file (containing the message ID)
78 because this apparently is needed for running Exim under Cygwin. If the entire
79 file is locked in one process, a sub-process cannot access it, even when passed
80 an open file descriptor (at least, I think that's the Cygwin story). On real
81 Unix systems it doesn't make any difference as long as Exim is consistent in
82 what it locks. */
83
84 (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) |
85 FD_CLOEXEC);
86
87 lock_data.l_type = F_WRLCK;
88 lock_data.l_whence = SEEK_SET;
89 lock_data.l_start = 0;
90 lock_data.l_len = SPOOL_DATA_START_OFFSET;
91
92 if (fcntl(fd, F_SETLK, &lock_data) < 0)
93 {
94 log_write(L_skip_delivery,
95 LOG_MAIN,
96 "Spool file is locked (another process is handling this message)");
97 (void)close(fd);
98 errno = 0;
99 return -1;
100 }
101
102 /* Get the size of the data; don't include the leading filename line
103 in the count, but add one for the newline before the data. */
104
105 if (fstat(fd, &statbuf) == 0)
106 {
107 message_body_size = statbuf.st_size - SPOOL_DATA_START_OFFSET;
108 message_size = message_body_size + 1;
109 }
110
111 return fd;
112 }
113 #endif /* COMPILE_UTILITY */
114
115
116
117 /*************************************************
118 * Read non-recipients tree from spool file *
119 *************************************************/
120
121 /* The tree of non-recipients is written to the spool file in a form that
122 makes it easy to read back into a tree. The format is as follows:
123
124 . Each node is preceded by two letter(Y/N) indicating whether it has left
125 or right children. There's one space after the two flags, before the name.
126
127 . The left subtree (if any) then follows, then the right subtree (if any).
128
129 This function is entered with the next input line in the buffer. Note we must
130 save the right flag before recursing with the same buffer.
131
132 Once the tree is read, we re-construct the balance fields by scanning the tree.
133 I forgot to write them out originally, and the compatible fix is to do it this
134 way. This initial local recursing function does the necessary.
135
136 Arguments:
137 node tree node
138
139 Returns: maximum depth below the node, including the node itself
140 */
141
142 static int
143 count_below(tree_node *node)
144 {
145 int nleft, nright;
146 if (node == NULL) return 0;
147 nleft = count_below(node->left);
148 nright = count_below(node->right);
149 node->balance = (nleft > nright)? 1 : ((nright > nleft)? 2 : 0);
150 return 1 + ((nleft > nright)? nleft : nright);
151 }
152
153 /* This is the real function...
154
155 Arguments:
156 connect pointer to the root of the tree
157 f FILE to read data from
158 buffer contains next input line; further lines read into it
159 buffer_size size of the buffer
160
161 Returns: FALSE on format error
162 */
163
164 static BOOL
165 read_nonrecipients_tree(tree_node **connect, FILE *f, uschar *buffer,
166 int buffer_size)
167 {
168 tree_node *node;
169 int n = Ustrlen(buffer);
170 BOOL right = buffer[1] == 'Y';
171
172 if (n < 5) return FALSE; /* malformed line */
173 buffer[n-1] = 0; /* Remove \n */
174 node = store_get(sizeof(tree_node) + n - 3);
175 *connect = node;
176 Ustrcpy(node->name, buffer + 3);
177 node->data.ptr = NULL;
178
179 if (buffer[0] == 'Y')
180 {
181 if (Ufgets(buffer, buffer_size, f) == NULL ||
182 !read_nonrecipients_tree(&node->left, f, buffer, buffer_size))
183 return FALSE;
184 }
185 else node->left = NULL;
186
187 if (right)
188 {
189 if (Ufgets(buffer, buffer_size, f) == NULL ||
190 !read_nonrecipients_tree(&node->right, f, buffer, buffer_size))
191 return FALSE;
192 }
193 else node->right = NULL;
194
195 (void) count_below(*connect);
196 return TRUE;
197 }
198
199
200
201
202 /*************************************************
203 * Read spool header file *
204 *************************************************/
205
206 /* This function reads a spool header file and places the data into the
207 appropriate global variables. The header portion is always read, but header
208 structures are built only if read_headers is set true. It isn't, for example,
209 while generating -bp output.
210
211 It may be possible for blocks of nulls (binary zeroes) to get written on the
212 end of a file if there is a system crash during writing. It was observed on an
213 earlier version of Exim that omitted to fsync() the files - this is thought to
214 have been the cause of that incident, but in any case, this code must be robust
215 against such an event, and if such a file is encountered, it must be treated as
216 malformed.
217
218 Arguments:
219 name name of the header file, including the -H
220 read_headers TRUE if in-store header structures are to be built
221 subdir_set TRUE is message_subdir is already set
222
223 Returns: spool_read_OK success
224 spool_read_notopen open failed
225 spool_read_enverror error in the envelope portion
226 spool_read_hdrdrror error in the header portion
227 */
228
229 int
230 spool_read_header(uschar *name, BOOL read_headers, BOOL subdir_set)
231 {
232 FILE *f = NULL;
233 int n;
234 int rcount = 0;
235 long int uid, gid;
236 BOOL inheader = FALSE;
237 uschar *p;
238
239 /* Reset all the global variables to their default values. However, there is
240 one exception. DO NOT change the default value of dont_deliver, because it may
241 be forced by an external setting. */
242
243 acl_var_c = acl_var_m = NULL;
244 authenticated_id = NULL;
245 authenticated_sender = NULL;
246 allow_unqualified_recipient = FALSE;
247 allow_unqualified_sender = FALSE;
248 body_linecount = 0;
249 body_zerocount = 0;
250 deliver_firsttime = FALSE;
251 deliver_freeze = FALSE;
252 deliver_frozen_at = 0;
253 deliver_manual_thaw = FALSE;
254 /* dont_deliver must NOT be reset */
255 header_list = header_last = NULL;
256 host_lookup_deferred = FALSE;
257 host_lookup_failed = FALSE;
258 interface_address = NULL;
259 interface_port = 0;
260 local_error_message = FALSE;
261 local_scan_data = NULL;
262 max_received_linelength = 0;
263 message_linecount = 0;
264 received_protocol = NULL;
265 received_count = 0;
266 recipients_list = NULL;
267 sender_address = NULL;
268 sender_fullhost = NULL;
269 sender_helo_name = NULL;
270 sender_host_address = NULL;
271 sender_host_name = NULL;
272 sender_host_port = 0;
273 sender_host_authenticated = NULL;
274 sender_ident = NULL;
275 sender_local = FALSE;
276 sender_set_untrusted = FALSE;
277 smtp_active_hostname = primary_hostname;
278 tree_nonrecipients = NULL;
279
280 #ifdef EXPERIMENTAL_BRIGHTMAIL
281 bmi_run = 0;
282 bmi_verdicts = NULL;
283 #endif
284
285 #ifndef DISABLE_DKIM
286 dkim_signers = NULL;
287 dkim_disable_verify = FALSE;
288 dkim_collect_input = FALSE;
289 #endif
290
291 #ifdef SUPPORT_TLS
292 tls_in.certificate_verified = FALSE;
293 # ifdef EXPERIMENTAL_DANE
294 tls_in.dane_verified = FALSE;
295 # endif
296 tls_in.cipher = NULL;
297 # ifndef COMPILE_UTILITY /* tls support fns not built in */
298 tls_free_cert(&tls_in.ourcert);
299 tls_free_cert(&tls_in.peercert);
300 # endif
301 tls_in.peerdn = NULL;
302 tls_in.sni = NULL;
303 tls_in.ocsp = OCSP_NOT_REQ;
304 #endif
305
306 #ifdef WITH_CONTENT_SCAN
307 spam_bar = NULL;
308 spam_score = NULL;
309 spam_score_int = NULL;
310 #endif
311
312 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
313 message_smtputf8 = FALSE;
314 message_utf8_downconvert = 0;
315 #endif
316
317 dsn_ret = 0;
318 dsn_envid = NULL;
319
320 /* Generate the full name and open the file. If message_subdir is already
321 set, just look in the given directory. Otherwise, look in both the split
322 and unsplit directories, as for the data file above. */
323
324 for (n = 0; n < 2; n++)
325 {
326 if (!subdir_set)
327 message_subdir[0] = split_spool_directory == (n == 0) ? name[5] : 0;
328
329 if ((f = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
330 break;
331 if (n != 0 || subdir_set || errno != ENOENT)
332 return spool_read_notopen;
333 }
334
335 errno = 0;
336
337 #ifndef COMPILE_UTILITY
338 DEBUG(D_deliver) debug_printf("reading spool file %s\n", name);
339 #endif /* COMPILE_UTILITY */
340
341 /* The first line of a spool file contains the message id followed by -H (i.e.
342 the file name), in order to make the file self-identifying. */
343
344 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
345 if (Ustrlen(big_buffer) != MESSAGE_ID_LENGTH + 3 ||
346 Ustrncmp(big_buffer, name, MESSAGE_ID_LENGTH + 2) != 0)
347 goto SPOOL_FORMAT_ERROR;
348
349 /* The next three lines in the header file are in a fixed format. The first
350 contains the login, uid, and gid of the user who caused the file to be written.
351 There are known cases where a negative gid is used, so we allow for both
352 negative uids and gids. The second contains the mail address of the message's
353 sender, enclosed in <>. The third contains the time the message was received,
354 and the number of warning messages for delivery delays that have been sent. */
355
356 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
357
358 p = big_buffer + Ustrlen(big_buffer);
359 while (p > big_buffer && isspace(p[-1])) p--;
360 *p = 0;
361 if (!isdigit(p[-1])) goto SPOOL_FORMAT_ERROR;
362 while (p > big_buffer && (isdigit(p[-1]) || '-' == p[-1])) p--;
363 gid = Uatoi(p);
364 if (p <= big_buffer || *(--p) != ' ') goto SPOOL_FORMAT_ERROR;
365 *p = 0;
366 if (!isdigit(p[-1])) goto SPOOL_FORMAT_ERROR;
367 while (p > big_buffer && (isdigit(p[-1]) || '-' == p[-1])) p--;
368 uid = Uatoi(p);
369 if (p <= big_buffer || *(--p) != ' ') goto SPOOL_FORMAT_ERROR;
370 *p = 0;
371
372 originator_login = string_copy(big_buffer);
373 originator_uid = (uid_t)uid;
374 originator_gid = (gid_t)gid;
375
376 /* envelope from */
377 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
378 n = Ustrlen(big_buffer);
379 if (n < 3 || big_buffer[0] != '<' || big_buffer[n-2] != '>')
380 goto SPOOL_FORMAT_ERROR;
381
382 sender_address = store_get(n-2);
383 Ustrncpy(sender_address, big_buffer+1, n-3);
384 sender_address[n-3] = 0;
385
386 /* time */
387 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
388 if (sscanf(CS big_buffer, "%d %d", &received_time, &warning_count) != 2)
389 goto SPOOL_FORMAT_ERROR;
390
391 message_age = time(NULL) - received_time;
392
393 #ifndef COMPILE_UTILITY
394 DEBUG(D_deliver) debug_printf("user=%s uid=%ld gid=%ld sender=%s\n",
395 originator_login, (long int)originator_uid, (long int)originator_gid,
396 sender_address);
397 #endif /* COMPILE_UTILITY */
398
399 /* Now there may be a number of optional lines, each starting with "-". If you
400 add a new setting here, make sure you set the default above.
401
402 Because there are now quite a number of different possibilities, we use a
403 switch on the first character to avoid too many failing tests. Thanks to Nico
404 Erfurth for the patch that implemented this. I have made it even more efficient
405 by not re-scanning the first two characters.
406
407 To allow new versions of Exim that add additional flags to interwork with older
408 versions that do not understand them, just ignore any lines starting with "-"
409 that we don't recognize. Otherwise it wouldn't be possible to back off a new
410 version that left new-style flags written on the spool. */
411
412 p = big_buffer + 2;
413 for (;;)
414 {
415 int len;
416 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
417 if (big_buffer[0] != '-') break;
418 while ( (len = Ustrlen(big_buffer)) == big_buffer_size-1
419 && big_buffer[len-1] != '\n'
420 )
421 { /* buffer not big enough for line; certs make this possible */
422 uschar * buf;
423 if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR;
424 buf = store_get_perm(big_buffer_size *= 2);
425 memcpy(buf, big_buffer, --len);
426 big_buffer = buf;
427 if (Ufgets(big_buffer+len, big_buffer_size-len, f) == NULL)
428 goto SPOOL_READ_ERROR;
429 }
430 big_buffer[len-1] = 0;
431
432 switch(big_buffer[1])
433 {
434 case 'a':
435
436 /* Nowadays we use "-aclc" and "-aclm" for the different types of ACL
437 variable, because Exim allows any number of them, with arbitrary names.
438 The line in the spool file is "-acl[cm] <name> <length>". The name excludes
439 the c or m. */
440
441 if (Ustrncmp(p, "clc ", 4) == 0 ||
442 Ustrncmp(p, "clm ", 4) == 0)
443 {
444 uschar *name, *endptr;
445 int count;
446 tree_node *node;
447 endptr = Ustrchr(big_buffer + 6, ' ');
448 if (endptr == NULL) goto SPOOL_FORMAT_ERROR;
449 name = string_sprintf("%c%.*s", big_buffer[4], endptr - big_buffer - 6,
450 big_buffer + 6);
451 if (sscanf(CS endptr, " %d", &count) != 1) goto SPOOL_FORMAT_ERROR;
452 node = acl_var_create(name);
453 node->data.ptr = store_get(count + 1);
454 if (fread(node->data.ptr, 1, count+1, f) < count) goto SPOOL_READ_ERROR;
455 ((uschar*)node->data.ptr)[count] = 0;
456 }
457
458 else if (Ustrcmp(p, "llow_unqualified_recipient") == 0)
459 allow_unqualified_recipient = TRUE;
460 else if (Ustrcmp(p, "llow_unqualified_sender") == 0)
461 allow_unqualified_sender = TRUE;
462
463 else if (Ustrncmp(p, "uth_id", 6) == 0)
464 authenticated_id = string_copy(big_buffer + 9);
465 else if (Ustrncmp(p, "uth_sender", 10) == 0)
466 authenticated_sender = string_copy(big_buffer + 13);
467 else if (Ustrncmp(p, "ctive_hostname", 14) == 0)
468 smtp_active_hostname = string_copy(big_buffer + 17);
469
470 /* For long-term backward compatibility, we recognize "-acl", which was
471 used before the number of ACL variables changed from 10 to 20. This was
472 before the subsequent change to an arbitrary number of named variables.
473 This code is retained so that upgrades from very old versions can still
474 handle old-format spool files. The value given after "-acl" is a number
475 that is 0-9 for connection variables, and 10-19 for message variables. */
476
477 else if (Ustrncmp(p, "cl ", 3) == 0)
478 {
479 int index, count;
480 uschar name[20]; /* Need plenty of space for %d format */
481 tree_node *node;
482 if ( sscanf(CS big_buffer + 5, "%d %d", &index, &count) != 2
483 || index >= 20
484 )
485 goto SPOOL_FORMAT_ERROR;
486 if (index < 10)
487 (void) string_format(name, sizeof(name), "%c%d", 'c', index);
488 else
489 (void) string_format(name, sizeof(name), "%c%d", 'm', index - 10);
490 node = acl_var_create(name);
491 node->data.ptr = store_get(count + 1);
492 if (fread(node->data.ptr, 1, count+1, f) < count) goto SPOOL_READ_ERROR;
493 ((uschar*)node->data.ptr)[count] = 0;
494 }
495 break;
496
497 case 'b':
498 if (Ustrncmp(p, "ody_linecount", 13) == 0)
499 body_linecount = Uatoi(big_buffer + 15);
500 else if (Ustrncmp(p, "ody_zerocount", 13) == 0)
501 body_zerocount = Uatoi(big_buffer + 15);
502 #ifdef EXPERIMENTAL_BRIGHTMAIL
503 else if (Ustrncmp(p, "mi_verdicts ", 12) == 0)
504 bmi_verdicts = string_copy(big_buffer + 14);
505 #endif
506 break;
507
508 case 'd':
509 if (Ustrcmp(p, "eliver_firsttime") == 0)
510 deliver_firsttime = TRUE;
511 /* Check if the dsn flags have been set in the header file */
512 else if (Ustrncmp(p, "sn_ret", 6) == 0)
513 dsn_ret= atoi(CS big_buffer + 8);
514 else if (Ustrncmp(p, "sn_envid", 8) == 0)
515 dsn_envid = string_copy(big_buffer + 11);
516 break;
517
518 case 'f':
519 if (Ustrncmp(p, "rozen", 5) == 0)
520 {
521 deliver_freeze = TRUE;
522 if (sscanf(CS big_buffer+7, TIME_T_FMT, &deliver_frozen_at) != 1)
523 goto SPOOL_READ_ERROR;
524 }
525 break;
526
527 case 'h':
528 if (Ustrcmp(p, "ost_lookup_deferred") == 0)
529 host_lookup_deferred = TRUE;
530 else if (Ustrcmp(p, "ost_lookup_failed") == 0)
531 host_lookup_failed = TRUE;
532 else if (Ustrncmp(p, "ost_auth", 8) == 0)
533 sender_host_authenticated = string_copy(big_buffer + 11);
534 else if (Ustrncmp(p, "ost_name", 8) == 0)
535 sender_host_name = string_copy(big_buffer + 11);
536 else if (Ustrncmp(p, "elo_name", 8) == 0)
537 sender_helo_name = string_copy(big_buffer + 11);
538
539 /* We now record the port number after the address, separated by a
540 dot. For compatibility during upgrading, do nothing if there
541 isn't a value (it gets left at zero). */
542
543 else if (Ustrncmp(p, "ost_address", 11) == 0)
544 {
545 sender_host_port = host_address_extract_port(big_buffer + 14);
546 sender_host_address = string_copy(big_buffer + 14);
547 }
548 break;
549
550 case 'i':
551 if (Ustrncmp(p, "nterface_address", 16) == 0)
552 {
553 interface_port = host_address_extract_port(big_buffer + 19);
554 interface_address = string_copy(big_buffer + 19);
555 }
556 else if (Ustrncmp(p, "dent", 4) == 0)
557 sender_ident = string_copy(big_buffer + 7);
558 break;
559
560 case 'l':
561 if (Ustrcmp(p, "ocal") == 0) sender_local = TRUE;
562 else if (Ustrcmp(big_buffer, "-localerror") == 0)
563 local_error_message = TRUE;
564 else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
565 local_scan_data = string_copy(big_buffer + 12);
566 break;
567
568 case 'm':
569 if (Ustrcmp(p, "anual_thaw") == 0) deliver_manual_thaw = TRUE;
570 else if (Ustrncmp(p, "ax_received_linelength", 22) == 0)
571 max_received_linelength = Uatoi(big_buffer + 24);
572 break;
573
574 case 'N':
575 if (*p == 0) dont_deliver = TRUE; /* -N */
576 break;
577
578 case 'r':
579 if (Ustrncmp(p, "eceived_protocol", 16) == 0)
580 received_protocol = string_copy(big_buffer + 19);
581 break;
582
583 case 's':
584 if (Ustrncmp(p, "ender_set_untrusted", 19) == 0)
585 sender_set_untrusted = TRUE;
586 #ifdef WITH_CONTENT_SCAN
587 else if (Ustrncmp(p, "pam_bar ", 8) == 0)
588 spam_bar = string_copy(big_buffer + 10);
589 else if (Ustrncmp(p, "pam_score ", 10) == 0)
590 spam_score = string_copy(big_buffer + 12);
591 else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
592 spam_score_int = string_copy(big_buffer + 16);
593 #endif
594 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
595 else if (Ustrncmp(p, "mtputf8", 7) == 0)
596 message_smtputf8 = TRUE;
597 #endif
598 break;
599
600 #ifdef SUPPORT_TLS
601 case 't':
602 if (Ustrncmp(p, "ls_certificate_verified", 23) == 0)
603 tls_in.certificate_verified = TRUE;
604 else if (Ustrncmp(p, "ls_cipher", 9) == 0)
605 tls_in.cipher = string_copy(big_buffer + 12);
606 # ifndef COMPILE_UTILITY /* tls support fns not built in */
607 else if (Ustrncmp(p, "ls_ourcert", 10) == 0)
608 (void) tls_import_cert(big_buffer + 13, &tls_in.ourcert);
609 else if (Ustrncmp(p, "ls_peercert", 11) == 0)
610 (void) tls_import_cert(big_buffer + 14, &tls_in.peercert);
611 # endif
612 else if (Ustrncmp(p, "ls_peerdn", 9) == 0)
613 tls_in.peerdn = string_unprinting(string_copy(big_buffer + 12));
614 else if (Ustrncmp(p, "ls_sni", 6) == 0)
615 tls_in.sni = string_unprinting(string_copy(big_buffer + 9));
616 else if (Ustrncmp(p, "ls_ocsp", 7) == 0)
617 tls_in.ocsp = big_buffer[10] - '0';
618 break;
619 #endif
620
621 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
622 case 'u':
623 if (Ustrncmp(p, "tf8_downcvt", 11) == 0)
624 message_utf8_downconvert = 1;
625 else if (Ustrncmp(p, "tf8_optdowncvt", 15) == 0)
626 message_utf8_downconvert = -1;
627 break;
628 #endif
629
630 default: /* Present because some compilers complain if all */
631 break; /* possibilities are not covered. */
632 }
633 }
634
635 /* Build sender_fullhost if required */
636
637 #ifndef COMPILE_UTILITY
638 host_build_sender_fullhost();
639 #endif /* COMPILE_UTILITY */
640
641 #ifndef COMPILE_UTILITY
642 DEBUG(D_deliver)
643 debug_printf("sender_local=%d ident=%s\n", sender_local,
644 (sender_ident == NULL)? US"unset" : sender_ident);
645 #endif /* COMPILE_UTILITY */
646
647 /* We now have the tree of addresses NOT to deliver to, or a line
648 containing "XX", indicating no tree. */
649
650 if (Ustrncmp(big_buffer, "XX\n", 3) != 0 &&
651 !read_nonrecipients_tree(&tree_nonrecipients, f, big_buffer, big_buffer_size))
652 goto SPOOL_FORMAT_ERROR;
653
654 #ifndef COMPILE_UTILITY
655 DEBUG(D_deliver)
656 {
657 debug_printf("Non-recipients:\n");
658 debug_print_tree(tree_nonrecipients);
659 }
660 #endif /* COMPILE_UTILITY */
661
662 /* After reading the tree, the next line has not yet been read into the
663 buffer. It contains the count of recipients which follow on separate lines. */
664
665 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
666 if (sscanf(CS big_buffer, "%d", &rcount) != 1) goto SPOOL_FORMAT_ERROR;
667
668 #ifndef COMPILE_UTILITY
669 DEBUG(D_deliver) debug_printf("recipients_count=%d\n", rcount);
670 #endif /* COMPILE_UTILITY */
671
672 recipients_list_max = rcount;
673 recipients_list = store_get(rcount * sizeof(recipient_item));
674
675 for (recipients_count = 0; recipients_count < rcount; recipients_count++)
676 {
677 int nn;
678 int pno = -1;
679 int dsn_flags = 0;
680 uschar *orcpt = NULL;
681 uschar *errors_to = NULL;
682 uschar *p;
683
684 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
685 nn = Ustrlen(big_buffer);
686 if (nn < 2) goto SPOOL_FORMAT_ERROR;
687
688 /* Remove the newline; this terminates the address if there is no additional
689 data on the line. */
690
691 p = big_buffer + nn - 1;
692 *p-- = 0;
693
694 /* Look back from the end of the line for digits and special terminators.
695 Since an address must end with a domain, we can tell that extra data is
696 present by the presence of the terminator, which is always some character
697 that cannot exist in a domain. (If I'd thought of the need for additional
698 data early on, I'd have put it at the start, with the address at the end. As
699 it is, we have to operate backwards. Addresses are permitted to contain
700 spaces, you see.)
701
702 This code has to cope with various versions of this data that have evolved
703 over time. In all cases, the line might just contain an address, with no
704 additional data. Otherwise, the possibilities are as follows:
705
706 Exim 3 type: <address><space><digits>,<digits>,<digits>
707
708 The second set of digits is the parent number for one_time addresses. The
709 other values were remnants of earlier experiments that were abandoned.
710
711 Exim 4 first type: <address><space><digits>
712
713 The digits are the parent number for one_time addresses.
714
715 Exim 4 new type: <address><space><data>#<type bits>
716
717 The type bits indicate what the contents of the data are.
718
719 Bit 01 indicates that, reading from right to left, the data
720 ends with <errors_to address><space><len>,<pno> where pno is
721 the parent number for one_time addresses, and len is the length
722 of the errors_to address (zero meaning none).
723
724 Bit 02 indicates that, again reading from right to left, the data continues
725 with orcpt len(orcpt),dsn_flags
726 */
727
728 while (isdigit(*p)) p--;
729
730 /* Handle Exim 3 spool files */
731
732 if (*p == ',')
733 {
734 int dummy;
735 while (isdigit(*(--p)) || *p == ',');
736 if (*p == ' ')
737 {
738 *p++ = 0;
739 (void)sscanf(CS p, "%d,%d", &dummy, &pno);
740 }
741 }
742
743 /* Handle early Exim 4 spool files */
744
745 else if (*p == ' ')
746 {
747 *p++ = 0;
748 (void)sscanf(CS p, "%d", &pno);
749 }
750
751 /* Handle current format Exim 4 spool files */
752
753 else if (*p == '#')
754 {
755 int flags;
756
757 #if !defined (COMPILE_UTILITY)
758 DEBUG(D_deliver) debug_printf("**** SPOOL_IN - Exim 4 standard format spoolfile\n");
759 #endif
760
761 (void)sscanf(CS p+1, "%d", &flags);
762
763 if ((flags & 0x01) != 0) /* one_time data exists */
764 {
765 int len;
766 while (isdigit(*(--p)) || *p == ',' || *p == '-');
767 (void)sscanf(CS p+1, "%d,%d", &len, &pno);
768 *p = 0;
769 if (len > 0)
770 {
771 p -= len;
772 errors_to = string_copy(p);
773 }
774 }
775
776 *(--p) = 0; /* Terminate address */
777 if ((flags & 0x02) != 0) /* one_time data exists */
778 {
779 int len;
780 while (isdigit(*(--p)) || *p == ',' || *p == '-');
781 (void)sscanf(CS p+1, "%d,%d", &len, &dsn_flags);
782 *p = 0;
783 if (len > 0)
784 {
785 p -= len;
786 orcpt = string_copy(p);
787 }
788 }
789
790 *(--p) = 0; /* Terminate address */
791 }
792 #if !defined(COMPILE_UTILITY)
793 else
794 { DEBUG(D_deliver) debug_printf("**** SPOOL_IN - No additional fields\n"); }
795
796 if ((orcpt != NULL) || (dsn_flags != 0))
797 {
798 DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| orcpt: |%s| dsn_flags: %d\n",
799 big_buffer, orcpt, dsn_flags);
800 }
801 if (errors_to != NULL)
802 {
803 DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| errorsto: |%s|\n",
804 big_buffer, errors_to);
805 }
806 #endif
807
808 recipients_list[recipients_count].address = string_copy(big_buffer);
809 recipients_list[recipients_count].pno = pno;
810 recipients_list[recipients_count].errors_to = errors_to;
811 recipients_list[recipients_count].orcpt = orcpt;
812 recipients_list[recipients_count].dsn_flags = dsn_flags;
813 }
814
815 /* The remainder of the spool header file contains the headers for the message,
816 separated off from the previous data by a blank line. Each header is preceded
817 by a count of its length and either a certain letter (for various identified
818 headers), space (for a miscellaneous live header) or an asterisk (for a header
819 that has been rewritten). Count the Received: headers. We read the headers
820 always, in order to check on the format of the file, but only create a header
821 list if requested to do so. */
822
823 inheader = TRUE;
824 if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
825 if (big_buffer[0] != '\n') goto SPOOL_FORMAT_ERROR;
826
827 while ((n = fgetc(f)) != EOF)
828 {
829 header_line *h;
830 uschar flag[4];
831 int i;
832
833 if (!isdigit(n)) goto SPOOL_FORMAT_ERROR;
834 if(ungetc(n, f) == EOF || fscanf(f, "%d%c ", &n, flag) == EOF)
835 goto SPOOL_READ_ERROR;
836 if (flag[0] != '*') message_size += n; /* Omit non-transmitted headers */
837
838 if (read_headers)
839 {
840 h = store_get(sizeof(header_line));
841 h->next = NULL;
842 h->type = flag[0];
843 h->slen = n;
844 h->text = store_get(n+1);
845
846 if (h->type == htype_received) received_count++;
847
848 if (header_list == NULL) header_list = h;
849 else header_last->next = h;
850 header_last = h;
851
852 for (i = 0; i < n; i++)
853 {
854 int c = fgetc(f);
855 if (c == 0 || c == EOF) goto SPOOL_FORMAT_ERROR;
856 if (c == '\n' && h->type != htype_old) message_linecount++;
857 h->text[i] = c;
858 }
859 h->text[i] = 0;
860 }
861
862 /* Not requiring header data, just skip through the bytes */
863
864 else for (i = 0; i < n; i++)
865 {
866 int c = fgetc(f);
867 if (c == 0 || c == EOF) goto SPOOL_FORMAT_ERROR;
868 }
869 }
870
871 /* We have successfully read the data in the header file. Update the message
872 line count by adding the body linecount to the header linecount. Close the file
873 and give a positive response. */
874
875 #ifndef COMPILE_UTILITY
876 DEBUG(D_deliver) debug_printf("body_linecount=%d message_linecount=%d\n",
877 body_linecount, message_linecount);
878 #endif /* COMPILE_UTILITY */
879
880 message_linecount += body_linecount;
881
882 fclose(f);
883 return spool_read_OK;
884
885
886 /* There was an error reading the spool or there was missing data,
887 or there was a format error. A "read error" with no errno means an
888 unexpected EOF, which we treat as a format error. */
889
890 SPOOL_READ_ERROR:
891 if (errno != 0)
892 {
893 n = errno;
894
895 #ifndef COMPILE_UTILITY
896 DEBUG(D_any) debug_printf("Error while reading spool file %s\n", name);
897 #endif /* COMPILE_UTILITY */
898
899 fclose(f);
900 errno = n;
901 return inheader? spool_read_hdrerror : spool_read_enverror;
902 }
903
904 SPOOL_FORMAT_ERROR:
905
906 #ifndef COMPILE_UTILITY
907 DEBUG(D_any) debug_printf("Format error in spool file %s\n", name);
908 #endif /* COMPILE_UTILITY */
909
910 fclose(f);
911 errno = ERRNO_SPOOLFORMAT;
912 return inheader? spool_read_hdrerror : spool_read_enverror;
913 }
914
915 /* vi: aw ai sw=2
916 */
917 /* End of spool_in.c */