[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[postfix-jp:240] Fw: Postfix 19991231 Patch 12 (low priority)



しらはたです.

FYI:
Postfix-19991231-pl12 がリリースされました.
バウンズメッセージを送信する際,デッドロックが生じる可能性がある
問題を修正したそうです.

ftp://ftp.porcupine.org/mirrors/postfix-release/official/
ftp://ftp.ring.gr.jp/pub/net/mail/postfix/official/
# まだ, 国内のRingサーバにはミラーされていないようです.

Forwarded by Shin SHIRAHATA <shin@xxxxxxxxxxxxxx>
----------------------- Original Message -----------------------
From:    wietse@xxxxxxxxxxxxx (Wietse Venema)
To:      postfix-announce@xxxxxxxxxxx (Postfix announce)
Date:    Fri,  8 Dec 2000 16:53:49 -0500 (EST)
Subject: Postfix 19991231 Patch 12 (low priority)
----

Postfix release 19991231 Patchlevel 12 is available.

While processing massive amounts of one-recipient mail, the Postfix
queue manager could deadlock for 10 seconds while sending a bounce
message. In order to remedy this, all queue manager bounce send
requests are now executed asynchronously.  This problem was reported
by El Bunzo (webpower.nl) and by Tiger Technologies (tigertech.com).

To apply the fix, cd into the top-level release 19991231 patchlevel
11 source code directory and feed this text as standard input to
Larry Wall's patch command:

    patch -p0 <message

A patched version of the source code will be made available from
the sites listed on the www.postfix.org eb site, primary distribution
site:

    ftp://ftp.porcupine.org/mirrors/postfix-release/

        postfix-19991231-patch12.gz         Source patch
        postfix-19991231-pl12.tar.sig       Source code
        postfix-19991231-pl12.tar.gz.sig    PGP signature

Or point your browser to 

    ftp://ftp.porcupine.org/mirrors/postfix-release/index.html

Happy Postfixing!

	Wietse

Prereq: "Postfix-19991231-pl11"
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/global/mail_version.h ./global/mail_version.h
*** ../postfix-19991231-pl11/global/mail_version.h	Tue Nov 21 19:46:24 2000
--- ./global/mail_version.h	Wed Dec  6 19:59:56 2000
***************
*** 15,21 ****
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #define DEF_MAIL_VERSION	"Postfix-19991231-pl11"
  extern char *var_mail_version;
  
  /* LICENSE
--- 15,21 ----
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #define DEF_MAIL_VERSION	"Postfix-19991231-pl12"
  extern char *var_mail_version;
  
  /* LICENSE
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/HISTORY ./HISTORY
*** ../postfix-19991231-pl11/HISTORY	Tue Nov 21 20:29:09 2000
--- ./HISTORY	Fri Dec  8 11:08:39 2000
***************
*** 3885,3887 ****
--- 3885,3897 ----
  	parallel connections to the same site) was too gentle and
  	Postfix would back off too quickly.  Final solution by
  	Patrik Rak. File: qmgr/qmgr_message.c.
+ 
+ 20001208
+ 
+ 	Bugfix: while processing massive amounts of one-recipient
+ 	mail, qmgr could deadlock for 10 seconds while sending a
+ 	bounce message. All queue manager bounce send requests are
+ 	now implemented asynchronously.  Files: global/abounce.[hc]
+ 	(asynchronous bounce client), qmgr/qmgr_active.c.  Problem
+ 	reported by El Bunzo (webpower.nl) and Tiger Technologies
+ 	(tigertech.com).
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/global/Makefile.in ./global/Makefile.in
*** ../postfix-19991231-pl11/global/Makefile.in	Tue Nov 21 20:01:00 2000
--- ./global/Makefile.in	Fri Dec  8 13:22:06 2000
***************
*** 17,23 ****
  	recipient_list.c record.c remove.c resolve_clnt.c resolve_local.c \
  	rewrite_clnt.c sent.c smtp_stream.c split_addr.c string_list.c \
  	sys_exits.c timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
! 	tok822_resolve.c tok822_rewrite.c tok822_tree.c
  OBJS	= been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
  	debug_peer.o debug_process.o defer.o deliver_completed.o \
  	deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
--- 17,23 ----
  	recipient_list.c record.c remove.c resolve_clnt.c resolve_local.c \
  	rewrite_clnt.c sent.c smtp_stream.c split_addr.c string_list.c \
  	sys_exits.c timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
! 	tok822_resolve.c tok822_rewrite.c tok822_tree.c abounce.c
  OBJS	= been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
  	debug_peer.o debug_process.o defer.o deliver_completed.o \
  	deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
***************
*** 36,42 ****
  	recipient_list.o record.o remove.o resolve_clnt.o resolve_local.o \
  	rewrite_clnt.o sent.o smtp_stream.o split_addr.o string_list.o \
  	sys_exits.o timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
! 	tok822_resolve.o tok822_rewrite.o tok822_tree.o
  HDRS	= been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
  	config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
  	deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
--- 36,42 ----
  	recipient_list.o record.o remove.o resolve_clnt.o resolve_local.o \
  	rewrite_clnt.o sent.o smtp_stream.o split_addr.o string_list.o \
  	sys_exits.o timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
! 	tok822_resolve.o tok822_rewrite.o tok822_tree.o abounce.o
  HDRS	= been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
  	config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
  	deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
***************
*** 51,57 ****
  	quote_822_local.h rec_streamlf.h rec_type.h recipient_list.h \
  	record.h resolve_clnt.h resolve_local.h rewrite_clnt.h sent.h \
  	smtp_stream.h split_addr.h string_list.h sys_exits.h timed_ipc.h \
! 	tok822.h
  TESTSRC	= rec2stream.c stream2rec.c recdump.c
  WARN	= -W -Wformat -Wimplicit -Wmissing-prototypes \
  	-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
--- 51,57 ----
  	quote_822_local.h rec_streamlf.h rec_type.h recipient_list.h \
  	record.h resolve_clnt.h resolve_local.h rewrite_clnt.h sent.h \
  	smtp_stream.h split_addr.h string_list.h sys_exits.h timed_ipc.h \
! 	tok822.h abounce.h
  TESTSRC	= rec2stream.c stream2rec.c recdump.c
  WARN	= -W -Wformat -Wimplicit -Wmissing-prototypes \
  	-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
***************
*** 220,225 ****
--- 220,236 ----
  	@make -f Makefile.in Makefile
  
  # do not edit below this line - it is generated by 'make depend'
+ abounce.o: abounce.c
+ abounce.o: ../include/sys_defs.h
+ abounce.o: ../include/msg.h
+ abounce.o: ../include/mymalloc.h
+ abounce.o: ../include/events.h
+ abounce.o: ../include/vstream.h
+ abounce.o: ../include/vbuf.h
+ abounce.o: mail_proto.h
+ abounce.o: ../include/iostuff.h
+ abounce.o: abounce.h
+ abounce.o: bounce.h
  been_here.o: been_here.c
  been_here.o: ../include/sys_defs.h
  been_here.o: ../include/msg.h
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/global/abounce.c ./global/abounce.c
*** ../postfix-19991231-pl11/global/abounce.c	Wed Dec 31 19:00:00 1969
--- ./global/abounce.c	Fri Dec  8 12:56:33 2000
***************
*** 0 ****
--- 1,208 ----
+ /*++
+ /* NAME
+ /*	abounce 3
+ /* SUMMARY
+ /*	asynchronous bounce/defer service client
+ /* SYNOPSIS
+ /*	#include <abounce.h>
+ /*
+ /*	void	abounce_flush(flags, queue, id, sender, callback, context)
+ /*	int	flags;
+ /*	const char *queue;
+ /*	const char *id;
+ /*	const char *sender;
+ /*	void	(*callback)(int status, char *context);
+ /*	char	*context;
+ /*
+ /*	void	adefer_flush(flags, queue, id, sender, callback, context)
+ /*	int	flags;
+ /*	const char *queue;
+ /*	const char *id;
+ /*	const char *sender;
+ /*	void	(*callback)(int status, char *context);
+ /*	char	*context;
+ /*
+ /*	void	adefer_warn(flags, queue, id, sender, callback, context)
+ /*	int	flags;
+ /*	const char *queue;
+ /*	const char *id;
+ /*	const char *sender;
+ /*	void	(*callback)(int status, char *context);
+ /*	char	*context;
+ /* DESCRIPTION
+ /*	This module implements an asynchronous interface to the
+ /*	bounce/defer service for submitting sender notifications
+ /*	without waiting for completion of the request.
+ /*
+ /*	abounce_flush() bounces the specified message to
+ /*	the specified sender, including the bounce log that was
+ /*	built with bounce_append().
+ /*
+ /*	adefer_flush() bounces the specified message to
+ /*	the specified sender, including the defer log that was
+ /*	built with defer_append().
+ /*
+ /*	adefer_warn() sends a "mail is delayed" notification to
+ /*	the specified sender, including the defer log that was
+ /*	built with defer_append().
+ /*
+ /*	Arguments:
+ /* .IP flags
+ /*	The bitwise OR of zero or more of the following (specify
+ /*	BOUNCE_FLAG_NONE to request no special processing):
+ /* .RS
+ /* .IP BOUNCE_FLAG_CLEAN
+ /*	Delete the bounce log in case of an error (as in: pretend
+ /*	that we never even tried to bounce this message).
+ /* .IP BOUNCE_FLAG_COPY
+ /*	Request that a postmaster copy is sent.
+ /* .RE
+ /* .IP queue
+ /*	The message queue name of the original message file.
+ /* .IP id
+ /*	The message queue id if the original message file. The bounce log
+ /*	file has the same name as the original message file.
+ /* .IP sender
+ /*	The sender envelope address.
+ /* .IP callback
+ /*	Name of a routine that receives the notification status as
+ /*	documented for bounce_flush() or defer_flush().
+ /* .IP context
+ /*	Application-specific context that is passed through to the
+ /*	callback routine. Use proper casts or the world will come
+ /*	to an end.
+ /* DIAGNOSTICS
+ /*	In case of success, these functions log the action, and return a
+ /*	zero result via the callback routine. Otherwise, the functions
+ /*	return a non-zero result via the callback routine, and when
+ /*	BOUNCE_FLAG_CLEAN is disabled, log that message delivery is deferred.
+ /* 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>
+ 
+ /* Utility library. */
+ 
+ #include <msg.h>
+ #include <mymalloc.h>
+ #include <events.h>
+ #include <vstream.h>
+ 
+ /* Global library. */
+ 
+ #include <mail_proto.h>
+ #include <abounce.h>
+ 
+ /* Application-specific. */
+ 
+  /*
+   * Each bounce/defer flush/warn request is implemented by sending the
+   * request to the bounce/defer server, and by creating a pseudo thread that
+   * suspends itself until the server replies (or dies). Upon wakeup, the
+   * pseudo thread delivers the request completion status to the application
+   * and destroys itself. The structure below maintains all the necessary
+   * request state while the pseudo thread is suspended.
+   */
+ typedef struct {
+     int     command;			/* bounce request type */
+     int     flags;			/* bounce options */
+     char   *id;				/* queue ID for logging */
+     ABOUNCE_FN callback;		/* application callback */
+     char   *context;			/* application context */
+     VSTREAM *fp;			/* server I/O handle */
+ } ABOUNCE;
+ 
+ /* abounce_done - deliver status to application and clean up pseudo thread */
+ 
+ static void abounce_done(ABOUNCE *ap, int status)
+ {
+     (void) vstream_fclose(ap->fp);
+     if (status != 0 && (ap->flags & BOUNCE_FLAG_CLEAN) == 0)
+ 	msg_info("%s: status=deferred (%s failed)", ap->id,
+ 		 ap->command == BOUNCE_CMD_FLUSH ? "bounce" :
+ 		 ap->command == BOUNCE_CMD_WARN ? "delay warning" :
+ 		 "whatever");
+     ap->callback(status, ap->context);
+     myfree(ap->id);
+     myfree((char *) ap);
+ }
+ 
+ /* abounce_event - resume pseudo thread after server reply event */
+ 
+ static void abounce_event(int unused_event, char *context)
+ {
+     ABOUNCE *ap = (ABOUNCE *) context;
+     int     status;
+ 
+     event_disable_readwrite(vstream_fileno(ap->fp));
+     abounce_done(ap, mail_scan(ap->fp, "%d", &status) == 1 ? status : -1);
+ }
+ 
+ /* abounce_request - suspend pseudo thread until server reply event */
+ 
+ static void abounce_request(const char *class, const char *service,
+ 			            int command, int flags,
+ 			            const char *queue, const char *id,
+ 			            const char *sender,
+ 			            ABOUNCE_FN callback,
+ 			            char *context)
+ {
+     ABOUNCE *ap;
+ 
+     /*
+      * Save pseudo thread state. Connect to the server. Send the request and
+      * suspend the pseudo thread until the server replies (or dies).
+      */
+     ap = (ABOUNCE *) mymalloc(sizeof(*ap));
+     ap->command = command;
+     ap->flags = flags;
+     ap->id = mystrdup(id);
+     ap->callback = callback;
+     ap->context = context;
+     ap->fp = mail_connect_wait(class, service);
+ 
+     if (mail_print(ap->fp, "%d %d %s %s %s %s", command,
+ 		   flags, queue, id, sender, MAIL_EOF) == 0
+ 	&& vstream_fflush(ap->fp) == 0) {
+ 	event_enable_read(vstream_fileno(ap->fp), abounce_event, (char *) ap);
+     } else {
+ 	abounce_done(ap, -1);
+     }
+ }
+ 
+ /* abounce_flush - asynchronous bounce flush */
+ 
+ void    abounce_flush(int flags, const char *queue, const char *id,
+ 	             const char *sender, ABOUNCE_FN callback, char *context)
+ {
+     abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE, BOUNCE_CMD_FLUSH,
+ 		    flags, queue, id, sender, callback, context);
+ }
+ 
+ /* adefer_flush - asynchronous defer flush */
+ 
+ void    adefer_flush(int flags, const char *queue, const char *id,
+ 	             const char *sender, ABOUNCE_FN callback, char *context)
+ {
+     abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER, BOUNCE_CMD_FLUSH,
+ 		    flags, queue, id, sender, callback, context);
+ }
+ 
+ /* adefer_warn - send copy of defer log to sender as warning bounce */
+ 
+ void    adefer_warn(int flags, const char *queue, const char *id,
+ 	             const char *sender, ABOUNCE_FN callback, char *context)
+ {
+     abounce_request(MAIL_CLASS_PRIVATE, MAIL_SERVICE_DEFER, BOUNCE_CMD_WARN,
+ 		    flags, queue, id, sender, callback, context);
+ }
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/global/abounce.h ./global/abounce.h
*** ../postfix-19991231-pl11/global/abounce.h	Wed Dec 31 19:00:00 1969
--- ./global/abounce.h	Thu Dec  7 15:55:42 2000
***************
*** 0 ****
--- 1,39 ----
+ #ifndef _ABOUNCE_H_INCLUDED_
+ #define _ABOUNCE_H_INCLUDED_
+ 
+ /*++
+ /* NAME
+ /*	abounce 3h
+ /* SUMMARY
+ /*	asynchronous bounce/defer service client
+ /* SYNOPSIS
+ /*	#include <abounce.h>
+ /* DESCRIPTION
+ /* .nf
+ 
+  /*
+   * Global library.
+   */
+ #include <bounce.h>
+ 
+  /*
+   * Client interface.
+   */
+ typedef void (*ABOUNCE_FN) (int, char *);
+ 
+ extern void abounce_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
+ extern void adefer_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
+ extern void adefer_warn(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
+ 
+ /* 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
+ /*--*/
+ 
+ #endif
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/qmgr/Makefile.in ./qmgr/Makefile.in
*** ../postfix-19991231-pl11/qmgr/Makefile.in	Tue Nov 21 20:01:50 2000
--- ./qmgr/Makefile.in	Fri Dec  8 13:22:53 2000
***************
*** 92,97 ****
--- 92,98 ----
  qmgr_active.o: ../include/recipient_list.h
  qmgr_active.o: ../include/bounce.h
  qmgr_active.o: ../include/defer.h
+ qmgr_active.o: ../include/abounce.h
  qmgr_active.o: ../include/rec_type.h
  qmgr_active.o: qmgr.h
  qmgr_active.o: ../include/scan_dir.h
diff -cr --new-file --exclude=.indent.pro ../postfix-19991231-pl11/qmgr/qmgr_active.c ./qmgr/qmgr_active.c
*** ../postfix-19991231-pl11/qmgr/qmgr_active.c	Wed Dec  8 22:10:41 1999
--- ./qmgr/qmgr_active.c	Fri Dec  8 10:58:42 2000
***************
*** 102,113 ****
--- 102,123 ----
  #include <recipient_list.h>
  #include <bounce.h>
  #include <defer.h>
+ #include <abounce.h>
  #include <rec_type.h>
  
  /* Application-specific. */
  
  #include "qmgr.h"
  
+  /*
+   * A bunch of call-back routines.
+   */
+ static void qmgr_active_done_2_bounce_flush(int, char *);
+ static void qmgr_active_done_2_generic(QMGR_MESSAGE *);
+ static void qmgr_active_done_3_defer_flush(int, char *);
+ static void qmgr_active_done_3_defer_warn(int, char *);
+ static void qmgr_active_done_3_generic(QMGR_MESSAGE *);
+ 
  /* qmgr_active_corrupt - move corrupted file out of the way */
  
  static void qmgr_active_corrupt(const char *queue_id)
***************
*** 235,242 ****
  {
      char   *myname = "qmgr_active_done";
      struct stat st;
-     const char *path;
-     int     delay;
  
      if (msg_verbose)
  	msg_info("%s: %s", myname, message->queue_id);
--- 245,250 ----
***************
*** 255,260 ****
--- 263,271 ----
       * Don't bounce when the bounce log is empty. The bounce process obviously
       * failed, and the delivery agent will have requested that the message be
       * deferred.
+      * 
+      * Bounces are sent asynchronously to avoid stalling while the cleanup
+      * daemon waits for the qmgr to accept the "new mail" trigger.
       */
      if (stat(mail_queue_path((VSTRING *) 0, MAIL_QUEUE_BOUNCE, message->queue_id), &st) == 0) {
  	if (st.st_size == 0) {
***************
*** 264,277 ****
  	} else {
  	    if (msg_verbose)
  		msg_info("%s: bounce %s", myname, message->queue_id);
! 	    message->flags |= bounce_flush(BOUNCE_FLAG_KEEP,
! 					   message->queue_name,
! 					   message->queue_id,
! 					   message->errors_to);
  	}
      }
  
      /*
       * A delivery agent marks a queue file as corrupt by changing its
       * attributes, and by pretending that delivery was deferred.
       */
--- 275,318 ----
  	} else {
  	    if (msg_verbose)
  		msg_info("%s: bounce %s", myname, message->queue_id);
! 	    abounce_flush(BOUNCE_FLAG_KEEP,
! 			  message->queue_name,
! 			  message->queue_id,
! 			  message->errors_to,
! 			  qmgr_active_done_2_bounce_flush,
! 			  (char *) message);
! 	    return;
  	}
      }
  
      /*
+      * Asynchronous processing does not reach this point.
+      */
+     qmgr_active_done_2_generic(message);
+ }
+ 
+ /* qmgr_active_done_2_bounce_flush - process abounce_flush() status */
+ 
+ static void qmgr_active_done_2_bounce_flush(int status, char *context)
+ {
+     QMGR_MESSAGE *message = (QMGR_MESSAGE *) context;
+ 
+     /*
+      * Process abounce_flush() status and continue processing.
+      */
+     message->flags |= status;
+     qmgr_active_done_2_generic(message);
+ }
+ 
+ /* qmgr_active_done_2_generic - continue processing */
+ 
+ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
+ {
+     char   *myname = "qmgr_active_done_2_generic";
+     const char *path;
+     struct stat st;
+ 
+     /*
       * A delivery agent marks a queue file as corrupt by changing its
       * attributes, and by pretending that delivery was deferred.
       */
***************
*** 304,309 ****
--- 345,353 ----
      /*
       * If we get to this point we have tried all recipients for this message.
       * If the message is too old, try to bounce it.
+      * 
+      * Bounces are sent asynchronously to avoid stalling while the cleanup
+      * daemon waits for the qmgr to accept the "new mail" trigger.
       */
  #define HOUR	3600
  #define DAY	86400
***************
*** 312,333 ****
  	if (event_time() > message->arrival_time + var_max_queue_time * DAY) {
  	    if (msg_verbose)
  		msg_info("%s: too old, bouncing %s", myname, message->queue_id);
! 	    message->flags = defer_flush(BOUNCE_FLAG_KEEP,
! 					 message->queue_name,
! 					 message->queue_id,
! 					 message->errors_to);
  	} else if (message->warn_time > 0
  		   && event_time() > message->warn_time) {
  	    if (msg_verbose)
  		msg_info("%s: sending defer warning for %s", myname, message->queue_id);
! 	    if (defer_warn(BOUNCE_FLAG_KEEP,
! 			   message->queue_name,
! 			   message->queue_id,
! 			   message->errors_to) == 0) {
! 		qmgr_message_update_warn(message);
! 	    }
  	}
      }
  
      /*
       * Some recipients need to be tried again. Move the queue file time
--- 356,421 ----
  	if (event_time() > message->arrival_time + var_max_queue_time * DAY) {
  	    if (msg_verbose)
  		msg_info("%s: too old, bouncing %s", myname, message->queue_id);
! 	    adefer_flush(BOUNCE_FLAG_KEEP,
! 			 message->queue_name,
! 			 message->queue_id,
! 			 message->errors_to,
! 			 qmgr_active_done_3_defer_flush,
! 			 (char *) message);
! 	    return;
  	} else if (message->warn_time > 0
  		   && event_time() > message->warn_time) {
  	    if (msg_verbose)
  		msg_info("%s: sending defer warning for %s", myname, message->queue_id);
! 	    adefer_warn(BOUNCE_FLAG_KEEP,
! 			message->queue_name,
! 			message->queue_id,
! 			message->errors_to,
! 			qmgr_active_done_3_defer_warn,
! 			(char *) message);
! 	    return;
  	}
      }
+ 
+     /*
+      * Asynchronous processing does not reach this point.
+      */
+     qmgr_active_done_3_generic(message);
+ }
+ 
+ /* qmgr_active_done_3_defer_warn - continue after adefer_warn() completion */
+ 
+ static void qmgr_active_done_3_defer_warn(int status, char *context)
+ {
+     QMGR_MESSAGE *message = (QMGR_MESSAGE *) context;
+ 
+     /*
+      * Process adefer_warn() completion status and continue processing.
+      */
+     if (status == 0)
+ 	qmgr_message_update_warn(message);
+     qmgr_active_done_3_generic(message);
+ }
+ 
+ /* qmgr_active_done_3_defer_flush - continue after adefer_flush() completion */
+ 
+ static void qmgr_active_done_3_defer_flush(int status, char *context)
+ {
+     QMGR_MESSAGE *message = (QMGR_MESSAGE *) context;
+ 
+     /*
+      * Process adefer_flush() status and continue processing.
+      */
+     message->flags = status;
+     qmgr_active_done_3_generic(message);
+ }
+ 
+ /* qmgr_active_done_3_generic - continue processing */
+ 
+ static void qmgr_active_done_3_generic(QMGR_MESSAGE *message)
+ {
+     char   *myname = "qmgr_active_done_3_generic";
+     int     delay;
  
      /*
       * Some recipients need to be tried again. Move the queue file time


--------------------- Original Message Ends --------------------


[検索ページ] [Postfix-JP ML Home]