<b>nation_recipient_limit</b> must be 1 (see SIN-
GLE-RECIPIENT DELIVERY above for details).
- This code also enforces loop detection
- (Postfix 2.5 and later). If a message
+ The <b>D</b> flag also enforces loop detection
+ (Postfix 2.5 and later): if a message
already contains a <b>Delivered-To:</b> header with
the same recipient address, then the message
is returned as undeliverable.
\fItransport\fB_destination_recipient_limit\fR must be 1
(see SINGLE-RECIPIENT DELIVERY above for details).
.sp
-This code also enforces loop detection (Postfix 2.5 and later).
-If a message already contains a \fBDelivered-To:\fR header
+The \fBD\fR flag also enforces loop detection (Postfix 2.5 and later):
+if a message already contains a \fBDelivered-To:\fR header
with the same recipient address, then the message is
returned as undeliverable.
.sp
/* \fItransport\fB_destination_recipient_limit\fR must be 1
/* (see SINGLE-RECIPIENT DELIVERY above for details).
/* .sp
-/* This code also enforces loop detection (Postfix 2.5 and later).
-/* If a message already contains a \fBDelivered-To:\fR header
+/* The \fBD\fR flag also enforces loop detection (Postfix 2.5 and later):
+/* if a message already contains a \fBDelivered-To:\fR header
/* with the same recipient address, then the message is
/* returned as undeliverable.
/* .sp
tp->transport_path = maps_create(transport_maps_name, transport_maps,
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
| DICT_FLAG_NO_REGSUB);
- tp->wildcard_channel = vstring_alloc(10);
- tp->wildcard_nexthop = vstring_alloc(10);
+ tp->wildcard_channel = tp->wildcard_nexthop = 0;
tp->transport_errno = 0;
tp->expire = 0;
return (tp);
static void transport_wildcard_init(TRANSPORT_INFO *tp)
{
+ VSTRING *channel = vstring_alloc(10);
+ VSTRING *nexthop = vstring_alloc(10);
+
+ /*
+ * Both channel and nexthop may be zero-length strings. Therefore we must
+ * use something else to represent "wild-card does not exist". We use
+ * null VSTRING pointers, for historical reasons.
+ */
+ if (tp->wildcard_channel)
+ vstring_free(tp->wildcard_channel);
+ if (tp->wildcard_nexthop)
+ vstring_free(tp->wildcard_nexthop);
/*
* Technically, the wildcard lookup pattern is redundant. A static map
#define FULL 0
#define PARTIAL DICT_FLAG_FIXED
- if (find_transport_entry(tp, WILDCARD, "", FULL,
- tp->wildcard_channel,
- tp->wildcard_nexthop)) {
+ if (find_transport_entry(tp, WILDCARD, "", FULL, channel, nexthop)) {
tp->transport_errno = 0;
+ tp->wildcard_channel = channel;
+ tp->wildcard_nexthop = nexthop;
if (msg_verbose)
msg_info("wildcard_{chan:hop}={%s:%s}",
- vstring_str(tp->wildcard_channel),
- vstring_str(tp->wildcard_nexthop));
+ vstring_str(channel), vstring_str(nexthop));
} else {
tp->transport_errno = dict_errno;
- VSTRING_RESET(tp->wildcard_channel);
- VSTRING_RESET(tp->wildcard_nexthop);
+ vstring_free(channel);
+ vstring_free(nexthop);
+ tp->wildcard_channel = 0;
+ tp->wildcard_nexthop = 0;
}
tp->expire = event_time() + 30; /* XXX make configurable */
}
if (tp->transport_errno) {
dict_errno = tp->transport_errno;
return (NOTFOUND);
- } else if (tp->wildcard_channel && VSTRING_LEN(tp->wildcard_channel)) {
+ } else if (tp->wildcard_channel) {
update_entry(STR(tp->wildcard_channel), STR(tp->wildcard_nexthop),
rcpt_domain, channel, nexthop);
return (FOUND);