{
if (addr->transport)
tree_add_nonrecipient(
- string_sprintf("%s/%s", addr->unique + 3, addr->transport->name));
+ string_sprintf("%s/%s", addr->unique + 3, addr->transport->drinst.name));
}
/* Non-homonymous child address */
const uschar * save_host = deliver_host;
const uschar * save_address = deliver_host_address;
const uschar * save_rn = router_name;
-uschar * save_tn = transport_name;
+const uschar * save_tn = transport_name;
const int save_port = deliver_host_port;
router_name = addr->router ? addr->router->drinst.name : NULL;
}
else
{
- transport_name = addr->transport->name;
+ const uschar * dr_name = addr->transport->drinst.driver_name;
+ transport_name = addr->transport->drinst.name;
(void) event_raise(addr->transport->event_action, event,
addr->host_used
- || Ustrcmp(addr->transport->driver_name, "smtp") == 0
- || Ustrcmp(addr->transport->driver_name, "lmtp") == 0
- || Ustrcmp(addr->transport->driver_name, "autoreply") == 0
+ || Ustrcmp(dr_name, "smtp") == 0
+ || Ustrcmp(dr_name, "lmtp") == 0
+ || Ustrcmp(dr_name, "autoreply") == 0
? addr->message : NULL,
NULL);
}
if ( testflag(addr, af_pfr)
|| ( success
&& addr->router && addr->router->log_as_local
- && addr->transport && addr->transport->info->local
+ && addr->transport
+ && ((transport_info *)addr->transport->drinst.info)->local
) )
{
if (testflag(addr, af_file) && addr->local_part[0] != '/')
if (addr->router)
g = string_append(g, 2, US" R=", addr->router->drinst.name);
-g = string_append(g, 2, US" T=", addr->transport->name);
+g = string_append(g, 2, US" T=", addr->transport->drinst.name);
if (LOGGING(delivery_size))
g = string_fmt_append(g, " S=%d", transport_count);
/* Local delivery */
-if (addr->transport->info->local)
+if (((transport_info *)addr->transport->drinst.info)->local)
{
if (addr->host_list)
g = string_append(g, 2, US" H=", addr->host_list->name);
if ( LOGGING(smtp_confirmation)
&& addr->message
- && (addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0)
+ && ( addr->host_used
+ || Ustrcmp(addr->transport->drinst.driver_name, "lmtp") == 0)
)
{
unsigned lim = big_buffer_size < 1024 ? big_buffer_size : 1024;
if (addr->router)
g = string_append(g, 2, US" R=", addr->router->drinst.name);
if (addr->transport)
- g = string_append(g, 2, US" T=", addr->transport->name);
+ g = string_append(g, 2, US" T=", addr->transport->drinst.name);
if (addr->host_used)
g = d_hostlog(g, addr);
{
if (addr->transport)
{
- driver_name = addr->transport->name;
+ driver_name = addr->transport->drinst.name;
driver_kind = US" transport";
f.disable_logging = addr->transport->disable_logging;
}
if (fstat(addr->return_file, &statbuf) == 0 && statbuf.st_size > 0)
{
- transport_instance *tb = addr->transport;
+ transport_instance * tb = addr->transport;
/* Handle logging options */
|| result == DEFER && tb->log_defer_output
)
{
- uschar *s;
- FILE *f = Ufopen(addr->return_filename, "rb");
+ uschar * s;
+ FILE * f = Ufopen(addr->return_filename, "rb");
if (!f)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to open %s to log output "
- "from %s transport: %s", addr->return_filename, tb->name,
+ "from %s transport: %s", addr->return_filename, tb->drinst.name,
strerror(errno));
else
if ((s = US Ufgets(big_buffer, big_buffer_size, f)))
*p = 0;
sp = string_printing(big_buffer);
log_write(0, LOG_MAIN, "<%s>: %s transport output: %s",
- addr->address, tb->name, sp);
+ addr->address, tb->drinst.name, sp);
}
(void)fclose(f);
}
else if (tp->expand_gid)
{
GET_OPTION("group");
- if (!route_find_expanded_group(tp->expand_gid, tp->name, US"transport", gidp,
- &addr->message))
+ if (!route_find_expanded_group(tp->expand_gid, tp->drinst.name, US"transport",
+ gidp, &addr->message))
{
common_error(FALSE, addr, ERRNO_GIDFAIL, NULL);
return FALSE;
{
struct passwd *pw;
GET_OPTION("user");
- if (!route_find_expanded_user(tp->expand_uid, tp->name, US"transport", &pw,
- uidp, &(addr->message)))
+ if (!route_find_expanded_user(tp->expand_uid, tp->drinst.name, US"transport",
+ &pw, uidp, &(addr->message)))
{
common_error(FALSE, addr, ERRNO_UIDFAIL, NULL);
return FALSE;
if (!gid_set)
{
common_error(TRUE, addr, ERRNO_GIDFAIL, US"User set without group for "
- "%s transport", tp->name);
+ "%s transport", tp->drinst.name);
return FALSE;
}
if (nuname)
{
common_error(TRUE, addr, ERRNO_UIDFAIL, US"User %ld set for %s transport "
- "is on the %s list", (long int)(*uidp), tp->name, nuname);
+ "is on the %s list", (long int)(*uidp), tp->drinst.name, nuname);
return FALSE;
}
rc = DEFER;
addr->message = size_limit == -1
? string_sprintf("failed to expand message_size_limit "
- "in %s transport: %s", tp->name, expand_string_message)
+ "in %s transport: %s", tp->drinst.name, expand_string_message)
: string_sprintf("invalid message_size_limit "
- "in %s transport: %s", tp->name, expand_string_message);
+ "in %s transport: %s", tp->drinst.name, expand_string_message);
}
else if (size_limit > 0 && message_size > size_limit)
{
previously_transported(address_item *addr, BOOL testing)
{
uschar * s = string_sprintf("%s/%s",
- addr->unique + (testflag(addr, af_homonym) ? 3:0), addr->transport->name);
+ addr->unique + (testflag(addr, af_homonym) ? 3:0),
+ addr->transport->drinst.name);
if (tree_search(tree_nonrecipients, s) != 0)
{
DEBUG(D_deliver|D_route|D_transport)
debug_printf("%s was previously delivered (%s transport): discarded\n",
- addr->address, addr->transport->name);
+ addr->address, addr->transport->drinst.name);
if (!testing) child_done(addr, tod_stamp(tod_log));
return TRUE;
}
pid_t pid;
uschar *working_directory;
address_item *addr2;
-transport_instance *tp = addr->transport;
+transport_instance * tp = addr->transport;
+const uschar * trname = tp->drinst.name;
/* Set up the return path from the errors or sender address. If the transport
has its own return path setting, expand it and replace the existing value. */
{
common_error(TRUE, addr, ERRNO_EXPANDFAIL,
US"Failed to expand return path \"%s\" in %s transport: %s",
- tp->return_path, tp->name, expand_string_message);
+ tp->return_path, trname, expand_string_message);
return;
}
}
if (!(deliver_home = expand_string(rawhome)))
{
common_error(TRUE, addr, ERRNO_EXPANDFAIL, US"home directory \"%s\" failed "
- "to expand for %s transport: %s", rawhome, tp->name,
+ "to expand for %s transport: %s", rawhome, trname,
expand_string_message);
return;
}
if (*deliver_home != '/')
{
common_error(TRUE, addr, ERRNO_NOTABSOLUTE, US"home directory path \"%s\" "
- "is not absolute for %s transport", deliver_home, tp->name);
+ "is not absolute for %s transport", deliver_home, trname);
return;
}
}
if (!(working_directory = expand_string(raw)))
{
common_error(TRUE, addr, ERRNO_EXPANDFAIL, US"current directory \"%s\" "
- "failed to expand for %s transport: %s", raw, tp->name,
+ "failed to expand for %s transport: %s", raw, trname,
expand_string_message);
return;
}
if (*working_directory != '/')
{
common_error(TRUE, addr, ERRNO_NOTABSOLUTE, US"current directory path "
- "\"%s\" is not absolute for %s transport", working_directory, tp->name);
+ "\"%s\" is not absolute for %s transport", working_directory, trname);
return;
}
}
if ((addr->return_file = open_msglog_file(addr->return_filename, 0400, &error)) < 0)
{
common_error(TRUE, addr, errno, US"Unable to %s file for %s transport "
- "to return message: %s", error, tp->name, strerror(errno));
+ "to return message: %s", error, trname, strerror(errno));
return;
}
}
FD_CLOEXEC);
exim_setugid(uid, gid, use_initgroups,
string_sprintf("local delivery to %s <%s> transport=%s", addr->local_part,
- addr->address, addr->transport->name));
+ addr->address, addr->transport->drinst.name));
DEBUG(D_deliver)
{
{
BOOL ok = TRUE;
set_process_info("delivering %s to %s using %s", message_id,
- addr->local_part, tp->name);
+ addr->local_part, trname);
/* Setting these globals in the subprocess means we need never clear them */
- transport_name = tp->name;
+ transport_name = trname;
if (addr->router) router_name = addr->router->drinst.name;
- driver_srcfile = tp->srcfile;
- driver_srcline = tp->srcline;
+ driver_srcfile = tp->drinst.srcfile;
+ driver_srcline = tp->drinst.srcline;
/* If a transport filter has been specified, set up its argument list.
Any errors will get put into the address, and FALSE yielded. */
if (ok)
{
+ transport_info * ti = tp->drinst.info;
debug_print_string(tp->debug_string);
- replicate = !(tp->info->code)(addr->transport, addr);
+ replicate = !(ti->code)(addr->transport, addr);
}
}
if (addr2->transport_return == OK)
{
if (testflag(addr2, af_homonym))
- sprintf(CS big_buffer, "%.500s/%s\n", addr2->unique + 3, tp->name);
+ sprintf(CS big_buffer, "%.500s/%s\n", addr2->unique + 3, trname);
else
sprintf(CS big_buffer, "%.500s\n", addr2->unique);
if (rc < 0 && errno == ECHILD) /* Process has vanished */
{
log_write(0, LOG_MAIN, "%s transport process vanished unexpectedly",
- addr->transport->driver_name);
+ addr->transport->drinst.driver_name);
status = 0;
break;
}
addr->special_action = SPECIAL_FREEZE;
log_write(0, LOG_MAIN|LOG_PANIC, "%s transport process returned non-zero "
"status 0x%04x: %s %d",
- addr->transport->driver_name,
+ addr->transport->drinst.driver_name,
status,
msb == 0 ? "terminated by signal" : "exit code",
code);
if (!(warn_message = expand_string(warn_message)))
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand \"%s\" (warning "
"message for %s transport): %s", addr->transport->warn_message,
- addr->transport->name, expand_string_message);
+ addr->transport->drinst.name, expand_string_message);
else if ((pid = child_open_exim(&fd, US"tpt-warning-message")) > 0)
{
static BOOL
tpt_parallel_check(transport_instance * tp, address_item * addr, uschar ** key)
{
+const uschar * trname = tp->drinst.name;
unsigned max_parallel;
GET_OPTION("max_parallel");
if (expand_string_message)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand max_parallel option "
- "in %s transport (%s): %s", tp->name, addr->address,
+ "in %s transport (%s): %s", trname, addr->address,
expand_string_message);
return TRUE;
}
if (max_parallel > 0)
{
- uschar * serialize_key = string_sprintf("tpt-serialize-%s", tp->name);
+ uschar * serialize_key = string_sprintf("tpt-serialize-%s", trname);
if (!enq_start(serialize_key, max_parallel))
{
address_item * next;
DEBUG(D_transport)
debug_printf("skipping tpt %s because concurrency limit %u reached\n",
- tp->name, max_parallel);
+ trname, max_parallel);
do
{
next = addr->next;
address_item *addr2, *addr3, *nextaddr;
int logflags = LOG_MAIN;
int logchar = f.dont_deliver? '*' : '=';
- transport_instance *tp;
+ transport_instance * tp;
uschar * serialize_key = NULL;
+ const uschar * trname;
/* Pick the first undelivered address off the chain */
post_process_one(addr, DEFER, logflags, EXIM_DTYPE_TRANSPORT, 0);
continue;
}
+ trname = tp->drinst.name;
/* Check that this base address hasn't previously been delivered to this
transport. The check is necessary at this point to handle homonymic addresses
if (!batch_id)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand batch_id option "
- "in %s transport (%s): %s", tp->name, addr->address,
+ "in %s transport (%s): %s", trname, addr->address,
expand_string_message);
batch_count = tp->batch_max;
}
if (!bid)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand batch_id option "
- "in %s transport (%s): %s", tp->name, next->address,
+ "in %s transport (%s): %s", trname, next->address,
expand_string_message);
ok = FALSE;
}
if ( tp->shadow
&& ( !tp->shadow_condition
- || expand_check_condition(tp->shadow_condition, tp->name, US"transport")
+ || expand_check_condition(tp->shadow_condition, trname, US"transport")
) )
{
- transport_instance *stp;
- address_item *shadow_addr = NULL;
- address_item **last = &shadow_addr;
+ transport_instance * stp;
+ address_item * shadow_addr = NULL;
+ address_item ** last = &shadow_addr;
- for (stp = transports; stp; stp = stp->next)
- if (Ustrcmp(stp->name, tp->shadow) == 0) break;
+ for (stp = transports; stp; stp = stp->drinst.next)
+ if (Ustrcmp(stp->drinst.name, tp->shadow) == 0) break;
if (!stp)
log_write(0, LOG_MAIN|LOG_PANIC, "shadow transport \"%s\" not found ",
if (shadow_addr)
{
+ const uschar * s_trname = stp->drinst.name;
int save_count = transport_count;
DEBUG(D_deliver|D_transport)
int sresult = shadow_addr->transport_return;
*(uschar **)shadow_addr->shadow_message =
sresult == OK
- ? string_sprintf(" ST=%s", stp->name)
- : string_sprintf(" ST=%s (%s%s%s)", stp->name,
+ ? string_sprintf(" ST=%s", s_trname)
+ : string_sprintf(" ST=%s (%s%s%s)", s_trname,
shadow_addr->basic_errno <= 0
? US""
: US strerror(shadow_addr->basic_errno),
DEBUG(D_deliver|D_transport)
debug_printf("%s shadow transport returned %s for %s\n",
- stp->name, rc_to_string(sresult), shadow_addr->address);
+ s_trname, rc_to_string(sresult), shadow_addr->address);
}
DEBUG(D_deliver|D_transport)
DEBUG(D_deliver|D_transport)
debug_printf("%s transport returned %s for %s\n",
- tp->name, rc_to_string(result), addr2->address);
+ trname, rc_to_string(result), addr2->address);
/* If there is a retry_record, or if delivery is deferred, build a retry
item for setting a new retry time or deleting the old retry record from
{
msg = string_sprintf("got " SSIZE_T_FMT " of %d bytes (pipeheader) "
"from transport process %ld for transport %s",
- got, PIPE_HEADER_SIZE, (long)pid, addr->transport->driver_name);
+ got, PIPE_HEADER_SIZE, (long)pid, addr->transport->drinst.driver_name);
done = TRUE;
break;
}
{
msg = string_sprintf("failed to read pipe "
"from transport process %ld for transport %s: error decoding size from header",
- (long)pid, addr ? addr->transport->driver_name : US"?");
+ (long)pid, addr ? addr->transport->drinst.driver_name : US"?");
done = TRUE;
break;
}
{
msg = string_sprintf("got only " SSIZE_T_FMT " of " SIZE_T_FMT
" bytes (pipedata) from transport process %ld for transport %s",
- got, required, (long)pid, addr->transport->driver_name);
+ got, required, (long)pid, addr->transport->drinst.driver_name);
done = TRUE;
break;
}
ADDR_MISMATCH:
msg = string_sprintf("address count mismatch for data read from pipe "
"for transport process %ld for transport %s",
- (long)pid, addrlist->transport->driver_name);
+ (long)pid, addrlist->transport->drinst.driver_name);
done = TRUE;
break;
}
default:
msg = string_sprintf("malformed data (%d) read from pipe for transport "
"process %ld for transport %s", ptr[-1], (long)pid,
- addr ? addr->transport->driver_name : US"?");
+ addr ? addr->transport->drinst.driver_name : US"?");
done = TRUE;
break;
}
if (!msg && addr)
msg = string_sprintf("insufficient address data read from pipe "
"for transport process %ld for transport %s", (long)pid,
- addr->transport->driver_name);
+ addr->transport->drinst.driver_name);
/* If an error message is set, something has gone wrong in getting back
the delivery data. Put the message into each address and freeze it. */
msg = string_sprintf("%s transport process returned non-zero status 0x%04x: "
"%s %d",
- addrlist->transport->driver_name,
+ addrlist->transport->drinst.driver_name,
status,
msb == 0 ? "terminated by signal" : "exit code",
code);
{
transport_instance * tp = doneaddr->transport;
if (tp->max_parallel)
- enq_end(string_sprintf("tpt-serialize-%s", tp->name));
+ enq_end(string_sprintf("tpt-serialize-%s", tp->drinst.name));
remote_post_process(doneaddr, LOG_MAIN, NULL, fallback);
}
if (tp->expand_multi_domain)
deliver_set_expansions(addr);
- if (exp_bool(addr, US"transport", tp->name, D_transport,
+ if (exp_bool(addr, US"transport", tp->drinst.name, D_transport,
US"multi_domain", tp->multi_domain, tp->expand_multi_domain,
&multi_domain) != OK)
{
|| ( (
(void)(!tp->expand_multi_domain || ((void)deliver_set_expansions(next), 1)),
exp_bool(addr,
- US"transport", next->transport->name, D_transport,
+ US"transport", next->transport->drinst.name, D_transport,
US"multi_domain", next->transport->multi_domain,
next->transport->expand_multi_domain, &md) == OK
)
f.continue_more = FALSE; /* In case got set for the last lot */
if (continue_transport)
{
- BOOL ok = Ustrcmp(continue_transport, tp->name) == 0;
+ BOOL ok = Ustrcmp(continue_transport, tp->drinst.name) == 0;
/*XXX do we need to check for a DANEd conn vs. a change of domain? */
/* If the transport is about to override the host list do not check
if (ok)
{
- smtp_transport_options_block * ob;
+ transport_info * ti = tp->drinst.info;
+ smtp_transport_options_block * ob = tp->drinst.options_block;
- if ( !( Ustrcmp(tp->info->driver_name, "smtp") == 0
- && (ob = (smtp_transport_options_block *)tp->options_block)
- && ob->hosts_override && ob->hosts
+ if ( !( Ustrcmp(ti->drinfo.driver_name, "smtp") == 0
+ && ob && ob->hosts_override && ob->hosts
)
&& addr->host_list
)
if (!ok)
{
DEBUG(D_deliver) debug_printf("not suitable for continue_transport (%s)\n",
- Ustrcmp(continue_transport, tp->name) != 0
- ? string_sprintf("tpt %s vs %s", continue_transport, tp->name)
+ Ustrcmp(continue_transport, tp->drinst.name) != 0
+ ? string_sprintf("tpt %s vs %s", continue_transport, tp->drinst.name)
: string_sprintf("no host matching %s", continue_hostname));
if (serialize_key) enq_end(serialize_key);
for (next = addr; ; next = next->next)
{
next->host_list = next->fallback_hosts;
- DEBUG(D_deliver) debug_printf("%s queued for fallback host(s)\n", next->address);
+ DEBUG(D_deliver)
+ debug_printf("%s queued for fallback host(s)\n", next->address);
if (!next->next) break;
}
next->next = addr_fallback;
/* Setting these globals in the subprocess means we need never clear them */
- transport_name = tp->name;
+ transport_name = tp->drinst.name;
if (addr->router) router_name = addr->router->drinst.name;
- driver_srcfile = tp->srcfile;
- driver_srcline = tp->srcline;
+ driver_srcfile = tp->drinst.srcfile;
+ driver_srcline = tp->drinst.srcline;
/* There are weird circumstances in which logging is disabled */
f.disable_logging = tp->disable_logging;
exim_setugid(uid, gid, use_initgroups,
string_sprintf("remote delivery to %s with transport=%s",
- addr->address, tp->name));
+ addr->address, tp->drinst.name));
/* Close the unwanted half of this process' pipe, set the process state,
and run the transport. Afterwards, transport_count will contain the number
of bytes written. */
(void)close(pfd[pipe_read]);
- set_process_info("delivering %s using %s", message_id, tp->name);
+ set_process_info("delivering %s using %s", message_id, tp->drinst.name);
debug_print_string(tp->debug_string);
- if (!(tp->info->code)(addr->transport, addr)) replicate_status(addr);
+
+ {
+ transport_info * ti = tp->drinst.info;
+ if (!(ti->code)(addr->transport, addr)) /* Call the transport */
+ replicate_status(addr);
+ }
set_process_info("delivering %s (just run %s for %s%s in subprocess)",
- message_id, tp->name, addr->address, addr->next ? ", ..." : "");
+ message_id, tp->drinst.name, addr->address, addr->next ? ", ..." : "");
/* Ensure any cached resources that we used are now released */
continue_closedown(void)
{
if (continue_transport)
- for (transport_instance * t = transports; t; t = t->next)
- if (Ustrcmp(t->name, continue_transport) == 0)
+ for (transport_instance * t = transports; t; t = t->drinst.next)
+ if (Ustrcmp(t->drinst.name, continue_transport) == 0)
{
- if (t->info->closedown) (t->info->closedown)(t);
+ transport_info * ti = t->drinst.info;
+ if (ti->closedown) (ti->closedown)(t);
continue_transport = NULL;
break;
}
if (tpname)
{
transport_instance *tp;
- for (tp = transports; tp; tp = tp->next)
- if (Ustrcmp(tp->name, tpname) == 0)
+ for (tp = transports; tp; tp = tp->drinst.next)
+ if (Ustrcmp(tp->drinst.name, tpname) == 0)
{ p->transport = tp; break; }
if (!tp)
p->message = string_sprintf("failed to find \"%s\" transport "
transport_instance * save_t = addr->transport;
transport_instance * t = store_get(sizeof(*t), save_t);
*t = *save_t;
- t->name = US"**bypassed**";
+ t->drinst.name = US"**bypassed**";
addr->transport = t;
(void)post_process_one(addr, OK, LOG_MAIN, EXIM_DTYPE_TRANSPORT, '=');
addr->transport= save_t;
delivery. */
DEBUG(D_deliver|D_route)
- debug_printf("queued for %s transport\n", addr->transport->name);
+ debug_printf("queued for %s transport\n", addr->transport->drinst.name);
addr->next = addr_local;
addr_local = addr;
continue; /* with the next new address */
if (!transport_name)
s = event_action;
else
- for(transport_instance * tp = transports; tp; tp = tp->next)
- if (Ustrcmp(tp->name, transport_name) == 0)
+ for(transport_instance * tp = transports; tp; tp = tp->drinst.next)
+ if (Ustrcmp(tp->drinst.name, transport_name) == 0)
{ s = tp->event_action; break; }
if (s)
transport_info transports_available[] = {
#ifdef TRANSPORT_APPENDFILE
{
- .driver_name = US"appendfile",
- .options = appendfile_transport_options,
- .options_count = &appendfile_transport_options_count,
- .options_block = &appendfile_transport_option_defaults, /* private options defaults */
- .options_len = sizeof(appendfile_transport_options_block),
- .init = appendfile_transport_init,
+ .drinfo = {
+ .driver_name = US"appendfile",
+ .options = appendfile_transport_options,
+ .options_count = &appendfile_transport_options_count,
+ .options_block = &appendfile_transport_option_defaults, /* private options defaults */
+ .options_len = sizeof(appendfile_transport_options_block),
+ .init = appendfile_transport_init,
+ },
.code = appendfile_transport_entry,
.tidyup = NULL,
.closedown = NULL,
#endif
#ifdef TRANSPORT_AUTOREPLY
{
- .driver_name = US"autoreply",
- .options = autoreply_transport_options,
- .options_count = &autoreply_transport_options_count,
- .options_block = &autoreply_transport_option_defaults,
- .options_len = sizeof(autoreply_transport_options_block),
- .init = autoreply_transport_init,
+ .drinfo = {
+ .driver_name = US"autoreply",
+ .options = autoreply_transport_options,
+ .options_count = &autoreply_transport_options_count,
+ .options_block = &autoreply_transport_option_defaults,
+ .options_len = sizeof(autoreply_transport_options_block),
+ .init = autoreply_transport_init,
+ },
.code = autoreply_transport_entry,
.tidyup = NULL,
.closedown = NULL,
#endif
#ifdef TRANSPORT_LMTP
{
- .driver_name = US"lmtp",
- .options = lmtp_transport_options,
- .options_count = &lmtp_transport_options_count,
- .options_block = &lmtp_transport_option_defaults,
- .options_len = sizeof(lmtp_transport_options_block),
- .init = lmtp_transport_init,
+ .drinfo = {
+ .driver_name = US"lmtp",
+ .options = lmtp_transport_options,
+ .options_count = &lmtp_transport_options_count,
+ .options_block = &lmtp_transport_option_defaults,
+ .options_len = sizeof(lmtp_transport_options_block),
+ .init = lmtp_transport_init,
+ },
.code = lmtp_transport_entry,
.tidyup = NULL,
.closedown = NULL,
#endif
#ifdef TRANSPORT_PIPE
{
- .driver_name = US"pipe",
- .options = pipe_transport_options,
- .options_count = &pipe_transport_options_count,
- .options_block = &pipe_transport_option_defaults,
- .options_len = sizeof(pipe_transport_options_block),
- .init = pipe_transport_init,
+ .drinfo = {
+ .driver_name = US"pipe",
+ .options = pipe_transport_options,
+ .options_count = &pipe_transport_options_count,
+ .options_block = &pipe_transport_option_defaults,
+ .options_len = sizeof(pipe_transport_options_block),
+ .init = pipe_transport_init,
+ },
.code = pipe_transport_entry,
.tidyup = NULL,
.closedown = NULL,
#endif
#ifdef EXPERIMENTAL_QUEUEFILE
{
- .driver_name = US"queuefile",
- .options = queuefile_transport_options,
- .options_count = &queuefile_transport_options_count,
- .options_block = &queuefile_transport_option_defaults,
- .options_len = sizeof(queuefile_transport_options_block),
- .init = queuefile_transport_init,
+ .drinfo = {
+ .driver_name = US"queuefile",
+ .options = queuefile_transport_options,
+ .options_count = &queuefile_transport_options_count,
+ .options_block = &queuefile_transport_option_defaults,
+ .options_len = sizeof(queuefile_transport_options_block),
+ .init = queuefile_transport_init,
+ },
.code = queuefile_transport_entry,
.tidyup = NULL,
.closedown = NULL,
#endif
#ifdef TRANSPORT_SMTP
{
- .driver_name = US"smtp",
- .options = smtp_transport_options,
- .options_count = &smtp_transport_options_count,
- .options_block = &smtp_transport_option_defaults,
- .options_len = sizeof(smtp_transport_options_block),
- .init = smtp_transport_init,
+ .drinfo = {
+ .driver_name = US"smtp",
+ .options = smtp_transport_options,
+ .options_count = &smtp_transport_options_count,
+ .options_block = &smtp_transport_option_defaults,
+ .options_len = sizeof(smtp_transport_options_block),
+ .init = smtp_transport_init,
+ },
.code = smtp_transport_entry,
.tidyup = NULL,
.closedown = smtp_transport_closedown,
extern const uschar *transport_rcpt_address(address_item *, BOOL);
extern BOOL transport_set_up_command(const uschar ***, const uschar *,
unsigned, int, address_item *, const uschar *, uschar **);
-extern void transport_update_waiting(host_item *, uschar *);
+extern void transport_update_waiting(host_item *, const uschar *);
extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
extern void transport_write_reset(int);
extern BOOL transport_write_string(int, const char *, ...);
const uschar *continue_host_address = NULL;
uschar continue_next_id[MESSAGE_ID_LENGTH +1] = {[0]='\0'};
int continue_sequence = 1;
-uschar *continue_transport = NULL;
+const uschar *continue_transport = NULL;
#ifndef COMPILE_UTILITY
open_db *continue_retry_db = NULL;
open_db *continue_wait_db = NULL;
};
int transport_count;
-uschar *transport_name = NULL;
+const uschar *transport_name = NULL;
int transport_newlines;
const uschar **transport_filter_argv = NULL;
int transport_filter_timeout;
extern const uschar *continue_host_address; /* IP address for ditto */
extern uschar continue_next_id[]; /* Next message_id from hintsdb */
extern int continue_sequence; /* Sequence num for continued delivery */
-extern uschar *continue_transport; /* Transport for continued delivery */
+extern const uschar *continue_transport; /* Transport for continued delivery */
#ifndef COMPILE_UTILITY
extern open_db *continue_retry_db; /* Hintsdb for retries */
extern open_db *continue_wait_db; /* Hintsdb for wait-transport */
extern struct timeval timestamp_startup; /* For development measurements */
#endif
-extern uschar *transport_name; /* Name of transport last started */
+extern const uschar *transport_name; /* Name of transport last started */
extern int transport_count; /* Count of bytes transported */
extern int transport_newlines; /* Accurate count of number of newline chars transported */
extern const uschar **transport_filter_argv; /* For on-the-fly filtering */
}
if (transport_name)
- for (transport_instance * t = transports; t; t = t->next)
- if (Ustrcmp(t->name, transport_name) == 0)
+ for (transport_instance * t = transports; t; t = t->drinst.next)
+ if (Ustrcmp(t->drinst.name, transport_name) == 0)
{
- const transport_info * ti = t->info;
+ const transport_info * ti = t->drinst.info;
/* Check for a listptr match first */
- for (optionlist * o = optionlist_transports; /* generic options */
+ for (optionlist * o = optionlist_transports; /* generic options */
o < optionlist_transports + optionlist_transports_size; o++)
if ( (o->type & opt_mask) == opt_stringptr
&& listptr == CS t + o->v.offset)
return US o->name;
- for (optionlist * o = ti->options; /* private options */
- o < ti->options + *ti->options_count; o++)
+ for (optionlist * o = ti->drinfo.options; /* private options */
+ o < ti->drinfo.options + *ti->drinfo.options_count; o++)
if ( (o->type & opt_mask) == opt_stringptr
- && listptr == CS t->options_block + o->v.offset)
+ && listptr == CS t->drinst.options_block + o->v.offset)
return US o->name;
/* Check for a list addr match, unless null */
if (!list) continue;
- for (optionlist * o = optionlist_transports; /* generic options */
+ for (optionlist * o = optionlist_transports; /* generic options */
o < optionlist_transports + optionlist_transports_size; o++)
if ( (o->type & opt_mask) == opt_stringptr
&& list == * USS(CS t + o->v.offset))
- if (name) return string_sprintf("DUP: %s %s vs. %s %s",
- drname, name, t->name, o->name);
- else { name = US o->name; drname = t->name; }
+ if (name)
+ return string_sprintf("DUP: %s %s vs. %s %s",
+ drname, name, t->drinst.name, o->name);
+ else
+ { name = US o->name; drname = t->drinst.name; }
- for (optionlist * o = ti->options; /* private options */
- o < ti->options + *ti->options_count; o++)
+ for (optionlist * o = ti->drinfo.options; /* private options */
+ o < ti->drinfo.options + *ti->drinfo.options_count; o++)
if ( (o->type & opt_mask) == opt_stringptr
- && list == * USS(CS t->options_block + o->v.offset))
- if (name) return string_sprintf("DUP: %s %s vs. %s %s",
- drname, name, t->name, o->name);
- else { name = US o->name; drname = t->name; }
+ && list == * USS(CS t->drinst.options_block + o->v.offset))
+ if (name)
+ return string_sprintf("DUP: %s %s vs. %s %s",
+ drname, name, t->drinst.name, o->name);
+ else
+ { name = US o->name; drname = t->drinst.name; }
}
return name ? name : US"";
{
debug_printf(" envelope to: %s\n", addr->address);
debug_printf(" transport: %s\n", addr->transport
- ? addr->transport->name : US"<none>");
+ ? addr->transport->drinst.name : US"<none>");
if (addr->prop.errors_address)
debug_printf(" errors to %s\n", addr->prop.errors_address);
const uschar * s = options;
Uskip_nonwhite(&options);
- n = options-s;
+ n = options - s;
if (Ustrncmp(s, "randomize", n) == 0) randomize = TRUE;
else if (Ustrncmp(s, "no_randomize", n) == 0) randomize = FALSE;
else if (Ustrncmp(s, "ipv4_only", n) == 0) lookup_type |= LK_IPV4_ONLY;
else
{
- transport_instance *t;
- for (t = transports; t; t = t->next)
- if (Ustrncmp(t->name, s, n) == 0)
+ transport_instance * t;
+ for (t = transports; t; t = t->drinst.next)
+ if (Ustrncmp(t->drinst.name, s, n) == 0)
{
transport = t;
individual_transport_set = TRUE;
/* Deal with the case of a local transport. The host list is passed over as a
single text string that ends up in $host. */
-if (transport && transport->info->local)
+if (transport)
{
- if (hostlist[0])
+ transport_info * ti = transport->drinst.info;
+ if (ti->local)
{
- host_item *h;
- addr->host_list = h = store_get(sizeof(host_item), GET_UNTAINTED);
- h->name = string_copy(hostlist);
- h->address = NULL;
- h->port = PORT_NONE;
- h->mx = MX_NONE;
- h->status = hstatus_unknown;
- h->why = hwhy_unknown;
- h->last_try = 0;
- h->next = NULL;
- }
+ if (hostlist[0])
+ {
+ host_item * h = store_get(sizeof(host_item), GET_UNTAINTED);
+ h->name = string_copy(hostlist);
+ h->address = NULL;
+ h->port = PORT_NONE;
+ h->mx = MX_NONE;
+ h->status = hstatus_unknown;
+ h->why = hwhy_unknown;
+ h->last_try = 0;
+ h->next = NULL;
+ addr->host_list = h;
+ }
- /* There is nothing more to do other than to queue the address for the
- local transport, filling in any uid/gid. This can be done by the common
- rf_queue_add() function. */
+ /* There is nothing more to do other than to queue the address for the
+ local transport, filling in any uid/gid. This can be done by the common
+ rf_queue_add() function. */
- addr->transport = transport;
- return rf_queue_add(addr, addr_local, addr_remote, rblock, pw) ? OK : DEFER;
+ addr->transport = transport;
+ return rf_queue_add(addr, addr_local, addr_remote, rblock, pw) ? OK : DEFER;
+ }
}
/* There is either no transport (verify_only) or a remote transport. A host
if ((s = expand_getkeyed(US"transport", rdata)) && *s)
{
- transport_instance *transport;
- for (transport = transports; transport; transport = transport->next)
- if (Ustrcmp(transport->name, s) == 0) break;
+ transport_instance * transport;
+ for (transport = transports; transport; transport = transport->drinst.next)
+ if (Ustrcmp(transport->drinst.name, s) == 0) break;
if (!transport)
{
addr->message = string_sprintf("unknown transport name %s yielded by "
next->address,
testflag(next, af_pfr)? "pipe, file, or autoreply\n " : "",
next->prop.errors_address,
- (next->transport == NULL)? US"NULL" : next->transport->name);
+ next->transport ? next->transport->drinst.name : US"NULL");
if (testflag(next, af_uid_set))
debug_printf(" uid=%ld ", (long int)(next->uid));
else
ss = tpname;
-for (transport_instance * tp = transports; tp; tp = tp->next)
- if (Ustrcmp(tp->name, ss) == 0)
+for (transport_instance * tp = transports; tp; tp = tp->drinst.next)
+ if (Ustrcmp(tp->drinst.name, ss) == 0)
{
DEBUG(D_route) debug_printf("set transport %s\n", ss);
*tpptr = tp;
rf_queue_add(address_item *addr, address_item **paddr_local,
address_item **paddr_remote, router_instance *rblock, struct passwd *pw)
{
+transport_instance * t = addr->transport;
+
addr->prop.domain_data = deliver_domain_data; /* Save these values for */
addr->prop.localpart_data = deliver_localpart_data; /* use in the transport */
/* Handle a local transport */
-if (addr->transport && addr->transport->info->local)
+if (t)
{
- ugid_block ugid;
-
- /* Default uid/gid and transport-time home directory are from the passwd file
- when check_local_user is set, but can be overridden by explicit settings.
- When getting the home directory out of the password information, set the
- flag that prevents expansion later. */
-
- if (pw)
+ transport_info * ti = t->drinst.info;
+ if (ti->local)
{
- addr->uid = pw->pw_uid;
- addr->gid = pw->pw_gid;
- setflag(addr, af_uid_set);
- setflag(addr, af_gid_set);
- setflag(addr, af_home_expanded);
- addr->home_dir = string_copy(US pw->pw_dir);
+ ugid_block ugid;
+
+ /* Default uid/gid and transport-time home directory are from the passwd file
+ when check_local_user is set, but can be overridden by explicit settings.
+ When getting the home directory out of the password information, set the
+ flag that prevents expansion later. */
+
+ if (pw)
+ {
+ addr->uid = pw->pw_uid;
+ addr->gid = pw->pw_gid;
+ setflag(addr, af_uid_set);
+ setflag(addr, af_gid_set);
+ setflag(addr, af_home_expanded);
+ addr->home_dir = string_copy(US pw->pw_dir);
+ }
+
+ if (!rf_get_ugid(rblock, addr, &ugid)) return FALSE;
+ rf_set_ugid(addr, &ugid);
+
+ /* transport_home_directory (in rblock->home_directory) takes priority;
+ otherwise use the expanded value of router_home_directory. The flag also
+ tells the transport not to re-expand it. */
+
+ if (rblock->home_directory)
+ {
+ addr->home_dir = rblock->home_directory;
+ clearflag(addr, af_home_expanded);
+ }
+ else if (!addr->home_dir && testflag(addr, af_home_expanded))
+ addr->home_dir = deliver_home;
+
+ addr->current_dir = rblock->current_directory;
+
+ addr->next = *paddr_local;
+ *paddr_local = addr;
+ goto donelocal;
}
-
- if (!rf_get_ugid(rblock, addr, &ugid)) return FALSE;
- rf_set_ugid(addr, &ugid);
-
- /* transport_home_directory (in rblock->home_directory) takes priority;
- otherwise use the expanded value of router_home_directory. The flag also
- tells the transport not to re-expand it. */
-
- if (rblock->home_directory)
- {
- addr->home_dir = rblock->home_directory;
- clearflag(addr, af_home_expanded);
- }
- else if (!addr->home_dir && testflag(addr, af_home_expanded))
- addr->home_dir = deliver_home;
-
- addr->current_dir = rblock->current_directory;
-
- addr->next = *paddr_local;
- *paddr_local = addr;
}
-/* For a remote transport, set up the fallback host list, and keep a count of
-the total number of addresses routed to remote transports. */
+/* For a remote transport or if we do not have one (eg verifying), set up the
+fallback host list, and keep a count of the total number of addresses routed
+to remote transports. */
-else
- {
- addr->fallback_hosts = rblock->fallback_hostlist;
- addr->next = *paddr_remote;
- *paddr_remote = addr;
- remote_delivery_count++;
- }
+addr->fallback_hosts = rblock->fallback_hostlist;
+addr->next = *paddr_remote;
+*paddr_remote = addr;
+remote_delivery_count++;
+
+donelocal:
DEBUG(D_route)
{
debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n"
" errors_to=%s\n",
- addr->transport ? addr->transport->name : US"<unset>",
+ t ? t->drinst.name : US"<unset>",
addr->local_part, addr->domain, addr->prop.errors_address);
debug_printf(" domain_data=%s local_part_data=%s\n", addr->prop.domain_data,
addr->prop.localpart_data);
smtp_boundsock(smtp_connect_args * sc)
{
transport_instance * tb = sc->tblock;
-smtp_transport_options_block * ob =
- (smtp_transport_options_block *)tb->options_block;
+smtp_transport_options_block * ob = tb->drinst.options_block;
const uschar * dscp = ob->dscp;
int sock, dscp_value, dscp_level, dscp_option;
int
smtp_sock_connect(smtp_connect_args * sc, int timeout, const blob * early_data)
{
-smtp_transport_options_block * ob =
- (smtp_transport_options_block *)sc->tblock->options_block;
+smtp_transport_options_block * ob = sc->tblock->drinst.options_block;
int sock;
int save_errno = 0;
const blob * fastopen_blob = NULL;
the main transport code. */
typedef struct transport_instance {
- struct transport_instance *next;
- uschar *name; /* Instance name */
- struct transport_info *info; /* Info for this driver */
- void *options_block; /* Pointer to private options */
- uschar *driver_name; /* Must be first */
- const uschar *srcfile;
- int srcline;
+ driver_instance drinst;
int (*setup)( /* Setup entry point */
struct transport_instance *,
} transport_instance;
-/* Structure for holding information about a type of transport. The first six
-fields must match driver_info above. */
+/* Structure for holding information about a type of transport. The first
+element must be a struct driver_info, to match auths and routers. */
typedef struct transport_info {
- uschar *driver_name; /* Driver name */
- optionlist *options; /* Table of private options names */
- int *options_count; /* -> Number of entries in table */
- void *options_block; /* Points to default private block */
- int options_len; /* Length of same in bytes */
- void (*init)( /* Initialization function */
- struct transport_instance *);
-/****/
+ driver_info drinfo;
+
BOOL (*code)( /* Main entry point */
transport_instance *,
struct address_item *);
static void
tls_client_creds_init(transport_instance * t, BOOL watch)
{
-smtp_transport_options_block * ob = t->options_block;
+smtp_transport_options_block * ob = t->drinst.options_block;
+const uschar * trname = t->drinst.name;
exim_gnutls_state_st tpt_dummy_state;
host_item * dummy_host = (host_item *)1;
uschar * dummy_errstr;
const uschar * pkey = ob->tls_privatekey;
DEBUG(D_tls)
- debug_printf("TLS: preloading client certs for transport '%s'\n", t->name);
+ debug_printf("TLS: preloading client certs for transport '%s'\n", trname);
/* The state->lib_state.x509_cred is used for the certs load, and is the sole
structure element used. So we can set up a dummy. The hoat arg only
}
else
DEBUG(D_tls)
- debug_printf("TLS: not preloading client certs, for transport '%s'\n", t->name);
+ debug_printf("TLS: not preloading client certs, for transport '%s'\n", trname);
/* If tls_verify_certificates is non-empty and has no $, load CAs.
If none was configured and we can't handle "system", treat as empty. */
if (!watch || tls_set_watch(ob->tls_verify_certificates, FALSE))
{
DEBUG(D_tls)
- debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name);
+ debug_printf("TLS: preloading CA bundle for transport '%s'\n", trname);
if (creds_load_cabundle(&tpt_dummy_state, ob->tls_verify_certificates,
dummy_host, &dummy_errstr) != OK)
return;
{
if (!watch || tls_set_watch(ob->tls_crl, FALSE))
{
- DEBUG(D_tls) debug_printf("TLS: preloading CRL for transport '%s'\n", t->name);
+ DEBUG(D_tls) debug_printf("TLS: preloading CRL for transport '%s'\n", trname);
if (creds_load_crl(&tpt_dummy_state, ob->tls_crl, &dummy_errstr) != OK)
return;
ob->tls_preload.crl = TRUE;
}
}
else
- DEBUG(D_tls) debug_printf("TLS: not preloading CRL, for transport '%s'\n", t->name);
+ DEBUG(D_tls) debug_printf("TLS: not preloading CRL, for transport '%s'\n", trname);
}
}
else
DEBUG(D_tls)
- debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", t->name);
+ debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", trname);
/* We do not preload tls_require_ciphers to to the transport as it implicitly
depends on DANE or plain usage. */
static void
tls_client_creds_invalidate(transport_instance * t)
{
-smtp_transport_options_block * ob = t->options_block;
+smtp_transport_options_block * ob = t->drinst.options_block;
if (ob->tls_preload.x509_cred)
gnutls_certificate_free_credentials(ob->tls_preload.x509_cred);
ob->tls_preload = null_tls_preload;
host_item * host = conn_args->host; /* for msgs and option-tests */
transport_instance * tb = conn_args->tblock; /* always smtp or NULL */
smtp_transport_options_block * ob = tb
- ? (smtp_transport_options_block *)tb->options_block
+ ? tb->drinst.options_block
: &smtp_transport_option_defaults;
int rc;
exim_gnutls_state_st * state = NULL;
static void
tls_client_creds_init(transport_instance * t, BOOL watch)
{
-smtp_transport_options_block * ob = t->options_block;
+smtp_transport_options_block * ob = t->drinst.options_block;
+const uschar * trname = t->drinst.name;
exim_openssl_state_st tpt_dummy_state;
host_item * dummy_host = (host_item *)1;
uschar * dummy_errstr;
uschar * pkey = ob->tls_privatekey;
DEBUG(D_tls)
- debug_printf("TLS: preloading client certs for transport '%s'\n",t->name);
+ debug_printf("TLS: preloading client certs for transport '%s'\n", trname);
if ( tls_add_certfile(ctx, &tpt_dummy_state, ob->tls_certificate,
&dummy_errstr) == 0
}
else
DEBUG(D_tls)
- debug_printf("TLS: not preloading client certs, for transport '%s'\n", t->name);
+ debug_printf("TLS: not preloading client certs, for transport '%s'\n", trname);
if ( opt_set_and_noexpand(ob->tls_verify_certificates)
{
uschar * v_certs = ob->tls_verify_certificates;
DEBUG(D_tls)
- debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name);
+ debug_printf("TLS: preloading CA bundle for transport '%s'\n", trname);
if (setup_certs(ctx, &v_certs,
ob->tls_crl, dummy_host, &dummy_errstr) == OK)
}
else
DEBUG(D_tls)
- debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", t->name);
+ debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", trname);
#endif /*EXIM_HAVE_INOTIFY*/
}
static void
tls_client_creds_invalidate(transport_instance * t)
{
-smtp_transport_options_block * ob = t->options_block;
+smtp_transport_options_block * ob = t->drinst.options_block;
SSL_CTX_free(ob->tls_preload.lib_ctx);
ob->tls_preload = null_tls_preload;
}
host_item * host = conn_args->host; /* for msgs and option-tests */
transport_instance * tb = conn_args->tblock; /* always smtp or NULL */
smtp_transport_options_block * ob = tb
- ? (smtp_transport_options_block *)tb->options_block
+ ? tb->drinst.options_block
: &smtp_transport_option_defaults;
exim_openssl_client_tls_ctx * exim_client_ctx;
uschar * expciphers;
void
tls_client_creds_reload(BOOL watch)
{
-for(transport_instance * t = transports; t; t = t->next)
- if (Ustrcmp(t->driver_name, "smtp") == 0)
+for(transport_instance * t = transports; t; t = t->drinst.next)
+ if (Ustrcmp(t->drinst.driver_name, "smtp") == 0)
{
#if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT)
tls_client_creds_invalidate(t);
conn_args.tblock = tb = store_get(sizeof(*tb), GET_UNTAINTED);
memset(tb, 0, sizeof(*tb));
- tb->options_block = ob = store_get(sizeof(*ob), GET_UNTAINTED);
+ tb->drinst.options_block = ob = store_get(sizeof(*ob), GET_UNTAINTED);
memcpy(ob, &smtp_transport_option_defaults, sizeof(*ob));
ob->tls_sni = sni;
{ "disable_logging", opt_bool|opt_public,
LOFF(disable_logging) },
{ "driver", opt_stringptr|opt_public,
- LOFF(driver_name) },
+ LOFF(drinst.driver_name) },
{ "envelope_to_add", opt_bool|opt_public,
LOFF(envelope_to_add) },
#ifndef DISABLE_EVENT
options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL);
-for (transport_info * ti = transports_available; ti->driver_name[0]; ti++)
+for (transport_info * ti= transports_available; ti->drinfo.driver_name[0]; ti++)
{
- spf(buf, sizeof(buf), US"_DRIVER_TRANSPORT_%T", ti->driver_name);
+ spf(buf, sizeof(buf), US"_DRIVER_TRANSPORT_%T", ti->drinfo.driver_name);
builtin_macro_create(buf);
- options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name);
+ options_from_list(ti->drinfo.options, (unsigned)*ti->drinfo.options_count,
+ US"TRANSPORT", ti->drinfo.driver_name);
}
}
/* Now scan the configured transports and check inconsistencies. A shadow
transport is permitted only for local transports. */
-for (transport_instance * t = transports; t; t = t->next)
+for (transport_instance * t = transports; t; t = t->drinst.next)
{
- if (!t->info->local && t->shadow)
+ transport_info * ti = t->drinst.info;
+ if (!ti->local && t->shadow)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
- "shadow transport not allowed on non-local transport %s", t->name);
+ "shadow transport not allowed on non-local transport %s", t->drinst.name);
if (t->body_only && t->headers_only)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"%s transport: body_only and headers_only are mutually exclusive",
- t->name);
+ t->drinst.name);
}
}
*/
void
-transport_update_waiting(host_item * hostlist, uschar * tpname)
+transport_update_waiting(host_item * hostlist, const uschar * tpname)
{
const uschar * prevname = US"";
open_db dbblock, * dbp;
/* Dummy values */
appendfile_transport_options_block appendfile_transport_option_defaults = {0};
-void appendfile_transport_init(transport_instance *tblock) {}
+void appendfile_transport_init(driver_instance *tblock) {}
BOOL appendfile_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
#else /*!MACRO_PREDEF*/
appendfile_transport_setup(transport_instance *tblock, address_item *addrlist,
transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg)
{
-appendfile_transport_options_block * ob =
- (appendfile_transport_options_block *)(tblock->options_block);
+appendfile_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
uschar * q;
double default_value = 0.0;
GET_OPTION("maildir_use_size_file");
ob->maildir_use_size_file =
expand_check_condition(ob->expand_maildir_use_size_file,
- US"`maildir_use_size_file` in transport", tblock->name);
+ US"`maildir_use_size_file` in transport", trname);
}
/* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size,
if (!(s = expand_string(q)))
{
*errmsg = string_sprintf("Expansion of \"%s\" in %s transport failed: "
- "%s", q, tblock->name, expand_string_message);
+ "%s", q, trname, expand_string_message);
return f.search_find_defer ? DEFER : FAIL;
}
else if ((int)d < 0 || (int)d > 100)
{
*errmsg = string_sprintf("Invalid quota_warn_threshold percentage (%d)"
- " for %s transport", (int)d, tblock->name);
+ " for %s transport", (int)d, trname);
return FAIL;
}
ob->quota_warn_threshold_is_percent = TRUE;
if (*rest)
{
*errmsg = string_sprintf("Malformed value \"%s\" (expansion of \"%s\") "
- "in %s transport", s, q, tblock->name);
+ "in %s transport", s, q, trname);
return FAIL;
}
}
if (which)
{
*errmsg = string_sprintf("%s value %.10g is too large (overflow) in "
- "%s transport", which, d, tblock->name);
+ "%s transport", which, d, trname);
return FAIL;
}
}
to be set up. */
void
-appendfile_transport_init(transport_instance *tblock)
+appendfile_transport_init(driver_instance * t)
{
-appendfile_transport_options_block *ob =
- (appendfile_transport_options_block *)(tblock->options_block);
+transport_instance * tblock = (transport_instance *)t;
+appendfile_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
uschar * s;
/* Set up the setup entry point, to be called in the privileged state */
if (ob->filename && ob->dirname)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "only one of \"file\" or \"directory\" can be specified", tblock->name);
+ "only one of \"file\" or \"directory\" can be specified", trname);
/* If a file name was specified, neither quota_filecount nor quota_directory
must be given. */
{
if (ob->quota_filecount)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "quota_filecount must not be set without \"directory\"", tblock->name);
+ "quota_filecount must not be set without \"directory\"", trname);
if (ob->quota_directory)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "quota_directory must not be set without \"directory\"", tblock->name);
+ "quota_directory must not be set without \"directory\"", trname);
}
/* The default locking depends on whether MBX is set or not. Change the
#ifdef NO_FLOCK
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
"flock() support was not available in the operating system when this "
- "binary was built", tblock->name);
+ "binary was built", trname);
#endif /* NO_FLOCK */
if (!ob->set_use_fcntl) ob->use_fcntl = FALSE;
}
if (!ob->use_fcntl && !ob->use_flock && !ob->use_lockfile && !ob->use_mbx_lock)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "no locking configured", tblock->name);
+ "no locking configured", trname);
/* Unset timeouts for non-used locking types */
{
if (ob->maildir_format && ob->mailstore_format)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "only one of maildir and mailstore may be specified", tblock->name);
+ "only one of maildir and mailstore may be specified", trname);
if (ob->quota_filecount != NULL && !ob->quota)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "quota must be set if quota_filecount is set", tblock->name);
+ "quota must be set if quota_filecount is set", trname);
if (ob->quota_directory != NULL && !ob->quota)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s transport:\n "
- "quota must be set if quota_directory is set", tblock->name);
+ "quota must be set if quota_directory is set", trname);
}
/* If a fixed uid field is set, then a gid field must also be set. */
if (tblock->uid_set && !tblock->gid_set && !tblock->expand_gid)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
- "user set without group for the %s transport", tblock->name);
+ "user set without group for the %s transport", trname);
/* If "create_file" is set, check that a valid option is given, and set the
integer variable. */
else
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"invalid value given for \"create_file\" for the %s transport: '%s'",
- tblock->name, s);
+ trname, s);
ob->create_file = val;
}
transport_instance *
check_file_format(int cfd, transport_instance *tblock, address_item *addr)
{
-const uschar *format =
- ((appendfile_transport_options_block *)(tblock->options_block))->file_format;
+appendfile_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * format = ob->file_format;
uschar data[256];
int len = read(cfd, data, sizeof(data));
int sep = 0;
if (match && tp)
{
- for (transport_instance * tt = transports; tt; tt = tt->next)
- if (Ustrcmp(tp, tt->name) == 0)
+ for (transport_instance * tt = transports; tt; tt = tt->drinst.next)
+ if (Ustrcmp(tp, tt->drinst.name) == 0)
{
DEBUG(D_transport)
- debug_printf("file format -> %s transport\n", tt->name);
+ debug_printf("file format -> %s transport\n", tt->drinst.name);
return tt;
}
addr->basic_errno = ERRNO_BADTRANSPORT;
transport_instance *tblock, /* data for this instantiation */
address_item *addr) /* address we are working on */
{
-appendfile_transport_options_block *ob =
- (appendfile_transport_options_block *)(tblock->options_block);
+appendfile_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
struct stat statbuf;
const uschar * deliver_dir;
-uschar *fdname = NULL;
-uschar *filename = NULL;
-uschar *hitchname = NULL;
-uschar *dataname = NULL;
-uschar *lockname = NULL;
-uschar *newname = NULL;
-uschar *nametag = NULL;
-uschar *cr = US"";
-uschar *filecount_msg = US"";
-uschar *path;
+uschar * fdname = NULL, * filename = NULL;
+uschar * hitchname = NULL, * dataname = NULL;
+uschar * lockname = NULL, * newname = NULL;
+uschar * nametag = NULL, * cr = US"";
+uschar * filecount_msg = US"";
+uschar * path;
struct utimbuf times;
struct timeval msg_tv;
-BOOL disable_quota = FALSE;
-BOOL isdirectory = FALSE;
-BOOL isfifo = FALSE;
+BOOL disable_quota = FALSE, isdirectory = FALSE, isfifo = FALSE;
BOOL wait_for_tick = FALSE;
uid_t uid = geteuid(); /* See note above */
gid_t gid = getegid();
int mbformat;
-int mode = (addr->mode > 0) ? addr->mode : ob->mode;
-off_t saved_size = -1;
-off_t mailbox_size = ob->mailbox_size_value;
+int mode = addr->mode > 0 ? addr->mode : ob->mode;
+off_t saved_size = -1, mailbox_size = ob->mailbox_size_value;
int mailbox_filecount = ob->mailbox_filecount_value;
-int hd = -1;
-int fd = -1;
-int yield = FAIL;
-int i;
+int hd = -1, fd = -1, yield = FAIL, i;
#ifdef SUPPORT_MBX
int save_fd = 0;
if (!fdname)
{
addr->message = string_sprintf("Mandatory file or directory option "
- "missing from %s transport", tblock->name);
+ "missing from %s transport", trname);
goto ret_panic;
}
}
{
addr->message = string_sprintf("mail%s_format requires \"directory\" "
"to be specified for the %s transport",
- ob->maildir_format ? "dir" : "store", tblock->name);
+ ob->maildir_format ? "dir" : "store", trname);
goto ret_panic;
}
if (!(path = expand_string(fdname)))
{
addr->message = string_sprintf("Expansion of \"%s\" (file or directory "
- "name for %s transport) failed: %s", fdname, tblock->name,
+ "name for %s transport) failed: %s", fdname, trname,
expand_string_message);
goto ret_panic;
}
{
DEBUG(D_transport)
debug_printf("*** delivery by %s transport bypassed by -N option\n",
- tblock->name);
+ trname);
addr->transport_return = OK;
return FALSE;
}
addr->message =
string_sprintf("failed to create directories for %s: %s", path,
exim_errstr(errno));
- DEBUG(D_transport) debug_printf("%s transport: %s\n", tblock->name, path);
+ DEBUG(D_transport) debug_printf("%s transport: %s\n", trname, path);
return FALSE;
}
}
{
if (tt)
{
+ transport_info * ti = tt->drinst.info;
set_process_info("delivering %s to %s using %s", message_id,
- addr->local_part, tt->name);
+ addr->local_part, tt->drinst.name);
debug_print_string(tt->debug_string);
addr->transport = tt;
- (tt->info->code)(tt, addr);
+ (ti->code)(tt, addr);
}
return FALSE;
}
{
addr->message = string_sprintf("Expansion of \"%s\" (quota_directory "
"name for %s transport) failed: %s", ob->quota_directory,
- tblock->name, expand_string_message);
+ trname, expand_string_message);
goto ret_panic;
}
if (nametag && !expand_string(nametag) && !f.expand_string_forcedfail)
{
addr->message = string_sprintf("Expansion of \"%s\" (maildir_tag "
- "for %s transport) failed: %s", nametag, tblock->name,
+ "for %s transport) failed: %s", nametag, trname,
expand_string_message);
goto ret_panic;
}
{
addr->basic_errno = errno;
addr->message = string_sprintf("fdopen of %s ("
- "for %s transport) failed", filename, tblock->name);
+ "for %s transport) failed", filename, trname);
(void)close(fd);
Uunlink(filename);
goto ret_panic;
{
addr->message = string_sprintf("Expansion of \"%s\" (mailstore "
"prefix for %s transport) failed: %s", ob->mailstore_prefix,
- tblock->name, expand_string_message);
+ trname, expand_string_message);
(void)fclose(env_file);
Uunlink(filename);
goto ret_panic;
{
addr->message = string_sprintf("Expansion of \"%s\" (mailstore "
"suffix for %s transport) failed: %s", ob->mailstore_suffix,
- tblock->name, expand_string_message);
+ trname, expand_string_message);
(void)fclose(env_file);
Uunlink(filename);
goto ret_panic;
errno = ERRNO_EXPANDFAIL;
addr->transport_return = PANIC;
addr->message = string_sprintf("Expansion of \"%s\" (prefix for %s "
- "transport) failed", ob->message_prefix, tblock->name);
+ "transport) failed", ob->message_prefix, trname);
yield = DEFER;
}
else if (!transport_write_string(fd, "%s", prefix))
errno = ERRNO_EXPANDFAIL;
addr->transport_return = PANIC;
addr->message = string_sprintf("Expansion of \"%s\" (suffix for %s "
- "transport) failed", ob->message_suffix, tblock->name);
+ "transport) failed", ob->message_suffix, trname);
yield = DEFER;
}
else if (!transport_write_string(fd, "%s", suffix))
addr->transport_return = PANIC;
addr->message = string_sprintf("Expansion of \"%s\" "
"(directory_file for %s transport) failed: %s",
- ob->dirfilename, tblock->name, expand_string_message);
+ ob->dirfilename, trname, expand_string_message);
goto RETURN;
}
tainted_ret_panic:
addr->message = string_sprintf("Tainted '%s' (file or directory "
- "name for %s transport) not permitted", path, tblock->name);
+ "name for %s transport) not permitted", path, trname);
ret_panic:
addr->transport_return = PANIC;
return FALSE;
/* The main and init entry points for the transport */
+extern void appendfile_transport_init(driver_instance *);
extern BOOL appendfile_transport_entry(transport_instance *, address_item *);
-extern void appendfile_transport_init(transport_instance *);
/* Function that is shared with tf_maildir.c */
/* Dummy values */
autoreply_transport_options_block autoreply_transport_option_defaults = {0};
-void autoreply_transport_init(transport_instance *tblock) {}
+void autoreply_transport_init(driver_instance *tblock) {}
BOOL autoreply_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
#else /*!MACRO_PREDEF*/
to be set up. */
void
-autoreply_transport_init(transport_instance *tblock)
+autoreply_transport_init(driver_instance * t)
{
+transport_instance * tblock = (transport_instance *)t;
/*
autoreply_transport_options_block *ob =
(autoreply_transport_options_block *)(tblock->options_block);
if (tblock->uid_set && !tblock->gid_set && tblock->expand_gid == NULL)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
- "user set without group for the %s transport", tblock->name);
+ "user set without group for the %s transport", t->name);
}
NULL otherwise
*/
-static uschar *
-checkexpand(uschar *s, address_item *addr, uschar *name, int type)
+static const uschar *
+checkexpand(const uschar * s, address_item * addr, const uschar * name,
+ int type)
{
-uschar *ss = expand_string(s);
+const uschar * ss = expand_cstring(s);
if (!ss)
{
return NULL;
}
-if (type != cke_text) for (uschar * t = ss; *t != 0; t++)
+if (type != cke_text) for (const uschar * t = ss; *t; t++)
{
int c = *t;
const uschar * sp;
Returns: edited replacement address list, or NULL, or original
*/
-static uschar *
-check_never_mail(uschar * list, const uschar * never_mail)
+static const uschar *
+check_never_mail(const uschar * list, const uschar * never_mail)
{
rmark reset_point = store_mark();
uschar * newlist = string_copy(list);
transport_instance *tblock, /* data for this instantiation */
address_item *addr) /* address we are working on */
{
+autoreply_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
int fd, pid, rc;
int cache_fd = -1;
int cache_size = 0;
int add_size = 0;
EXIM_DB * dbm_file = NULL;
BOOL file_expand, return_message;
-uschar *from, *reply_to, *to, *cc, *bcc, *subject, *headers, *text, *file;
-uschar *logfile, *oncelog;
-uschar *cache_buff = NULL;
-uschar *cache_time = NULL;
-uschar *message_id = NULL;
-header_line *h;
+const uschar * from, * reply_to, * to, * cc, * bcc, * subject, * headers;
+const uschar * text, * file, * logfile, * oncelog;
+uschar * cache_buff = NULL, * cache_time = NULL, * message_id = NULL;
+header_line * h;
time_t now = time(NULL);
time_t once_repeat_sec = 0;
FILE *fp;
FILE *ff = NULL;
-autoreply_transport_options_block *ob =
- (autoreply_transport_options_block *)(tblock->options_block);
-
-DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
+DEBUG(D_transport) debug_printf("%s transport entered\n", trname);
/* Set up for the good case */
}
else
{
- uschar * oncerepeat;
+ const uschar * oncerepeat;
DEBUG(D_transport) debug_printf("taking data from transport\n");
GET_OPTION("once_repeat"); oncerepeat = ob->once_repeat;
file_expand = ob->file_expand;
return_message = ob->return_message;
- if ( from && !(from = checkexpand(from, addr, tblock->name, cke_hdr))
- || reply_to && !(reply_to = checkexpand(reply_to, addr, tblock->name, cke_hdr))
- || to && !(to = checkexpand(to, addr, tblock->name, cke_hdr))
- || cc && !(cc = checkexpand(cc, addr, tblock->name, cke_hdr))
- || bcc && !(bcc = checkexpand(bcc, addr, tblock->name, cke_hdr))
- || subject && !(subject = checkexpand(subject, addr, tblock->name, cke_hdr))
- || headers && !(headers = checkexpand(headers, addr, tblock->name, cke_text))
- || text && !(text = checkexpand(text, addr, tblock->name, cke_text))
- || file && !(file = checkexpand(file, addr, tblock->name, cke_file))
- || logfile && !(logfile = checkexpand(logfile, addr, tblock->name, cke_file))
- || oncelog && !(oncelog = checkexpand(oncelog, addr, tblock->name, cke_file))
- || oncerepeat && !(oncerepeat = checkexpand(oncerepeat, addr, tblock->name, cke_file))
+ if ( from && !(from = checkexpand(from, addr, trname, cke_hdr))
+ || reply_to && !(reply_to = checkexpand(reply_to, addr, trname, cke_hdr))
+ || to && !(to = checkexpand(to, addr, trname, cke_hdr))
+ || cc && !(cc = checkexpand(cc, addr, trname, cke_hdr))
+ || bcc && !(bcc = checkexpand(bcc, addr, trname, cke_hdr))
+ || subject && !(subject = checkexpand(subject, addr, trname, cke_hdr))
+ || headers && !(headers = checkexpand(headers, addr, trname, cke_text))
+ || text && !(text = checkexpand(text, addr, trname, cke_text))
+ || file && !(file = checkexpand(file, addr, trname, cke_file))
+ || logfile && !(logfile = checkexpand(logfile, addr, trname, cke_file))
+ || oncelog && !(oncelog = checkexpand(oncelog, addr, trname, cke_file))
+ || oncerepeat && !(oncerepeat = checkexpand(oncerepeat, addr, trname, cke_file))
)
return FALSE;
{
addr->transport_return = FAIL;
addr->message = string_sprintf("Invalid time value \"%s\" for "
- "\"once_repeat\" in %s transport", oncerepeat, tblock->name);
+ "\"once_repeat\" in %s transport", oncerepeat, trname);
return FALSE;
}
}
if (ob->never_mail)
{
- const uschar *never_mail = expand_string(ob->never_mail);
+ const uschar * never_mail = expand_string(ob->never_mail);
if (!never_mail)
{
addr->transport_return = FAIL;
addr->message = string_sprintf("Failed to expand \"%s\" for "
- "\"never_mail\" in %s transport", ob->never_mail, tblock->name);
+ "\"never_mail\" in %s transport", ob->never_mail, trname);
return FALSE;
}
{
DEBUG(D_transport)
debug_printf("*** delivery by %s transport bypassed by -N option\n",
- tblock->name);
+ trname);
return FALSE;
}
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
addr->message = string_sprintf("Tainted '%s' (once file for %s transport)"
- " not permitted", oncelog, tblock->name);
+ " not permitted", oncelog, trname);
goto END_OFF;
}
addr->basic_errno = errno;
addr->message = string_sprintf("Failed to %s \"once\" file %s when "
"sending message from %s transport: %s",
- cache_fd < 0 ? "open" : "stat", oncelog, tblock->name, strerror(errno));
+ cache_fd < 0 ? "open" : "stat", oncelog, trname, strerror(errno));
goto END_OFF;
}
addr->transport_return = DEFER;
addr->basic_errno = errno;
addr->message = string_sprintf("Failed to open %s file %s when sending "
- "message from %s transport: %s", EXIM_DBTYPE, oncelog, tblock->name,
+ "message from %s transport: %s", EXIM_DBTYPE, oncelog, trname,
strerror(errno));
goto END_OFF;
}
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
addr->message = string_sprintf("Tainted '%s' (logfile for %s transport)"
- " not permitted", logfile, tblock->name);
+ " not permitted", logfile, trname);
goto END_OFF;
}
if(write(log_fd, log_buffer, ptr - log_buffer) != ptr-log_buffer
|| close(log_fd))
DEBUG(D_transport) debug_printf("Problem writing log file %s for %s "
- "transport\n", logfile, tblock->name);
+ "transport\n", logfile, trname);
}
goto END_OFF;
}
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
addr->message = string_sprintf("Tainted '%s' (file for %s transport)"
- " not permitted", file, tblock->name);
+ " not permitted", file, trname);
return FALSE;
}
if (!(ff = Ufopen(file, "rb")) && !ob->file_optional)
addr->transport_return = DEFER;
addr->basic_errno = errno;
addr->message = string_sprintf("Failed to open file %s when sending "
- "message from %s transport: %s", file, tblock->name, strerror(errno));
+ "message from %s transport: %s", file, trname, strerror(errno));
return FALSE;
}
}
addr->transport_return = DEFER;
addr->basic_errno = errno;
addr->message = string_sprintf("Failed to create child process to send "
- "message from %s transport: %s", tblock->name, strerror(errno));
+ "message from %s transport: %s", trname, strerror(errno));
DEBUG(D_transport) debug_printf("%s\n", addr->message);
if (dbm_file) exim_dbclose(dbm_file);
return FALSE;
memcpy(cache_time, &now, sizeof(time_t));
if(write(cache_fd, from, size) != size)
DEBUG(D_transport) debug_printf("Problem writing cache file %s for %s "
- "transport\n", oncelog, tblock->name);
+ "transport\n", oncelog, trname);
}
}
EXIM_DATUM key_datum, value_datum;
exim_datum_init(&key_datum); /* Some DBM libraries need to have */
exim_datum_init(&value_datum); /* cleared datums. */
- exim_datum_data_set(&key_datum, to);
+ exim_datum_data_set(&key_datum, US to); /*XXX rely on dbput not modifying */
exim_datum_size_set(&key_datum, Ustrlen(to) + 1);
/* Many OS define the datum value, sensibly, as a void *. However, there
if (rc == EXIT_NORECIPIENTS)
{
DEBUG(D_any) debug_printf("%s transport: message contained no recipients\n",
- tblock->name);
+ trname);
}
else
{
addr->transport_return = DEFER;
addr->message = string_sprintf("Failed to send message from %s "
- "transport (%d)", tblock->name, rc);
+ "transport (%d)", trname, rc);
goto END_OFF;
}
g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " %s\n", headers);
if(write(log_fd, g->s, g->ptr) != g->ptr || close(log_fd))
DEBUG(D_transport) debug_printf("Problem writing log file %s for %s "
- "transport\n", logfile, tblock->name);
+ "transport\n", logfile, trname);
}
else DEBUG(D_transport) debug_printf("Failed to open log file %s for %s "
- "transport: %s\n", logfile, tblock->name, strerror(errno));
+ "transport: %s\n", logfile, trname, strerror(errno));
}
END_OFF:
if (dbm_file) exim_dbclose(dbm_file);
if (cache_fd > 0) (void)close(cache_fd);
-DEBUG(D_transport) debug_printf("%s transport succeeded\n", tblock->name);
+DEBUG(D_transport) debug_printf("%s transport succeeded\n", trname);
return FALSE;
}
/* The main and init entry points for the transport */
+extern void autoreply_transport_init(driver_instance *);
extern BOOL autoreply_transport_entry(transport_instance *, address_item *);
-extern void autoreply_transport_init(transport_instance *);
/* End of transports/autoreply.h */
/* Dummy values */
lmtp_transport_options_block lmtp_transport_option_defaults = {0};
-void lmtp_transport_init(transport_instance *tblock) {}
+void lmtp_transport_init(driver_instance *tblock) {}
BOOL lmtp_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
#else /*!MACRO_PREDEF*/
to be set up. */
void
-lmtp_transport_init(transport_instance *tblock)
+lmtp_transport_init(driver_instance * t)
{
-lmtp_transport_options_block *ob =
- (lmtp_transport_options_block *)(tblock->options_block);
+transport_instance * tblock = (transport_instance *)t;
+lmtp_transport_options_block * ob = t->options_block;
/* Either the command field or the socket field must be set */
if ((ob->cmd == NULL) == (ob->skt == NULL))
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"one (and only one) of command or socket must be set for the %s transport",
- tblock->name);
+ tblock->drinst.name);
/* If a fixed uid field is set, then a gid field must also be set. */
if (tblock->uid_set && !tblock->gid_set && tblock->expand_gid == NULL)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
- "user set without group for the %s transport", tblock->name);
+ "user set without group for the %s transport", tblock->drinst.name);
/* Set up the bitwise options for transport_write_message from the various
driver options. Only one of body_only and headers_only can be set. */
ob->options |=
- (tblock->body_only? topt_no_headers : 0) |
- (tblock->headers_only? topt_no_body : 0) |
- (tblock->return_path_add? topt_add_return_path : 0) |
- (tblock->delivery_date_add? topt_add_delivery_date : 0) |
- (tblock->envelope_to_add? topt_add_envelope_to : 0) |
+ (tblock->body_only ? topt_no_headers : 0) |
+ (tblock->headers_only ? topt_no_body : 0) |
+ (tblock->return_path_add ? topt_add_return_path : 0) |
+ (tblock->delivery_date_add ? topt_add_delivery_date : 0) |
+ (tblock->envelope_to_add ? topt_add_envelope_to : 0) |
topt_use_crlf | topt_end_dot;
}
transport_instance *tblock, /* data for this instantiation */
address_item *addrlist) /* address(es) we are working on */
{
+lmtp_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
pid_t pid = 0;
FILE *out;
-lmtp_transport_options_block *ob =
- (lmtp_transport_options_block *)(tblock->options_block);
struct sockaddr_un sockun; /* don't call this "sun" ! */
int timeout = ob->timeout;
int fd_in = -1, fd_out = -1;
const uschar **argv;
uschar buffer[256];
-DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
+DEBUG(D_transport) debug_printf("%s transport entered\n", trname);
/* Initialization ensures that either a command or a socket is specified, but
not both. When a command is specified, call the common function for creating an
if (ob->cmd)
{
DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
- sprintf(CS buffer, "%.50s transport", tblock->name);
+ sprintf(CS buffer, "%.50s transport", trname);
if (!transport_set_up_command(&argv, ob->cmd, TSUC_EXPAND_ARGS, PANIC,
addrlist, buffer, NULL))
return FALSE;
US"lmtp-tpt-cmd")) < 0)
{
addrlist->message = string_sprintf(
- "Failed to create child process for %s transport: %s", tblock->name,
+ "Failed to create child process for %s transport: %s", trname,
strerror(errno));
return FALSE;
}
if (!(sockname = expand_string(ob->skt)))
{
addrlist->message = string_sprintf("Expansion of \"%s\" (socket setting "
- "for %s transport) failed: %s", ob->skt, tblock->name,
+ "for %s transport) failed: %s", ob->skt, trname,
expand_string_message);
return FALSE;
}
{
addrlist->message = string_sprintf(
"Failed to create socket %s for %s transport: %s",
- ob->skt, tblock->name, strerror(errno));
+ ob->skt, trname, strerror(errno));
return FALSE;
}
{
addrlist->message = string_sprintf(
"Failed to connect to socket %s for %s transport: %s",
- sockun.sun_path, tblock->name, strerror(errno));
+ sockun.sun_path, trname, strerror(errno));
return FALSE;
}
}
if (fd_out >= 0) (void)fclose(out);
DEBUG(D_transport)
- debug_printf("%s transport yields %d\n", tblock->name, yield);
+ debug_printf("%s transport yields %d\n", trname, yield);
return yield;
MINUS_N:
DEBUG(D_transport)
debug_printf("*** delivery by %s transport bypassed by -N option",
- tblock->name);
+ trname);
addrlist->transport_return = OK;
return FALSE;
}
/* The main and init entry points for the transport */
+extern void lmtp_transport_init(driver_instance *);
extern BOOL lmtp_transport_entry(transport_instance *, address_item *);
-extern void lmtp_transport_init(transport_instance *);
/* End of transports/lmtp.h */
/* Dummy values */
pipe_transport_options_block pipe_transport_option_defaults = {0};
-void pipe_transport_init(transport_instance *tblock) {}
+void pipe_transport_init(driver_instance *tblock) {}
BOOL pipe_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
#else /*!MACRO_PREDEF*/
pipe_transport_setup(transport_instance *tblock, address_item *addrlist,
transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg)
{
-pipe_transport_options_block *ob =
- (pipe_transport_options_block *)(tblock->options_block);
+pipe_transport_options_block * ob = tblock->drinst.options_block;
#ifdef HAVE_SETCLASSRESOURCES
if (ob->use_classresources)
to be set up. */
void
-pipe_transport_init(transport_instance *tblock)
+pipe_transport_init(driver_instance * t)
{
-pipe_transport_options_block *ob =
- (pipe_transport_options_block *)(tblock->options_block);
+transport_instance * tblock = (transport_instance *)t;
+const uschar * trname = t->name;
+pipe_transport_options_block * ob = t->options_block;
/* Set up the setup entry point, to be called in the privileged state */
tblock->expand_uid != NULL || tblock->expand_gid != NULL))
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"both pipe_as_creator and an explicit uid/gid are set for the %s "
- "transport", tblock->name);
+ "transport", trname);
/* If a fixed uid field is set, then a gid field must also be set. */
if (tblock->uid_set && !tblock->gid_set && tblock->expand_gid == NULL)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
- "user set without group for the %s transport", tblock->name);
+ "user set without group for the %s transport", trname);
/* Temp_errors must consist only of digits and colons, but there can be
spaces round the colons, so allow them too. */
if (ob->temp_errors[p] != 0)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"temp_errors must be a list of numbers or an asterisk for the %s "
- "transport", tblock->name);
+ "transport", trname);
}
/* Only one of return_output/return_fail_output or log_output/log_fail_output
if (tblock->return_output && tblock->return_fail_output)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"both return_output and return_fail_output set for %s transport",
- tblock->name);
+ trname);
if (tblock->log_output && tblock->log_fail_output)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"both log_output and log_fail_output set for the %s transport",
- tblock->name);
+ trname);
/* If batch SMTP is set, force the check and escape strings, and arrange that
headers are also escaped. */
if (ob->restrict_to_path && ob->use_shell)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"both restrict_to_path and use_shell set for %s transport",
- tblock->name);
+ trname);
/* The allow_commands and use_shell options are incompatible */
if (ob->allow_commands && ob->use_shell)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"both allow_commands and use_shell set for %s transport",
- tblock->name);
+ trname);
/* Set up the bitwise options for transport_write_message from the various
driver options. Only one of body_only and headers_only can be set. */
static BOOL
set_up_direct_command(const uschar *** argvptr, const uschar * cmd,
- BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname,
- pipe_transport_options_block * ob)
+ BOOL expand_arguments, int expand_fail, address_item * addr,
+ const uschar * tname, pipe_transport_options_block * ob)
{
BOOL permitted = FALSE;
const uschar **argv;
static BOOL
set_up_shell_command(const uschar *** argvptr, const uschar * cmd,
- BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname)
+ BOOL expand_arguments, int expand_fail, address_item * addr,
+ const uschar * tname)
{
const uschar **argv;
transport_instance *tblock, /* data for this instantiation */
address_item *addr) /* address(es) we are working on */
{
+pipe_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
pid_t pid, outpid;
int fd_in, fd_out, rc;
-int envcount = 0;
-int envsep = 0;
-int expand_fail;
-pipe_transport_options_block *ob =
- (pipe_transport_options_block *)(tblock->options_block);
-int timeout = ob->timeout;
-BOOL written_ok = FALSE;
-BOOL expand_arguments;
+int envcount = 0, envsep = 0, expand_fail, timeout = ob->timeout;
+BOOL written_ok = FALSE, expand_arguments;
const uschar ** argv;
uschar * envp[50];
-const uschar * envlist = ob->environment;
-const uschar * cmd;
+const uschar * envlist = ob->environment, * cmd;
uschar * ss;
uschar * eol = ob->use_crlf ? US"\r\n" : US"\n";
transport_ctx tctx = {
ob->options | topt_not_socket /* set at initialization time */
};
-DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
+DEBUG(D_transport) debug_printf("%s transport entered\n", trname);
/* Set up for the good case */
{
addr->transport_return = DEFER;
addr->message = string_sprintf("no command specified for %s transport",
- tblock->name);
+ trname);
return FALSE;
}
if (is_tainted(cmd))
{
DEBUG(D_transport) debug_printf("cmd '%s' is tainted\n", cmd);
addr->message = string_sprintf("Tainted '%s' (command "
- "for %s transport) not permitted", cmd, tblock->name);
+ "for %s transport) not permitted", cmd, trname);
addr->transport_return = PANIC;
return FALSE;
}
if (ob->use_shell)
{
if (!set_up_shell_command(&argv, cmd, expand_arguments, expand_fail, addr,
- tblock->name)) return FALSE;
+ trname)) return FALSE;
}
else if (!set_up_direct_command(&argv, cmd, expand_arguments, expand_fail, addr,
- tblock->name, ob)) return FALSE;
+ trname, ob)) return FALSE;
expand_nmax = -1; /* Reset */
filter_thisaddress = NULL;
{
addr->transport_return = DEFER;
addr->message = string_sprintf("failed to expand string \"%s\" "
- "for %s transport: %s", ob->environment, tblock->name,
+ "for %s transport: %s", ob->environment, trname,
expand_string_message);
return FALSE;
}
addr->transport_return = DEFER;
addr->basic_errno = E2BIG;
addr->message = string_sprintf("too many environment settings for "
- "%s transport", tblock->name);
+ "%s transport", trname);
return FALSE;
}
envp[envcount++] = string_copy(ss);
{
DEBUG(D_transport)
debug_printf("*** delivery by %s transport bypassed by -N option",
- tblock->name);
+ trname);
return FALSE;
}
{
addr->transport_return = DEFER;
addr->message = string_sprintf(
- "Failed to create child process for %s transport: %s", tblock->name,
+ "Failed to create child process for %s transport: %s", trname,
strerror(errno));
return FALSE;
}
addr->transport_return = DEFER;
addr->message = string_sprintf(
"Failed to create process for handling output in %s transport",
- tblock->name);
+ trname);
(void)close(fd_in);
(void)close(fd_out);
return FALSE;
{
addr->transport_return = f.search_find_defer? DEFER : PANIC;
addr->message = string_sprintf("Expansion of \"%s\" (prefix for %s "
- "transport) failed: %s", ob->message_prefix, tblock->name,
+ "transport) failed: %s", ob->message_prefix, trname,
expand_string_message);
return FALSE;
}
{
addr->transport_return = f.search_find_defer? DEFER : PANIC;
addr->message = string_sprintf("Expansion of \"%s\" (suffix for %s "
- "transport) failed: %s", ob->message_suffix, tblock->name,
+ "transport) failed: %s", ob->message_suffix, trname,
expand_string_message);
return FALSE;
}
{
addr->transport_return = PANIC;
addr->message = string_sprintf("Wait() failed for child process of %s "
- "transport: %s%s", tblock->name, strerror(errno), tmsg);
+ "transport: %s%s", trname, strerror(errno), tmsg);
}
/* Since the transport_filter timed out we assume it has sent the child process
addr->transport_return = DEFER;
addr->special_action = SPECIAL_FREEZE;
addr->message = string_sprintf("Child process of %s transport (running "
- "command \"%s\") was terminated by signal %d (%s)%s", tblock->name, cmd,
+ "command \"%s\") was terminated by signal %d (%s)%s", trname, cmd,
-rc, os_strsignal(-rc), tmsg);
}
else if (!ob->ignore_status)
{
addr->transport_return = FAIL;
addr->message = string_sprintf("Child process of %s transport (running "
- "command \"%s\") was terminated by signal %d (%s)%s", tblock->name, cmd,
+ "command \"%s\") was terminated by signal %d (%s)%s", trname, cmd,
-rc, os_strsignal(-rc), tmsg);
}
}
doesn't have to be brilliantly efficient - it is an error situation. */
addr->message = string_sprintf("Child process of %s transport returned "
- "%d", tblock->name, rc);
+ "%d", trname, rc);
g = string_cat(NULL, addr->message);
/* If the return code is > 128, it often means that a shell command
while (wait(&rc) >= 0);
-DEBUG(D_transport) debug_printf("%s transport yielded %d\n", tblock->name,
+DEBUG(D_transport) debug_printf("%s transport yielded %d\n", trname,
addr->transport_return);
/* If there has been a problem, the message in addr->message contains details
/* The main and init entry points for the transport */
+extern void pipe_transport_init(driver_instance *);
extern BOOL pipe_transport_entry(transport_instance *, address_item *);
-extern void pipe_transport_init(transport_instance *);
/* End of transports/pipe.h */
/* Dummy values */
queuefile_transport_options_block queuefile_transport_option_defaults = {0};
-void queuefile_transport_init(transport_instance *tblock) {}
+void queuefile_transport_init(driver_instance *tblock) {}
BOOL queuefile_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
#else /*!MACRO_PREDEF*/
* Initialization entry point *
*************************************************/
-void queuefile_transport_init(transport_instance *tblock)
+void queuefile_transport_init(driver_instance * t)
{
-queuefile_transport_options_block *ob =
- (queuefile_transport_options_block *) tblock->options_block;
+transport_instance * tblock = (transport_instance *)t;
+queuefile_transport_options_block * ob = t->options_block;
if (!ob->dirname)
log_write(0, LOG_PANIC_DIE | LOG_CONFIG,
- "directory must be set for the %s transport", tblock->name);
+ "directory must be set for the %s transport", t->name);
}
/* This function will copy from a file to another
copy_spool_files(transport_instance * tb, address_item * addr,
const uschar * dstpath, int sdfd, int ddfd, BOOL link_file, int srcfd)
{
+const uschar * trname = tb->drinst.name;
BOOL is_hdr_file = srcfd < 0;
const uschar * suffix = srcfd < 0 ? US"H" : US"D";
int dstfd;
if (link_file)
{
DEBUG(D_transport) debug_printf("%s transport, linking %s => %s\n",
- tb->name, srcpath, dstpath);
+ trname, srcpath, dstpath);
if (linkat(sdfd, CCS filename, ddfd, CCS filename, 0) >= 0)
return TRUE;
else /* use data copy */
{
DEBUG(D_transport) debug_printf("%s transport, copying %s => %s\n",
- tb->name, srcpath, dstpath);
+ trname, srcpath, dstpath);
if ( (s = dstpath,
(dstfd = exim_openat4(ddfd, CCS filename, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE))
addr->basic_errno = errno;
addr->message = string_sprintf("%s transport %s file: %s failed with error: %s",
- tb->name, op, s, strerror(errno));
+ trname, op, s, strerror(errno));
addr->transport_return = DEFER;
return FALSE;
}
BOOL
queuefile_transport_entry(transport_instance * tblock, address_item * addr)
{
-queuefile_transport_options_block * ob =
- (queuefile_transport_options_block *) tblock->options_block;
+queuefile_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
BOOL can_link;
uschar * sourcedir = spool_dname(US"input", message_subdir);
uschar * s, * dstdir;
int ddfd = -1, sdfd = -1;
DEBUG(D_transport)
- debug_printf("%s transport entered\n", tblock->name);
+ debug_printf("%s transport entered\n", trname);
#ifndef O_DIRECTORY
# define O_DIRECTORY 0
if (!(dstdir = expand_string(ob->dirname)))
{
addr->message = string_sprintf("%s transport: failed to expand dirname option",
- tblock->name);
+ trname);
addr->transport_return = DEFER;
return FALSE;
}
{
addr->transport_return = PANIC;
addr->message = string_sprintf("%s transport directory: "
- "%s is not absolute", tblock->name, dstdir);
+ "%s is not absolute", trname, dstdir);
return FALSE;
}
addr->transport_return = PANIC;
addr->basic_errno = errno;
addr->message = string_sprintf("%s transport accessing directory: %s "
- "failed with error: %s", tblock->name, s, strerror(errno));
+ "failed with error: %s", trname, s, strerror(errno));
if (ddfd >= 0) (void) close(ddfd);
return FALSE;
}
addr->transport_return = PANIC;
addr->basic_errno = errno;
addr->message = string_sprintf("%s transport fstat on directory fd: "
- "%s failed with error: %s", tblock->name, s, strerror(errno));
+ "%s failed with error: %s", trname, s, strerror(errno));
goto RETURN;
}
can_link = (dstatbuf.st_dev == sstatbuf.st_dev);
{
DEBUG(D_transport)
debug_printf("*** delivery by %s transport bypassed by -N option\n",
- tblock->name);
+ trname);
addr->transport_return = OK;
goto RETURN;
}
/* Link or copy the header and data spool files */
DEBUG(D_transport)
- debug_printf("%s transport, copying header file\n", tblock->name);
+ debug_printf("%s transport, copying header file\n", trname);
if (!copy_spool_files(tblock, addr, dstdir, sdfd, ddfd, can_link, -1))
goto RETURN;
DEBUG(D_transport)
- debug_printf("%s transport, copying data file\n", tblock->name);
+ debug_printf("%s transport, copying data file\n", trname);
if (!copy_spool_files(tblock, addr, dstdir, sdfd, ddfd, can_link,
deliver_datafile))
{
DEBUG(D_transport)
debug_printf("%s transport, copying data file failed, "
- "unlinking the header file\n", tblock->name);
+ "unlinking the header file\n", trname);
Uunlink(string_sprintf("%s/%s-H", dstdir, message_id));
goto RETURN;
}
DEBUG(D_transport)
- debug_printf("%s transport succeeded\n", tblock->name);
+ debug_printf("%s transport succeeded\n", trname);
addr->transport_return = OK;
/* The main and init entry points for the transport */
+extern void queuefile_transport_init(driver_instance *);
extern BOOL queuefile_transport_entry(transport_instance *, address_item *);
-extern void queuefile_transport_init(transport_instance *);
/* End of transports/queuefile.h */
/* Dummy values */
smtp_transport_options_block smtp_transport_option_defaults = {0};
-void smtp_transport_init(transport_instance *tblock) {}
+void smtp_transport_init(driver_instance *tblock) {}
BOOL smtp_transport_entry(transport_instance *tblock, address_item *addr) {return FALSE;}
void smtp_transport_closedown(transport_instance *tblock) {}
smtp_transport_setup(transport_instance *tblock, address_item *addrlist,
transport_feedback *tf, uid_t uid, gid_t gid, uschar **errmsg)
{
-smtp_transport_options_block *ob = SOB tblock->options_block;
+smtp_transport_options_block * ob = tblock->drinst.options_block;
/* Pass back options if required. This interface is getting very messy. */
*/
void
-smtp_transport_init(transport_instance *tblock)
+smtp_transport_init(driver_instance * t)
{
-smtp_transport_options_block * ob = SOB tblock->options_block;
+transport_instance * tblock = (transport_instance *)t;
+smtp_transport_options_block * ob = t->options_block;
int old_pool = store_pool;
/* Retry_use_local_part defaults FALSE if unset */
ob->final_timeout <= 0)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"command, data, or final timeout value is zero for %s transport",
- tblock->name);
+ t->name);
/* If hosts_override is set and there are local hosts, set the global
flag that stops verify from showing router hosts. */
{
uschar * action = addr->transport->event_action;
const uschar * save_domain, * save_local;
-const uschar * save_rn;
-uschar * save_tn;
+const uschar * save_rn, * save_tn;
if (!action)
return;
event_defer_errno = addr->basic_errno;
router_name = addr->router->drinst.name;
-transport_name = addr->transport->name;
+transport_name = addr->transport->drinst.name;
deliver_domain = addr->domain;
deliver_localpart = addr->local_part;
static uschar *
smtp_local_identity(const uschar * sender, struct transport_instance * tblock)
{
+smtp_transport_options_block * ob = tblock->drinst.options_block;
address_item * addr1;
uschar * if1 = US"";
uschar * helo1 = US"";
#endif
const uschar * save_sender_address = sender_address;
uschar * local_identity = NULL;
-smtp_transport_options_block * ob = SOB tblock->options_block;
sender_address = sender;
smtp_chunk_cmd_callback(transport_ctx * tctx, unsigned chunk_size,
unsigned flags)
{
-smtp_transport_options_block * ob = SOB tctx->tblock->options_block;
+smtp_transport_options_block * ob = tctx->tblock->drinst.options_block;
smtp_context * sx = tctx->smtp_context;
int cmd_count = 0;
int prev_cmd_count;
int
smtp_setup_conn(smtp_context * sx, BOOL suppress_tls)
{
-smtp_transport_options_block * ob = sx->conn_args.tblock->options_block;
+smtp_transport_options_block * ob = sx->conn_args.tblock->drinst.options_block;
BOOL pass_message = FALSE;
uschar * message = NULL;
int yield = OK;
uschar *interface, transport_instance *tblock,
BOOL *message_defer, BOOL suppress_tls)
{
-smtp_transport_options_block * ob = SOB tblock->options_block;
+smtp_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
int yield = OK;
int save_errno;
int rc;
if (!transport_set_up_command(&transport_filter_argv,
tblock->filter_command, TSUC_EXPAND_ARGS, DEFER, addrlist,
- string_sprintf("%.50s transport filter", tblock->name), NULL))
+ string_sprintf("%.50s transport filter", trname), NULL))
{
set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
FALSE, &sx->delivery_start);
)
&&
#endif
- transport_check_waiting(tblock->name, host->name,
+ transport_check_waiting(trname, host->name,
tblock->connection_max_messages, continue_next_id,
(oicf)smtp_are_same_identities, (void*)&t_compare);
if (!tcw)
write error, as it may prove possible to update the spool file later. */
if (testflag(addr, af_homonym))
- sprintf(CS sx->buffer, "%.500s/%s\n", addr->unique + 3, tblock->name);
+ sprintf(CS sx->buffer, "%.500s/%s\n", addr->unique + 3, trname);
else
sprintf(CS sx->buffer, "%.500s\n", addr->unique);
if (addr->transport_return == OK)
{
if (testflag(addr, af_homonym))
- sprintf(CS sx->buffer, "%.500s/%s\n", addr->unique + 3, tblock->name);
+ sprintf(CS sx->buffer, "%.500s/%s\n", addr->unique + 3, trname);
else
sprintf(CS sx->buffer, "%.500s\n", addr->unique);
)
&&
#endif
- transport_check_waiting(tblock->name, host->name,
+ transport_check_waiting(trname, host->name,
sx->max_mail, continue_next_id,
(oicf)smtp_are_same_identities, (void*)&t_compare)
) )
*/
void
-smtp_transport_closedown(transport_instance *tblock)
+smtp_transport_closedown(transport_instance * tblock)
{
-smtp_transport_options_block * ob = SOB tblock->options_block;
+smtp_transport_options_block * ob = tblock->drinst.options_block;
client_conn_ctx cctx;
smtp_context sx = {0};
uschar buffer[256];
transport_instance * tblock, /* data for this instantiation */
address_item * addrlist) /* addresses we are working on */
{
+smtp_transport_options_block * ob = tblock->drinst.options_block;
+const uschar * trname = tblock->drinst.name;
int defport;
int hosts_defer = 0, hosts_fail = 0, hosts_looked_up = 0;
int hosts_retry = 0, hosts_serial = 0, hosts_total = 0, total_hosts_tried = 0;
BOOL expired = TRUE;
uschar * expanded_hosts = NULL, * pistring;
-uschar * tid = string_sprintf("%s transport", tblock->name);
-smtp_transport_options_block * ob = SOB tblock->options_block;
+uschar * tid = string_sprintf("%s transport", trname);
host_item * hostlist = addrlist->host_list, * host = NULL;
DEBUG(D_transport)
{
- debug_printf("%s transport entered\n", tblock->name);
+ debug_printf("%s transport entered\n", trname);
for (address_item * addr = addrlist; addr; addr = addr->next)
debug_printf(" %s\n", addr->address);
if (hostlist)
if (!ob->hosts)
{
addrlist->message = string_sprintf("%s transport called with no hosts set",
- tblock->name);
+ trname);
addrlist->transport_return = PANIC;
return FALSE; /* Only top address has status */
}
if (!(expanded_hosts = expand_string(s)))
{
addrlist->message = string_sprintf("failed to expand list of hosts "
- "\"%s\" in %s transport: %s", s, tblock->name, expand_string_message);
+ "\"%s\" in %s transport: %s", s, trname, expand_string_message);
addrlist->transport_return = f.search_find_defer ? DEFER : PANIC;
return FALSE; /* Only top address has status */
}
{
log_write(0, LOG_MAIN|LOG_PANIC,
"attempt to use tainted host list '%s' from '%s' in transport %s",
- s, ob->hosts, tblock->name);
+ s, ob->hosts, trname);
/* Avoid leaking info to an attacker */
addrlist->message = US"internal configuration error";
addrlist->transport_return = PANIC;
if (!hostlist)
{
addrlist->message =
- string_sprintf("%s transport has empty hosts setting", tblock->name);
+ string_sprintf("%s transport has empty hosts setting", trname);
addrlist->transport_return = PANIC;
return FALSE; /* Only top address has status */
}
{
addr->basic_errno = ERRNO_HOST_IS_LOCAL;
addr->message = string_sprintf("%s transport found host %s to be "
- "local", tblock->name, host->name);
+ "local", trname, host->name);
}
goto END_TRANSPORT;
}
If either of these retry records are actually read, the keys used are
returned to save recomputing them later. */
- if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+ if (exp_bool(addrlist, US"transport", trname, D_transport,
US"retry_include_ip_address", ob->retry_include_ip_address,
ob->expand_retry_include_ip_address, &incl_ip) != OK)
continue; /* with next host */
DEBUG(D_transport)
{
debug_printf("*** delivery by %s transport bypassed by -N option\n"
- "*** host and remaining hosts:\n", tblock->name);
+ "*** host and remaining hosts:\n", trname);
for (host_item * host2 = host; host2; host2 = host2->next)
debug_printf(" %s [%s]\n", host2->name,
host2->address ? host2->address : US"unset");
if (!retry_host_key)
{
BOOL incl_ip;
- if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+ if (exp_bool(addrlist, US"transport", trname, D_transport,
US"retry_include_ip_address", ob->retry_include_ip_address,
ob->expand_retry_include_ip_address, &incl_ip) != OK)
incl_ip = TRUE; /* error; use most-specific retry record */
if (!retry_message_key)
{
BOOL incl_ip;
- if (exp_bool(addrlist, US"transport", tblock->name, D_transport,
+ if (exp_bool(addrlist, US"transport", trname, D_transport,
US"retry_include_ip_address", ob->retry_include_ip_address,
ob->expand_retry_include_ip_address, &incl_ip) != OK)
incl_ip = TRUE; /* error; use most-specific retry record */
to create/update the per-transport wait-<transport_name> database. */
if (update_waiting && tblock->connection_max_messages != 1)
- transport_update_waiting(hostlist, tblock->name);
+ transport_update_waiting(hostlist, trname);
END_TRANSPORT:
-DEBUG(D_transport) debug_printf("Leaving %s transport\n", tblock->name);
+DEBUG(D_transport) debug_printf("Leaving %s transport\n", trname);
return TRUE; /* Each address has its status */
}
/* The main, init, and closedown entry points for the transport */
+extern void smtp_transport_init(driver_instance *);
extern BOOL smtp_transport_entry(transport_instance *, address_item *);
-extern void smtp_transport_init(transport_instance *);
extern void smtp_transport_closedown(transport_instance *);
socks_sock_connect(host_item * host, int host_af, int port, uschar * interface,
transport_instance * tb, int timeout)
{
-smtp_transport_options_block * ob =
- (smtp_transport_options_block *)tb->options_block;
-const uschar * proxy_list;
-const uschar * proxy_spec;
+smtp_transport_options_block * ob = tb->drinst.options_block;
+const uschar * proxy_list, * proxy_spec;
int sep = 0;
int fd;
time_t tmo;
if (!(proxy_list = expand_string(ob->socks_proxy)))
{
log_write(0, LOG_MAIN|LOG_PANIC, "Bad expansion for socks_proxy in %s",
- tb->name);
+ tb->drinst.name);
return -1;
}
deliver_host_address = host->address;
deliver_host_port = host->port;
deliver_domain = addr->domain;
- transport_name = addr->transport->name;
+ transport_name = addr->transport->drinst.name;
host_af = Ustrchr(host->address, ':') ? AF_INET6 : AF_INET;
HDEBUG(D_verify) debug_printf("cannot callout via null transport\n");
}
-else if (Ustrcmp(addr->transport->driver_name, "smtp") != 0)
+else if (Ustrcmp(addr->transport->drinst.driver_name, "smtp") != 0)
log_write(0, LOG_MAIN|LOG_PANIC|LOG_CONFIG_FOR, "callout transport '%s': %s is non-smtp",
- addr->transport->name, addr->transport->driver_name);
+ addr->transport->drinst.name, addr->transport->drinst.driver_name);
else
{
- smtp_transport_options_block *ob =
- (smtp_transport_options_block *)addr->transport->options_block;
+ smtp_transport_options_block * ob = addr->transport->drinst.options_block;
smtp_context * sx = NULL;
/* The information wasn't available in the cache, so we have to do a real
deliver_host_address = host->address;
deliver_host_port = host->port;
deliver_domain = addr->domain;
- transport_name = addr->transport->name;
+ transport_name = addr->transport->drinst.name;
GET_OPTION("interface");
if ( !smtp_get_interface(tf->interface, host_af, addr, &interface,
/* We assume no buffer in use in the outblock */
cutthrough.cctx = sx->cctx;
cutthrough.nrcpt = 1;
- cutthrough.transport = addr->transport->name;
+ cutthrough.transport = addr->transport->drinst.name;
cutthrough.interface = interface;
cutthrough.snd_port = sending_port;
cutthrough.peer_options = smtp_peer_options;
fprintf(fp, "\n*** Error in setting up pipe, file, or autoreply:\n"
"%s\n", addr->message);
else if (allow)
- fprintf(fp, "\n transport = %s\n", addr->transport->name);
+ fprintf(fp, "\n transport = %s\n", addr->transport->drinst.name);
else
fprintf(fp, " *** forbidden ***\n");
}
sending a message to this address. */
if ((tp = addr->transport))
- if (!tp->info->local)
+ {
+ transport_info * ti = tp->drinst.info;
+ if (!ti->local)
{
(void)(tp->setup)(tp, addr, &tf, 0, 0, NULL);
{
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand list of hosts "
"\"%s\" in %s transport for callout: %s", tf.hosts,
- tp->name, expand_string_message);
+ tp->drinst.name, expand_string_message);
}
else
{
else
{
const dnssec_domains * dsp = NULL;
- if (Ustrcmp(tp->driver_name, "smtp") == 0)
+ if (Ustrcmp(tp->drinst.driver_name, "smtp") == 0)
{
- smtp_transport_options_block * ob =
- (smtp_transport_options_block *) tp->options_block;
+ smtp_transport_options_block * ob = tp->drinst.options_block;
dsp = &ob->dnssec;
}
}
}
else if ( options & vopt_quota
- && Ustrcmp(tp->driver_name, "appendfile") == 0)
+ && Ustrcmp(tp->drinst.driver_name, "appendfile") == 0)
local_verify = TRUE;
+ }
/* Can only do a callout if we have at least one host! If the callout
fails, it will have set ${sender,recipient}_verify_failure. */
/* Show router, and transport */
fprintf(fp, "router = %s, transport = %s\n",
- addr->router->drinst.name, tp ? tp->name : US"unset");
+ addr->router->drinst.name, tp ? tp->drinst.name : US"unset");
/* Show any hosts that are set up by a router unless the transport
is going to override them; fiddle a bit to get a nice format. */
if (addr->host_list && tp && !tp->overrides_hosts)
{
+ transport_info * ti = tp->drinst.info;
int maxlen = 0;
int maxaddlen = 0;
for (host_item * h = addr->host_list; h; h = h->next)
if (h->address)
fprintf(fp, "[%s%-*c", h->address, maxaddlen+1 - Ustrlen(h->address), ']');
- else if (tp->info->local)
+ else if (ti->local)
fprintf(fp, " %-*s ", maxaddlen, ""); /* Omit [unknown] for local */
else
fprintf(fp, "[%s%-*c", "unknown", maxaddlen+1 - 7, ']');