]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20010204
authorWietse Venema <wietse@porcupine.org>
Sun, 4 Feb 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:09 +0000 (06:27 +0000)
34 files changed:
postfix/.indent.pro
postfix/DEBUG_README
postfix/HISTORY
postfix/html/error.8.html
postfix/html/local.8.html
postfix/html/nqmgr.8.html
postfix/html/postdrop.1.html
postfix/html/qmgr.8.html
postfix/html/trivial-rewrite.8.html
postfix/html/uce.html
postfix/mantools/postlink
postfix/src/dns/dns_lookup.c
postfix/src/global/mail_version.h
postfix/src/nqmgr/qmgr_entry.c
postfix/src/nqmgr/qmgr_job.c
postfix/src/nqmgr/qmgr_message.c
postfix/src/smtp/smtp_addr.c
postfix/src/util/Makefile.in
postfix/src/util/dict.c
postfix/src/util/dict.h
postfix/src/util/dict_db.c
postfix/src/util/dict_dbm.c
postfix/src/util/dict_debug.c [new file with mode: 0644]
postfix/src/util/dict_env.c
postfix/src/util/dict_ldap.c
postfix/src/util/dict_mysql.c
postfix/src/util/dict_ni.c
postfix/src/util/dict_nis.c
postfix/src/util/dict_nisplus.c
postfix/src/util/dict_pcre.c
postfix/src/util/dict_regexp.c
postfix/src/util/dict_tcp.c
postfix/src/util/dict_unix.c
postfix/src/util/rand_sleep.c

index 7223e9d27269c0e843019d4562f817ac81f5886d..c35b4962ff877e69d2556ae590744d51a8930f57 100644 (file)
@@ -27,6 +27,7 @@
 -TDICT_ENV
 -TDICT_HT
 -TDICT_LDAP
+-TDICT_DEBUG
 -TDICT_MYSQL
 -TDICT_NI
 -TDICT_NIS
index 4e8f2cea25f1b6f646baba70d89c41e3a0d1d5c3..cd2593eb682e3974679857fcd37e98cd39e3c4c3 100644 (file)
@@ -18,8 +18,21 @@ from or to the loopback interface:
 
 You can specify one or more hosts, domains, addresses or net/masks.
 
-3 - Making daemon programs more verbose
-=======================================
+2b - Record the SMTP connection with a sniffer
+==============================================
+
+This example uses tcpdump. In order to record a conversation you
+need to specify a large enough buffer or else you will miss some
+or all of the packet payload.
+
+    tcpdump -w /file/name -s 2000 host hostname and port 25
+
+Run this for a while, stop with Ctrl-C when done. To view the data
+use a binary viewer, or use my tcpdumpx utility that is available
+from ftp://ftp.porcupine.org/pub/debugging.
+
+3 - Making Postfix daemon programs more verbose
+===============================================
 
 Append one or more -v options to selected daemon definitions in
 /etc/postfix/master.cf and type "postfix reload". This will cause
index 8f095ce1c9e344106ec36e3f58b7af8d152823c3..0ab32a6be6071f1cc628afff5ed4d9000403b9ee 100644 (file)
@@ -4831,13 +4831,6 @@ Apologies for any names omitted.
        bug that causes mail delivery problems when "." and "CRLF"
        arrive in separate packets. File:  html/faq.html.
 
-20010131
-
-       The code that reports a DNS lookup error now includes the
-       record type that was being looked up, so that people will
-       not misinterpret an MX lookup problem as an A record lookup
-       problem.  File:  dns/dns_lookup.c.
-
 20010201
 
        Bugfix: another missing initialization in the mysql client.
@@ -4860,3 +4853,19 @@ Apologies for any names omitted.
        Feature: disable mailbox size limits for the local and
        virtual delivery agents by setting mailbox_size_limit or
        virtual_mailbox_limit to zero.
+
+20010203
+
+       Update: null candidate patch from Patrick Rak. Files:
+       nqmgr/qmgr_entry.c nqmgr/qmgr_job.c nqmgr/qmgr_message.c.
+
+       Cleanup: added one gruesome command to the postlink script
+       for hyperlinking nroff manual page output. Word abbreviation
+       broke some <a href...> </a> instances across line boundaries.
+       sed(1) is an amazing tool.  File: mantools/postlink.
+
+20010204
+
+       Laid the ground work for logging of table accesses. This
+       will give more insight into how Postfix uses its lookup
+       tables. User interface comes later.  File:  util/dict_debug.c.
index 2a3d401f8c8ed83a2af12d8de8d51db2daa5aa5c..d36ab9919bd1c3c25761475fa750a2cacda4168e 100644 (file)
@@ -16,8 +16,8 @@ ERROR(8)                                                 ERROR(8)
        requests from the queue manager. Each request specifies  a
        queue  file,  a sender address, a domain or host name that
        is treated as the reason for non-delivery,  and  recipient
-       information.  This program expects to be run from the <a href="master.8.html"><b>mas-</b>
-       <b>ter</b>(8)</a> process manager.
+       information.  This program expects to be run from the <a href="master.8.html"><b>mas-</b></a>
+       <a href="master.8.html"><b>ter</b>(8)</a> process manager.
 
        The error mailer client forces all recipients  to  bounce,
        using  the  domain  or  host information as the reason for
index 5aac19255773d2d7007ead1bf91f9516aec22b34..36c8002010656ace6842320610593a6abc56983d 100644 (file)
@@ -16,8 +16,8 @@ LOCAL(8)                                                 LOCAL(8)
        Postfix queue manager to deliver mail to local recipients.
        Each  delivery  request  specifies  a queue file, a sender
        address, a domain or host to deliver to, and one  or  more
-       recipients.   This program expects to be run from the <a href="master.8.html"><b>mas-</b>
-       <b>ter</b>(8)</a> process manager.
+       recipients.   This program expects to be run from the <a href="master.8.html"><b>mas-</b></a>
+       <a href="master.8.html"><b>ter</b>(8)</a> process manager.
 
        The <b>local</b> daemon updates queue files and marks  recipients
        as finished, or it informs the queue manager that delivery
index 624352aa2d7079da6bfd0dd57cec5bb22e0624e0..6fbbe7f9b26df5e4a607b9dede3206541c45fd57 100644 (file)
@@ -14,8 +14,8 @@ NQMGR(8)                                                 NQMGR(8)
 <b>DESCRIPTION</b>
        The  <b>nqmgr</b>  daemon awaits the arrival of incoming mail and
        arranges for its delivery via Postfix delivery  processes.
-       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b>
-       <b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
+       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b></a>
+       <a href="trivial-rewrite.8.html"><b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
        from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
 
        Mail  addressed  to  the  local  <b>double-bounce</b>  address is
index b9f3b7963dfd0e6aefe78b13d56ea8ee92ab3b50..372b037a3922d0424f4c3975379c1e45c2fc7a93 100644 (file)
@@ -19,8 +19,8 @@ POSTDROP(1)                                           POSTDROP(1)
        and  with  group  write  permission  to the <b>maildrop</b> queue
        directory.
 
-       The <b>postdrop</b> command is automatically invoked by the <a href="sendmail.1.html"><b>send-</b>
-       <b>mail</b>(1)</a>  mail posting agent when the <b>maildrop</b> queue direc-
+       The <b>postdrop</b> command is automatically invoked by the <a href="sendmail.1.html"><b>send-</b></a>
+       <a href="sendmail.1.html"><b>mail</b>(1)</a>  mail posting agent when the <b>maildrop</b> queue direc-
        tory is not world-writable.
 
        Options:
index 213a35b04f6f64281f755bbc9f39bd093d07d816..032e6dfdbc6857f519dd7f8b7be1308c95ee5a23 100644 (file)
@@ -14,8 +14,8 @@ QMGR(8)                                                   QMGR(8)
 <b>DESCRIPTION</b>
        The  <b>qmgr</b>  daemon  awaits the arrival of incoming mail and
        arranges for its delivery via Postfix delivery  processes.
-       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b>
-       <b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
+       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b></a>
+       <a href="trivial-rewrite.8.html"><b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
        from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
 
        Mail  addressed  to  the  local  <b>double-bounce</b>  address is
index ce97479f810ff20b57345162d3aa40598dc13ab2..f24125814790db4c5b98216e32d387fcda2b2aac 100644 (file)
@@ -43,8 +43,8 @@ TRIVIAL-REWRITE(8)                             TRIVIAL-REWRITE(8)
 
               The  <b>trivial-rewrite</b> daemon by default only distin-
               guishes between local and non-local mail. For finer
-              control  over mail routing, use the optional <a href="transport.5.html"><b>trans-</b>
-              <b>port</b>(5)</a> lookup table.
+              control  over mail routing, use the optional <a href="transport.5.html"><b>trans-</b></a>
+              <a href="transport.5.html"><b>port</b>(5)</a> lookup table.
 
        This program expects to be run from the <a href="master.8.html"><b>master</b>(8)</a>  process
        manager.
index d35330a2f104c41dddcf100d282e9eea20ea1c20..1fe7b0cbfb1dfb1282bf75675452c062f30a349c 100644 (file)
@@ -979,7 +979,7 @@ appear as part of a client hostname/address restriction list.
 
 <dt>Default:
 
-<dd><b>maps_rbl_domains = rbl.maps.vix.com, dul.maps.vix.com</b>
+<dd><b>maps_rbl_domains = blackholes.mail-abuse.org</b>
 
 <p>
 
index 1328075ee2fb34953115b4faa1c20d6d8070466e..d9c57a9c15038f0a592fe38edf778d81c4093def 100755 (executable)
@@ -46,5 +46,6 @@ exec sed '
        s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
        s/[<bB>]*virtual[</bB>]*(5)/<a href="virtual.5.html">&<\/a>/
        s/[<bB>]*virtual[</bB>]*(8)/<a href="virtual.8.html">&<\/a>/
+       s/\(<a href="[^"]*">\)\([<bB>]*[a-z0-9-]*[-</bB>]*\)\(\n *\)\([<bB>]*[a-z0-9-]*[</bB>]*([0-9])\)\(<\/a>\)/\1\2\5\3\1\4\5/
        s/RFC *\([0-9]*\)/<a href="http:\/\/www.faqs.org\/rfcs\/rfc\1.html">&<\/a>/
 ' "$@"
index 6f8e9d078f6a31480c7a3930dcf69ed5442d318d..f08923fc0b89bc871d445fa19e1565a616a7e4b3 100644 (file)
@@ -168,8 +168,8 @@ static int dns_query(const char *name, int type, int flags,
     len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
     if (len < 0) {
        if (why)
-           vstring_sprintf(why, "Name service error for %s (%s) while looking up the %s record.",
-                           name, dns_strerror(h_errno), dns_strtype(type));
+           vstring_sprintf(why, "Name service error for %s: %s",
+                           name, dns_strerror(h_errno));
        if (msg_verbose)
            msg_info("dns_query: %s (%s): %s",
                     name, dns_strtype(type), dns_strerror(h_errno));
index 82f068e6d1f434805dc43f3346bfc16401422ab9..a1c3a8171de84c4c5d221e45f7fb60c161d956db 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20010202"
+#define DEF_MAIL_VERSION       "Snapshot-20010204"
 extern char *var_mail_version;
 
 /* LICENSE
index e6b84f577dba4b3784ba1542e2eb0098c5180a09..64cec0b28f854280744fd876df07b6b9f3c8bb14 100644 (file)
@@ -193,6 +193,10 @@ void    qmgr_entry_done(QMGR_ENTRY *entry, int which)
      * the queue is not marked as a blocker anymore, with extra handling of
      * queues which were declared dead.
      * 
+     * Note that changing the blocker status also affects the candidate cache.
+     * Most of the cases would be automatically recognized by the current job
+     * change, but we play safe and reset the cache explicitly below.
+     * 
      * Keeping the transport blocker tag odd is an easy way to make sure the tag
      * never matches jobs that are not explicitly marked as blockers.
      */
@@ -200,6 +204,7 @@ void    qmgr_entry_done(QMGR_ENTRY *entry, int which)
        if (queue->window > queue->busy_refcount && queue->todo.next != 0) {
            transport->blocker_tag += 2;
            transport->job_current = transport->job_list.next;
+           transport->candidate_cache_current = 0;
        }
        if (queue->window > queue->busy_refcount || queue->window == 0)
            queue->blocker_tag = 0;
index 2b8ea133061fdcd95c01ef4906ad06663d8935d6..5e604cf1ae61b346a1f1887ab68570978f427d04 100644 (file)
@@ -489,11 +489,17 @@ static QMGR_JOB *qmgr_job_candidate(QMGR_JOB *current)
      * Fetch the result directly from the cache if the cache is still valid.
      * 
      * Note that we cache negative results too, so the cache must be invalidated
-     * by resetting the cache time or current job pointer, not the candidate
-     * pointer itself.
+     * by resetting the cached current job pointer, not the candidate pointer
+     * itself.
+     * 
+     * In case the cache is valid and contains no candidate, we can ignore the
+     * time change, as it affects only which candidate is the best, not if
+     * one exists. However, this feature requires that we no longer relax the
+     * cache resetting rules, depending on the automatic cache timeout.
      */
     if (transport->candidate_cache_current == current
-       && transport->candidate_cache_time == now)
+       && (transport->candidate_cache_time == now
+           || transport->candidate_cache == 0))
        return (transport->candidate_cache);
 
     /*
@@ -726,19 +732,25 @@ static void qmgr_job_pop(QMGR_JOB *job)
      */
     job->stack_level = 0;
 
+    /*
+     * Explicitely reset the candidate cache. It's not worth trying to skip
+     * this under some complicated conditions - in most cases the popped job
+     * is the current job so we would have to reset it anyway.
+     */
+    RESET_CANDIDATE_CACHE(transport);
+
     /*
      * Here we leave the remaining work involving the proper placement on the
      * job list to the caller. The most important reason for this is that it
      * allows us not to look up where exactly to place the job.
      * 
-     * The caller is also made responsible for invalidating the candidate and
-     * current job caches if necessary.
+     * The caller is also made responsible for invalidating the current job
+     * cache if necessary.
      */
 #if 0
     QMGR_LIST_UNLINK(transport->job_list, QMGR_JOB *, job, transport_peers);
     QMGR_LIST_LINK(transport->job_list, some_prev, job, some_next, transport_peers);
 
-    RESET_CANDIDATE_CACHE(transport);
     if (transport->job_current == job)
        transport->job_current = job->transport_peers.next;
 #endif
index 3078f3ffe94a86c189ff9cf7c3ec1232b64e8344..45bb0f78a4fe81346a62e32c8e243d3e254bf385 100644 (file)
@@ -848,11 +848,10 @@ static void qmgr_message_assign(QMGR_MESSAGE *message)
     /*
      * Note that even if qmgr_job_obtain() reset the job candidate cache of
      * all transports to which we assigned new recipients, this message may
-     * have other jobs which we didn't touch at all this time. But as the
-     * number of unread recipients affecting the candidate selection might
-     * have changed considerably, let's invalidate the caches if it seems it
-     * might be of some use. It's not critical though because the cache will
-     * expire within one second anyway.
+     * have other jobs which we didn't touch at all this time. But the number
+     * of unread recipients affecting the candidate selection might have
+     * changed considerably, so we must invalidate the caches if it might be
+     * of some use.
      */
     for (job = message->job_list.next; job; job = job->message_peers.next)
        if (job->selected_entries < job->read_entries
index d86c694e173faa306f9b92d97838665b1246c72e..c9109fa3a4b53644e48811f8878c3800db62e284 100644 (file)
@@ -338,7 +338,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
        dns_rr_free(mx_names);
        if (addr_list == 0) {
            smtp_errno = SMTP_RETRY;
-           msg_warn("MX hosts for %s have no valid A record", name);
+           msg_warn("no MX host for %s has a valid A record", name);
            break;
        }
        best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
index edf47f4198806836a7ed3a3687cce029cc3ffd25..90dd044a2b3429442b853969e961e9cb98b9e1e3 100644 (file)
@@ -22,7 +22,7 @@ SRCS  = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
        stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
        clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
        sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
-       hex_quote.c dict_alloc.c rand_sleep.c sane_time.c
+       hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c
 OBJS   = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
        dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
@@ -46,7 +46,7 @@ OBJS  = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
        clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
        sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
-       hex_quote.o dict_alloc.o rand_sleep.o sane_time.o
+       hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
        dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
@@ -402,6 +402,14 @@ dict_db.o: argv.h
 dict_db.o: dict_db.h
 dict_dbm.o: dict_dbm.c
 dict_dbm.o: sys_defs.h
+dict_debug.o: dict_debug.c
+dict_debug.o: sys_defs.h
+dict_debug.o: msg.h
+dict_debug.o: mymalloc.h
+dict_debug.o: dict.h
+dict_debug.o: vstream.h
+dict_debug.o: vbuf.h
+dict_debug.o: argv.h
 dict_env.o: dict_env.c
 dict_env.o: sys_defs.h
 dict_env.o: mymalloc.h
index 2a02ce958a41357aecc4a3ab7577f938b184e4a3..7d07d3be0be538baaaf2805a0af6670db67e68bb 100644 (file)
 /*     dict_sequence() steps throuh the named dictionary and returns
 /*     keys and values in some implementation-defined order. The func
 /*     argument is DICT_SEQ_FUN_FIRST to set the cursor to the first
-/*     entry or DICT_SEQ_FUN_NEXT so select the next entry. The result
+/*     entry or DICT_SEQ_FUN_NEXT to select the next entry. The result
 /*     is owned by the underlying dictionary method. Make a copy if the
 /*     result is to be modified, or if the result is to survive multiple
 /*     dict_sequence() calls.
index c9fb8e9815d0a1996f12b0b57d39c9db52451e59..5a669aa096dca5a9039528b49510cad8147ca49f 100644 (file)
@@ -42,6 +42,9 @@ typedef struct DICT {
 extern DICT *dict_alloc(const char *, const char *, int);
 extern void dict_free(DICT *);
 
+extern DICT *dict_debug(DICT *);
+#define DICT_DEBUG(d) ((d)->flags & DICT_FLAG_DEBUG ? dict_debug(d) : (d))
+
 #define DICT_FLAG_DUP_WARN     (1<<0)  /* if file, warn about dups */
 #define DICT_FLAG_DUP_IGNORE   (1<<1)  /* if file, ignore dups */
 #define DICT_FLAG_TRY0NULL     (1<<2)  /* do not append 0 to key/value */
@@ -51,6 +54,7 @@ extern void dict_free(DICT *);
 #define DICT_FLAG_LOCK         (1<<6)  /* lock before access */
 #define DICT_FLAG_DUP_REPLACE  (1<<7)  /* if file, replace dups */
 #define DICT_FLAG_SYNC_UPDATE  (1<<8)  /* if file, sync updates */
+#define DICT_FLAG_DEBUG                (1<<9)  /* log access */
 
 extern int dict_unknown_allowed;
 extern int dict_errno;
index a887b4be2a8a2557dfc0e8a980ce3e7c2295282b..02b72baf47aee50ef2aeaf249f968089c3b93b12 100644 (file)
@@ -523,7 +523,7 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
        dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
     dict_db->db = db;
     myfree(db_path);
-    return (&dict_db->dict);
+    return (DICT_DEBUG(&dict_db->dict));
 }
 
 /* dict_hash_open - create association with data base */
index 332c38f77d5129a4756e0b44423259dcf778abc3..6f3a5611ad73a348a07b1e4bab71f1594fe95d2d 100644 (file)
@@ -409,7 +409,7 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
        dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
     dict_dbm->dbm = dbm;
 
-    return (&dict_dbm->dict);
+    return (DICT_DEBUG(&dict_dbm->dict));
 }
 
 #endif
diff --git a/postfix/src/util/dict_debug.c b/postfix/src/util/dict_debug.c
new file mode 100644 (file)
index 0000000..9b85f1e
--- /dev/null
@@ -0,0 +1,134 @@
+/*++
+/* NAME
+/*     dict_debug 3
+/* SUMMARY
+/*     dictionary manager, logging proxy
+/* SYNOPSIS
+/*     #include <dict.h>
+/*
+/*     DICT    *dict_debug(dict_handle)
+/*     DICT    *dict_handle;
+/*
+/*     DICT    *DICT_DEBUG(dict_handle)
+/*     DICT    *dict_handle;
+/* DESCRIPTION
+/*     dict_debug() encapsulates the given dictionary object and returns
+/*     a proxy object that logs all access to the encapsulated object.
+/*     This is more convenient than having to add logging capability
+/*     to each individual dictionary access method.
+/*
+/*     DICT_DEBUG() is an unsafe macro that returns the original object if
+/*     the object's debugging flag is not set, and that otherwise encapsulates
+/*     the object with dict_debug(). This macro simplifies usage by avoiding
+/*     clumsy expressions. The macro evaluates its argument multiple times.
+/* DIAGNOSTICS
+/*     Fatal errors: out of memory.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System libraries. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <dict.h>
+
+/* Application-specific. */
+
+typedef struct {
+    DICT    dict;                      /* the proxy service */
+    DICT   *real_dict;                 /* encapsulated object */
+} DICT_DEBUG;
+
+/* dict_debug_lookup - log lookup operation */
+
+static const char *dict_debug_lookup(DICT *dict, const char *key)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    const char *result;
+
+    result = dict_get(dict_debug->real_dict, key);
+    msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
+            result ? result : dict_errno ? "try again" : "not_found");
+    return (result);
+}
+
+/* dict_debug_update - log update operation */
+
+static void dict_debug_update(DICT *dict, const char *key, const char *value)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+
+    msg_info("%s:%s update: \"%s\" = \"%s\"", dict->type, dict->name,
+            key, value);
+    dict_put(dict_debug->real_dict, key, value);
+}
+
+/* dict_debug_delete - log delete operation */
+
+static int dict_debug_delete(DICT *dict, const char *key)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    int     result;
+
+    result = dict_del(dict_debug->real_dict, key);
+    msg_info("%s:%s delete: \"%s\" = \"%s\"", dict->type, dict->name, key,
+            result ? "failed" : "success");
+    return (result);
+}
+
+/* dict_debug_sequence - log sequence operation */
+
+static int dict_debug_sequence(DICT *dict, int function,
+                                      const char **key, const char **value)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    int     result;
+
+    result = dict_seq(dict_debug->real_dict, function, key, value);
+    if (result == 0)
+       msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
+                *key, *value);
+    else
+       msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
+    return (result);
+}
+
+/* dict_debug_close - log operation */
+
+static void dict_debug_close(DICT *dict)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+
+    dict_close(dict_debug->real_dict);
+    dict_free(dict);
+}
+
+/* dict_debug - encapsulate dictionary object and install proxies */
+
+DICT   *dict_debug(DICT *real_dict)
+{
+    DICT_DEBUG *dict_debug;
+
+    dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
+                                     real_dict->name, sizeof(*dict_debug));
+    dict_debug->dict.flags = real_dict->flags; /* XXX not synchronized */
+    dict_debug->dict.lookup = dict_debug_lookup;
+    dict_debug->dict.update = dict_debug_update;
+    dict_debug->dict.delete = dict_debug_delete;
+    dict_debug->dict.sequence = dict_debug_sequence;
+    dict_debug->dict.close = dict_debug_close;
+    dict_debug->real_dict = real_dict;
+    return (&dict_debug->dict);
+}
index 34c0e8447275fd5c933a45ad4f4fc1af57cdd181..e87ac15a93d60a0d605820e96f52479d01fd658d 100644 (file)
@@ -80,5 +80,5 @@ DICT   *dict_env_open(const char *name, int unused_flags, int dict_flags)
     dict->update = dict_env_update;
     dict->close = dict_env_close;
     dict->flags = dict_flags | DICT_FLAG_FIXED;
-    return (dict);
+    return (DICT_DEBUG(dict));
 }
index 13c0e54ab89ac4b095f1abcf8b0dafc7c3996e4d..e39fed3fb4b1ebc2a838d809f0c039e8dd8f4bb0 100644 (file)
@@ -842,7 +842,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     /*
      * Otherwise, we're all set. Return the new dict_ldap structure.
      */
-    return (&dict_ldap->dict);
+    return (DICT_DEBUG(&dict_ldap->dict));
 }
 
 #endif
index 55560815d4d59dc8acd0613506886ab67ed059bf..d16c90c85bef0c57b5f6b71f1bf1b9fecfb19c7d 100644 (file)
@@ -360,7 +360,7 @@ DICT   *dict_mysql_open(const char *name, int unused_open_flags, int dict_flags)
     if (dict_mysql->pldb == NULL)
        msg_fatal("couldn't intialize pldb!\n");
     dict_register(name, (DICT *) dict_mysql);
-    return &dict_mysql->dict;
+    return (DICT_DEBUG(&dict_mysql->dict));
 }
 
 /* mysqlname_parse - parse mysql configuration file */
index acee1c50ecef4c251dd4585777e5a632ee1db8b1..dafb687df5106efe58dc54323d558169877fd517 100644 (file)
@@ -174,7 +174,7 @@ DICT   *dict_ni_open(const char *path, int unused_flags, int dict_flags)
     d->dict.close = dict_ni_close;
     d->dict.flags = dict_flags | DICT_FLAG_FIXED;
 
-    return &d->dict;
+    return (DICT_DEBUG(&d->dict));
 }
 
 #endif
index fa95efc35ab15743c5036b9c95cf819883ec24ea..f72c14aa289b7695657aacbc2fc77e3b25532a9a 100644 (file)
@@ -216,7 +216,7 @@ DICT   *dict_nis_open(const char *map, int unused_flags, int dict_flags)
        dict_nis->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
     if (dict_nis_domain == 0)
        dict_nis_init();
-    return (&dict_nis->dict);
+    return (DICT_DEBUG(&dict_nis->dict));
 }
 
 #endif
index 46b88ce3384d894083e221d57c636ee3191f4695..e6f3467d8afb83601164b2effad140708bca9790 100644 (file)
@@ -65,5 +65,5 @@ DICT   *dict_nisplus_open(const char *map, int unused_flags, int dict_flags)
                                               sizeof(*dict_nisplus));
     dict_nisplus->dict.close = dict_nisplus_close;
     dict_nisplus->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_nisplus->dict);
+    return (DICT_DEBUG(&dict_nisplus->dict));
 }
index 8181057396efd709e4ea28e79458a46c25e713da..1e8e84b6bf5a33ff28fd5bcafd25e38172bcd74c 100644 (file)
@@ -364,7 +364,7 @@ DICT   *dict_pcre_open(const char *map, int unused_flags, int dict_flags)
     vstring_free(line_buffer);
     vstream_fclose(map_fp);
 
-    return (&dict_pcre->dict);
+    return (DICT_DEBUG(&dict_pcre->dict));
 }
 
 #endif                                 /* HAS_PCRE */
index 795eecd4b28163c4d64c8c0282c5d771b29d9396..0d4eaf852352693c00d706117c6050e3cbc5f5ef 100644 (file)
@@ -345,8 +345,8 @@ DICT   *dict_regexp_open(const char *map, int unused_flags, int dict_flags)
 
     line_buffer = vstring_alloc(100);
 
-    dict_regexp = (DICT_REGEXP *) dict_alloc(DICT_TYPE_REGEXP, map, 
-       sizeof(*dict_regexp));
+    dict_regexp = (DICT_REGEXP *) dict_alloc(DICT_TYPE_REGEXP, map,
+                                            sizeof(*dict_regexp));
     dict_regexp->dict.lookup = dict_regexp_lookup;
     dict_regexp->dict.close = dict_regexp_close;
     dict_regexp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
@@ -386,7 +386,7 @@ DICT   *dict_regexp_open(const char *map, int unused_flags, int dict_flags)
     vstring_free(line_buffer);
     vstream_fclose(map_fp);
 
-    return (&dict_regexp->dict);
+    return (DICT_DEBUG(&dict_regexp->dict));
 }
 
 #endif
index f6fc3540d199bb756a15c6ed2b85fd80379b22a2..6686055802e5dc4dadfa95eb08cf2c1f5903671d 100644 (file)
@@ -268,5 +268,5 @@ DICT   *dict_tcp_open(const char *map, int unused_flags, int dict_flags)
     dict_tcp->dict.lookup = dict_tcp_lookup;
     dict_tcp->dict.close = dict_tcp_close;
     dict_tcp->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_tcp->dict);
+    return (DICT_DEBUG(&dict_tcp->dict));
 }
index d750b8d1ece748915aff59b7362f72fb1d85d618..1409746c6d9a7a8ce1ca2c451dd99889e321e798 100644 (file)
@@ -146,5 +146,5 @@ DICT   *dict_unix_open(const char *map, int unused_flags, int dict_flags)
     dict_unix->dict.lookup = lp->lookup;
     dict_unix->dict.close = dict_unix_close;
     dict_unix->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_unix->dict);
+    return (DICT_DEBUG(&dict_unix->dict));
 }
index ecc051fdba9f0153a549cef4a2cefded3642194a..0173e9693f4a2e19eb9c5138b295c274eb4a291e 100644 (file)
@@ -11,7 +11,7 @@
 /*     unsigned variation;
 /* DESCRIPTION
 /*     rand_sleep() blocks the current process for an amount of time
-/*     pseudo-randomly chosen from the interval (delay += variation/2).
+/*     pseudo-randomly chosen from the interval (delay +- variation/2).
 /*
 /*     Arguments:
 /* .IP delay