diff options
Diffstat (limited to 'src/cleanup/cleanup_map11.c')
-rw-r--r-- | src/cleanup/cleanup_map11.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/cleanup/cleanup_map11.c b/src/cleanup/cleanup_map11.c new file mode 100644 index 0000000..4934aac --- /dev/null +++ b/src/cleanup/cleanup_map11.c @@ -0,0 +1,183 @@ +/*++ +/* NAME +/* cleanup_map11 3 +/* SUMMARY +/* one-to-one mapping +/* SYNOPSIS +/* #include <cleanup.h> +/* +/* int cleanup_map11_external(state, addr, maps, propagate) +/* CLEANUP_STATE *state; +/* VSTRING *addr; +/* MAPS *maps; +/* int propagate; +/* +/* int cleanup_map11_internal(state, addr, maps, propagate) +/* CLEANUP_STATE *state; +/* VSTRING *addr; +/* MAPS *maps; +/* int propagate; +/* +/* int cleanup_map11_tree(state, tree, maps, propagate) +/* CLEANUP_STATE *state; +/* TOK822 *tree; +/* MAPS *maps; +/* int propagate; +/* DESCRIPTION +/* This module performs one-to-one map lookups. +/* +/* If an address has a mapping, the lookup result is +/* subjected to another iteration of rewriting and mapping. +/* Recursion continues until an address maps onto itself, +/* or until an unreasonable recursion level is reached. +/* An unmatched address extension is propagated when +/* \fIpropagate\fR is non-zero. +/* These functions return non-zero when the address was changed. +/* +/* cleanup_map11_external() looks up the external (quoted) string +/* form of an address in the maps specified via the \fImaps\fR argument. +/* +/* cleanup_map11_internal() is a wrapper around the +/* cleanup_map11_external() routine that transforms from +/* internal (quoted) string form to external form and back. +/* +/* cleanup_map11_tree() is a wrapper around the +/* cleanup_map11_external() routine that transforms from +/* internal parse tree form to external form and back. +/* DIAGNOSTICS +/* Recoverable errors: the global \fIcleanup_errs\fR flag is updated. +/* SEE ALSO +/* mail_addr_find(3) address lookups +/* mail_addr_map(3) address mappings +/* 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 +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <string.h> + +/* Utility library. */ + +#include <msg.h> +#include <vstring.h> +#include <dict.h> +#include <mymalloc.h> +#include <stringops.h> + +/* Global library. */ + +#include <cleanup_user.h> +#include <mail_addr_map.h> +#include <quote_822_local.h> + +/* Application-specific. */ + +#include "cleanup.h" + +#define STR vstring_str +#define MAX_RECURSION 10 + +/* cleanup_map11_external - one-to-one table lookups */ + +int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr, + MAPS *maps, int propagate) +{ + int count; + int expand_to_self; + ARGV *new_addr; + char *saved_addr; + int did_rewrite = 0; + + /* + * Produce sensible output even in the face of a recoverable error. This + * simplifies error recovery considerably because we can do delayed error + * checking in one place, instead of having error handling code all over + * the place. + */ + for (count = 0; count < MAX_RECURSION; count++) { + if ((new_addr = mail_addr_map_opt(maps, STR(addr), propagate, + MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, + MA_FORM_EXTERNAL)) != 0) { + if (new_addr->argc > 1) + msg_warn("%s: multi-valued %s entry for %s", + state->queue_id, maps->title, STR(addr)); + saved_addr = mystrdup(STR(addr)); + did_rewrite |= strcmp(new_addr->argv[0], STR(addr)); + vstring_strcpy(addr, new_addr->argv[0]); + expand_to_self = !strcasecmp_utf8(saved_addr, STR(addr)); + myfree(saved_addr); + argv_free(new_addr); + if (expand_to_self) + return (did_rewrite); + } else if (maps->error != 0) { + msg_warn("%s: %s map lookup problem for %s -- " + "message not accepted, try again later", + state->queue_id, maps->title, STR(addr)); + state->errs |= CLEANUP_STAT_WRITE; + return (did_rewrite); + } else { + return (did_rewrite); + } + } + msg_warn("%s: unreasonable %s map nesting for %s -- " + "message not accepted, try again later", + state->queue_id, maps->title, STR(addr)); + return (did_rewrite); +} + +/* cleanup_map11_tree - rewrite address node */ + +int cleanup_map11_tree(CLEANUP_STATE *state, TOK822 *tree, + MAPS *maps, int propagate) +{ + VSTRING *temp = vstring_alloc(100); + int did_rewrite; + + /* + * Produce sensible output even in the face of a recoverable error. This + * simplifies error recovery considerably because we can do delayed error + * checking in one place, instead of having error handling code all over + * the place. + */ + tok822_externalize(temp, tree->head, TOK822_STR_DEFL); + did_rewrite = cleanup_map11_external(state, temp, maps, propagate); + tok822_free_tree(tree->head); + tree->head = tok822_scan(STR(temp), &tree->tail); + vstring_free(temp); + return (did_rewrite); +} + +/* cleanup_map11_internal - rewrite address internal form */ + +int cleanup_map11_internal(CLEANUP_STATE *state, VSTRING *addr, + MAPS *maps, int propagate) +{ + VSTRING *temp = vstring_alloc(100); + int did_rewrite; + + /* + * Produce sensible output even in the face of a recoverable error. This + * simplifies error recovery considerably because we can do delayed error + * checking in one place, instead of having error handling code all over + * the place. + */ + quote_822_local(temp, STR(addr)); + did_rewrite = cleanup_map11_external(state, temp, maps, propagate); + unquote_822_local(addr, STR(temp)); + vstring_free(temp); + return (did_rewrite); +} |