7 /* generic address mapping
9 /* #include <mail_addr_map.h>
11 /* ARGV *mail_addr_map(path, address, propagate)
13 /* const char *address;
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.
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().
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
31 /* Dictionary search path (see maps(3)).
33 /* The address to be looked up.
35 /* Warnings: map lookup returns a non-address result.
37 /* The global \fIdict_errno\fR is non-zero when the lookup
38 /* should be tried again.
40 /* mail_addr_find(3), mail address matching
41 /* mail_addr_crunch(3), mail address parsing and rewriting
45 /* The Secure Mailer license must be distributed with this software.
48 /* IBM T.J. Watson Research
50 /* Yorktown Heights, NY 10598, USA
58 /* Utility library. */
68 #include <mail_addr_find.h>
69 #include <mail_addr_crunch.h>
70 #include <mail_addr_map.h>
72 /* Application-specific. */
74 #define STR vstring_str
75 #define LEN VSTRING_LEN
77 /* mail_addr_map - map a canonical address */
79 ARGV
*mail_addr_map(MAPS
*path
, const char *address
, int propagate
)
82 const char *myname
= "mail_addr_map";
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.
93 if ((string
= mail_addr_find(path
, address
, &extension
)) != 0) {
96 * Prepend the original user to @otherdomain, but do not propagate
97 * the unmatched address extension.
100 buffer
= vstring_alloc(100);
101 if ((ratsign
= strrchr(address
, '@')) != 0)
102 vstring_strncpy(buffer
, address
, ratsign
- address
);
104 vstring_strcpy(buffer
, address
);
106 vstring_truncate(buffer
, LEN(buffer
) - strlen(extension
));
107 vstring_strcat(buffer
, string
);
108 string
= STR(buffer
);
112 * Canonicalize and externalize the result, and propagate the
113 * unmatched extension to each address found.
115 argv
= mail_addr_crunch(string
, propagate
? extension
: 0);
117 vstring_free(buffer
);
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
;
134 msg_info("%s: %s -> %s", myname
, address
,
135 dict_errno
? "(try again)" : "(not found)");
150 * Proof-of-concept test program. Read an address from stdin, and spit out
154 #include <mail_conf.h>
156 #include <vstring_vstream.h>
157 #include <mail_params.h>
159 int main(int argc
, char **argv
)
161 VSTRING
*buffer
= vstring_alloc(100);
169 msg_fatal("usage: %s database", argv
[0]);
174 #define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); }
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)
186 msg_info("=== Address extension on, extension propagation off ===");
187 if ((result
= mail_addr_map(path
, STR(buffer
), 0)) != 0)
189 msg_info("=== Address extension off ===");
190 UPDATE(var_rcpt_delim
, "");
191 if ((result
= mail_addr_map(path
, STR(buffer
), 1)) != 0)
194 vstring_free(buffer
);