From edac954e0e8ea7488cf7767d7f08134b153f33b9 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sun, 4 Feb 2001 00:00:00 -0500 Subject: [PATCH] snapshot-20010204 --- postfix/.indent.pro | 1 + postfix/DEBUG_README | 17 +++- postfix/HISTORY | 23 +++-- postfix/html/error.8.html | 4 +- postfix/html/local.8.html | 4 +- postfix/html/nqmgr.8.html | 4 +- postfix/html/postdrop.1.html | 4 +- postfix/html/qmgr.8.html | 4 +- postfix/html/trivial-rewrite.8.html | 4 +- postfix/html/uce.html | 2 +- postfix/mantools/postlink | 1 + postfix/src/dns/dns_lookup.c | 4 +- postfix/src/global/mail_version.h | 2 +- postfix/src/nqmgr/qmgr_entry.c | 5 ++ postfix/src/nqmgr/qmgr_job.c | 24 +++-- postfix/src/nqmgr/qmgr_message.c | 9 +- postfix/src/smtp/smtp_addr.c | 2 +- postfix/src/util/Makefile.in | 12 ++- postfix/src/util/dict.c | 2 +- postfix/src/util/dict.h | 4 + postfix/src/util/dict_db.c | 2 +- postfix/src/util/dict_dbm.c | 2 +- postfix/src/util/dict_debug.c | 134 ++++++++++++++++++++++++++++ postfix/src/util/dict_env.c | 2 +- postfix/src/util/dict_ldap.c | 2 +- postfix/src/util/dict_mysql.c | 2 +- postfix/src/util/dict_ni.c | 2 +- postfix/src/util/dict_nis.c | 2 +- postfix/src/util/dict_nisplus.c | 2 +- postfix/src/util/dict_pcre.c | 2 +- postfix/src/util/dict_regexp.c | 6 +- postfix/src/util/dict_tcp.c | 2 +- postfix/src/util/dict_unix.c | 2 +- postfix/src/util/rand_sleep.c | 2 +- 34 files changed, 241 insertions(+), 55 deletions(-) create mode 100644 postfix/src/util/dict_debug.c diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 7223e9d27..c35b4962f 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -27,6 +27,7 @@ -TDICT_ENV -TDICT_HT -TDICT_LDAP +-TDICT_DEBUG -TDICT_MYSQL -TDICT_NI -TDICT_NIS diff --git a/postfix/DEBUG_README b/postfix/DEBUG_README index 4e8f2cea2..cd2593eb6 100644 --- a/postfix/DEBUG_README +++ b/postfix/DEBUG_README @@ -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 diff --git a/postfix/HISTORY b/postfix/HISTORY index 8f095ce1c..0ab32a6be 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -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 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. diff --git a/postfix/html/error.8.html b/postfix/html/error.8.html index 2a3d401f8..d36ab9919 100644 --- a/postfix/html/error.8.html +++ b/postfix/html/error.8.html @@ -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 mas- - ter(8) process manager. + information. This program expects to be run from the mas- + ter(8) process manager. The error mailer client forces all recipients to bounce, using the domain or host information as the reason for diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index 5aac19255..36c800201 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -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 mas- - ter(8) process manager. + recipients. This program expects to be run from the mas- + ter(8) process manager. The local daemon updates queue files and marks recipients as finished, or it informs the queue manager that delivery diff --git a/postfix/html/nqmgr.8.html b/postfix/html/nqmgr.8.html index 624352aa2..6fbbe7f9b 100644 --- a/postfix/html/nqmgr.8.html +++ b/postfix/html/nqmgr.8.html @@ -14,8 +14,8 @@ NQMGR(8) NQMGR(8) DESCRIPTION The nqmgr 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 triv- - ial-rewrite(8) daemon. This program expects to be run + The actual mail routing strategy is delegated to the triv- + ial-rewrite(8) daemon. This program expects to be run from the master(8) process manager. Mail addressed to the local double-bounce address is diff --git a/postfix/html/postdrop.1.html b/postfix/html/postdrop.1.html index b9f3b7963..372b037a3 100644 --- a/postfix/html/postdrop.1.html +++ b/postfix/html/postdrop.1.html @@ -19,8 +19,8 @@ POSTDROP(1) POSTDROP(1) and with group write permission to the maildrop queue directory. - The postdrop command is automatically invoked by the send- - mail(1) mail posting agent when the maildrop queue direc- + The postdrop command is automatically invoked by the send- + mail(1) mail posting agent when the maildrop queue direc- tory is not world-writable. Options: diff --git a/postfix/html/qmgr.8.html b/postfix/html/qmgr.8.html index 213a35b04..032e6dfdb 100644 --- a/postfix/html/qmgr.8.html +++ b/postfix/html/qmgr.8.html @@ -14,8 +14,8 @@ QMGR(8) QMGR(8) DESCRIPTION The qmgr 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 triv- - ial-rewrite(8) daemon. This program expects to be run + The actual mail routing strategy is delegated to the triv- + ial-rewrite(8) daemon. This program expects to be run from the master(8) process manager. Mail addressed to the local double-bounce address is diff --git a/postfix/html/trivial-rewrite.8.html b/postfix/html/trivial-rewrite.8.html index ce97479f8..f24125814 100644 --- a/postfix/html/trivial-rewrite.8.html +++ b/postfix/html/trivial-rewrite.8.html @@ -43,8 +43,8 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8) The trivial-rewrite daemon by default only distin- guishes between local and non-local mail. For finer - control over mail routing, use the optional trans- - port(5) lookup table. + control over mail routing, use the optional trans- + port(5) lookup table. This program expects to be run from the master(8) process manager. diff --git a/postfix/html/uce.html b/postfix/html/uce.html index d35330a2f..1fe7b0cbf 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -979,7 +979,7 @@ appear as part of a client hostname/address restriction list.
Default: -
maps_rbl_domains = rbl.maps.vix.com, dul.maps.vix.com +
maps_rbl_domains = blackholes.mail-abuse.org

diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 1328075ee..d9c57a9c1 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -46,5 +46,6 @@ exec sed ' s/[]*trans[-]*\n*[ ]*port[]*(5)/&<\/a>/ s/[]*virtual[]*(5)/&<\/a>/ s/[]*virtual[]*(8)/&<\/a>/ + s/\(\)\([]*[a-z0-9-]*[-]*\)\(\n *\)\([]*[a-z0-9-]*[]*([0-9])\)\(<\/a>\)/\1\2\5\3\1\4\5/ s/RFC *\([0-9]*\)/&<\/a>/ ' "$@" diff --git a/postfix/src/dns/dns_lookup.c b/postfix/src/dns/dns_lookup.c index 6f8e9d078..f08923fc0 100644 --- a/postfix/src/dns/dns_lookup.c +++ b/postfix/src/dns/dns_lookup.c @@ -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)); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 82f068e6d..a1c3a8171 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 diff --git a/postfix/src/nqmgr/qmgr_entry.c b/postfix/src/nqmgr/qmgr_entry.c index e6b84f577..64cec0b28 100644 --- a/postfix/src/nqmgr/qmgr_entry.c +++ b/postfix/src/nqmgr/qmgr_entry.c @@ -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; diff --git a/postfix/src/nqmgr/qmgr_job.c b/postfix/src/nqmgr/qmgr_job.c index 2b8ea1330..5e604cf1a 100644 --- a/postfix/src/nqmgr/qmgr_job.c +++ b/postfix/src/nqmgr/qmgr_job.c @@ -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 diff --git a/postfix/src/nqmgr/qmgr_message.c b/postfix/src/nqmgr/qmgr_message.c index 3078f3ffe..45bb0f78a 100644 --- a/postfix/src/nqmgr/qmgr_message.c +++ b/postfix/src/nqmgr/qmgr_message.c @@ -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 diff --git a/postfix/src/smtp/smtp_addr.c b/postfix/src/smtp/smtp_addr.c index d86c694e1..c9109fa3a 100644 --- a/postfix/src/smtp/smtp_addr.c +++ b/postfix/src/smtp/smtp_addr.c @@ -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); diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index edf47f419..90dd044a2 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -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 diff --git a/postfix/src/util/dict.c b/postfix/src/util/dict.c index 2a02ce958..7d07d3be0 100644 --- a/postfix/src/util/dict.c +++ b/postfix/src/util/dict.c @@ -109,7 +109,7 @@ /* 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. diff --git a/postfix/src/util/dict.h b/postfix/src/util/dict.h index c9fb8e981..5a669aa09 100644 --- a/postfix/src/util/dict.h +++ b/postfix/src/util/dict.h @@ -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; diff --git a/postfix/src/util/dict_db.c b/postfix/src/util/dict_db.c index a887b4be2..02b72baf4 100644 --- a/postfix/src/util/dict_db.c +++ b/postfix/src/util/dict_db.c @@ -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 */ diff --git a/postfix/src/util/dict_dbm.c b/postfix/src/util/dict_dbm.c index 332c38f77..6f3a5611a 100644 --- a/postfix/src/util/dict_dbm.c +++ b/postfix/src/util/dict_dbm.c @@ -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 index 000000000..9b85f1e54 --- /dev/null +++ b/postfix/src/util/dict_debug.c @@ -0,0 +1,134 @@ +/*++ +/* NAME +/* dict_debug 3 +/* SUMMARY +/* dictionary manager, logging proxy +/* SYNOPSIS +/* #include +/* +/* 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 + +/* Utility library. */ + +#include +#include +#include + +/* 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); +} diff --git a/postfix/src/util/dict_env.c b/postfix/src/util/dict_env.c index 34c0e8447..e87ac15a9 100644 --- a/postfix/src/util/dict_env.c +++ b/postfix/src/util/dict_env.c @@ -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)); } diff --git a/postfix/src/util/dict_ldap.c b/postfix/src/util/dict_ldap.c index 13c0e54ab..e39fed3fb 100644 --- a/postfix/src/util/dict_ldap.c +++ b/postfix/src/util/dict_ldap.c @@ -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 diff --git a/postfix/src/util/dict_mysql.c b/postfix/src/util/dict_mysql.c index 55560815d..d16c90c85 100644 --- a/postfix/src/util/dict_mysql.c +++ b/postfix/src/util/dict_mysql.c @@ -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 */ diff --git a/postfix/src/util/dict_ni.c b/postfix/src/util/dict_ni.c index acee1c50e..dafb687df 100644 --- a/postfix/src/util/dict_ni.c +++ b/postfix/src/util/dict_ni.c @@ -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 diff --git a/postfix/src/util/dict_nis.c b/postfix/src/util/dict_nis.c index fa95efc35..f72c14aa2 100644 --- a/postfix/src/util/dict_nis.c +++ b/postfix/src/util/dict_nis.c @@ -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 diff --git a/postfix/src/util/dict_nisplus.c b/postfix/src/util/dict_nisplus.c index 46b88ce33..e6f3467d8 100644 --- a/postfix/src/util/dict_nisplus.c +++ b/postfix/src/util/dict_nisplus.c @@ -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)); } diff --git a/postfix/src/util/dict_pcre.c b/postfix/src/util/dict_pcre.c index 818105739..1e8e84b6b 100644 --- a/postfix/src/util/dict_pcre.c +++ b/postfix/src/util/dict_pcre.c @@ -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 */ diff --git a/postfix/src/util/dict_regexp.c b/postfix/src/util/dict_regexp.c index 795eecd4b..0d4eaf852 100644 --- a/postfix/src/util/dict_regexp.c +++ b/postfix/src/util/dict_regexp.c @@ -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 diff --git a/postfix/src/util/dict_tcp.c b/postfix/src/util/dict_tcp.c index f6fc3540d..668605580 100644 --- a/postfix/src/util/dict_tcp.c +++ b/postfix/src/util/dict_tcp.c @@ -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)); } diff --git a/postfix/src/util/dict_unix.c b/postfix/src/util/dict_unix.c index d750b8d1e..1409746c6 100644 --- a/postfix/src/util/dict_unix.c +++ b/postfix/src/util/dict_unix.c @@ -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)); } diff --git a/postfix/src/util/rand_sleep.c b/postfix/src/util/rand_sleep.c index ecc051fdb..0173e9693 100644 --- a/postfix/src/util/rand_sleep.c +++ b/postfix/src/util/rand_sleep.c @@ -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