1 /* $NetBSD: cleanup_map11.c,v 1.1.1.1 2009/06/23 10:08:43 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* cleanup_map11 3 6 /* SUMMARY 7 /* one-to-one mapping 8 /* SYNOPSIS 9 /* #include <cleanup.h> 10 /* 11 /* int cleanup_map11_external(state, addr, maps, propagate) 12 /* CLEANUP_STATE *state; 13 /* VSTRING *addr; 14 /* MAPS *maps; 15 /* int propagate; 16 /* 17 /* int cleanup_map11_internal(state, addr, maps, propagate) 18 /* CLEANUP_STATE *state; 19 /* VSTRING *addr; 20 /* MAPS *maps; 21 /* int propagate; 22 /* 23 /* int cleanup_map11_tree(state, tree, maps, propagate) 24 /* CLEANUP_STATE *state; 25 /* TOK822 *tree; 26 /* MAPS *maps; 27 /* int propagate; 28 /* DESCRIPTION 29 /* This module performs one-to-one map lookups. 30 /* 31 /* If an address has a mapping, the lookup result is 32 /* subjected to another iteration of rewriting and mapping. 33 /* Recursion continues until an address maps onto itself, 34 /* or until an unreasonable recursion level is reached. 35 /* An unmatched address extension is propagated when 36 /* \fIpropagate\fR is non-zero. 37 /* These functions return non-zero when the address was changed. 38 /* 39 /* cleanup_map11_external() looks up the external (quoted) string 40 /* form of an address in the maps specified via the \fImaps\fR argument. 41 /* 42 /* cleanup_map11_internal() is a wrapper around the 43 /* cleanup_map11_external() routine that transforms from 44 /* internal (quoted) string form to external form and back. 45 /* 46 /* cleanup_map11_tree() is a wrapper around the 47 /* cleanup_map11_external() routine that transforms from 48 /* internal parse tree form to external form and back. 49 /* DIAGNOSTICS 50 /* Recoverable errors: the global \fIcleanup_errs\fR flag is updated. 51 /* SEE ALSO 52 /* mail_addr_find(3) address lookups 53 /* mail_addr_map(3) address mappings 54 /* LICENSE 55 /* .ad 56 /* .fi 57 /* The Secure Mailer license must be distributed with this software. 58 /* AUTHOR(S) 59 /* Wietse Venema 60 /* IBM T.J. Watson Research 61 /* P.O. Box 704 62 /* Yorktown Heights, NY 10598, USA 63 /*--*/ 64 65 /* System library. */ 66 67 #include <sys_defs.h> 68 #include <string.h> 69 70 #ifdef STRCASECMP_IN_STRINGS_H 71 #include <strings.h> 72 #endif 73 74 /* Utility library. */ 75 76 #include <msg.h> 77 #include <vstring.h> 78 #include <dict.h> 79 #include <mymalloc.h> 80 81 /* Global library. */ 82 83 #include <cleanup_user.h> 84 #include <mail_addr_map.h> 85 #include <quote_822_local.h> 86 87 /* Application-specific. */ 88 89 #include "cleanup.h" 90 91 #define STR vstring_str 92 #define MAX_RECURSION 10 93 94 /* cleanup_map11_external - one-to-one table lookups */ 95 96 int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr, 97 MAPS *maps, int propagate) 98 { 99 int count; 100 int expand_to_self; 101 ARGV *new_addr; 102 char *saved_addr; 103 int did_rewrite = 0; 104 105 /* 106 * Produce sensible output even in the face of a recoverable error. This 107 * simplifies error recovery considerably because we can do delayed error 108 * checking in one place, instead of having error handling code all over 109 * the place. 110 */ 111 for (count = 0; count < MAX_RECURSION; count++) { 112 if ((new_addr = mail_addr_map(maps, STR(addr), propagate)) != 0) { 113 if (new_addr->argc > 1) 114 msg_warn("%s: multi-valued %s entry for %s", 115 state->queue_id, maps->title, STR(addr)); 116 saved_addr = mystrdup(STR(addr)); 117 did_rewrite |= strcmp(new_addr->argv[0], STR(addr)); 118 vstring_strcpy(addr, new_addr->argv[0]); 119 expand_to_self = !strcasecmp(saved_addr, STR(addr)); 120 myfree(saved_addr); 121 argv_free(new_addr); 122 if (expand_to_self) 123 return (did_rewrite); 124 } else if (dict_errno != 0) { 125 msg_warn("%s: %s map lookup problem for %s", 126 state->queue_id, maps->title, STR(addr)); 127 state->errs |= CLEANUP_STAT_WRITE; 128 return (did_rewrite); 129 } else { 130 return (did_rewrite); 131 } 132 } 133 msg_warn("%s: unreasonable %s map nesting for %s", 134 state->queue_id, maps->title, STR(addr)); 135 return (did_rewrite); 136 } 137 138 /* cleanup_map11_tree - rewrite address node */ 139 140 int cleanup_map11_tree(CLEANUP_STATE *state, TOK822 *tree, 141 MAPS *maps, int propagate) 142 { 143 VSTRING *temp = vstring_alloc(100); 144 int did_rewrite; 145 146 /* 147 * Produce sensible output even in the face of a recoverable error. This 148 * simplifies error recovery considerably because we can do delayed error 149 * checking in one place, instead of having error handling code all over 150 * the place. 151 */ 152 tok822_externalize(temp, tree->head, TOK822_STR_DEFL); 153 did_rewrite = cleanup_map11_external(state, temp, maps, propagate); 154 tok822_free_tree(tree->head); 155 tree->head = tok822_scan(STR(temp), &tree->tail); 156 vstring_free(temp); 157 return (did_rewrite); 158 } 159 160 /* cleanup_map11_internal - rewrite address internal form */ 161 162 int cleanup_map11_internal(CLEANUP_STATE *state, VSTRING *addr, 163 MAPS *maps, int propagate) 164 { 165 VSTRING *temp = vstring_alloc(100); 166 int did_rewrite; 167 168 /* 169 * Produce sensible output even in the face of a recoverable error. This 170 * simplifies error recovery considerably because we can do delayed error 171 * checking in one place, instead of having error handling code all over 172 * the place. 173 */ 174 quote_822_local(temp, STR(addr)); 175 did_rewrite = cleanup_map11_external(state, temp, maps, propagate); 176 unquote_822_local(addr, STR(temp)); 177 vstring_free(temp); 178 return (did_rewrite); 179 } 180