214 spelling fixes
[exim.git] / src / src / transports / appendfile.c
index e5ab657653f45a39dfabb7837aff4d4a4c3d19df..9b3379be2dbe0412dafa2ce16f167c97f6570eeb 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.27 2010/06/07 00:12:42 pdp Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -21,7 +19,7 @@ supported only if SUPPORT_MBX is set. */
 
 enum { mbf_unix, mbf_mbx, mbf_smail, mbf_maildir, mbf_mailstore };
 
-static char *mailbox_formats[] = {
+static const char *mailbox_formats[] = {
   "unix", "mbx", "smail", "maildir", "mailstore" };
 
 
@@ -38,6 +36,10 @@ stored in the publicly visible instance block - these are flagged with the
 opt_public flag. */
 
 optionlist appendfile_transport_options[] = {
+#ifdef SUPPORT_MAILDIR
+  { "*expand_maildir_use_size_file", opt_stringptr,
+      (void *)offsetof(appendfile_transport_options_block, expand_maildir_use_size_file) },
+#endif
   { "*set_use_fcntl_lock",opt_bool | opt_hidden,
       (void *)offsetof(appendfile_transport_options_block, set_use_fcntl) },
   { "*set_use_flock_lock",opt_bool | opt_hidden,
@@ -105,7 +107,7 @@ optionlist appendfile_transport_options[] = {
       (void *)offsetof(appendfile_transport_options_block, maildir_retries) },
   { "maildir_tag",       opt_stringptr,
       (void *)offsetof(appendfile_transport_options_block, maildir_tag) },
-  { "maildir_use_size_file", opt_bool,
+  { "maildir_use_size_file", opt_expand_bool,
       (void *)offsetof(appendfile_transport_options_block, maildir_use_size_file ) } ,
   { "maildirfolder_create_regex", opt_stringptr,
       (void *)offsetof(appendfile_transport_options_block, maildirfolder_create_regex ) },
@@ -184,6 +186,7 @@ appendfile_transport_options_block appendfile_transport_option_defaults = {
   NULL,           /* quota_warn_threshold */
   NULL,           /* mailbox_size_string */
   NULL,           /* mailbox_filecount_string */
+  NULL,           /* expand_maildir_use_size_file */
   US"^(?:cur|new|\\..*)$",  /* maildir_dir_regex */
   NULL,           /* maildir_tag */
   NULL,           /* maildirfolder_create_regex */
@@ -272,6 +275,10 @@ dummy = dummy;
 uid = uid;
 gid = gid;
 
+if (ob->expand_maildir_use_size_file)
+       ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file,
+               US"`maildir_use_size_file` in transport", tblock->name);
+
 /* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size,
 mailbox_filecount */
 
@@ -612,19 +619,18 @@ if (host_find_byname(&host, NULL, 0, NULL, FALSE) == HOST_FIND_FAILED)
 host.address = US"127.0.0.1";
 
 
-for (h = &host; h != NULL; h = h->next)
+for (h = &host; h; h = h->next)
   {
   int sock, rc;
-  int host_af = (Ustrchr(h->address, ':') != NULL)? AF_INET6 : AF_INET;
+  int host_af = Ustrchr(h->address, ':') != NULL ? AF_INET6 : AF_INET;
 
   DEBUG(D_transport) debug_printf("calling comsat on %s\n", h->address);
 
-  sock = ip_socket(SOCK_DGRAM, host_af);
-  if (sock < 0) continue;
+  if ((sock = ip_socket(SOCK_DGRAM, host_af)) < 0) continue;
 
   /* Connect never fails for a UDP socket, so don't set a timeout. */
 
-  (void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0);
+  (void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0, FALSE);
   rc = send(sock, buffer, Ustrlen(buffer) + 1, 0);
   (void)close(sock);
 
@@ -657,7 +663,7 @@ Returns:       pointer to the required transport, or NULL
 transport_instance *
 check_file_format(int cfd, transport_instance *tblock, address_item *addr)
 {
-uschar *format =
+const uschar *format =
   ((appendfile_transport_options_block *)(tblock->options_block))->file_format;
 uschar data[256];
 int len = read(cfd, data, sizeof(data));
@@ -672,15 +678,16 @@ if (len == 0) return tblock;
 
 /* Search the formats for a match */
 
-while ((s = string_nextinlist(&format,&sep,big_buffer,big_buffer_size))!= NULL)
+while ((s = string_nextinlist(&format,&sep,big_buffer,big_buffer_size)))
   {
   int slen = Ustrlen(s);
   BOOL match = len >= slen && Ustrncmp(data, s, slen) == 0;
   uschar *tp = string_nextinlist(&format, &sep, big_buffer, big_buffer_size);
-  if (match)
+
+  if (match && tp)
     {
     transport_instance *tt;
-    for (tt = transports; tt != NULL; tt = tt->next)
+    for (tt = transports; tt; tt = tt->next)
       if (Ustrcmp(tp, tt->name) == 0)
         {
         DEBUG(D_transport)
@@ -1139,7 +1146,7 @@ directory name) is given, that is, when appending to a single file:
 
      Open with O_WRONLY + O_EXCL + O_CREAT with configured mode, unless we know
      this is via a symbolic link (only possible if allow_symlinks is set), in
-     which case don't use O_EXCL, as it dosn't work.
+     which case don't use O_EXCL, as it doesn't work.
 
      If open fails because the file already exists, go to (6f). To avoid
      looping for ever in a situation where the file is continuously being
@@ -1613,6 +1620,7 @@ if (!isdirectory)
 
   if (ob->use_lockfile)
     {
+    /* cf. exim_lock.c */
     lockname = string_sprintf("%s.lock", filename);
     hitchname = string_sprintf( "%s.%s.%08x.%08x", lockname, primary_hostname,
       (unsigned int)(time(NULL)), (unsigned int)getpid());
@@ -1764,8 +1772,14 @@ if (!isdirectory)
       /* We have successfully created and opened the file. Ensure that the group
       and the mode are correct. */
 
-      (void)Uchown(filename, uid, gid);
-      (void)Uchmod(filename, mode);
+      if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+        {
+        addr->basic_errno = errno;
+        addr->message = string_sprintf("while setting perms on mailbox %s",
+          filename);
+        addr->transport_return = FAIL;
+        goto RETURN;
+        }
       }
 
 
@@ -2419,18 +2433,12 @@ else
           "%s/maildirsize", check_path);
         return FALSE;
         }
-      else if (maildirsize_fd == -2)
-        {
-        DEBUG(D_transport) debug_printf("disabling quota check because of "
-          "races updating %s/maildirsize", check_path);
-        disable_quota = TRUE;
-        }
+      /* can also return -2, which means that the file was removed because of
+      raciness; but in this case, the size & filecount will still have been
+      updated. */
 
-      if (maildirsize_fd >= 0)
-        {
-        if (mailbox_size < 0) mailbox_size = size;
-        if (mailbox_filecount < 0) mailbox_filecount = filecount;
-        }
+      if (mailbox_size < 0) mailbox_size = size;
+      if (mailbox_filecount < 0) mailbox_filecount = filecount;
       }
 
     /* No quota enforcement; ensure file does *not* exist; calculate size if
@@ -2532,8 +2540,8 @@ else
       uschar *basename;
 
       (void)gettimeofday(&msg_tv, NULL);
-      basename = string_sprintf("%lu.H%luP%lu.%s", msg_tv.tv_sec,
-        msg_tv.tv_usec, getpid(), primary_hostname);
+      basename = string_sprintf(TIME_T_FMT ".H%luP%lu.%s",
+               msg_tv.tv_sec, msg_tv.tv_usec, getpid(), primary_hostname);
 
       filename = dataname = string_sprintf("tmp/%s", basename);
       newname = string_sprintf("new/%s", basename);
@@ -2572,8 +2580,13 @@ else
     /* Why are these here? Put in because they are present in the non-maildir
     directory case above. */
 
-    (void)Uchown(filename, uid, gid);
-    (void)Uchmod(filename, mode);
+    if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on maildir %s",
+        filename);
+      return FALSE;
+      }
     }
 
   #endif  /* SUPPORT_MAILDIR */
@@ -2614,8 +2627,13 @@ else
     /* Why are these here? Put in because they are present in the non-maildir
     directory case above. */
 
-    (void)Uchown(filename, uid, gid);
-    (void)Uchmod(filename, mode);
+    if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on file %s",
+        filename);
+      return FALSE;
+      }
 
     /* Built a C stream from the open file descriptor. */
 
@@ -2706,8 +2724,13 @@ else
       Uunlink(filename);
       return FALSE;
       }
-    (void)Uchown(dataname, uid, gid);
-    (void)Uchmod(dataname, mode);
+    if(Uchown(dataname, uid, gid) || Uchmod(dataname, mode))
+      {
+      addr->basic_errno = errno;
+      addr->message = string_sprintf("while setting perms on file %s",
+        dataname);
+      return FALSE;
+      }
     }
 
   #endif  /* SUPPORT_MAILSTORE */
@@ -2716,8 +2739,13 @@ else
   /* In all cases of writing to a new file, ensure that the file which is
   going to be renamed has the correct ownership and mode. */
 
-  (void)Uchown(filename, uid, gid);
-  (void)Uchmod(filename, mode);
+  if(Uchown(filename, uid, gid) || Uchmod(filename, mode))
+    {
+    addr->basic_errno = errno;
+    addr->message = string_sprintf("while setting perms on file %s",
+      filename);
+    return FALSE;
+    }
   }
 
 
@@ -2845,9 +2873,14 @@ at initialization time. */
 
 if (yield == OK)
   {
-  if (!transport_write_message(addr, fd, ob->options, 0, tblock->add_headers,
-      tblock->remove_headers, ob->check_string, ob->escape_string,
-      tblock->rewrite_rules, tblock->rewrite_existflags))
+  transport_ctx tctx = {
+    tblock,
+    addr,
+    ob->check_string,
+    ob->escape_string,
+    ob->options
+  };
+  if (!transport_write_message(fd, &tctx, 0))
     yield = DEFER;
   }
 
@@ -2927,7 +2960,8 @@ if (!disable_quota)
   if (yield == OK && maildirsize_fd >= 0)
     maildir_record_length(maildirsize_fd, message_size);
   maildir_save_errno = errno;    /* Preserve errno while closing the file */
-  (void)close(maildirsize_fd);
+  if (maildirsize_fd >= 0)
+    (void)close(maildirsize_fd);
   errno = maildir_save_errno;
   }
 #endif  /* SUPPORT_MAILDIR */
@@ -3093,7 +3127,8 @@ if (yield != OK)
   investigated so far have ftruncate(), whereas not all have the F_FREESP
   fcntl() call (BSDI & FreeBSD do not). */
 
-  if (!isdirectory) (void)ftruncate(fd, saved_size);
+  if (!isdirectory && ftruncate(fd, saved_size))
+    DEBUG(D_transport) debug_printf("Error resetting file size\n");
   }
 
 /* Handle successful writing - we want the modification time to be now for