Exemple #1
0
void    qmgr_active_done(QMGR_MESSAGE *message)
{
    char   *myname = "qmgr_active_done";
    struct stat st;

    if (msg_verbose)
	msg_info("%s: %s", myname, message->queue_id);

    /*
     * During a previous iteration, an attempt to bounce this message may
     * have failed, so there may still be a bounce log lying around. XXX By
     * groping around in the bounce queue, we're trespassing on the bounce
     * service's territory. But doing so is more robust than depending on the
     * bounce daemon to do the lookup for us, and for us to do the deleting
     * after we have received a successful status from the bounce service.
     * The bounce queue directory blocks are most likely in memory anyway. If
     * these lookups become a performance problem we will have to build an
     * in-core cache into the bounce daemon.
     * 
     * 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) {
	    if (mail_queue_remove(MAIL_QUEUE_BOUNCE, message->queue_id))
		msg_fatal("remove %s %s: %m",
			  MAIL_QUEUE_BOUNCE, message->queue_id);
	} else {
	    if (msg_verbose)
		msg_info("%s: bounce %s", myname, message->queue_id);
	    if (message->verp_delims == 0 || var_verp_bounce_off)
		abounce_flush(BOUNCE_FLAG_KEEP,
			      message->queue_name,
			      message->queue_id,
			      message->encoding,
			      message->errors_to,
			      qmgr_active_done_2_bounce_flush,
			      (char *) message);
	    else
		abounce_flush_verp(BOUNCE_FLAG_KEEP,
				   message->queue_name,
				   message->queue_id,
				   message->encoding,
				   message->errors_to,
				   message->verp_delims,
				   qmgr_active_done_2_bounce_flush,
				   (char *) message);
	    return;
	}
    }

    /*
     * Asynchronous processing does not reach this point.
     */
    qmgr_active_done_2_generic(message);
}
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);
}