More care with time types
[exim.git] / src / src / spool_in.c
index b4506c8aff022186d14c2d9394ed5af752674ba5..6dcb512e42c9c75d7a59ef53d1378b6a197dfcd4 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/spool_in.c,v 1.19 2007/01/08 10:50:18 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2012 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for reading spool files. When compiling for a utility (eximon),
@@ -255,6 +253,7 @@ interface_address = NULL;
 interface_port = 0;
 local_error_message = FALSE;
 local_scan_data = NULL;
+max_received_linelength = 0;
 message_linecount = 0;
 received_protocol = NULL;
 received_count = 0;
@@ -277,20 +276,31 @@ bmi_run = 0;
 bmi_verdicts = NULL;
 #endif
 
-#ifdef EXPERIMENTAL_DOMAINKEYS
-dk_do_verify = 0;
+#ifndef DISABLE_DKIM
+dkim_signers = NULL;
+dkim_disable_verify = FALSE;
+dkim_collect_input = FALSE;
 #endif
 
 #ifdef SUPPORT_TLS
-tls_certificate_verified = FALSE;
-tls_cipher = NULL;
-tls_peerdn = NULL;
+tls_in.certificate_verified = FALSE;
+tls_in.cipher = NULL;
+tls_in.ourcert = NULL;
+tls_in.peercert = NULL;
+tls_in.peerdn = NULL;
+tls_in.sni = NULL;
+tls_in.ocsp = OCSP_NOT_REQ;
 #endif
 
 #ifdef WITH_CONTENT_SCAN
 spam_score_int = NULL;
 #endif
 
+#ifdef EXPERIMENTAL_DSN
+dsn_ret = 0;
+dsn_envid = NULL;
+#endif
+
 /* Generate the full name and open the file. If message_subdir is already
 set, just look in the given directory. Otherwise, look in both the split
 and unsplit directories, as for the data file above. */
@@ -465,13 +475,24 @@ for (;;)
     case 'd':
     if (Ustrcmp(p, "eliver_firsttime") == 0)
       deliver_firsttime = TRUE;
+    #ifdef EXPERIMENTAL_DSN
+    /* Check if the dsn flags have been set in the header file */
+    else if (Ustrncmp(p, "sn_ret", 6) == 0)
+      {
+      dsn_ret= atoi(big_buffer + 8);
+      }
+    else if (Ustrncmp(p, "sn_envid", 8) == 0)
+      {
+      dsn_envid = string_copy(big_buffer + 11);
+      }
+    #endif
     break;
 
     case 'f':
     if (Ustrncmp(p, "rozen", 5) == 0)
       {
       deliver_freeze = TRUE;
-      deliver_frozen_at = Uatoi(big_buffer + 7);
+      sscanf(big_buffer+7, TIME_T_FMT, &deliver_frozen_at);
       }
     break;
 
@@ -518,6 +539,8 @@ for (;;)
 
     case 'm':
     if (Ustrcmp(p, "anual_thaw") == 0) deliver_manual_thaw = TRUE;
+    else if (Ustrncmp(p, "ax_received_linelength", 22) == 0)
+      max_received_linelength = Uatoi(big_buffer + 24);
     break;
 
     case 'N':
@@ -541,11 +564,21 @@ for (;;)
     #ifdef SUPPORT_TLS
     case 't':
     if (Ustrncmp(p, "ls_certificate_verified", 23) == 0)
-      tls_certificate_verified = TRUE;
+      tls_in.certificate_verified = TRUE;
     else if (Ustrncmp(p, "ls_cipher", 9) == 0)
-      tls_cipher = string_copy(big_buffer + 12);
+      tls_in.cipher = string_copy(big_buffer + 12);
+#ifndef COMPILE_UTILITY
+    else if (Ustrncmp(p, "ls_ourcert", 10) == 0)
+      (void) tls_import_cert(big_buffer + 13, &tls_in.ourcert);
+    else if (Ustrncmp(p, "ls_peercert", 11) == 0)
+      (void) tls_import_cert(big_buffer + 14, &tls_in.peercert);
+#endif
     else if (Ustrncmp(p, "ls_peerdn", 9) == 0)
-      tls_peerdn = string_copy(big_buffer + 12);
+      tls_in.peerdn = string_unprinting(string_copy(big_buffer + 12));
+    else if (Ustrncmp(p, "ls_sni", 6) == 0)
+      tls_in.sni = string_unprinting(string_copy(big_buffer + 9));
+    else if (Ustrncmp(p, "ls_ocsp", 7) == 0)
+      tls_in.ocsp = big_buffer[10] - '0';
     break;
     #endif
 
@@ -598,6 +631,10 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
   {
   int nn;
   int pno = -1;
+  #ifdef EXPERIMENTAL_DSN
+  int dsn_flags = 0;
+  uschar *orcpt = NULL;
+  #endif
   uschar *errors_to = NULL;
   uschar *p;
 
@@ -640,6 +677,9 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
       ends with <errors_to address><space><len>,<pno> where pno is
       the parent number for one_time addresses, and len is the length
       of the errors_to address (zero meaning none).
+
+    Bit 02 indicates that, again reading from right to left, the data continues
+     with orcpt len(orcpt),dsn_flags
    */
 
   while (isdigit(*p)) p--;
@@ -670,6 +710,13 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
   else if (*p == '#')
     {
     int flags;
+
+    #ifdef EXPERIMENTAL_DSN
+    #ifndef COMPILE_UTILITY
+      DEBUG(D_deliver) debug_printf("**** SPOOL_IN - Exim 4 standard format spoolfile\n");
+    #endif  /* COMPILE_UTILITY */
+    #endif
+
     (void)sscanf(CS p+1, "%d", &flags);
 
     if ((flags & 0x01) != 0)      /* one_time data exists */
@@ -682,15 +729,54 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
         {
         p -= len;
         errors_to = string_copy(p);
-        }
+        }      
+      }
+
+    *(--p) = 0;   /* Terminate address */
+#ifdef EXPERIMENTAL_DSN
+    if ((flags & 0x02) != 0)      /* one_time data exists */
+      {
+      int len;
+      while (isdigit(*(--p)) || *p == ',' || *p == '-');
+      (void)sscanf(CS p+1, "%d,%d", &len, &dsn_flags);
+      *p = 0;
+      if (len > 0)
+        {
+        p -= len;
+        orcpt = string_copy(p);
+        }      
       }
 
     *(--p) = 0;   /* Terminate address */
+#endif  /* EXPERIMENTAL_DSN */
     }
+#ifdef EXPERIMENTAL_DSN
+  #ifndef COMPILE_UTILITY
+  else
+    {
+       DEBUG(D_deliver) debug_printf("**** SPOOL_IN - No additional fields\n");
+    }
+
+  if ((orcpt != NULL) || (dsn_flags != 0))
+    {
+    DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| orcpt: |%s| dsn_flags: %d\n",
+      big_buffer, orcpt, dsn_flags);
+    }
+  if (errors_to != NULL)
+    {
+    DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| errorsto: |%s|\n",
+      big_buffer, errors_to);
+    }
+  #endif  /* COMPILE_UTILITY */
+#endif  /* EXPERIMENTAL_DSN */
 
   recipients_list[recipients_count].address = string_copy(big_buffer);
   recipients_list[recipients_count].pno = pno;
   recipients_list[recipients_count].errors_to = errors_to;
+  #ifdef EXPERIMENTAL_DSN
+  recipients_list[recipients_count].orcpt = orcpt;
+  recipients_list[recipients_count].dsn_flags = dsn_flags;
+  #endif
   }
 
 /* The remainder of the spool header file contains the headers for the message,
@@ -712,8 +798,8 @@ while ((n = fgetc(f)) != EOF)
   int i;
 
   if (!isdigit(n)) goto SPOOL_FORMAT_ERROR;
-  (void)ungetc(n, f);
-  (void)fscanf(f, "%d%c ", &n, flag);
+  if(ungetc(n, f) == EOF  ||  fscanf(f, "%d%c ", &n, flag) == EOF)
+    goto SPOOL_READ_ERROR;
   if (flag[0] != '*') message_size += n;  /* Omit non-transmitted headers */
 
   if (read_headers)
@@ -793,4 +879,6 @@ errno = ERRNO_SPOOLFORMAT;
 return inheader? spool_read_hdrerror : spool_read_enverror;
 }
 
+/* vi: aw ai sw=2
+*/
 /* End of spool_in.c */