1 /* $NetBSD: mail_addr_map.c,v 1.1.1.1 2009/06/23 10:08:46 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* mail_addr_map 3 6 /* SUMMARY 7 /* generic address mapping 8 /* SYNOPSIS 9 /* #include <mail_addr_map.h> 10 /* 11 /* ARGV *mail_addr_map(path, address, propagate) 12 /* MAPS *path; 13 /* const char *address; 14 /* int propagate; 15 /* DESCRIPTION 16 /* mail_addr_map() returns the translation for the named address, 17 /* or a null pointer if none is found. The result is in canonical 18 /* external (quoted) form. The search is case insensitive. 19 /* 20 /* When the \fBpropagate\fR argument is non-zero, 21 /* address extensions that aren't explicitly matched in the lookup 22 /* table are propagated to the result addresses. The caller is 23 /* expected to pass the result to argv_free(). 24 /* 25 /* Lookups are performed by mail_addr_find(). When the result has the 26 /* form \fI@otherdomain\fR, the result is the original user in 27 /* \fIotherdomain\fR. 28 /* 29 /* Arguments: 30 /* .IP path 31 /* Dictionary search path (see maps(3)). 32 /* .IP address 33 /* The address to be looked up. 34 /* DIAGNOSTICS 35 /* Warnings: map lookup returns a non-address result. 36 /* 37 /* The global \fIdict_errno\fR is non-zero when the lookup 38 /* should be tried again. 39 /* SEE ALSO 40 /* mail_addr_find(3), mail address matching 41 /* mail_addr_crunch(3), mail address parsing and rewriting 42 /* LICENSE 43 /* .ad 44 /* .fi 45 /* The Secure Mailer license must be distributed with this software. 46 /* AUTHOR(S) 47 /* Wietse Venema 48 /* IBM T.J. Watson Research 49 /* P.O. Box 704 50 /* Yorktown Heights, NY 10598, USA 51 /*--*/ 52 53 /* System library. */ 54 55 #include <sys_defs.h> 56 #include <string.h> 57 58 /* Utility library. */ 59 60 #include <msg.h> 61 #include <vstring.h> 62 #include <dict.h> 63 #include <argv.h> 64 #include <mymalloc.h> 65 66 /* Global library. */ 67 68 #include <mail_addr_find.h> 69 #include <mail_addr_crunch.h> 70 #include <mail_addr_map.h> 71 72 /* Application-specific. */ 73 74 #define STR vstring_str 75 #define LEN VSTRING_LEN 76 77 /* mail_addr_map - map a canonical address */ 78 79 ARGV *mail_addr_map(MAPS *path, const char *address, int propagate) 80 { 81 VSTRING *buffer = 0; 82 const char *myname = "mail_addr_map"; 83 const char *string; 84 char *ratsign; 85 char *extension = 0; 86 ARGV *argv = 0; 87 int i; 88 89 /* 90 * Look up the full address; if no match is found, look up the address 91 * with the extension stripped off, and remember the unmatched extension. 92 */ 93 if ((string = mail_addr_find(path, address, &extension)) != 0) { 94 95 /* 96 * Prepend the original user to @otherdomain, but do not propagate 97 * the unmatched address extension. 98 */ 99 if (*string == '@') { 100 buffer = vstring_alloc(100); 101 if ((ratsign = strrchr(address, '@')) != 0) 102 vstring_strncpy(buffer, address, ratsign - address); 103 else 104 vstring_strcpy(buffer, address); 105 if (extension) 106 vstring_truncate(buffer, LEN(buffer) - strlen(extension)); 107 vstring_strcat(buffer, string); 108 string = STR(buffer); 109 } 110 111 /* 112 * Canonicalize and externalize the result, and propagate the 113 * unmatched extension to each address found. 114 */ 115 argv = mail_addr_crunch(string, propagate ? extension : 0); 116 if (buffer) 117 vstring_free(buffer); 118 if (msg_verbose) 119 for (i = 0; i < argv->argc; i++) 120 msg_info("%s: %s -> %d: %s", myname, address, i, argv->argv[i]); 121 if (argv->argc == 0) { 122 msg_warn("%s lookup of %s returns non-address result \"%s\"", 123 path->title, address, string); 124 argv = argv_free(argv); 125 dict_errno = DICT_ERR_RETRY; 126 } 127 } 128 129 /* 130 * No match found. 131 */ 132 else { 133 if (msg_verbose) 134 msg_info("%s: %s -> %s", myname, address, 135 dict_errno ? "(try again)" : "(not found)"); 136 } 137 138 /* 139 * Cleanup. 140 */ 141 if (extension) 142 myfree(extension); 143 144 return (argv); 145 } 146 147 #ifdef TEST 148 149 /* 150 * Proof-of-concept test program. Read an address from stdin, and spit out 151 * the lookup result. 152 */ 153 #include <unistd.h> 154 #include <mail_conf.h> 155 #include <vstream.h> 156 #include <vstring_vstream.h> 157 #include <mail_params.h> 158 159 int main(int argc, char **argv) 160 { 161 VSTRING *buffer = vstring_alloc(100); 162 MAPS *path; 163 ARGV *result; 164 165 /* 166 * Parse JCL. 167 */ 168 if (argc != 2) 169 msg_fatal("usage: %s database", argv[0]); 170 171 /* 172 * Initialize. 173 */ 174 #define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); } 175 176 mail_conf_read(); 177 msg_verbose = 1; 178 if (chdir(var_queue_dir) < 0) 179 msg_fatal("chdir %s: %m", var_queue_dir); 180 path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); 181 while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { 182 msg_info("=== Address extension on, extension propagation on ==="); 183 UPDATE(var_rcpt_delim, "+"); 184 if ((result = mail_addr_map(path, STR(buffer), 1)) != 0) 185 argv_free(result); 186 msg_info("=== Address extension on, extension propagation off ==="); 187 if ((result = mail_addr_map(path, STR(buffer), 0)) != 0) 188 argv_free(result); 189 msg_info("=== Address extension off ==="); 190 UPDATE(var_rcpt_delim, ""); 191 if ((result = mail_addr_map(path, STR(buffer), 1)) != 0) 192 argv_free(result); 193 } 194 vstring_free(buffer); 195 maps_free(path); 196 return (0); 197 } 198 199 #endif 200