Add tcp_wrappers_daemon_name (closes: bug #278)
[exim.git] / src / src / readconf.c
index fbba2069087e50fad83b09962b2a0eefc0c753d0..33f10690b8670da900c0e65fd32d000db5f80063 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.41 2010/06/07 00:12:42 pdp Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.44 2010/06/12 15:21:26 jetmore Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -399,6 +399,9 @@ static optionlist optionlist_config[] = {
   { "system_filter_reply_transport",opt_stringptr,&system_filter_reply_transport },
   { "system_filter_user",       opt_uid,         &system_filter_uid },
   { "tcp_nodelay",              opt_bool,        &tcp_nodelay },
+#ifdef USE_TCP_WRAPPERS
+  { "tcp_wrappers_daemon_name", opt_stringptr,   &tcp_wrappers_daemon_name },
+#endif
   { "timeout_frozen_after",     opt_time,        &timeout_frozen_after },
   { "timezone",                 opt_stringptr,   &timezone_string },
 #ifdef SUPPORT_TLS
@@ -1358,6 +1361,7 @@ uid_t uid;
 gid_t gid;
 BOOL boolvalue = TRUE;
 BOOL freesptr = TRUE;
+BOOL extra_condition = FALSE;
 optionlist *ol, *ol2;
 struct passwd *pw;
 void *reset_point;
@@ -1365,6 +1369,8 @@ int intbase = 0;
 uschar *inttype = US"";
 uschar *sptr;
 uschar *s = buffer;
+uschar *saved_condition, *strtemp;
+uschar **str_target;
 uschar name[64];
 uschar name2[64];
 
@@ -1422,8 +1428,11 @@ if ((ol->type & opt_set) != 0)
   {
   uschar *mname = name;
   if (Ustrncmp(mname, "no_", 3) == 0) mname += 3;
-  log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
-    "\"%s\" option set for the second time", mname);
+  if (Ustrcmp(mname, "condition") == 0)
+    extra_condition = TRUE;
+  else
+    log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
+      "\"%s\" option set for the second time", mname);
   }
 
 ol->type |= opt_set | issecure;
@@ -1504,6 +1513,39 @@ switch (type)
     control block and flags word. */
 
     case opt_stringptr:
+    if (data_block == NULL)
+      str_target = (uschar **)(ol->value);
+    else
+      str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
+    if (extra_condition)
+      {
+      /* We already have a condition, we're conducting a crude hack to let
+      multiple condition rules be chained together, despite storing them in
+      text form. */
+      saved_condition = *str_target;
+      strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
+          saved_condition, sptr);
+      *str_target = string_copy_malloc(strtemp);
+      /* TODO(pdp): there is a memory leak here when we set 3 or more
+      conditions; I still don't understand the store mechanism enough
+      to know what's the safe way to free content from an earlier store.
+      AFAICT, stores stack, so freeing an early stored item also stores
+      all data alloc'd after it.  If we knew conditions were adjacent,
+      we could survive that, but we don't.  So I *think* we need to take
+      another bit from opt_type to indicate "malloced"; this seems like
+      quite a hack, especially for this one case.  It also means that
+      we can't ever reclaim the store from the *first* condition.
+
+      Because we only do this once, near process start-up, I'm prepared to
+      let this slide for the time being, even though it rankles.  */
+      }
+    else
+      {
+      *str_target = sptr;
+      freesptr = FALSE;
+      }
+    break;
+
     case opt_rewrite:
     if (data_block == NULL)
       *((uschar **)(ol->value)) = sptr;