Wietse Venema: > [EMAIL PROTECTED]: > > Any ideas what causes these? > > > > Jul 21 23:14:43 kd1 postfix/qmgr[20699]: warning: F320A29569: rcpt count > > mismatch (-2) > ... > > Version is postfix-2.3.r8,3 (FreeBSD port) > > This problem was removed by a code reorganization in Postfix 2.4, > when I added support for "message body" replacement.
This patch fixes the Postfix 2.3 "rcpt count mismatch" warning message that is logged after Milter applications add a recipient to a queue file. Postfix 2.3 is the oldest Postfix release that is still being updated. The current patchlevel is 15. Wietse diff -cr --new-file /var/tmp/postfix-2.3.8/src/cleanup/Makefile.in ./src/cleanup/Makefile.in *** /var/tmp/postfix-2.3.8/src/cleanup/Makefile.in Thu Oct 19 11:16:17 2006 --- ./src/cleanup/Makefile.in Mon Sep 8 08:46:28 2008 *************** *** 3,14 **** cleanup_extracted.c cleanup_state.c cleanup_rewrite.c \ cleanup_map11.c cleanup_map1n.c cleanup_masquerade.c \ cleanup_out_recipient.c cleanup_init.c cleanup_api.c \ ! cleanup_addr.c cleanup_bounce.c cleanup_milter.c OBJS = cleanup.o cleanup_out.o cleanup_envelope.o cleanup_message.o \ cleanup_extracted.o cleanup_state.o cleanup_rewrite.o \ cleanup_map11.o cleanup_map1n.o cleanup_masquerade.o \ cleanup_out_recipient.o cleanup_init.o cleanup_api.o \ ! cleanup_addr.o cleanup_bounce.o cleanup_milter.o HDRS = TESTSRC = DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) --- 3,14 ---- cleanup_extracted.c cleanup_state.c cleanup_rewrite.c \ cleanup_map11.c cleanup_map1n.c cleanup_masquerade.c \ cleanup_out_recipient.c cleanup_init.c cleanup_api.c \ ! cleanup_addr.c cleanup_bounce.c cleanup_milter.c cleanup_final.c OBJS = cleanup.o cleanup_out.o cleanup_envelope.o cleanup_message.o \ cleanup_extracted.o cleanup_state.o cleanup_rewrite.o \ cleanup_map11.o cleanup_map1n.o cleanup_masquerade.o \ cleanup_out_recipient.o cleanup_init.o cleanup_api.o \ ! cleanup_addr.o cleanup_bounce.o cleanup_milter.o cleanup_final.o HDRS = TESTSRC = DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) *************** *** 321,326 **** --- 321,352 ---- cleanup_extracted.o: ../../include/vstring.h cleanup_extracted.o: cleanup.h cleanup_extracted.o: cleanup_extracted.c + cleanup_final.o: ../../include/argv.h + cleanup_final.o: ../../include/been_here.h + cleanup_final.o: ../../include/cleanup_user.h + cleanup_final.o: ../../include/dict.h + cleanup_final.o: ../../include/header_opts.h + cleanup_final.o: ../../include/htable.h + cleanup_final.o: ../../include/mail_conf.h + cleanup_final.o: ../../include/mail_stream.h + cleanup_final.o: ../../include/maps.h + cleanup_final.o: ../../include/match_list.h + cleanup_final.o: ../../include/match_ops.h + cleanup_final.o: ../../include/milter.h + cleanup_final.o: ../../include/mime_state.h + cleanup_final.o: ../../include/msg.h + cleanup_final.o: ../../include/mymalloc.h + cleanup_final.o: ../../include/nvtable.h + cleanup_final.o: ../../include/rec_type.h + cleanup_final.o: ../../include/resolve_clnt.h + cleanup_final.o: ../../include/string_list.h + cleanup_final.o: ../../include/sys_defs.h + cleanup_final.o: ../../include/tok822.h + cleanup_final.o: ../../include/vbuf.h + cleanup_final.o: ../../include/vstream.h + cleanup_final.o: ../../include/vstring.h + cleanup_final.o: cleanup.h + cleanup_final.o: cleanup_final.c cleanup_init.o: ../../include/argv.h cleanup_init.o: ../../include/been_here.h cleanup_init.o: ../../include/dict.h diff -cr --new-file /var/tmp/postfix-2.3.8/src/cleanup/cleanup.h ./src/cleanup/cleanup.h *** /var/tmp/postfix-2.3.8/src/cleanup/cleanup.h Thu Oct 19 11:16:17 2006 --- ./src/cleanup/cleanup.h Mon Sep 8 08:45:45 2008 *************** *** 220,225 **** --- 220,230 ---- extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, ssize_t); /* + * cleanup_final.c + */ + extern void cleanup_final(CLEANUP_STATE *); + + /* * cleanup_rewrite.c */ extern int cleanup_rewrite_external(const char *, VSTRING *, const char *); diff -cr --new-file /var/tmp/postfix-2.3.8/src/cleanup/cleanup_api.c ./src/cleanup/cleanup_api.c *** /var/tmp/postfix-2.3.8/src/cleanup/cleanup_api.c Thu Jun 15 14:07:15 2006 --- ./src/cleanup/cleanup_api.c Mon Sep 8 08:47:12 2008 *************** *** 235,240 **** --- 235,247 ---- } /* + * Update the preliminary message size and count fields with the actual + * values. + */ + if (CLEANUP_OUT_OK(state)) + cleanup_final(state); + + /* * If there was an error that requires us to generate a bounce message * (mail submitted with the Postfix sendmail command, mail forwarded by * the local(8) delivery agent, or mail re-queued with "postsuper -r"), diff -cr --new-file /var/tmp/postfix-2.3.8/src/cleanup/cleanup_extracted.c ./src/cleanup/cleanup_extracted.c *** /var/tmp/postfix-2.3.8/src/cleanup/cleanup_extracted.c Tue Jun 13 17:59:07 2006 --- ./src/cleanup/cleanup_extracted.c Mon Sep 8 08:43:28 2008 *************** *** 300,331 **** * Terminate the extracted segment. */ cleanup_out_string(state, REC_TYPE_END, ""); - - /* - * vstream_fseek() would flush the buffer anyway, but the code just reads - * better if we flush first, because it makes seek error handling more - * straightforward. - */ - if (vstream_fflush(state->dst)) { - if (errno == EFBIG) { - msg_warn("%s: queue file size limit exceeded", state->queue_id); - state->errs |= CLEANUP_STAT_SIZE; - } else { - msg_warn("%s: write queue file: %m", state->queue_id); - state->errs |= CLEANUP_STAT_WRITE; - } - return; - } - - /* - * Update the preliminary message size and count fields with the actual - * values. - */ - if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0) - msg_fatal("%s: vstream_fseek %s: %m", myname, cleanup_path); - cleanup_out_format(state, REC_TYPE_SIZE, REC_TYPE_SIZE_FORMAT, - (REC_TYPE_SIZE_CAST1) (state->xtra_offset - state->data_offset), - (REC_TYPE_SIZE_CAST2) state->data_offset, - (REC_TYPE_SIZE_CAST3) state->rcpt_count, - (REC_TYPE_SIZE_CAST4) state->qmgr_opts); } --- 300,303 ---- diff -cr --new-file /var/tmp/postfix-2.3.8/src/cleanup/cleanup_final.c ./src/cleanup/cleanup_final.c *** /var/tmp/postfix-2.3.8/src/cleanup/cleanup_final.c Wed Dec 31 19:00:00 1969 --- ./src/cleanup/cleanup_final.c Mon Sep 8 08:45:13 2008 *************** *** 0 **** --- 1,76 ---- + /*++ + /* NAME + /* cleanup_final 3 + /* SUMMARY + /* finalize queue file + /* SYNOPSIS + /* #include "cleanup.h" + /* + /* void cleanup_final(state) + /* CLEANUP_STATE *state; + /* DESCRIPTION + /* cleanup_final() performs final queue file content (not + /* attribute) updates so that the file is ready to be closed. + /* 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 library. */ + + #include <sys_defs.h> + #include <errno.h> + + /* Utility library. */ + + #include <msg.h> + + /* Global library. */ + + #include <cleanup_user.h> + #include <rec_type.h> + + /* Application-specific. */ + + #include "cleanup.h" + + /* cleanup_final - final queue file content updates */ + + void cleanup_final(CLEANUP_STATE *state) + { + const char *myname = "cleanup_final"; + + /* + * vstream_fseek() would flush the buffer anyway, but the code just reads + * better if we flush first, because it makes seek error handling more + * straightforward. + */ + if (vstream_fflush(state->dst)) { + if (errno == EFBIG) { + msg_warn("%s: queue file size limit exceeded", state->queue_id); + state->errs |= CLEANUP_STAT_SIZE; + } else { + msg_warn("%s: write queue file: %m", state->queue_id); + state->errs |= CLEANUP_STAT_WRITE; + } + return; + } + + /* + * Update the preliminary message size and count fields with the actual + * values. + */ + if (vstream_fseek(state->dst, 0L, SEEK_SET) < 0) + msg_fatal("%s: vstream_fseek %s: %m", myname, cleanup_path); + cleanup_out_format(state, REC_TYPE_SIZE, REC_TYPE_SIZE_FORMAT, + (REC_TYPE_SIZE_CAST1) (state->xtra_offset - state->data_offset), + (REC_TYPE_SIZE_CAST2) state->data_offset, + (REC_TYPE_SIZE_CAST3) state->rcpt_count, + (REC_TYPE_SIZE_CAST4) state->qmgr_opts); + }