static void qmgr_active_done_25_generic(QMGR_MESSAGE *message) { const char *myname = "qmgr_active_done_25_generic"; /* * 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. */ if (message->flags) { if (event_time() >= message->create_time + (*message->sender ? var_max_queue_time : var_dsn_queue_time)) { msg_info("%s: from=<%s>, status=expired, returned to sender", message->queue_id, message->sender); if (message->verp_delims == 0 || var_verp_bounce_off) adefer_flush(BOUNCE_FLAG_KEEP, message->queue_name, message->queue_id, message->encoding, message->sender, message->dsn_envid, message->dsn_ret, qmgr_active_done_3_defer_flush, (char *) message); else adefer_flush_verp(BOUNCE_FLAG_KEEP, message->queue_name, message->queue_id, message->encoding, message->sender, message->dsn_envid, message->dsn_ret, message->verp_delims, qmgr_active_done_3_defer_flush, (char *) message); return; } else if (message->warn_time > 0 && event_time() >= message->warn_time - 1) { 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->encoding, message->sender, message->dsn_envid, message->dsn_ret, qmgr_active_done_3_defer_warn, (char *) message); return; } } /* * Asynchronous processing does not reach this point. */ qmgr_active_done_3_generic(message); }
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); }
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); }
static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) { char *myname = "qmgr_active_done_2_generic"; const char *path; struct stat st; int status; /* * A delivery agent marks a queue file as corrupt by changing its * attributes, and by pretending that delivery was deferred. */ if (message->flags && mail_open_ok(MAIL_QUEUE_ACTIVE, message->queue_id, &st, &path) == MAIL_OPEN_NO) { qmgr_active_corrupt(message->queue_id); qmgr_message_free(message); return; } /* * If we did not read all recipients from this file, go read some more, * but remember whether some recipients have to be tried again. * * Throwing away queue files seems bad, especially when they made it this * far into the mail system. Therefore we save bad files to a separate * directory for further inspection by a human being. */ if (message->rcpt_offset > 0) { if (qmgr_message_realloc(message) == 0) { qmgr_active_corrupt(message->queue_id); qmgr_message_free(message); } else { if (message->refcount == 0) qmgr_active_done(message); /* recurse for consistency */ } return; } /* * As a temporary implementation, synchronously inform the sender of * trace information. This will block for 10 seconds when the qmgr FIFO * is full. */ if (message->tflags & (DEL_REQ_FLAG_EXPAND | DEL_REQ_FLAG_RECORD)) { status = trace_flush(message->tflags, message->queue_name, message->queue_id, message->encoding, message->sender); if (status == 0 && message->tflags_offset) qmgr_message_kill_record(message, message->tflags_offset); message->flags |= status; } /* * 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. */ if (message->flags) { if (event_time() >= message->arrival_time + (*message->sender ? var_max_queue_time : var_dsn_queue_time)) { msg_info("%s: from=<%s>, status=expired, returned to sender", message->queue_id, message->sender); if (message->verp_delims == 0 || var_verp_bounce_off) adefer_flush(BOUNCE_FLAG_KEEP, message->queue_name, message->queue_id, message->encoding, message->errors_to, qmgr_active_done_3_defer_flush, (char *) message); else adefer_flush_verp(BOUNCE_FLAG_KEEP, message->queue_name, message->queue_id, message->encoding, message->errors_to, message->verp_delims, 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->encoding, 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); }