static int smtpd_proxy_save_rec_fprintf(VSTREAM *stream, int rec_type, const char *fmt,...) { const char *myname = "smtpd_proxy_save_rec_fprintf"; va_list ap; int ret; /* * Sanity check. */ if (stream == 0) msg_panic("%s: attempt to use closed stream", myname); /* * Save one content record. Errors and results must be as with * rec_fprintf(). */ va_start(ap, fmt); if (rec_type == REC_TYPE_NORM) ret = rec_vfprintf(stream, rec_type, fmt, ap); else msg_panic("%s: need REC_TYPE_NORM", myname); va_end(ap); /* * Errors last. */ if (ret != rec_type) { (void) smtpd_proxy_replay_rdwr_error(VSTREAM_TO_SMTPD_STATE(stream)); return (REC_TYPE_ERROR); } return (rec_type); }
int post_mail_fprintf(VSTREAM *cleanup, const char *format,...) { int status; va_list ap; va_start(ap, format); status = rec_vfprintf(cleanup, REC_TYPE_NORM, format, ap); va_end(ap); return (status != REC_TYPE_NORM ? CLEANUP_STAT_WRITE : 0); }
static int smtpd_proxy_save_cmd(SMTPD_STATE *state, int expect, const char *fmt,...) { va_list ap; /* * Errors first. */ if (vstream_ferror(smtpd_proxy_replay_stream) || vstream_feof(smtpd_proxy_replay_stream)) return (smtpd_proxy_replay_rdwr_error(state)); /* * Save the expected reply first, so that the replayer can safely * overwrite the input buffer with the command. */ rec_fprintf(smtpd_proxy_replay_stream, REC_TYPE_RCPT, "%d", expect); /* * The command can be omitted at the start of an SMTP session. This is * not documented as part of the official interface because it is used * only internally to this module. Use an explicit null string in case * the SMTPD_PROXY_CONN_FMT implementation details change. */ if (fmt == SMTPD_PROXY_CONN_FMT) fmt = ""; /* * Save the command to the replay log, and send it to the before-queue * filter after we have received the entire message. */ va_start(ap, fmt); rec_vfprintf(smtpd_proxy_replay_stream, REC_TYPE_FROM, fmt, ap); va_end(ap); /* * If we just saved the "." command, replay the log. */ return (strcmp(fmt, ".") ? 0 : smtpd_proxy_replay_send(state)); }