Esempio n. 1
0
void    cleanup_state_free(CLEANUP_STATE *state)
{
    vstring_free(state->attr_buf);
    vstring_free(state->temp1);
    vstring_free(state->temp2);
    if (cleanup_strip_chars)
	vstring_free(state->stripped_buf);
    if (state->fullname)
	myfree(state->fullname);
    if (state->sender)
	myfree(state->sender);
    if (state->recip)
	myfree(state->recip);
    if (state->orig_rcpt)
	myfree(state->orig_rcpt);
    if (state->return_receipt)
	myfree(state->return_receipt);
    if (state->errors_to)
	myfree(state->errors_to);
    argv_free(state->auto_hdrs);
    if (state->hbc_rcpt)
	argv_free(state->hbc_rcpt);
    if (state->queue_name)
	myfree(state->queue_name);
    if (state->queue_id)
	myfree(state->queue_id);
    been_here_free(state->dups);
    if (state->reason)
	myfree(state->reason);
    if (state->smtp_reply)
	myfree(state->smtp_reply);
    nvtable_free(state->attr);
    if (state->mime_state)
	mime_state_free(state->mime_state);
    if (state->filter)
	myfree(state->filter);
    if (state->redirect)
	myfree(state->redirect);
    if (state->dsn_envid)
	myfree(state->dsn_envid);
    if (state->dsn_orcpt)
	myfree(state->dsn_orcpt);
    if (state->verp_delims)
	myfree(state->verp_delims);
    if (state->milters)
	milter_free(state->milters);
    if (state->milter_ext_from)
	vstring_free(state->milter_ext_from);
    if (state->milter_ext_rcpt)
	vstring_free(state->milter_ext_rcpt);
    if (state->milter_err_text)
	vstring_free(state->milter_err_text);
    cleanup_region_done(state);
    myfree((void *) state);
}
Esempio n. 2
0
static int local_deliver(DELIVER_REQUEST *rqst, char *service)
{
    const char *myname = "local_deliver";
    RECIPIENT *rcpt_end = rqst->rcpt_list.info + rqst->rcpt_list.len;
    RECIPIENT *rcpt;
    int     rcpt_stat;
    int     msg_stat;
    LOCAL_STATE state;
    USER_ATTR usr_attr;

    if (msg_verbose)
	msg_info("local_deliver: %s from %s", rqst->queue_id, rqst->sender);

    /*
     * Initialize the delivery attributes that are not recipient specific.
     * While messages are being delivered and while aliases or forward files
     * are being expanded, this attribute list is being changed constantly.
     * For this reason, the list is passed on by value (except when it is
     * being initialized :-), so that there is no need to undo attribute
     * changes made by lower-level routines. The alias/include/forward
     * expansion attribute list is part of a tree with self and parent
     * references (see the EXPAND_ATTR definitions). The user-specific
     * attributes are security sensitive, and are therefore kept separate.
     * All this results in a noticeable level of clumsiness, but passing
     * things around by value gives good protection against accidental change
     * by subroutines.
     */
    state.level = 0;
    deliver_attr_init(&state.msg_attr);
    state.msg_attr.queue_name = rqst->queue_name;
    state.msg_attr.queue_id = rqst->queue_id;
    state.msg_attr.fp = rqst->fp;
    state.msg_attr.offset = rqst->data_offset;
    state.msg_attr.encoding = rqst->encoding;
    state.msg_attr.sender = rqst->sender;
    state.msg_attr.dsn_envid = rqst->dsn_envid;
    state.msg_attr.dsn_ret = rqst->dsn_ret;
    state.msg_attr.relay = service;
    state.msg_attr.msg_stats = rqst->msg_stats;
    state.msg_attr.request = rqst;
    RESET_OWNER_ATTR(state.msg_attr, state.level);
    RESET_USER_ATTR(usr_attr, state.level);
    state.loop_info = delivered_hdr_init(rqst->fp, rqst->data_offset,
					 FOLD_ADDR_ALL);
    state.request = rqst;

    /*
     * Iterate over each recipient named in the delivery request. When the
     * mail delivery status for a given recipient is definite (i.e. bounced
     * or delivered), update the message queue file and cross off the
     * recipient. Update the per-message delivery status.
     */
    for (msg_stat = 0, rcpt = rqst->rcpt_list.info; rcpt < rcpt_end; rcpt++) {
	state.dup_filter = been_here_init(var_dup_filter_limit, BH_FLAG_FOLD);
	forward_init();
	state.msg_attr.rcpt = *rcpt;
	rcpt_stat = deliver_recipient(state, usr_attr);
	rcpt_stat |= forward_finish(rqst, state.msg_attr, rcpt_stat);
	if (rcpt_stat == 0 && (rqst->flags & DEL_REQ_FLAG_SUCCESS))
	    deliver_completed(state.msg_attr.fp, rcpt->offset);
	been_here_free(state.dup_filter);
	msg_stat |= rcpt_stat;
    }

    /*
     * Clean up.
     */
    delivered_hdr_free(state.loop_info);
    deliver_attr_free(&state.msg_attr);

    return (msg_stat);
}