7 /* one-to-many address mapping
9 /* #include <cleanup.h>
11 /* ARGV *cleanup_map1n_internal(state, addr, maps, propagate)
12 /* CLEANUP_STATE *state;
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.
26 /* Recoverable errors: the global \fIcleanup_errs\fR flag is updated.
28 /* mail_addr_map(3) address mappings
29 /* mail_addr_find(3) address lookups
33 /* The Secure Mailer license must be distributed with this software.
36 /* IBM T.J. Watson Research
38 /* Yorktown Heights, NY 10598, USA
46 #ifdef STRCASECMP_IN_STRINGS_H
50 /* Utility 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. */
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
)
87 argv_add(argv
, addr
, ARGV_END
);
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
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
);
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)
115 if (count
>= var_virt_recur_limit
) {
116 msg_warn("%s: unreasonable %s map nesting for %s",
117 state
->queue_id
, maps
->title
, addr
);
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
]);
126 UPDATE(argv
->argv
[arg
], STR(state
->temp1
));
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
);
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
;