#include <sys_defs.h>
#include <unistd.h>
#include <string.h>
#include <msg.h>
#include <vstring.h>
#include <htable.h>
#include <mail_proto.h>
#include <resolve_clnt.h>
#include <rewrite_clnt.h>
#include <tok822.h>
#include <mail_params.h>
#include <defer.h>
#include "local.h"
int deliver_resolve_addr(LOCAL_STATE state, USER_ATTR usr_attr, char *addr)
{
TOK822 *tree;
int result;
tree = tok822_scan_addr(addr);
result = deliver_resolve_tree(state, usr_attr, tree);
tok822_free_tree(tree);
return (result);
}
int deliver_resolve_tree(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr)
{
const char *myname = "deliver_resolve_tree";
RESOLVE_REPLY reply;
int status;
ssize_t ext_len;
char *ratsign;
int rcpt_delim;
state.level++;
if (msg_verbose)
MSG_LOG_STATE(myname, state);
resolve_clnt_init(&reply);
tok822_rewrite(addr, REWRITE_CANON);
tok822_resolve(addr, &reply);
if (reply.flags & RESOLVE_FLAG_FAIL) {
dsb_simple(state.msg_attr.why, "4.3.0", "address resolver failure");
status = defer_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr));
} else if (reply.flags & RESOLVE_FLAG_ERROR) {
dsb_simple(state.msg_attr.why, "5.1.3",
"bad recipient address syntax: %s", STR(reply.recipient));
status = bounce_append(BOUNCE_FLAGS(state.request),
BOUNCE_ATTR(state.msg_attr));
} else {
if (state.msg_attr.unmatched) {
rcpt_delim = state.msg_attr.local[strlen(state.msg_attr.user)];
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0) {
VSTRING_ADDCH(reply.recipient, rcpt_delim);
vstring_strcat(reply.recipient, state.msg_attr.unmatched);
} else {
ext_len = strlen(state.msg_attr.unmatched);
VSTRING_SPACE(reply.recipient, ext_len + 2);
if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0)
msg_panic("%s: recipient @ botch", myname);
memmove(ratsign + ext_len + 1, ratsign, strlen(ratsign) + 1);
*ratsign = rcpt_delim;
memcpy(ratsign + 1, state.msg_attr.unmatched, ext_len);
VSTRING_SKIP(reply.recipient);
}
}
state.msg_attr.rcpt.address = STR(reply.recipient);
if (strcmp(state.msg_attr.relay, STR(reply.transport)) == 0) {
status = deliver_recipient(state, usr_attr);
} else {
status = deliver_indirect(state);
}
}
resolve_clnt_free(&reply);
return (status);
}