/*++ /* NAME /* cleanup_extracted 3 /* SUMMARY /* process extracted segment /* SYNOPSIS /* #include "cleanup.h" /* /* void cleanup_extracted(state, type, buf, len) /* CLEANUP_STATE *state; /* int type; /* const char *buf; /* ssize_t len; /* DESCRIPTION /* This module processes message records with information extracted /* from message content, or with recipients that are stored after the /* message content. It updates recipient records, writes extracted /* information records to the output, and writes the queue /* file end marker. The queue file is left in a state that /* is suitable for Milter inspection, but the size record still /* contains dummy values. /* /* Arguments: /* .IP state /* Queue file and message processing state. This state is updated /* as records are processed and as errors happen. /* .IP type /* Record type. /* .IP buf /* Record content. /* .IP len /* Record content length. /* 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
/*--*/
/* cleanup_extracted_process - process one extracted envelope record */
void cleanup_extracted_process(CLEANUP_STATE *state, int type, constchar *buf, ssize_t len)
{ constchar *myname = "cleanup_extracted_process"; constchar *encoding; char *attr_name; char *attr_value; constchar *error_text; int extra_opts; int junk;
#ifdef DELAY_ACTION int defer_delay;
#endif
if (msg_verbose)
msg_info("extracted envelope %c %.*s", type, (int) len, buf);
if (type == REC_TYPE_FLGS) { /* Not part of queue file format. */
extra_opts = atoi(buf); if (extra_opts & ~CLEANUP_FLAG_MASK_EXTRA)
msg_warn("%s: ignoring bad extra flags: 0x%x",
state->queue_id, extra_opts); else
state->flags |= extra_opts; return;
} #ifdef DELAY_ACTION if (type == REC_TYPE_DELAY) { /* Not part of queue file format. */
defer_delay = atoi(buf); if (defer_delay <= 0)
msg_warn("%s: ignoring bad delay time: %s", state->queue_id, buf); else
state->defer_delay = defer_delay; return;
} #endif
if (strchr(REC_TYPE_EXTRACT, type) == 0) {
msg_warn("%s: message rejected: " "unexpected record type %d in extracted envelope",
state->queue_id, type);
state->errs |= CLEANUP_STAT_BAD; return;
}
/* *MapDSNattributenametopseudorecordtypesothatwedon'thaveto *pollutethequeuefilewithrecordsthatareincompatiblewithpast *Postfixversions.Preferably,peopleshouldbeabletobackoutfrom *anupgradewithoutlosingmail.
*/ if (type == REC_TYPE_ATTR) {
vstring_strcpy(state->attr_buf, buf);
error_text = split_nameval(STR(state->attr_buf), &attr_name, &attr_value); if (error_text != 0) {
msg_warn("%s: message rejected: malformed attribute: %s: %.100s",
state->queue_id, error_text, buf);
state->errs |= CLEANUP_STAT_BAD; return;
} /* Zero-length values are place holders for unavailable values. */ if (*attr_value == 0) {
msg_warn("%s: spurious null attribute value for \"%s\" -- ignored",
state->queue_id, attr_name); return;
} if ((junk = rec_attr_map(attr_name)) != 0) {
buf = attr_value;
type = junk;
}
}
/* *Onthetransitionfromnon-recipientrecordstorecipientrecords, *emitoptionalinformationfromheader/bodycontent.
*/ if ((state->flags & CLEANUP_FLAG_INRCPT) == 0
&& strchr(REC_TYPE_EXT_RECIPIENT, type) != 0) { if (state->filter != 0)
cleanup_out_string(state, REC_TYPE_FILT, state->filter); if (state->redirect != 0)
cleanup_out_string(state, REC_TYPE_RDR, state->redirect); if (state->message_id != 0) {
cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_MESSAGE_ID, state->message_id);
} if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) != 0)
cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ENCODING, encoding);
state->flags |= CLEANUP_FLAG_INRCPT; /* Make room to append more meta records. */ if (state->milters || cleanup_milters) { if ((state->append_meta_pt_offset = vstream_ftell(state->dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, 0L); if ((state->append_meta_pt_target = vstream_ftell(state->dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
}
}
/* *Extractedenveloperecipientrecordprocessing.
*/ if (type == REC_TYPE_RCPT) { if (state->sender == 0) { /* protect showq */
msg_warn("%s: message rejected: envelope recipient precedes sender",
state->queue_id);
state->errs |= CLEANUP_STAT_BAD; return;
} if (state->orig_rcpt == 0)
state->orig_rcpt = mystrdup(buf);
cleanup_addr_recipient(state, buf); if (cleanup_milters != 0
&& state->milters == 0
&& CLEANUP_MILTER_OK(state))
cleanup_milter_emul_rcpt(state, cleanup_milters, state->recip);
myfree(state->orig_rcpt);
state->orig_rcpt = 0; if (state->dsn_orcpt != 0) {
myfree(state->dsn_orcpt);
state->dsn_orcpt = 0;
}
state->dsn_notify = 0; return;
} if (type == REC_TYPE_DONE || type == REC_TYPE_DRCP) { if (state->orig_rcpt != 0) {
myfree(state->orig_rcpt);
state->orig_rcpt = 0;
} if (state->dsn_orcpt != 0) {
myfree(state->dsn_orcpt);
state->dsn_orcpt = 0;
}
state->dsn_notify = 0; return;
} if (type == REC_TYPE_DSN_ORCPT) { if (state->dsn_orcpt) {
msg_warn("%s: ignoring out-of-order DSN original recipient record <%.200s>",
state->queue_id, state->dsn_orcpt);
myfree(state->dsn_orcpt);
}
state->dsn_orcpt = mystrdup(buf); return;
} if (type == REC_TYPE_DSN_NOTIFY) { if (state->dsn_notify) {
msg_warn("%s: ignoring out-of-order DSN notify record <%d>",
state->queue_id, state->dsn_notify);
state->dsn_notify = 0;
} if (!alldig(buf) || (junk = atoi(buf)) == 0 || DSN_NOTIFY_OK(junk) == 0)
msg_warn("%s: ignoring malformed dsn notify record <%.200s>",
state->queue_id, buf); else
state->qmgr_opts |=
QMGR_READ_FLAG_FROM_DSN(state->dsn_notify = junk); return;
} if (type == REC_TYPE_ORCP) { if (state->orig_rcpt != 0) {
msg_warn("%s: ignoring out-of-order original recipient record <%.200s>",
state->queue_id, buf);
myfree(state->orig_rcpt);
}
state->orig_rcpt = mystrdup(buf); return;
} if (type == REC_TYPE_END) { /* Make room to append recipient. */ if ((state->milters || cleanup_milters)
&& state->append_rcpt_pt_offset < 0) { if ((state->append_rcpt_pt_offset = vstream_ftell(state->dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, 0L); if ((state->append_rcpt_pt_target = vstream_ftell(state->dst)) < 0)
msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
}
state->flags &= ~CLEANUP_FLAG_INRCPT;
state->flags |= CLEANUP_FLAG_END_SEEN;
cleanup_extracted_finish(state); return;
}
/* *Extractedenvelopenon-recipientrecordprocessing.
*/ if (state->flags & CLEANUP_FLAG_INRCPT) /* Tell qmgr that recipient records are mixed with other information. */
state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER;
cleanup_out(state, type, buf, len); return;
}
/* cleanup_extracted_finish - complete the third message segment */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.