X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/13a4b4c1810a1a9f3c956f1e92807a0d86c6f5bf..HEAD:/src/src/transports/lmtp.c diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index 32c57166c..1bff274c1 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -2,11 +2,15 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" +#ifdef TRANSPORT_LMTP /* Remainder of file */ + #include "lmtp.h" #define PENDING_OK 256 @@ -45,7 +49,7 @@ int lmtp_transport_options_count = /* 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*/ @@ -72,33 +76,33 @@ enable consistency checks to be done, or anything else that needs 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; } @@ -239,7 +243,7 @@ if (!string_vformat(&gs, SVFMT_TAINT_NOCHK, CS format, ap)) return FALSE; } va_end(ap); -DEBUG(D_transport|D_v) debug_printf(" LMTP>> %s", string_from_gstring(&gs)); +DEBUG(D_transport|D_v) debug_printf(" LMTP>> %Y", &gs); rc = write(fd, gs.s, gs.ptr); gs.ptr -= 2; string_from_gstring(&gs); /* remove \r\n for debug and error message */ if (rc > 0) return TRUE; @@ -463,10 +467,10 @@ lmtp_transport_entry( 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; @@ -478,7 +482,7 @@ uschar *sockname = NULL; 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 @@ -487,9 +491,9 @@ argument list and expanding the items. */ if (ob->cmd) { DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd); - sprintf(CS buffer, "%.50s transport", tblock->name); - if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, buffer, - NULL)) + sprintf(CS buffer, "%.50s transport", trname); + if (!transport_set_up_command(&argv, ob->cmd, TSUC_EXPAND_ARGS, PANIC, + addrlist, buffer, NULL)) return FALSE; /* If the -N option is set, can't do any more. Presume all has gone well. */ @@ -500,10 +504,11 @@ if (ob->cmd) uid/gid and current directory. Request that the new process be a process group leader, so we can kill it and all its children on an error. */ - if ((pid = child_open(USS argv, NULL, 0, &fd_in, &fd_out, TRUE)) < 0) + if ((pid = child_open(USS argv, NULL, 0, &fd_in, &fd_out, TRUE, + 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; } @@ -514,11 +519,10 @@ leader, so we can kill it and all its children on an error. */ else { DEBUG(D_transport) debug_printf("using socket %s\n", ob->skt); - sockname = expand_string(ob->skt); - if (sockname == NULL) + 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; } @@ -526,7 +530,7 @@ else { 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; } @@ -540,7 +544,7 @@ else { 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; } } @@ -557,23 +561,23 @@ allows for message+recipient checks after the message has been received. */ /* First thing is to wait for an initial greeting. */ Ustrcpy(big_buffer, US"initial connection"); -if (!lmtp_read_response(out, buffer, sizeof(buffer), '2', - timeout)) goto RESPONSE_FAILED; +if (!lmtp_read_response(out, buffer, sizeof(buffer), '2', timeout)) + goto RESPONSE_FAILED; /* Next, we send a LHLO command, and expect a positive response */ -if (!lmtp_write_command(fd_in, "%s %s\r\n", "LHLO", - primary_hostname)) goto WRITE_FAILED; +if (!lmtp_write_command(fd_in, "%s %s\r\n", "LHLO", primary_hostname)) + goto WRITE_FAILED; -if (!lmtp_read_response(out, buffer, sizeof(buffer), '2', - timeout)) goto RESPONSE_FAILED; +if (!lmtp_read_response(out, buffer, sizeof(buffer), '2', timeout)) + goto RESPONSE_FAILED; /* If the ignore_quota option is set, note whether the server supports the IGNOREQUOTA option, and if so, set an appropriate addition for RCPT. */ if (ob->ignore_quota) - igquotstr = (pcre_exec(regex_IGNOREQUOTA, NULL, CS buffer, - Ustrlen(CS buffer), 0, PCRE_EOPT, NULL, 0) >= 0)? US" IGNOREQUOTA" : US""; + igquotstr = regex_match(regex_IGNOREQUOTA, buffer, -1, NULL) + ? US" IGNOREQUOTA" : US""; /* Now the envelope sender */ @@ -791,7 +795,7 @@ if (fd_in >= 0) (void)close(fd_in); 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; @@ -799,10 +803,36 @@ 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; } + + + +# ifdef DYNLOOKUP +# define lmtp_transport_info _transport_info +# endif + +transport_info lmtp_transport_info = { +.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, +# ifdef DYNLOOKUP + .dyn_magic = TRANSPORT_MAGIC, +# endif + }, +.code = lmtp_transport_entry, +.tidyup = NULL, +.closedown = NULL, +.local = TRUE +}; + #endif /*!MACRO_PREDEF*/ +#endif /*TRANSPORT_LMTP*/ /* End of transport/lmtp.c */