Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / mail_addr_map.c
blobc00e43d3d3084a7f097d6cf9bd3ff30e2efb9442
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* mail_addr_map 3
6 /* SUMMARY
7 /* generic address mapping
8 /* SYNOPSIS
9 /* #include <mail_addr_map.h>
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.
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
27 /* \fIotherdomain\fR.
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.
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 /*--*/
53 /* System library. */
55 #include <sys_defs.h>
56 #include <string.h>
58 /* Utility library. */
60 #include <msg.h>
61 #include <vstring.h>
62 #include <dict.h>
63 #include <argv.h>
64 #include <mymalloc.h>
66 /* Global 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)
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;
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.
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);
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);
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;
130 * No match found.
132 else {
133 if (msg_verbose)
134 msg_info("%s: %s -> %s", myname, address,
135 dict_errno ? "(try again)" : "(not found)");
139 * Cleanup.
141 if (extension)
142 myfree(extension);
144 return (argv);
147 #ifdef TEST
150 * Proof-of-concept test program. Read an address from stdin, and spit out
151 * the lookup result.
153 #include <unistd.h>
154 #include <mail_conf.h>
155 #include <vstream.h>
156 #include <vstring_vstream.h>
157 #include <mail_params.h>
159 int main(int argc, char **argv)
161 VSTRING *buffer = vstring_alloc(100);
162 MAPS *path;
163 ARGV *result;
166 * Parse JCL.
168 if (argc != 2)
169 msg_fatal("usage: %s database", argv[0]);
172 * Initialize.
174 #define UPDATE(dst, src) { myfree(dst); dst = mystrdup(src); }
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);
194 vstring_free(buffer);
195 maps_free(path);
196 return (0);
199 #endif