QMGR_MESSAGE *qmgr_message_realloc(QMGR_MESSAGE *message) { const char *myname = "qmgr_message_realloc"; /* * Sanity checks. */ if (message->rcpt_offset <= 0) msg_panic("%s: invalid offset: %ld", myname, message->rcpt_offset); if (msg_verbose) msg_info("%s: %s %s offset %ld", myname, message->queue_name, message->queue_id, message->rcpt_offset); /* * Extract recipient addresses. Skip files with malformed envelope * information. */ if (qmgr_message_open(message) < 0) return (0); if (qmgr_message_read(message) < 0) { qmgr_message_close(message); return (0); } else { qmgr_message_sort(message); qmgr_message_resolve(message); qmgr_message_sort(message); qmgr_message_assign(message); qmgr_message_close(message); if (message->rcpt_offset == 0) qmgr_message_move_limits(message); return (message); } }
void qmgr_message_kill_record(QMGR_MESSAGE *message, long offset) { if (offset <= 0) msg_panic("qmgr_message_kill_record: bad offset 0x%lx", offset); if (qmgr_message_open(message) || rec_put_type(message->fp, REC_TYPE_KILL, offset) < 0 || vstream_fflush(message->fp)) msg_fatal("update queue file %s: %m", VSTREAM_PATH(message->fp)); qmgr_message_close(message); }
void qmgr_message_update_warn(QMGR_MESSAGE *message) { /* * After the "mail delayed" warning, optionally send a "delay cleared" * notification. */ if (qmgr_message_open(message) || vstream_fseek(message->fp, message->warn_offset, SEEK_SET) < 0 || rec_fprintf(message->fp, REC_TYPE_WARN, REC_TYPE_WARN_FORMAT, REC_TYPE_WARN_ARG(-1)) < 0 || vstream_fflush(message->fp)) msg_fatal("update queue file %s: %m", VSTREAM_PATH(message->fp)); qmgr_message_close(message); }
void qmgr_message_update_warn(QMGR_MESSAGE *message) { /* * XXX eventually this should let us schedule multiple warnings, right * now it just allows for one. */ if (qmgr_message_open(message) || vstream_fseek(message->fp, message->warn_offset, SEEK_SET) < 0 || rec_fprintf(message->fp, REC_TYPE_WARN, REC_TYPE_WARN_FORMAT, REC_TYPE_WARN_ARG(0)) < 0 || vstream_fflush(message->fp)) msg_fatal("update queue file %s: %m", VSTREAM_PATH(message->fp)); qmgr_message_close(message); }
QMGR_MESSAGE *qmgr_message_alloc(const char *queue_name, const char *queue_id, int qflags, mode_t mode) { const char *myname = "qmgr_message_alloc"; QMGR_MESSAGE *message; if (msg_verbose) msg_info("%s: %s %s", myname, queue_name, queue_id); /* * Create an in-core message structure. */ message = qmgr_message_create(queue_name, queue_id, qflags); /* * Extract message envelope information: time of arrival, sender address, * recipient addresses. Skip files with malformed envelope information. */ #define QMGR_LOCK_MODE (MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) if (qmgr_message_open(message) < 0) { qmgr_message_free(message); return (0); } if (myflock(vstream_fileno(message->fp), INTERNAL_LOCK, QMGR_LOCK_MODE) < 0) { msg_info("%s: skipped, still being delivered", queue_id); qmgr_message_close(message); qmgr_message_free(message); return (QMGR_MESSAGE_LOCKED); } if (qmgr_message_read(message) < 0) { qmgr_message_close(message); qmgr_message_free(message); return (0); } else { /* * We have validated the queue file content, so it is safe to modify * the file properties now. */ if (mode != 0 && fchmod(vstream_fileno(message->fp), mode) < 0) msg_fatal("fchmod %s: %m", VSTREAM_PATH(message->fp)); /* * Reset the defer log. This code should not be here, but we must * reset the defer log *after* acquiring the exclusive lock on the * queue file and *before* resolving new recipients. Since all those * operations are encapsulated so nicely by this routine, the defer * log reset has to be done here as well. * * Note: it is safe to remove the defer logfile from a previous queue * run of this queue file, because the defer log contains information * about recipients that still exist in this queue file. */ if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT) msg_fatal("%s: %s: remove %s %s: %m", myname, queue_id, MAIL_QUEUE_DEFER, queue_id); qmgr_message_sort(message); qmgr_message_resolve(message); qmgr_message_sort(message); qmgr_message_assign(message); qmgr_message_close(message); if (message->rcpt_offset == 0) qmgr_message_move_limits(message); return (message); } }