X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/fbe8578a39505c146223ffcf2c63a5ba8bb0d9a4..dd19ce4f24eec64177cdcfcf294b8efbb631a24b:/src/src/smtp_in.c diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index ee248c517..7cb966f24 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3,7 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 */ +/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for handling an incoming SMTP call. */ @@ -346,8 +346,6 @@ static BOOL wouldblock_reading(void) { int fd, rc; -fd_set fds; -struct timeval tzero = {.tv_sec = 0, .tv_usec = 0}; #ifndef DISABLE_TLS if (tls_in.active.sock >= 0) @@ -358,9 +356,7 @@ if (smtp_inptr < smtp_inend) return FALSE; fd = fileno(smtp_in); -FD_ZERO(&fds); -FD_SET(fd, &fds); -rc = select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tzero); +rc = poll_one_fd(fd, POLLIN, 0); if (rc <= 0) return TRUE; /* Not ready to read */ rc = smtp_getc(GETC_BUFFER_UNLIMITED); @@ -563,6 +559,12 @@ if (smtp_inptr >= smtp_inend) return *smtp_inptr++; } +BOOL +smtp_hasc(void) +{ +return smtp_inptr < smtp_inend; +} + uschar * smtp_getbuf(unsigned * len) { @@ -581,12 +583,12 @@ return buf; } void -smtp_get_cache(void) +smtp_get_cache(unsigned lim) { #ifndef DISABLE_DKIM int n = smtp_inend - smtp_inptr; -if (chunking_state == CHUNKING_LAST && chunking_data_left < n) - n = chunking_data_left; +if (n > lim) + n = lim; if (n > 0) dkim_exim_verify_feed(smtp_inptr, n); #endif @@ -661,7 +663,9 @@ for(;;) if (chunking_state == CHUNKING_LAST) { #ifndef DISABLE_DKIM + dkim_collect_input = dkim_save; dkim_exim_verify_feed(NULL, 0); /* notify EOD */ + dkim_collect_input = 0; #endif return EOD; } @@ -743,6 +747,14 @@ next_cmd: } } +BOOL +bdat_hasc(void) +{ +if (chunking_data_left > 0) + return lwr_receive_hasc(); +return TRUE; +} + uschar * bdat_getbuf(unsigned * len) { @@ -782,10 +794,11 @@ bdat_push_receive_functions(void) /* push the current receive_* function on the "stack", and replace them by bdat_getc(), which in turn will use the lwr_receive_* functions to do the dirty work. */ -if (lwr_receive_getc == NULL) +if (!lwr_receive_getc) { lwr_receive_getc = receive_getc; lwr_receive_getbuf = receive_getbuf; + lwr_receive_hasc = receive_hasc; lwr_receive_ungetc = receive_ungetc; } else @@ -795,23 +808,26 @@ else receive_getc = bdat_getc; receive_getbuf = bdat_getbuf; +receive_hasc = bdat_hasc; receive_ungetc = bdat_ungetc; } static inline void bdat_pop_receive_functions(void) { -if (lwr_receive_getc == NULL) +if (!lwr_receive_getc) { DEBUG(D_receive) debug_printf("chunking double-pop receive functions\n"); return; } receive_getc = lwr_receive_getc; receive_getbuf = lwr_receive_getbuf; +receive_hasc = lwr_receive_hasc; receive_ungetc = lwr_receive_ungetc; lwr_receive_getc = NULL; lwr_receive_getbuf = NULL; +lwr_receive_hasc = NULL; lwr_receive_ungetc = NULL; } @@ -2574,12 +2590,14 @@ smtp_inbuffer[IN_BUFFER_SIZE-1] = '\0'; receive_getc = smtp_getc; receive_getbuf = smtp_getbuf; receive_get_cache = smtp_get_cache; +receive_hasc = smtp_hasc; receive_ungetc = smtp_ungetc; receive_feof = smtp_feof; receive_ferror = smtp_ferror; receive_smtp_buffered = smtp_buffered; lwr_receive_getc = NULL; lwr_receive_getbuf = NULL; +lwr_receive_hasc = NULL; lwr_receive_ungetc = NULL; smtp_inptr = smtp_inend = smtp_inbuffer; smtp_had_eof = smtp_had_error = 0; @@ -3266,27 +3284,26 @@ void smtp_message_code(uschar **code, int *codelen, uschar **msg, uschar **log_msg, BOOL check_valid) { -int n; -int ovector[3]; +uschar * match; +int len; -if (!msg || !*msg) return; - -if ((n = pcre_exec(regex_smtp_code, NULL, CS *msg, Ustrlen(*msg), 0, - PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int))) < 0) return; +if (!msg || !*msg || !regex_match(regex_smtp_code, *msg, -1, &match)) + return; +len = Ustrlen(match); if (check_valid && (*msg)[0] != (*code)[0]) { log_write(0, LOG_MAIN|LOG_PANIC, "configured error code starts with " "incorrect digit (expected %c) in \"%s\"", (*code)[0], *msg); - if (log_msg != NULL && *log_msg == *msg) - *log_msg = string_sprintf("%s %s", *code, *log_msg + ovector[1]); + if (log_msg && *log_msg == *msg) + *log_msg = string_sprintf("%s %s", *code, *log_msg + len); } else { *code = *msg; - *codelen = ovector[1]; /* Includes final space */ + *codelen = len; /* Includes final space */ } -*msg += ovector[1]; /* Chop the code off the message */ +*msg += len; /* Chop the code off the message */ return; } @@ -3921,16 +3938,8 @@ log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", /* Pause, hoping client will FIN first so that they get the TIME_WAIT. The socket should become readble (though with no data) */ - { - int fd = fileno(smtp_in); - fd_set fds; - struct timeval t_limit = {.tv_sec = 0, .tv_usec = 200*1000}; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - (void) select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &t_limit); - } -#endif /*!DAEMON_CLOSE_NOWAIT*/ +(void) poll_one_fd(fileno(smtp_in), POLLIN, 200); +#endif /*!SERVERSIDE_CLOSE_NOWAIT*/ }