int delivered_hdr_find(DELIVERED_HDR_INFO *info, const char *address) { HTABLE_INFO *ht; /* * mail_copy() uses quote_822_local() when writing the Delivered-To: * header. We must therefore apply the same transformation when looking * up the recipient. Lowercase the delivered-to address for consistency. */ quote_822_local(info->buf, address); if (info->flags & FOLD_ADDR_ALL) fold_addr(STR(info->buf), info->flags); ht = htable_locate(info->table, STR(info->buf)); return (ht != 0); }
DELIVERED_HDR_INFO *delivered_hdr_init(VSTREAM *fp, off_t offset, int flags) { char *cp; DELIVERED_HDR_INFO *info; const HEADER_OPTS *hdr; /* * Sanity check. */ info = (DELIVERED_HDR_INFO *) mymalloc(sizeof(*info)); info->flags = flags; info->buf = vstring_alloc(10); info->table = htable_create(0); if (vstream_fseek(fp, offset, SEEK_SET) < 0) msg_fatal("seek queue file %s: %m", VSTREAM_PATH(fp)); /* * XXX Assume that mail_copy() produces delivered-to headers that fit in * a REC_TYPE_NORM record. Lowercase the delivered-to addresses for * consistency. * * XXX Don't get bogged down by gazillions of delivered-to headers. */ #define DELIVERED_HDR_LIMIT 1000 while (rec_get(fp, info->buf, 0) == REC_TYPE_NORM && info->table->used < DELIVERED_HDR_LIMIT) { if (is_header(STR(info->buf))) { if ((hdr = header_opts_find(STR(info->buf))) != 0 && hdr->type == HDR_DELIVERED_TO) { cp = STR(info->buf) + strlen(hdr->name) + 1; while (ISSPACE(*cp)) cp++; if (info->flags & FOLD_ADDR_ALL) fold_addr(cp, info->flags); if (msg_verbose) msg_info("delivered_hdr_init: %s", cp); htable_enter(info->table, cp, (char *) 0); } } else if (ISSPACE(STR(info->buf)[0])) { continue; } else { break; } } return (info); }
static void morph_recipient(VSTRING *buf, const char *address, int flags) { /* * Quote the recipient address as appropriate. */ if (flags & PIPE_OPT_QUOTE_LOCAL) quote_822_local(buf, address); else vstring_strcpy(buf, address); /* * Fold the recipient address as appropriate. */ if (flags & PIPE_OPT_FOLD_ALL) fold_addr(STR(buf), PIPE_OPT_FOLD_FLAGS(flags)); }
int main(int argc, char **argv) { VSTRING *line_buffer = vstring_alloc(1); VSTRING *fold_buffer = vstring_alloc(1); ARGV *cmd; char **args; msg_vstream_init(argv[0], VSTREAM_ERR); util_utf8_enable = 1; while (vstring_fgets_nonl(line_buffer, VSTREAM_IN)) { vstream_printf("> %s\n", STR(line_buffer)); cmd = argv_split(STR(line_buffer), CHARS_SPACE); if (cmd->argc == 0 || cmd->argv[0][0] == '#') { argv_free(cmd); continue; } args = cmd->argv; /* * Fold the host. */ if (strcmp(args[0], "host") == 0 && cmd->argc == 2) { vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer, args[1], FOLD_ADDR_HOST)); } /* * Fold the user. */ else if (strcmp(args[0], "user") == 0 && cmd->argc == 2) { vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer, args[1], FOLD_ADDR_USER)); } /* * Fold user and host. */ else if (strcmp(args[0], "all") == 0 && cmd->argc == 2) { vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer, args[1], FOLD_ADDR_ALL)); } /* * Fold none. */ else if (strcmp(args[0], "none") == 0 && cmd->argc == 2) { vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer, args[1], 0)); } /* * Usage. */ else { vstream_printf("Usage: %s host <addr> | user <addr> | all <addr>\n", argv[0]); } vstream_fflush(VSTREAM_OUT); argv_free(cmd); } vstring_free(line_buffer); vstring_free(fold_buffer); exit(0); }