static void mail_rcpt(MIME_NODE *node, const HEADER_OPTS *header_info) { TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; ACL_VSTRING *temp; const char *cp; temp = acl_vstring_alloc(10); cp = STR(node->buffer) + strlen(header_info->name) + 1; tree = tok822_parse(cp); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { tok822_internalize(temp, tpp[0]->head, TOK822_STR_DEFL); if (header_info->type == HDR_TO) { node->header_to_list = mail_addr_add(node->header_to_list, STR(temp)); } else if (header_info->type == HDR_CC) { node->header_cc_list = mail_addr_add(node->header_cc_list, STR(temp)); } else if (header_info->type == HDR_BCC) { node->header_bcc_list = mail_addr_add(node->header_bcc_list, STR(temp)); } } acl_myfree(addr_list); tok822_free_tree(tree); acl_vstring_free(temp); }
static void cleanup_rewrite_recip(CLEANUP_STATE *state, const HEADER_OPTS *hdr_opts, VSTRING *header_buf) { TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; int did_rewrite = 0; if (msg_verbose) msg_info("rewrite_recip: %s", hdr_opts->name); /* * Parse the header line, rewrite each address found, and regenerate the * header line. Finally, pipe the result through the header line folding * routine. */ tree = tok822_parse_limit(vstring_str(header_buf) + strlen(hdr_opts->name) + 1, var_token_limit); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { did_rewrite |= cleanup_rewrite_tree(state->hdr_rewrite_context, *tpp); if (state->flags & CLEANUP_FLAG_MAP_OK) { if (cleanup_rcpt_canon_maps && (cleanup_rcpt_canon_flags & CLEANUP_CANON_FLAG_HDR_RCPT)) did_rewrite |= cleanup_map11_tree(state, *tpp, cleanup_rcpt_canon_maps, cleanup_ext_prop_mask & EXT_PROP_CANONICAL); if (cleanup_comm_canon_maps && (cleanup_comm_canon_flags & CLEANUP_CANON_FLAG_HDR_RCPT)) did_rewrite |= cleanup_map11_tree(state, *tpp, cleanup_comm_canon_maps, cleanup_ext_prop_mask & EXT_PROP_CANONICAL); if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_RCPT)) did_rewrite |= cleanup_masquerade_tree(state, *tpp, cleanup_masq_domains); } } if (did_rewrite) { vstring_truncate(header_buf, strlen(hdr_opts->name)); vstring_strcat(header_buf, ": "); tok822_externalize(header_buf, tree, TOK822_STR_HEAD); } myfree((char *) addr_list); tok822_free_tree(tree); if ((hdr_opts->flags & HDR_OPT_DROP) == 0) { if (did_rewrite) cleanup_fold_header(state, header_buf); else cleanup_out_header(state, header_buf); } }
ARGV *mail_addr_crunch(const char *string, const char *extension) { VSTRING *extern_addr = vstring_alloc(100); VSTRING *canon_addr = vstring_alloc(100); ARGV *argv = argv_alloc(1); TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; char *ratsign; ssize_t extlen; if (extension) extlen = strlen(extension); #define STR(x) vstring_str(x) /* * Parse the string, rewrite each address to canonical form, and convert * the result to external (quoted) form. Optionally apply the extension * to each address found. * * XXX Workaround for the null address. This works for envelopes but * produces ugly results for message headers. */ if (*string == 0 || strcmp(string, "<>") == 0) string = "\"\""; tree = tok822_parse(string); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL); canon_addr_external(canon_addr, STR(extern_addr)); if (extension) { VSTRING_SPACE(canon_addr, extlen + 1); if ((ratsign = strrchr(STR(canon_addr), '@')) == 0) { vstring_strcat(canon_addr, extension); } else { memmove(ratsign + extlen, ratsign, strlen(ratsign) + 1); memcpy(ratsign, extension, extlen); VSTRING_SKIP(canon_addr); } } argv_add(argv, STR(canon_addr), ARGV_END); } argv_terminate(argv); myfree((char *) addr_list); tok822_free_tree(tree); vstring_free(canon_addr); vstring_free(extern_addr); return (argv); }
static void mail_from(MIME_NODE *node, const HEADER_OPTS *header_info) { //MIME_STATE *state = node->state; TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; ACL_VSTRING *temp; const char *cp; temp = acl_vstring_alloc(10); cp = STR(node->buffer) + strlen(header_info->name) + 1; tree = tok822_parse(cp); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { tok822_internalize(temp, tpp[0]->head, TOK822_STR_DEFL); if (header_info->type == HDR_SENDER) { if (node->header_sender) acl_myfree(node->header_sender); node->header_sender = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_FROM) { if (node->header_from) acl_myfree(node->header_from); node->header_from = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_REPLY_TO) { if (node->header_replyto) acl_myfree(node->header_replyto); node->header_replyto = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_RETURN_PATH) { if (node->header_returnpath) acl_myfree(node->header_returnpath); node->header_returnpath = acl_mystrdup(STR(temp)); } } acl_myfree(addr_list); tok822_free_tree(tree); acl_vstring_free(temp); }
static void output_header(void *context, int header_class, const HEADER_OPTS *header_info, VSTRING *buf, off_t offset) { SM_STATE *state = (SM_STATE *) context; TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; ARGV *rcpt; char *start; char *line; char *next_line; ssize_t len; /* * Parse the header line, and save copies of recipient addresses in the * appropriate place. */ if (header_class == MIME_HDR_PRIMARY && header_info && (header_info->flags & HDR_OPT_RECIP) && (header_info->flags & HDR_OPT_EXTRACT) && (state->resent == 0 || (header_info->flags & HDR_OPT_RR))) { if (header_info->flags & HDR_OPT_RR) { rcpt = state->resent_recip; if (state->resent == 0) state->resent = 1; } else rcpt = state->recipients; tree = tok822_parse(STR(buf) + strlen(header_info->name) + 1); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { tok822_internalize(state->temp, tpp[0]->head, TOK822_STR_DEFL); argv_add(rcpt, STR(state->temp), (char *) 0); } myfree((void *) addr_list); tok822_free_tree(tree); } /* * Pipe the unmodified message header through the header line folding * routine, and ensure that long lines are chopped appropriately. */ for (line = start = STR(buf); line; line = next_line) { next_line = split_at(line, '\n'); len = next_line ? next_line - line - 1 : strlen(line); do { if (len > var_line_limit) { output_text(context, REC_TYPE_CONT, line, var_line_limit, offset); line += var_line_limit; len -= var_line_limit; offset += var_line_limit; } else { output_text(context, REC_TYPE_NORM, line, len, offset); offset += len; break; } } while (len > 0); offset += 1; } }