Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / cleanup / cleanup_map1n.c
blob5fb0059fcb9a534b4b82bfa1bfe839c61a6fe1de
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* cleanup_map1n 3
6 /* SUMMARY
7 /* one-to-many address mapping
8 /* SYNOPSIS
9 /* #include <cleanup.h>
11 /* ARGV *cleanup_map1n_internal(state, addr, maps, propagate)
12 /* CLEANUP_STATE *state;
13 /* const char *addr;
14 /* MAPS *maps;
15 /* int propagate;
16 /* DESCRIPTION
17 /* This module implements one-to-many table mapping via table lookup.
18 /* Table lookups are done with quoted (externalized) address forms.
19 /* The process is recursive. The recursion terminates when the
20 /* left-hand side appears in its own expansion, or when a maximal
21 /* nesting level is reached.
23 /* cleanup_map1n_internal() is the interface for addresses in
24 /* internal (unquoted) form.
25 /* DIAGNOSTICS
26 /* Recoverable errors: the global \fIcleanup_errs\fR flag is updated.
27 /* SEE ALSO
28 /* mail_addr_map(3) address mappings
29 /* mail_addr_find(3) address lookups
30 /* LICENSE
31 /* .ad
32 /* .fi
33 /* The Secure Mailer license must be distributed with this software.
34 /* AUTHOR(S)
35 /* Wietse Venema
36 /* IBM T.J. Watson Research
37 /* P.O. Box 704
38 /* Yorktown Heights, NY 10598, USA
39 /*--*/
41 /* System library. */
43 #include <sys_defs.h>
44 #include <string.h>
46 #ifdef STRCASECMP_IN_STRINGS_H
47 #include <strings.h>
48 #endif
50 /* Utility library. */
52 #include <mymalloc.h>
53 #include <msg.h>
54 #include <argv.h>
55 #include <vstring.h>
56 #include <dict.h>
58 /* Global library. */
60 #include <mail_params.h>
61 #include <mail_addr_map.h>
62 #include <cleanup_user.h>
63 #include <quote_822_local.h>
64 #include <been_here.h>
66 /* Application-specific. */
68 #include "cleanup.h"
70 /* cleanup_map1n_internal - one-to-many table lookups */
72 ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
73 MAPS *maps, int propagate)
75 ARGV *argv;
76 ARGV *lookup;
77 int count;
78 int i;
79 int arg;
80 BH_TABLE *been_here;
81 char *saved_lhs;
84 * Initialize.
86 argv = argv_alloc(1);
87 argv_add(argv, addr, ARGV_END);
88 argv_terminate(argv);
89 been_here = been_here_init(0, BH_FLAG_FOLD);
92 * Rewrite the address vector in place. With each map lookup result,
93 * split it into separate addresses, then rewrite and flatten each
94 * address, and repeat the process. Beware: argv is being changed, so we
95 * must index the array explicitly, instead of running along it with a
96 * pointer.
98 #define UPDATE(ptr,new) { myfree(ptr); ptr = mystrdup(new); }
99 #define STR vstring_str
100 #define RETURN(x) { been_here_free(been_here); return (x); }
102 for (arg = 0; arg < argv->argc; arg++) {
103 if (argv->argc > var_virt_expan_limit) {
104 msg_warn("%s: unreasonable %s map expansion size for %s",
105 state->queue_id, maps->title, addr);
106 break;
108 for (count = 0; /* void */ ; count++) {
111 * Don't expand an address that already expanded into itself.
113 if (been_here_check_fixed(been_here, argv->argv[arg]) != 0)
114 break;
115 if (count >= var_virt_recur_limit) {
116 msg_warn("%s: unreasonable %s map nesting for %s",
117 state->queue_id, maps->title, addr);
118 break;
120 quote_822_local(state->temp1, argv->argv[arg]);
121 if ((lookup = mail_addr_map(maps, STR(state->temp1), propagate)) != 0) {
122 saved_lhs = mystrdup(argv->argv[arg]);
123 for (i = 0; i < lookup->argc; i++) {
124 unquote_822_local(state->temp1, lookup->argv[i]);
125 if (i == 0) {
126 UPDATE(argv->argv[arg], STR(state->temp1));
127 } else {
128 argv_add(argv, STR(state->temp1), ARGV_END);
129 argv_terminate(argv);
133 * Allow an address to expand into itself once.
135 if (strcasecmp(saved_lhs, STR(state->temp1)) == 0)
136 been_here_fixed(been_here, saved_lhs);
138 myfree(saved_lhs);
139 argv_free(lookup);
140 } else if (dict_errno != 0) {
141 msg_warn("%s: %s map lookup problem for %s",
142 state->queue_id, maps->title, addr);
143 state->errs |= CLEANUP_STAT_WRITE;
144 RETURN(argv);
145 } else {
146 break;
150 RETURN(argv);