Overhaul the debug_selector and log_selector machinery to support variable-length...
authorTony Finch <dot@dotat.at>
Thu, 13 Aug 2015 14:16:48 +0000 (15:16 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 14 Aug 2015 14:55:47 +0000 (15:55 +0100)
21 files changed:
doc/doc-txt/ChangeLog
src/src/acl.c
src/src/daemon.c
src/src/deliver.c
src/src/exim.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/host.c
src/src/log.c
src/src/macros.h
src/src/match.c
src/src/rda.c
src/src/receive.c
src/src/rewrite.c
src/src/smtp_in.c
src/src/structs.h
src/src/tls-openssl.c
src/src/transports/lmtp.c
src/src/transports/smtp.c
src/src/verify.c

index 45eea03195aca4948c6c8209e3bb4b45c7514de4..c3904dab9cc68d02417d38c0c0d30dad09e890d2 100644 (file)
@@ -9,6 +9,9 @@ JH/01 Bug 1664: Disable OCSP for GnuTLS library versions at/before 3.3.16
       it does even when not requested, resulting in a stapling non-aware
       client dropping the TLS connection.
 
+TF/01 Code cleanup: Overhaul the debug_selector and log_selector machinery to
+      support variable-length bit vectors. No functional change.
+
 
 Exim version 4.86
 -----------------
index 91ee571481d942c0007abe55bb086faedd15fb7c..f2e0ef28ba433484d0fe58adcd8bb7e206d2866e 100644 (file)
@@ -4287,7 +4287,7 @@ while (acl != NULL)
     case ACL_WARN:
     if (cond == OK)
       acl_warn(where, *user_msgptr, *log_msgptr);
-    else if (cond == DEFER && (log_extra_selector & LX_acl_warn_skipped) != 0)
+    else if (cond == DEFER && LOGGING(acl_warn_skipped))
       log_write(0, LOG_MAIN, "%s Warning: ACL \"warn\" statement skipped: "
         "condition test deferred%s%s", host_and_ident(TRUE),
         (*log_msgptr == NULL)? US"" : US": ",
index 894a96f25780ed80cb48feb383431d69345a0ca6..2d10387f6345fd21706cee946431ceeefe20c722 100644 (file)
@@ -145,7 +145,7 @@ int dup_accept_socket = -1;
 int max_for_this_host = 0;
 int wfsize = 0;
 int wfptr = 0;
-int use_log_write_selector = log_write_selector;
+int save_log_selector = *log_selector;
 uschar *whofrom = NULL;
 
 void *reset_point = store_get(0);
@@ -206,11 +206,11 @@ memory is reclaimed. */
 
 whofrom = string_append(whofrom, &wfsize, &wfptr, 3, "[", sender_host_address, "]");
 
-if ((log_extra_selector & LX_incoming_port) != 0)
+if (LOGGING(incoming_port))
   whofrom = string_append(whofrom, &wfsize, &wfptr, 2, ":", string_sprintf("%d",
     sender_host_port));
 
-if ((log_extra_selector & LX_incoming_interface) != 0)
+if (LOGGING(incoming_interface))
   whofrom = string_append(whofrom, &wfsize, &wfptr, 4, " I=[",
     interface_address, "]:", string_sprintf("%d", interface_port));
 
@@ -338,11 +338,11 @@ the generalized logging code each time when the selector is false. If the
 selector is set, check whether the host is on the list for logging. If not,
 arrange to unset the selector in the subprocess. */
 
-if ((log_write_selector & L_smtp_connection) != 0)
+if (LOGGING(smtp_connection))
   {
   uschar *list = hosts_connection_nolog;
   if (list != NULL && verify_check_host(&list) == OK)
-    use_log_write_selector &= ~L_smtp_connection;
+    save_log_selector &= ~L_smtp_connection;
   else
     log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %s "
       "(TCP/IP connection count = %d)", whofrom, smtp_accept_count + 1);
@@ -372,7 +372,7 @@ if (pid == 0)
 
   /* May have been modified for the subprocess */
 
-  log_write_selector = use_log_write_selector;
+  *log_selector = save_log_selector;
 
   /* Get the local interface address into permanent store */
 
index 78f8f4bd47163cc5570dae14978ebf344de551fb..c796de040229fd73061285305c4942dc4069a141 100644 (file)
@@ -682,7 +682,7 @@ d_hostlog(uschar * s, int * sizep, int * ptrp, address_item * addr)
 {
   s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
     US" [", addr->host_used->address, US"]");
-  if ((log_extra_selector & LX_outgoing_port) != 0)
+  if (LOGGING(outgoing_port))
     s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
       addr->host_used->port));
   return s;
@@ -692,10 +692,9 @@ d_hostlog(uschar * s, int * sizep, int * ptrp, address_item * addr)
 static uschar *
 d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
 {
-  if ((log_extra_selector & LX_tls_cipher) != 0 && addr->cipher != NULL)
+  if (LOGGING(tls_cipher) && addr->cipher != NULL)
     s = string_append(s, sizep, ptrp, 2, US" X=", addr->cipher);
-  if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
-       addr->cipher != NULL)
+  if (LOGGING(tls_certificate_verified) && addr->cipher != NULL)
     s = string_append(s, sizep, ptrp, 2, US" CV=",
       testflag(addr, af_cert_verified)
       ?
@@ -706,7 +705,7 @@ d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
 #endif
         "yes"
       : "no");
-  if ((log_extra_selector & LX_tls_peerdn) != 0 && addr->peerdn != NULL)
+  if (LOGGING(tls_peerdn) && addr->peerdn != NULL)
     s = string_append(s, sizep, ptrp, 3, US" DN=\"",
       string_printing(addr->peerdn), US"\"");
   return s;
@@ -808,7 +807,7 @@ pointer to a single host item in their host list, for use by the transport. */
 
 s = reset_point = store_get(size);
 
-log_address = string_log_address(addr, (log_write_selector & L_all_parents) != 0, TRUE);
+log_address = string_log_address(addr, LOGGING(all_parents), TRUE);
 if (msg)
   s = string_append(s, &size, &ptr, 3, host_and_ident(TRUE), US" ", log_address);
 else
@@ -817,11 +816,11 @@ else
   s = string_append(s, &size, &ptr, 2, US"> ", log_address);
   }
 
-if (log_extra_selector & LX_incoming_interface  &&  sending_ip_address)
+if (LOGGING(incoming_interface) && sending_ip_address)
   s = string_append(s, &size, &ptr, 3, US" I=[", sending_ip_address, US"]");
   /* for the port:  string_sprintf("%d", sending_port) */
 
-if ((log_extra_selector & LX_sender_on_delivery) != 0  ||  msg)
+if (LOGGING(sender_on_delivery) || msg)
   s = string_append(s, &size, &ptr, 3, US" F=<",
 #ifdef EXPERIMENTAL_INTERNATIONAL
     testflag(addr, af_utf8_downcvt)
@@ -841,8 +840,7 @@ delivery; indeed, I did for some time, until this statement crashed. The case
 when it is not set is for a delivery to /dev/null which is optimised by not
 being run at all. */
 
-if (used_return_path != NULL &&
-      (log_extra_selector & LX_return_path_on_delivery) != 0)
+if (used_return_path != NULL && LOGGING(return_path_on_delivery))
   s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
 
 if (msg)
@@ -854,7 +852,7 @@ if (addr->router != NULL)
 
 s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name);
 
-if ((log_extra_selector & LX_delivery_size) != 0)
+if (LOGGING(delivery_size))
   s = string_append(s, &size, &ptr, 2, US" S=",
     string_sprintf("%d", transport_count));
 
@@ -901,7 +899,7 @@ else
     if (addr->auth_id)
       {
       s = string_append(s, &size, &ptr, 2, US":", addr->auth_id);
-      if (log_extra_selector & LX_smtp_mailauth  &&  addr->auth_sndr)
+      if (LOGGING(smtp_mailauth) && addr->auth_sndr)
         s = string_append(s, &size, &ptr, 2, US":", addr->auth_sndr);
       }
     }
@@ -914,8 +912,7 @@ else
 
 /* confirmation message (SMTP (host_used) and LMTP (driver_name)) */
 
-if (log_extra_selector & LX_smtp_confirmation &&
-    addr->message &&
+if (LOGGING(smtp_confirmation) && addr->message &&
     (addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0))
   {
   unsigned i;
@@ -935,11 +932,11 @@ if (log_extra_selector & LX_smtp_confirmation &&
 
 /* Time on queue and actual time taken to deliver */
 
-if ((log_extra_selector & LX_queue_time) != 0)
+if (LOGGING(queue_time))
   s = string_append(s, &size, &ptr, 2, US" QT=",
     readconf_printtime( (int) ((long)time(NULL) - (long)received_time)) );
 
-if ((log_extra_selector & LX_deliver_time) != 0)
+if (LOGGING(deliver_time))
   s = string_append(s, &size, &ptr, 2, US" DT=",
     readconf_printtime(addr->more_errno));
 
@@ -1230,8 +1227,7 @@ else if (result == DEFER || result == PANIC)
     /* Create the address string for logging. Must not do this earlier, because
     an OK result may be changed to FAIL when a pipe returns text. */
 
-    log_address = string_log_address(addr,
-      (log_write_selector & L_all_parents) != 0, result == OK);
+    log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
 
     s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
 
@@ -1342,18 +1338,16 @@ else
   /* Create the address string for logging. Must not do this earlier, because
   an OK result may be changed to FAIL when a pipe returns text. */
 
-  log_address = string_log_address(addr,
-    (log_write_selector & L_all_parents) != 0, result == OK);
+  log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
 
   s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
 
-  if ((log_extra_selector & LX_sender_on_delivery) != 0)
+  if (LOGGING(sender_on_delivery))
     s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
 
   /* Return path may not be set if no delivery actually happened */
 
-  if (used_return_path != NULL &&
-      (log_extra_selector & LX_return_path_on_delivery) != 0)
+  if (used_return_path != NULL && LOGGING(return_path_on_delivery))
     s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
 
   if (addr->router != NULL)
@@ -4449,7 +4443,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
       }
 
     /* Local interface address/port */
-    if (log_extra_selector & LX_incoming_interface  &&  sending_ip_address)
+    if (LOGGING(incoming_interface) && sending_ip_address)
       {
       uschar * ptr = big_buffer;
       sprintf(CS ptr, "%.128s", sending_ip_address);
@@ -7365,7 +7359,7 @@ if (addr_defer == NULL)
 
   /* Log the end of this message, with queue time if requested. */
 
-  if ((log_extra_selector & LX_queue_time_overall) != 0)
+  if (LOGGING(queue_time_overall))
     log_write(0, LOG_MAIN, "Completed QT=%s",
       readconf_printtime( (int) ((long)time(NULL) - (long)received_time)) );
   else
index f9d57ab9c614d72b3abca990689e988b5e92f9a9..d7cb5d88b13e90bff71642b90cf257c747e352ba 100644 (file)
@@ -1639,6 +1639,10 @@ if (log_buffer == NULL)
   exit(EXIT_FAILURE);
   }
 
+/* Initialize the default log options. */
+
+bits_set(log_selector, log_selector_size, log_default);
+
 /* Set log_stderr to stderr, provided that stderr exists. This gets reset to
 NULL when the daemon is run and the file is closed. We have to use this
 indirection, because some systems don't allow writing to the variable "stderr".
@@ -2451,8 +2455,8 @@ for (i = 1; i < argc; i++)
         argrest++;
         }
       if (*argrest != 0)
-        decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options,
-          debug_options_count, US"debug", 0);
+        decode_bits(&selector, 1, debug_notall, argrest,
+          debug_options, debug_options_count, US"debug", 0);
       debug_selector = selector;
       }
     break;
@@ -3787,14 +3791,17 @@ else
 
 /* Handle the decoding of logging options. */
 
-decode_bits(&log_write_selector, &log_extra_selector, 0, 0,
+decode_bits(log_selector, log_selector_size, log_notall,
   log_selector_string, log_options, log_options_count, US"log", 0);
 
 DEBUG(D_any)
   {
+  int i;
   debug_printf("configuration file is %s\n", config_main_filename);
-  debug_printf("log selectors = %08x %08x\n", log_write_selector,
-    log_extra_selector);
+  debug_printf("log selectors =");
+  for (i = 0; i < log_selector_size; i++)
+    debug_printf(" %08x", log_selector[i]);
+  debug_printf("\n");
   }
 
 /* If domain literals are not allowed, check the sender address that was
@@ -4001,7 +4008,7 @@ a debugging feature for finding out what arguments certain MUAs actually use.
 Don't attempt it if logging is disabled, or if listing variables or if
 verifying/testing addresses or expansions. */
 
-if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
+if (((debug_selector & D_any) != 0 || LOGGING(arguments))
       && really_exim && !list_options && !checking)
   {
   int i;
@@ -4036,7 +4043,7 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
     while (*p) p++;
     }
 
-  if ((log_extra_selector & LX_arguments) != 0)
+  if (LOGGING(arguments))
     log_write(0, LOG_MAIN, "%s", big_buffer);
   else
     debug_printf("%s\n", big_buffer);
@@ -5021,7 +5028,7 @@ if (host_checking)
       sender_host_address);
 
   if (verify_check_host(&hosts_connection_nolog) == OK)
-    log_write_selector &= ~L_smtp_connection;
+    BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection);
   log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info());
 
   /* NOTE: We do *not* call smtp_log_no_mail() if smtp_start_session() fails,
@@ -5195,7 +5202,7 @@ if (smtp_input)
   smtp_in = stdin;
   smtp_out = stdout;
   if (verify_check_host(&hosts_connection_nolog) == OK)
-    log_write_selector &= ~L_smtp_connection;
+    BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection);
   log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info());
   if (!smtp_start_session())
     {
index 02579040eccc1731c260877aec042a87e07c39f4..4af0017c1d4f844dd7d339a0c189e25d789303c4 100644 (file)
@@ -99,6 +99,9 @@ extern int     auth_get_no64_data(uschar **, uschar *);
 extern uschar *auth_xtextencode(uschar *, int);
 extern int     auth_xtextdecode(uschar *, uschar **);
 
+extern void    bits_clear(unsigned int *, size_t, int *);
+extern void    bits_set(unsigned int *, size_t, int *);
+
 extern void    cancel_cutthrough_connection(const char *);
 extern int     check_host(void *, const uschar *, const uschar **, uschar **);
 extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
@@ -123,8 +126,8 @@ extern void    debug_print_ids(uschar *);
 extern void    debug_print_string(uschar *);
 extern void    debug_print_tree(tree_node *);
 extern void    debug_vprintf(const char *, va_list);
-extern void    decode_bits(unsigned int *, unsigned int *,
-                  int, int, uschar *, bit_table *, int, uschar *, int);
+extern void    decode_bits(unsigned int *, size_t, int *,
+                  uschar *, bit_table *, int, uschar *, int);
 extern address_item *deliver_make_addr(uschar *, BOOL);
 extern void    deliver_init(void);
 extern void    delivery_log(int, address_item *, int, uschar *);
index 66baffe450257af3a53b693042eca1ac0c4062ce..1344b5aeda133b75a87688232632ce57f4dde5b7 100644 (file)
@@ -536,40 +536,45 @@ uschar *dccifd_options         = US"header";
 BOOL    debug_daemon           = FALSE;
 int     debug_fd               = -1;
 FILE   *debug_file             = NULL;
-bit_table debug_options[]      = {
-  { US"acl",            D_acl },
-  { US"all",            D_all },
-  { US"auth",           D_auth },
-  { US"deliver",        D_deliver },
-  { US"dns",            D_dns },
-  { US"dnsbl",          D_dnsbl },
-  { US"exec",           D_exec },
-  { US"expand",         D_expand },
-  { US"filter",         D_filter },
-  { US"hints_lookup",   D_hints_lookup },
-  { US"host_lookup",    D_host_lookup },
-  { US"ident",          D_ident },
-  { US"interface",      D_interface },
-  { US"lists",          D_lists },
-  { US"load",           D_load },
-  { US"local_scan",     D_local_scan },
-  { US"lookup",         D_lookup },
-  { US"memory",         D_memory },
-  { US"pid",            D_pid },
-  { US"process_info",   D_process_info },
-  { US"queue_run",      D_queue_run },
-  { US"receive",        D_receive },
-  { US"resolver",       D_resolver },
-  { US"retry",          D_retry },
-  { US"rewrite",        D_rewrite },
-  { US"route",          D_route },
-  { US"timestamp",      D_timestamp },
-  { US"tls",            D_tls },
-  { US"transport",      D_transport },
-  { US"uid",            D_uid },
-  { US"verify",         D_verify }
+int     debug_notall[]         = {
+  Di_memory,
+  -1
 };
-int     debug_options_count    = sizeof(debug_options)/sizeof(bit_table);
+bit_table debug_options[]      = { /* must be in alphabetical order */
+  BIT_TABLE(D, acl),
+  BIT_TABLE(D, all),
+  BIT_TABLE(D, auth),
+  BIT_TABLE(D, deliver),
+  BIT_TABLE(D, dns),
+  BIT_TABLE(D, dnsbl),
+  BIT_TABLE(D, exec),
+  BIT_TABLE(D, expand),
+  BIT_TABLE(D, filter),
+  BIT_TABLE(D, hints_lookup),
+  BIT_TABLE(D, host_lookup),
+  BIT_TABLE(D, ident),
+  BIT_TABLE(D, interface),
+  BIT_TABLE(D, lists),
+  BIT_TABLE(D, load),
+  BIT_TABLE(D, local_scan),
+  BIT_TABLE(D, lookup),
+  BIT_TABLE(D, memory),
+  BIT_TABLE(D, pid),
+  BIT_TABLE(D, process_info),
+  BIT_TABLE(D, queue_run),
+  BIT_TABLE(D, receive),
+  BIT_TABLE(D, resolver),
+  BIT_TABLE(D, retry),
+  BIT_TABLE(D, rewrite),
+  BIT_TABLE(D, route),
+  BIT_TABLE(D, timestamp),
+  BIT_TABLE(D, tls),
+  BIT_TABLE(D, transport),
+  BIT_TABLE(D, uid),
+  BIT_TABLE(D, verify),
+};
+int     debug_options_count    = nelem(debug_options);
+
 unsigned int debug_selector    = 0;
 int     delay_warning[DELAY_WARNING_SIZE] = { DELAY_WARNING_SIZE, 1, 24*60*60 };
 uschar *delay_warning_condition=
@@ -813,78 +818,91 @@ uid_t   local_user_uid         = (uid_t)(-1);
 tree_node *localpartlist_anchor= NULL;
 int     localpartlist_count    = 0;
 uschar *log_buffer             = NULL;
-unsigned int log_extra_selector = LX_default;
+
+int     log_default[]          = { /* for initializing log_selector */
+  Li_acl_warn_skipped,
+  Li_connection_reject,
+  Li_delay_delivery,
+  Li_dnslist_defer,
+  Li_etrn,
+  Li_host_lookup_failed,
+  Li_lost_incoming_connection,
+  Li_queue_run,
+  Li_rejected_header,
+  Li_retry_defer,
+  Li_sender_verify_fail,
+  Li_size_reject,
+  Li_skip_delivery,
+  Li_smtp_confirmation,
+  Li_tls_certificate_verified,
+  Li_tls_cipher,
+  -1
+};
+
 uschar *log_file_path          = US LOG_FILE_PATH
                            "\0<--------------Space to patch log_file_path->";
 
-/* Those log options with L_xxx identifiers have values less than 0x800000 and
-are the ones that get put into log_write_selector. They can be used in calls to
-log_write() to test for the bit. The options with LX_xxx identifiers have
-values greater than 0x80000000 and are put into log_extra_selector (without the
-top bit). They are never used in calls to log_write(), but are tested
-independently. This separation became necessary when the number of log
-selectors was getting close to filling a 32-bit word. */
-
-/* Note that this list must be in alphabetical order. */
-
-bit_table log_options[]        = {
-  { US"8bitmime",                     LX_8bitmime },
-  { US"acl_warn_skipped",             LX_acl_warn_skipped },
-  { US"address_rewrite",              L_address_rewrite },
-  { US"all",                          L_all },
-  { US"all_parents",                  L_all_parents },
-  { US"arguments",                    LX_arguments },
-  { US"connection_reject",            L_connection_reject },
-  { US"delay_delivery",               L_delay_delivery },
-  { US"deliver_time",                 LX_deliver_time },
-  { US"delivery_size",                LX_delivery_size },
-  { US"dnslist_defer",                L_dnslist_defer },
-  { US"etrn",                         L_etrn },
-  { US"host_lookup_failed",           L_host_lookup_failed },
-  { US"ident_timeout",                LX_ident_timeout },
-  { US"incoming_interface",           LX_incoming_interface },
-  { US"incoming_port",                LX_incoming_port },
-  { US"lost_incoming_connection",     L_lost_incoming_connection },
-  { US"outgoing_port",                LX_outgoing_port },
-  { US"pid",                          LX_pid },
+int     log_notall[]           = {
+  -1
+};
+bit_table log_options[]        = { /* must be in alphabetical order */
+  BIT_TABLE(L, 8bitmime),
+  BIT_TABLE(L, acl_warn_skipped),
+  BIT_TABLE(L, address_rewrite),
+  BIT_TABLE(L, all),
+  BIT_TABLE(L, all_parents),
+  BIT_TABLE(L, arguments),
+  BIT_TABLE(L, connection_reject),
+  BIT_TABLE(L, delay_delivery),
+  BIT_TABLE(L, deliver_time),
+  BIT_TABLE(L, delivery_size),
+  BIT_TABLE(L, dnslist_defer),
+  BIT_TABLE(L, etrn),
+  BIT_TABLE(L, host_lookup_failed),
+  BIT_TABLE(L, ident_timeout),
+  BIT_TABLE(L, incoming_interface),
+  BIT_TABLE(L, incoming_port),
+  BIT_TABLE(L, lost_incoming_connection),
+  BIT_TABLE(L, outgoing_port),
+  BIT_TABLE(L, pid),
 #ifdef EXPERIMENTAL_PROXY
-  { US"proxy",                        LX_proxy },
+  BIT_TABLE(L, proxy),
 #endif
-  { US"queue_run",                    L_queue_run },
-  { US"queue_time",                   LX_queue_time },
-  { US"queue_time_overall",           LX_queue_time_overall },
-  { US"received_recipients",          LX_received_recipients },
-  { US"received_sender",              LX_received_sender },
-  { US"rejected_header",              LX_rejected_header },
-  { US"rejected_headers",             LX_rejected_header },
-  { US"retry_defer",                  L_retry_defer },
-  { US"return_path_on_delivery",      LX_return_path_on_delivery },
-  { US"sender_on_delivery",           LX_sender_on_delivery },
-  { US"sender_verify_fail",           LX_sender_verify_fail },
-  { US"size_reject",                  L_size_reject },
-  { US"skip_delivery",                L_skip_delivery },
-  { US"smtp_confirmation",            LX_smtp_confirmation },
-  { US"smtp_connection",              L_smtp_connection },
-  { US"smtp_incomplete_transaction",  L_smtp_incomplete_transaction },
-  { US"smtp_mailauth",                LX_smtp_mailauth },
-  { US"smtp_no_mail",                 LX_smtp_no_mail },
-  { US"smtp_protocol_error",          L_smtp_protocol_error },
-  { US"smtp_syntax_error",            L_smtp_syntax_error },
-  { US"subject",                      LX_subject },
-  { US"tls_certificate_verified",     LX_tls_certificate_verified },
-  { US"tls_cipher",                   LX_tls_cipher },
-  { US"tls_peerdn",                   LX_tls_peerdn },
-  { US"tls_sni",                      LX_tls_sni },
-  { US"unknown_in_list",              LX_unknown_in_list }
+  BIT_TABLE(L, queue_run),
+  BIT_TABLE(L, queue_time),
+  BIT_TABLE(L, queue_time_overall),
+  BIT_TABLE(L, received_recipients),
+  BIT_TABLE(L, received_sender),
+  BIT_TABLE(L, rejected_header),
+  { US"rejected_headers", Li_rejected_header },
+  BIT_TABLE(L, retry_defer),
+  BIT_TABLE(L, return_path_on_delivery),
+  BIT_TABLE(L, sender_on_delivery),
+  BIT_TABLE(L, sender_verify_fail),
+  BIT_TABLE(L, size_reject),
+  BIT_TABLE(L, skip_delivery),
+  BIT_TABLE(L, smtp_confirmation),
+  BIT_TABLE(L, smtp_connection),
+  BIT_TABLE(L, smtp_incomplete_transaction),
+  BIT_TABLE(L, smtp_mailauth),
+  BIT_TABLE(L, smtp_no_mail),
+  BIT_TABLE(L, smtp_protocol_error),
+  BIT_TABLE(L, smtp_syntax_error),
+  BIT_TABLE(L, subject),
+  BIT_TABLE(L, tls_certificate_verified),
+  BIT_TABLE(L, tls_cipher),
+  BIT_TABLE(L, tls_peerdn),
+  BIT_TABLE(L, tls_sni),
+  BIT_TABLE(L, unknown_in_list),
 };
+int     log_options_count      = nelem(log_options);
 
-int     log_options_count      = sizeof(log_options)/sizeof(bit_table);
 int     log_reject_target      = 0;
+unsigned int log_selector[log_selector_size]; /* initialized in main() */
 uschar *log_selector_string    = NULL;
 FILE   *log_stderr             = NULL;
 BOOL    log_testing_mode       = FALSE;
 BOOL    log_timezone           = FALSE;
-unsigned int log_write_selector= L_default;
 uschar *login_sender_address   = NULL;
 uschar *lookup_dnssec_authenticated = NULL;
 int     lookup_open_max        = 25;
index ab03302bbfba57a77eb968913b5458e1347bea27..978a4cc78ab1fe35194ef247ddc3b9c3391dde7a 100644 (file)
@@ -319,6 +319,7 @@ extern uschar *dccifd_options;         /* options for the dccifd daemon */
 extern BOOL    debug_daemon;           /* Debug the daemon process only */
 extern int     debug_fd;               /* The fd for debug_file */
 extern FILE   *debug_file;             /* Where to write debugging info */
+extern int     debug_notall[];         /* Debug options excluded from +all */
 extern bit_table debug_options[];      /* Table of debug options */
 extern int     debug_options_count;    /* Size of table */
 extern int     delay_warning[];        /* Times between warnings */
@@ -531,16 +532,17 @@ extern uid_t   local_user_uid;         /* As it says; may be set in routers */
 extern tree_node *localpartlist_anchor;/* Tree of defined localpart lists */
 extern int     localpartlist_count;    /* Number defined */
 extern uschar *log_buffer;             /* For constructing log entries */
-extern unsigned int log_extra_selector;/* Bit map of logging options other than used by log_write() */
+extern int     log_default[];          /* Initialization list for log_selector */
 extern uschar *log_file_path;          /* If unset, use default */
+extern int     log_notall[];           /* Log options excluded from +all */
 extern bit_table log_options[];        /* Table of options */
 extern int     log_options_count;      /* Size of table */
 extern int     log_reject_target;      /* Target log for ACL rejections */
+extern unsigned int log_selector[];    /* Bit map of logging options */
 extern uschar *log_selector_string;    /* As supplied in the config */
 extern FILE   *log_stderr;             /* Copy of stderr for log use, or NULL */
 extern BOOL    log_testing_mode;       /* TRUE in various testing modes */
 extern BOOL    log_timezone;           /* TRUE to include the timezone in log lines */
-extern unsigned int log_write_selector;/* Bit map of logging options for log_write() */
 extern uschar *login_sender_address;   /* The actual sender address */
 extern lookup_info **lookup_list;      /* Array of pointers to available lookups */
 extern int     lookup_list_count;      /* Number of entries in the list */
index 31c2bbff4251fe81e8468f5e0b858e18c24ac8f7..5c69c7fc25a2dfbcce38f29505da54668af47c73 100644 (file)
@@ -544,7 +544,7 @@ use this directly as the first item for Received: because it ain't an RFC 2822
 domain. Sigh. */
 
 address = string_sprintf("[%s]:%d", sender_host_address, sender_host_port);
-if ((log_extra_selector & LX_incoming_port) == 0 || sender_host_port <= 0)
+if (!LOGGING(incoming_port) || sender_host_port <= 0)
   *(Ustrrchr(address, ':')) = 0;
 
 /* If there's no EHLO/HELO data, we can't show it. */
@@ -695,8 +695,7 @@ else
   {
   uschar *flag = useflag? US"H=" : US"";
   uschar *iface = US"";
-  if ((log_extra_selector & LX_incoming_interface) != 0 &&
-       interface_address != NULL)
+  if (LOGGING(incoming_interface) && interface_address != NULL)
     iface = string_sprintf(" I=[%s]:%d", interface_address, interface_port);
   if (sender_ident == NULL)
     (void)string_format(big_buffer, big_buffer_size, "%s%s%s",
index 11b3edfdfc4303b6a4b39f49c61439daf146dc2e..b2d1fcfc1c5280e06464db6589d7eb4fc502d445 100644 (file)
@@ -613,7 +613,7 @@ If a message_id exists, we include it after the timestamp.
 
 Arguments:
   selector  write to main log or LOG_INFO only if this value is zero, or if
-              its bit is set in log_write_selector
+              its bit is set in log_selector[0]
   flags     each bit indicates some independent action:
               LOG_SENDER      add raw sender to the message
               LOG_RECIPIENTS  add raw recipients list to message
@@ -749,15 +749,12 @@ DEBUG(D_any|D_v)
   Ustrcpy(ptr, "LOG:");
   ptr += 4;
 
-  /* Show the options that were passed into the call. These are those whose
-  flag values do not have the 0x80000000 bit in them. Note that this
-  automatically exclude the "all" setting. */
+  /* Show the selector that was passed into the call. */
 
   for (i = 0; i < log_options_count; i++)
     {
     unsigned int bit = log_options[i].bit;
-    if ((bit & 0x80000000) != 0) continue;
-    if ((selector & bit) != 0)
+    if (bit < BITWORDSIZE && selector == BIT(bit))
       {
       *ptr++ = ' ';
       Ustrcpy(ptr, log_options[i].name);
@@ -809,7 +806,7 @@ ptr = log_buffer;
 sprintf(CS ptr, "%s ", tod_stamp(tod_log));
 while(*ptr) ptr++;
 
-if ((log_extra_selector & LX_pid) != 0)
+if (LOGGING(pid))
   {
   sprintf(CS ptr, "[%d] ", (int)getpid());
   while (*ptr) ptr++;
@@ -869,7 +866,7 @@ or unless there is no log_stderr (expn called from daemon, for example). */
 if (!really_exim || log_testing_mode)
   {
   if (debug_selector == 0 && log_stderr != NULL &&
-      (selector == 0 || (selector & log_write_selector) != 0))
+      (selector == 0 || (selector & log_selector[0]) != 0))
     {
     if (host_checking)
       fprintf(log_stderr, "LOG: %s", CS(log_buffer + 20));  /* no timestamp */
@@ -887,7 +884,7 @@ has been renamed. Therefore, do a stat() and see if the inode has changed, and
 if so, re-open. */
 
 if ((flags & LOG_MAIN) != 0 &&
-    (selector == 0 || (selector & log_write_selector) != 0))
+    (selector == 0 || (selector & log_selector[0]) != 0))
   {
   if ((logging_mode & LOG_MODE_SYSLOG) != 0 &&
       (syslog_duplication || (flags & (LOG_REJECT|LOG_PANIC)) == 0))
@@ -956,7 +953,7 @@ if ((flags & LOG_REJECT) != 0)
   {
   header_line *h;
 
-  if (header_list != NULL && (log_extra_selector & LX_rejected_header) != 0)
+  if (header_list != NULL && LOGGING(rejected_header))
     {
     if (recipients_count > 0)
       {
@@ -1141,6 +1138,35 @@ syslog_open = FALSE;
 
 
 
+/*************************************************
+*             Multi-bit set or clear             *
+*************************************************/
+
+/* These functions take a list of bit indexes (terminated by -1) and
+clear or set the corresponding bits in the selector.
+
+Arguments:
+  selector       address of the bit string
+  selsize        number of words in the bit string
+  bits           list of bits to set
+*/
+
+void
+bits_clear(unsigned int *selector, size_t selsize, int *bits)
+{
+for(; *bits != -1; ++bits)
+  BIT_CLEAR(selector, selsize, *bits);
+}
+
+void
+bits_set(unsigned int *selector, size_t selsize, int *bits)
+{
+for(; *bits != -1; ++bits)
+  BIT_SET(selector, selsize, *bits);
+}
+
+
+
 /*************************************************
 *         Decode bit settings for log/debug      *
 *************************************************/
@@ -1151,13 +1177,9 @@ also recognizes a numeric setting of the form =<number>, but this is not
 intended for user use. It's an easy way for Exim to pass the debug settings
 when it is re-exec'ed.
 
-The log options are held in two unsigned ints (because there became too many
-for one). The top bit in the table means "put in 2nd selector". This does not
-yet apply to debug options, so the "=" facility sets only the first selector.
-
-The "all" selector, which must be equal to 0xffffffff, is recognized specially.
-It sets all the bits in both selectors. However, there is a facility for then
-unsetting certain bits, because we want to turn off "memory" in the debug case.
+The option table is a list of names and bit indexes. The index -1
+means "set all bits, except for those listed in notall". The notall
+list is terminated by -1.
 
 The action taken for bad values varies depending upon why we're here.
 For log messages, or if the debugging is triggered from config, then we write
@@ -1165,10 +1187,9 @@ to the log on the way out.  For debug setting triggered from the command-line,
 we treat it as an unknown option: error message to stderr and die.
 
 Arguments:
-  selector1      address of the first bit string
-  selector2      address of the second bit string, or NULL
-  notall1        bits to exclude from "all" for selector1
-  notall2        bits to exclude from "all" for selector2
+  selector       address of the bit string
+  selsize        number of words in the bit string
+  notall         list of bits to exclude from "all"
   string         the configured string
   options        the table of option names
   count          size of table
@@ -1179,9 +1200,8 @@ Returns:         nothing on success - bomb out on failure
 */
 
 void
-decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1,
-  int notall2, uschar *string, bit_table *options, int count, uschar *which,
-  int flags)
+decode_bits(unsigned int *selector, size_t selsize, int *notall,
+  uschar *string, bit_table *options, int count, uschar *which, int flags)
 {
 uschar *errmsg;
 if (string == NULL) return;
@@ -1189,7 +1209,8 @@ if (string == NULL) return;
 if (*string == '=')
   {
   char *end;    /* Not uschar */
-  *selector1 = strtoul(CS string+1, &end, 0);
+  memset(selector, 0, sizeof(*selector)*selsize);
+  *selector = strtoul(CS string+1, &end, 0);
   if (*end == 0) return;
   errmsg = string_sprintf("malformed numeric %s_selector setting: %s", which,
     string);
@@ -1232,40 +1253,22 @@ else for(;;)
       if (middle->name[len] != 0) c = -1; else
         {
         unsigned int bit = middle->bit;
-        unsigned int *selector;
-
-        /* The value with all bits set means "force all bits in both selectors"
-        in the case where two are being handled. However, the top bit in the
-        second selector is never set. When setting, some bits can be excluded.
-        */
-
-        if (bit == 0xffffffff)
-          {
-          if (adding)
-            {
-            *selector1 = 0xffffffff ^ notall1;
-            if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2;
-            }
-          else
-            {
-            *selector1 = 0;
-            if (selector2 != NULL) *selector2 = 0;
-            }
-          }
-
-        /* Otherwise, the 0x80000000 bit means "this value, without the top
-        bit, belongs in the second selector". */
 
-        else
-          {
-          if ((bit & 0x80000000) != 0)
-            {
-            selector = selector2;
-            bit &= 0x7fffffff;
-            }
-          else selector = selector1;
-          if (adding) *selector |= bit; else *selector &= ~bit;
-          }
+       if (bit == -1)
+         {
+         if (adding)
+           {
+           memset(selector, -1, sizeof(*selector)*selsize);
+           bits_clear(selector, selsize, notall);
+           }
+         else
+           memset(selector, 0, sizeof(*selector)*selsize);
+         }
+       else if (adding)
+         BIT_SET(selector, selsize, bit);
+       else
+         BIT_CLEAR(selector, selsize, bit);
+
         break;  /* Out of loop to match selector name */
         }
       }
@@ -1335,10 +1338,8 @@ if (tag_name != NULL && (Ustrchr(tag_name, '/') != NULL))
 
 debug_selector = D_default;
 if (opts)
-  {
-  decode_bits(&debug_selector, NULL, D_memory, 0, opts,
+  decode_bits(&debug_selector, 1, debug_notall, opts,
       debug_options, debug_options_count, US"debug", DEBUG_FROM_CONFIG);
-  }
 
 /* When activating from a transport process we may never have logged at all
 resulting in certain setup not having been done.  Hack this for now so we
index 61f9ca67487246e1ef45f0d46b8345fe88b6fff7..d63025ec251a2a05290288036bec872675893561 100644 (file)
@@ -321,46 +321,84 @@ for having to swallow the rest of an SMTP message is whether the value is
 #define END_SIZE       4    /* Reading ended because message too big */
 #define END_WERROR     5    /* Write error while reading the message */
 
-/* Options bits for debugging; D_v and D_local_scan are also in local_scan.h */
-
-#define D_v                          0x00000001
-#define D_local_scan                 0x00000002
-
-#define D_acl                        0x00000004
-#define D_auth                       0x00000008
-#define D_deliver                    0x00000010
-#define D_dns                        0x00000020
-#define D_dnsbl                      0x00000040
-#define D_exec                       0x00000080
-#define D_expand                     0x00000100
-#define D_filter                     0x00000200
-#define D_hints_lookup               0x00000400
-#define D_host_lookup                0x00000800
-#define D_ident                      0x00001000
-#define D_interface                  0x00002000
-#define D_lists                      0x00004000
-#define D_load                       0x00008000
-#define D_lookup                     0x00010000
-#define D_memory                     0x00020000
-#define D_pid                        0x00040000
-#define D_process_info               0x00080000
-#define D_queue_run                  0x00100000
-#define D_receive                    0x00200000
-#define D_resolver                   0x00400000
-#define D_retry                      0x00800000
-#define D_rewrite                    0x01000000
-#define D_route                      0x02000000
-#define D_timestamp                  0x04000000
-#define D_tls                        0x08000000
-#define D_transport                  0x10000000
-#define D_uid                        0x20000000
-#define D_verify                     0x40000000
-
-/* The D_all value must always have all bits set, as it is recognized specially
-by the function that decodes debug and log selectors. This is to enable it to
-set all the bits in a multi-word selector. Debug doesn't use this yet, but we
-are getting close. In fact, we want to omit "memory" for -d+all, but can't
-handle this here. It is fudged externally. */
+/* Bit masks for debug and log selectors */
+
+/* Assume words are 32 bits wide. Tiny waste of space on 64 bit
+platforms, but this ensures bit vectors always work the same way. */
+#define BITWORDSIZE 32
+
+/* This macro is for single-word bit vectors: the debug selector,
+and the first word of the log selector. */
+#define BIT(n) (1 << (n))
+
+/* And these are for multi-word vectors. */
+#define BITWORD(n) (     (n) / BITWORDSIZE)
+#define BITMASK(n) (1 << (n) % BITWORDSIZE)
+
+#define BIT_CLEAR(s,z,n) ((s)[BITWORD(n)] &= ~BITMASK(n))
+#define BIT_SET(s,z,n)   ((s)[BITWORD(n)] |=  BITMASK(n))
+#define BIT_TEST(s,z,n) (((s)[BITWORD(n)] &   BITMASK(n)) != 0)
+
+/* Used in globals.c for initializing bit_table structures. T will be either
+D or L correspondong to the debug and log selector bits declared below. */
+
+#define BIT_TABLE(T,name) { US #name, T##i_##name }
+
+/* IOTA allows us to keep an implicit sequential count, like a simple enum,
+but we can have sequentially numbered identifiers which are not declared
+sequentially. We use this for more compact declarations of bit indexes and
+masks, alternating between sequential bit index and corresponding mask. */
+
+#define IOTA(iota)      (__LINE__ - iota)
+#define IOTA_INIT(zero) (__LINE__ - zero + 1)
+
+/* Options bits for debugging. DEBUG_BIT() declares both a bit index and the
+corresponding mask. Di_all is a special value recognized by decode_bits().
+
+Exim's code assumes in a number of places that the debug_selector is one
+word, and this is exposed in the local_scan ABI. The D_v and D_local_scan bit
+masks are part of the local_scan API so are #defined in local_scan.h */
+
+#define DEBUG_BIT(name) Di_##name = IOTA(Di_iota), D_##name = BIT(Di_##name)
+
+enum {
+  Di_all        = -1,
+  Di_v          = 0,
+  Di_local_scan = 1,
+
+  Di_iota = IOTA_INIT(2),
+  DEBUG_BIT(acl),
+  DEBUG_BIT(auth),
+  DEBUG_BIT(deliver),
+  DEBUG_BIT(dns),
+  DEBUG_BIT(dnsbl),
+  DEBUG_BIT(exec),
+  DEBUG_BIT(expand),
+  DEBUG_BIT(filter),
+  DEBUG_BIT(hints_lookup),
+  DEBUG_BIT(host_lookup),
+  DEBUG_BIT(ident),
+  DEBUG_BIT(interface),
+  DEBUG_BIT(lists),
+  DEBUG_BIT(load),
+  DEBUG_BIT(lookup),
+  DEBUG_BIT(memory),
+  DEBUG_BIT(pid),
+  DEBUG_BIT(process_info),
+  DEBUG_BIT(queue_run),
+  DEBUG_BIT(receive),
+  DEBUG_BIT(resolver),
+  DEBUG_BIT(retry),
+  DEBUG_BIT(rewrite),
+  DEBUG_BIT(route),
+  DEBUG_BIT(timestamp),
+  DEBUG_BIT(tls),
+  DEBUG_BIT(transport),
+  DEBUG_BIT(uid),
+  DEBUG_BIT(verify),
+};
+
+/* Multi-bit debug masks */
 
 #define D_all                        0xffffffff
 
@@ -380,81 +418,67 @@ handle this here. It is fudged externally. */
                                          D_timestamp   | \
                                          D_resolver))
 
-/* Options bits for logging. Those that will end up in log_write_selector have
-values < 0x80000000. They can be used in calls to log_write(). The others have
-values > 0x80000000 and are put into log_extra_selector (without the top bit).
-These are only ever tested independently. "All" is a magic value that is used
-only in the name table to set all options in both bit maps. */
-
-/* The L_all value must always have all bits set, as it is recognized specially
-by the function that decodes debug and log selectors. This is to enable it to
-set all the bits in a multi-word selector. */
-
-#define L_all                          0xffffffff
-
-#define L_address_rewrite              0x00000001
-#define L_all_parents                  0x00000002
-#define L_connection_reject            0x00000004
-#define L_delay_delivery               0x00000008
-#define L_dnslist_defer                0x00000010
-#define L_etrn                         0x00000020
-#define L_host_lookup_failed           0x00000040
-#define L_lost_incoming_connection     0x00000080
-#define L_queue_run                    0x00000100
-#define L_retry_defer                  0x00000200
-#define L_size_reject                  0x00000400
-#define L_skip_delivery                0x00000800
-#define L_smtp_connection              0x00001000
-#define L_smtp_incomplete_transaction  0x00002000
-#define L_smtp_protocol_error          0x00004000
-#define L_smtp_syntax_error            0x00008000
-
-#define LX_acl_warn_skipped            0x80000001
-#define LX_arguments                   0x80000002
-#define LX_deliver_time                0x80000004
-#define LX_delivery_size               0x80000008
-#define LX_ident_timeout               0x80000010
-#define LX_incoming_interface          0x80000020
-#define LX_incoming_port               0x80000040
-#define LX_outgoing_port               0x80000080
-#define LX_pid                         0x80000100
-#define LX_queue_time                  0x80000200
-#define LX_queue_time_overall          0x80000400
-#define LX_received_sender             0x80000800
-#define LX_received_recipients         0x80001000
-#define LX_rejected_header             0x80002000
-#define LX_return_path_on_delivery     0x80004000
-#define LX_sender_on_delivery          0x80008000
-#define LX_sender_verify_fail          0x80010000
-#define LX_smtp_confirmation           0x80020000
-#define LX_smtp_no_mail                0x80040000
-#define LX_subject                     0x80080000
-#define LX_tls_certificate_verified    0x80100000
-#define LX_tls_cipher                  0x80200000
-#define LX_tls_peerdn                  0x80400000
-#define LX_tls_sni                     0x80800000
-#define LX_unknown_in_list             0x81000000
-#define LX_8bitmime                    0x82000000
-#define LX_smtp_mailauth               0x84000000
-#define LX_proxy                       0x88000000
-
-#define L_default     (L_connection_reject        | \
-                       L_delay_delivery           | \
-                       L_dnslist_defer            | \
-                       L_etrn                     | \
-                       L_host_lookup_failed       | \
-                       L_lost_incoming_connection | \
-                       L_queue_run                | \
-                       L_retry_defer              | \
-                       L_size_reject              | \
-                       L_skip_delivery)
-
-#define LX_default   ((LX_acl_warn_skipped        | \
-                       LX_rejected_header         | \
-                       LX_sender_verify_fail      | \
-                       LX_smtp_confirmation       | \
-                       LX_tls_certificate_verified| \
-                       LX_tls_cipher) & 0x7fffffff)
+/* Options bits for logging. Those that have values < BITWORDSIZE can be used
+in calls to log_write(). The others are put into later words in log_selector
+and are only ever tested independently, so they do not need bit mask
+declarations. The Li_all value is recognized specially by decode_bits(). */
+
+#define LOG_BIT(name) Li_##name = IOTA(Li_iota), L_##name = BIT(Li_##name)
+
+enum {
+  Li_all = -1,
+
+  Li_iota = IOTA_INIT(0),
+  LOG_BIT(address_rewrite),
+  LOG_BIT(all_parents),
+  LOG_BIT(connection_reject),
+  LOG_BIT(delay_delivery),
+  LOG_BIT(dnslist_defer),
+  LOG_BIT(etrn),
+  LOG_BIT(host_lookup_failed),
+  LOG_BIT(lost_incoming_connection),
+  LOG_BIT(queue_run),
+  LOG_BIT(retry_defer),
+  LOG_BIT(size_reject),
+  LOG_BIT(skip_delivery),
+  LOG_BIT(smtp_connection),
+  LOG_BIT(smtp_incomplete_transaction),
+  LOG_BIT(smtp_protocol_error),
+  LOG_BIT(smtp_syntax_error),
+
+  Li_acl_warn_skipped = BITWORDSIZE,
+  Li_arguments,
+  Li_deliver_time,
+  Li_delivery_size,
+  Li_ident_timeout,
+  Li_incoming_interface,
+  Li_incoming_port,
+  Li_outgoing_port,
+  Li_pid,
+  Li_queue_time,
+  Li_queue_time_overall,
+  Li_received_sender,
+  Li_received_recipients,
+  Li_rejected_header,
+  Li_return_path_on_delivery,
+  Li_sender_on_delivery,
+  Li_sender_verify_fail,
+  Li_smtp_confirmation,
+  Li_smtp_no_mail,
+  Li_subject,
+  Li_tls_certificate_verified,
+  Li_tls_cipher,
+  Li_tls_peerdn,
+  Li_tls_sni,
+  Li_unknown_in_list,
+  Li_8bitmime,
+  Li_smtp_mailauth,
+  Li_proxy,
+
+  log_selector_size = BITWORD(Li_proxy) + 1
+};
+
+#define LOGGING(opt) BIT_TEST(log_selector, log_selector_size, Li_##opt)
 
 /* Private error numbers for delivery failures, set negative so as not
 to conflict with system errno values. */
index 9e471105b3dd9ce0a33c5d1143190094c09abac1..fa42187dd1be5bbb22d1a65989582db5033e3d19 100644 (file)
@@ -771,7 +771,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
             include_unknown? "yes":"no", error);
           if (!include_unknown)
             {
-            if ((log_extra_selector & LX_unknown_in_list) != 0)
+            if (LOGGING(unknown_in_list))
               log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
             return FAIL;
             }
@@ -880,7 +880,7 @@ while ((sss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
           (void)fclose(f);
           if (!include_unknown)
             {
-            if ((log_extra_selector & LX_unknown_in_list) != 0)
+            if (LOGGING(unknown_in_list))
               log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
             return FAIL;
             }
index 7596466b53b00b6b815188269ac3eaa9b2f0eacb..2afd6dc8aa1cafcd6ca8b9a0c072933193747ae9 100644 (file)
@@ -635,7 +635,7 @@ if ((pid = fork()) == 0)
     {
     DEBUG(D_rewrite) debug_printf("turned off address rewrite logging (not "
       "root or exim in this process)\n");
-    log_write_selector &= ~L_address_rewrite;
+    BIT_CLEAR(log_selector, log_selector_size, Li_address_rewrite);
     }
 
   /* Now do the business */
index 64cf1ae7031be7030cc44abbcd13990ce0aaba46..b430ee26197754e50e90611dc1e4e5c8e97875ad 100644 (file)
@@ -1118,8 +1118,7 @@ add_host_info_for_log(uschar *s, int *sizeptr, int *ptrptr)
 if (sender_fullhost != NULL)
   {
   s = string_append(s, sizeptr, ptrptr, 2, US" H=", sender_fullhost);
-  if ((log_extra_selector & LX_incoming_interface) != 0 &&
-       interface_address != NULL)
+  if (LOGGING(incoming_interface) && interface_address != NULL)
     {
     uschar *ss = string_sprintf(" I=[%s]:%d", interface_address,
       interface_port);
@@ -2529,7 +2528,7 @@ if (msgid_header == NULL &&
 rewriting. Must copy the count, because later ACLs and the local_scan()
 function may mess with the real recipients. */
 
-if ((log_extra_selector & LX_received_recipients) != 0)
+if (LOGGING(received_recipients))
   {
   raw_recipients = store_get(recipients_count * sizeof(uschar *));
   for (i = 0; i < recipients_count; i++)
@@ -3573,7 +3572,7 @@ else
     goto TEMPREJECT;
 
     case LOCAL_SCAN_REJECT_NOLOGHDR:
-    log_extra_selector &= ~LX_rejected_header;
+    BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header);
     /* Fall through */
 
     case LOCAL_SCAN_REJECT:
@@ -3582,7 +3581,7 @@ else
     break;
 
     case LOCAL_SCAN_TEMPREJECT_NOLOGHDR:
-    log_extra_selector &= ~LX_rejected_header;
+    BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header);
     /* Fall through */
 
     case LOCAL_SCAN_TEMPREJECT:
@@ -3747,15 +3746,15 @@ if (message_reference != NULL)
 s = add_host_info_for_log(s, &size, &sptr);
 
 #ifdef SUPPORT_TLS
-if (log_extra_selector & LX_tls_cipher && tls_in.cipher)
+if (LOGGING(tls_cipher) && tls_in.cipher)
   s = string_append(s, &size, &sptr, 2, US" X=", tls_in.cipher);
-if (log_extra_selector & LX_tls_certificate_verified && tls_in.cipher)
+if (LOGGING(tls_certificate_verified) && tls_in.cipher)
   s = string_append(s, &size, &sptr, 2, US" CV=",
     tls_in.certificate_verified? "yes":"no");
-if (log_extra_selector & LX_tls_peerdn && tls_in.peerdn)
+if (LOGGING(tls_peerdn) && tls_in.peerdn)
   s = string_append(s, &size, &sptr, 3, US" DN=\"",
     string_printing(tls_in.peerdn), US"\"");
-if (log_extra_selector & LX_tls_sni && tls_in.sni)
+if (LOGGING(tls_sni) && tls_in.sni)
   s = string_append(s, &size, &sptr, 3, US" SNI=\"",
     string_printing(tls_in.sni), US"\"");
 #endif
@@ -3766,7 +3765,7 @@ if (sender_host_authenticated)
   if (authenticated_id != NULL)
     {
     s = string_append(s, &size, &sptr, 2, US":", authenticated_id);
-    if (log_extra_selector & LX_smtp_mailauth  &&  authenticated_sender != NULL)
+    if (LOGGING(smtp_mailauth) && authenticated_sender != NULL)
       s = string_append(s, &size, &sptr, 2, US":", authenticated_sender);
     }
   }
@@ -3777,7 +3776,7 @@ if (prdr_requested)
 #endif
 
 #ifdef EXPERIMENTAL_PROXY
-if (proxy_session &&  log_extra_selector & LX_proxy)
+if (proxy_session && LOGGING(proxy))
   s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_host_address);
 #endif
 
@@ -3788,7 +3787,7 @@ s = string_append(s, &size, &sptr, 2, US" S=", big_buffer);
    0 ... no BODY= used
    7 ... 7BIT
    8 ... 8BITMIME */
-if (log_extra_selector & LX_8bitmime)
+if (LOGGING(8bitmime))
   {
   sprintf(CS big_buffer, "%d", body_8bitmime);
   s = string_append(s, &size, &sptr, 2, US" M8S=", big_buffer);
@@ -3814,7 +3813,7 @@ if (msgid_header != NULL)
 /* If subject logging is turned on, create suitable printing-character
 text. By expanding $h_subject: we make use of the MIME decoding. */
 
-if ((log_extra_selector & LX_subject) != 0 && subject_header != NULL)
+if (LOGGING(subject) && subject_header != NULL)
   {
   int i;
   uschar *p = big_buffer;
@@ -4003,8 +4002,8 @@ if(!smtp_reply)
 #endif
   {
   log_write(0, LOG_MAIN |
-    (((log_extra_selector & LX_received_recipients) != 0)? LOG_RECIPIENTS : 0) |
-    (((log_extra_selector & LX_received_sender) != 0)? LOG_SENDER : 0),
+    (LOGGING(received_recipients)? LOG_RECIPIENTS : 0) |
+    (LOGGING(received_sender)? LOG_SENDER : 0),
     "%s", s);
 
   /* Log any control actions taken by an ACL or local_scan(). */
index 296fe8c6b8bb47fc337c195b265b60d6300ca89f..ca7fb6a115c4a3d8abcfc61aff371c16d010c3ee 100644 (file)
@@ -247,8 +247,7 @@ for (rule = rewrite_rules;
 
   /* We have a validly rewritten address */
 
-  if ((log_write_selector & L_address_rewrite) != 0 ||
-      (debug_selector & D_rewrite) != 0)
+  if (LOGGING(address_rewrite) || (debug_selector & D_rewrite) != 0)
     {
     int i;
     const uschar *where = CUS"?";
index effc63672708336ce117e75eb5913f9d6ed0aaca..998245137f2a65d84de9854dc08b14fcd84fa044 100644 (file)
@@ -1234,8 +1234,7 @@ if (sender_host_unknown || sender_host_notsocket)
 if (is_inetd)
   return string_sprintf("SMTP connection from %s (via inetd)", hostname);
 
-if ((log_extra_selector & LX_incoming_interface) != 0 &&
-     interface_address != NULL)
+if (LOGGING(incoming_interface) && interface_address != NULL)
   return string_sprintf("SMTP connection from %s I=[%s]:%d", hostname,
     interface_address, interface_port);
 
@@ -1260,16 +1259,15 @@ s_tlslog(uschar * s, int * sizep, int * ptrp)
   int size = sizep ? *sizep : 0;
   int ptr = ptrp ? *ptrp : 0;
 
-  if ((log_extra_selector & LX_tls_cipher) != 0 && tls_in.cipher != NULL)
+  if (LOGGING(tls_cipher) && tls_in.cipher != NULL)
     s = string_append(s, &size, &ptr, 2, US" X=", tls_in.cipher);
-  if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
-       tls_in.cipher != NULL)
+  if (LOGGING(tls_certificate_verified) && tls_in.cipher != NULL)
     s = string_append(s, &size, &ptr, 2, US" CV=",
       tls_in.certificate_verified? "yes":"no");
-  if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_in.peerdn != NULL)
+  if (LOGGING(tls_peerdn) && tls_in.peerdn != NULL)
     s = string_append(s, &size, &ptr, 3, US" DN=\"",
       string_printing(tls_in.peerdn), US"\"");
-  if ((log_extra_selector & LX_tls_sni) != 0 && tls_in.sni != NULL)
+  if (LOGGING(tls_sni) && tls_in.sni != NULL)
     s = string_append(s, &size, &ptr, 3, US" SNI=\"",
       string_printing(tls_in.sni), US"\"");
 
@@ -1301,7 +1299,7 @@ smtp_log_no_mail(void)
 int size, ptr, i;
 uschar *s, *sep;
 
-if (smtp_mailcmd_count > 0 || (log_extra_selector & LX_smtp_no_mail) == 0)
+if (smtp_mailcmd_count > 0 || !LOGGING(smtp_no_mail))
   return;
 
 s = NULL;
@@ -2510,8 +2508,8 @@ static void
 incomplete_transaction_log(uschar *what)
 {
 if (sender_address == NULL ||                 /* No transaction in progress */
-    (log_write_selector & L_smtp_incomplete_transaction) == 0  /* Not logging */
-  return;
+    !LOGGING(smtp_incomplete_transaction))
+  return;
 
 /* Build list of recipients for logging */
 
@@ -2762,7 +2760,7 @@ if (sender_verified_failed != NULL &&
 
   setflag(sender_verified_failed, af_sverify_told);
 
-  if (rc != FAIL || (log_extra_selector & LX_sender_verify_fail) != 0)
+  if (rc != FAIL || LOGGING(sender_verify_fail))
     log_write(0, LOG_MAIN|LOG_REJECT, "%s sender verify %s for <%s>%s",
       host_and_ident(TRUE),
       ((sender_verified_failed->special_action & 255) == DEFER)? "defer":"fail",
index 6f143d63472c70ccb441625f47243b081e5223a1..438b52168561ac822b56e1ca86e91428fb03f06a 100644 (file)
@@ -38,7 +38,7 @@ typedef struct macro_item {
 
 typedef struct bit_table {
   uschar *name;
-  unsigned int bit;
+  int bit;
 } bit_table;
 
 /* Block for holding a uid and gid, possibly unset, and an initgroups flag. */
index b1dccb8eeeb201b6068ab6d3840d1ce6e2bca286..73ac80734ca8dca50e86c434b289aca194195537 100644 (file)
@@ -1111,8 +1111,7 @@ len = SSL_get_tlsext_status_ocsp_resp(s, &p);
 if(!p)
  {
   /* Expect this when we requested ocsp but got none */
-  if (  cbinfo->u_ocsp.client.verify_required
-     && log_extra_selector & LX_tls_cipher)
+  if (cbinfo->u_ocsp.client.verify_required && LOGGING(tls_cipher))
     log_write(0, LOG_MAIN, "Received TLS status callback, null content");
   else
     DEBUG(D_tls) debug_printf(" null\n");
@@ -1122,7 +1121,7 @@ if(!p)
 if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
  {
   tls_out.ocsp = OCSP_FAILED;
-  if (log_extra_selector & LX_tls_cipher)
+  if (LOGGING(tls_cipher))
     log_write(0, LOG_MAIN, "Received TLS cert status response, parse error");
   else
     DEBUG(D_tls) debug_printf(" parse error\n");
@@ -1132,7 +1131,7 @@ if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
 if(!(bs = OCSP_response_get1_basic(rsp)))
   {
   tls_out.ocsp = OCSP_FAILED;
-  if (log_extra_selector & LX_tls_cipher)
+  if (LOGGING(tls_cipher))
     log_write(0, LOG_MAIN, "Received TLS cert status response, error parsing response");
   else
     DEBUG(D_tls) debug_printf(" error parsing response\n");
@@ -1163,7 +1162,7 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
              cbinfo->u_ocsp.client.verify_store, 0)) <= 0)
       {
       tls_out.ocsp = OCSP_FAILED;
-      if (log_extra_selector & LX_tls_cipher)
+      if (LOGGING(tls_cipher))
        log_write(0, LOG_MAIN, "Received TLS cert status response, itself unverifiable");
       BIO_printf(bp, "OCSP response verify failure\n");
       ERR_print_errors(bp);
index 0cd89af8f8dd6350936f48b46ef13267c7475755..1f4d7a6bf56ee9ec210436f05e5cfa47a23f87db 100644 (file)
@@ -654,7 +654,7 @@ if (send_data)
     if (lmtp_read_response(out, buffer, sizeof(buffer), '2', timeout))
       {
       addr->transport_return = OK;
-      if ((log_extra_selector & LX_smtp_confirmation) != 0)
+      if (LOGGING(smtp_confirmation))
         {
         const uschar *s = string_printing(buffer);
        /* de-const safe here as string_printing known to have alloc'n'copied */
index a9524134943dd297b8d06b9c1c25760055deecec..609dba3aedb5362b4c1ecd6da33213fbe60ff65d 100644 (file)
@@ -638,7 +638,7 @@ if (addr->message)
   }
 else
   {
-  if (log_extra_selector & LX_outgoing_port)
+  if (LOGGING(outgoing_port))
     message = string_sprintf("%s:%d", message,
                host->port == PORT_NONE ? 25 : host->port);
   log_write(0, LOG_MAIN, "%s %s", message, strerror(addr->basic_errno));
@@ -2380,7 +2380,7 @@ if (!ok) ok = TRUE; else
 
     if (
 #ifndef EXPERIMENTAL_EVENT
-          (log_extra_selector & LX_smtp_confirmation) != 0 &&
+          LOGGING(smtp_confirmation) &&
 #endif
           !lmtp
        )
@@ -2435,7 +2435,7 @@ if (!ok) ok = TRUE; else
           continue;
           }
         completed_address = TRUE;   /* NOW we can set this flag */
-        if ((log_extra_selector & LX_smtp_confirmation) != 0)
+        if (LOGGING(smtp_confirmation))
           {
           const uschar *s = string_printing(buffer);
          /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
index e00e7b9eba828f4dbfc5512496a8d971041f1e85..7992d58fc381da3fe7860d32c69e30214b8dffbe 100644 (file)
@@ -2916,7 +2916,7 @@ if (ip_bind(sock, host_af, interface_address, 0) < 0)
 if (ip_connect(sock, host_af, sender_host_address, port, rfc1413_query_timeout)
      < 0)
   {
-  if (errno == ETIMEDOUT && (log_extra_selector & LX_ident_timeout) != 0)
+  if (errno == ETIMEDOUT && LOGGING(ident_timeout))
     {
     log_write(0, LOG_MAIN, "ident connection to %s timed out",
       sender_host_address);