diff --git a/src/bdat.c b/src/bdat.c index 6a77da8..1ad386f 100644 --- a/src/bdat.c +++ b/src/bdat.c @@ -21,8 +21,6 @@ void reset_bdat_counters(struct smtp_session *session){ - session->bdat_rounds = 0; - session->bdat_last_round = 0; session->bdat_bytes_to_read = 0; session->bad = 0; } @@ -31,17 +29,12 @@ void get_bdat_size_to_read(struct smtp_session *session, char *buf){ char *p; - session->bdat_rounds++; session->bdat_bytes_to_read = 0; session->protocol_state = SMTP_STATE_BDAT; - // determine if this is the last BDAT command - p = strcasestr(buf, " LAST"); if(p){ - session->bdat_last_round = 1; - syslog(LOG_INFO, "%s: BDAT LAST", session->ttmpfile); *p = '\0'; } @@ -61,12 +54,11 @@ void process_bdat(struct smtp_session *session, char *readbuf, int readlen, struct config *cfg){ - int i; char buf[SMALLBUFSIZE]; if(readlen <= 0) return; - if(session->bdat_rounds == 1 && session->fd == -1){ + if(session->fd == -1){ session->fd = open(session->ttmpfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP); if(session->fd == -1){ syslog(LOG_PRIORITY, "%s: %s", ERR_OPEN_TMP_FILE, session->ttmpfile); @@ -81,7 +73,7 @@ if(write(session->fd, readbuf, readlen) != -1){ session->tot_len += readlen; - if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_INFO, "%s: wrote %d bytes, %d bytes to go", session->ttmpfile, readlen, session->bdat_bytes_to_read); + if(session->cfg->verbosity >= _LOG_EXTREME) syslog(LOG_INFO, "%s: wrote %d bytes, %d bytes to go", session->ttmpfile, readlen, session->bdat_bytes_to_read); } else syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); } @@ -94,45 +86,36 @@ close(session->fd); unlink(session->ttmpfile); + + session->fd = 1; } - if(session->bdat_bytes_to_read == 0){ - if(session->bdat_last_round == 1){ - if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_INFO, "%s: read all bdat data in %d rounds", session->ttmpfile, session->bdat_rounds); + // If there's nothing more to read, then send response to smtp client - // send back the smtp answers - for(i=0; ibdat_rounds; i++){ - if(session->fd == -1){ - send_smtp_response(session, SMTP_RESP_421_ERR_WRITE_FAILED); - } - else { - if(i == 0){ - fsync(session->fd); - close(session->fd); + if(session->bdat_bytes_to_read <= 0){ - move_email(session); + if(session->fd == -1){ + close(session->fd); + session->fd = -1; - snprintf(buf, sizeof(buf)-1, "250 OK <%s>\r\n", session->ttmpfile); - send_smtp_response(session, buf); - syslog(LOG_PRIORITY, "received: %s, from=%s, size=%d, client=%s", session->ttmpfile, session->mailfrom, session->tot_len, session->remote_host); - } - else send_smtp_response(session, SMTP_RESP_250_BDAT); - } - } - - // technically we are not in the PERIOD state, but it's good enough - // to quit the BDAT processing state - session->protocol_state = SMTP_STATE_PERIOD; + send_smtp_response(session, SMTP_RESP_421_ERR_WRITE_FAILED); + } + else { + fsync(session->fd); + close(session->fd); session->fd = -1; + + move_email(session); + + snprintf(buf, sizeof(buf)-1, "250 OK <%s>\r\n", session->ttmpfile); + send_smtp_response(session, buf); + syslog(LOG_PRIORITY, "received: %s, from=%s, size=%d, client=%s", session->ttmpfile, session->mailfrom, session->tot_len, session->remote_host); } - else { - // this is not the last BDAT round, let's go back - // after the rcpt state, and wait for the next - // BDAT command - session->protocol_state = SMTP_STATE_RCPT_TO; - } + // technically we are not in the PERIOD state, but it's good enough + // to quit the BDAT processing state + session->protocol_state = SMTP_STATE_PERIOD; } } diff --git a/src/config.h b/src/config.h index 007fc36..063bac4 100644 --- a/src/config.h +++ b/src/config.h @@ -11,7 +11,7 @@ #define VERSION "1.3.5-pre1" -#define BUILD 995 +#define BUILD 996 #define HOSTID "mailarchiver" diff --git a/src/defs.h b/src/defs.h index 8ab3290..64b6281 100644 --- a/src/defs.h +++ b/src/defs.h @@ -393,8 +393,6 @@ int buflen; int last_data_char; int tot_len; - int bdat_rounds; - int bdat_last_round; int bdat_bytes_to_read; int num_of_rcpt_to; struct config *cfg; diff --git a/src/session.c b/src/session.c index 7e72ba4..b98d3da 100644 --- a/src/session.c +++ b/src/session.c @@ -163,6 +163,13 @@ close(sessions[slot]->net.socket); + if(sessions[slot]->fd != -1){ + syslog(LOG_PRIORITY, "Removing %s", sessions[slot]->ttmpfile); + close(sessions[slot]->fd); + unlink(sessions[slot]->ttmpfile); + sessions[slot]->fd = -1; + } + free_smtp_session(sessions[slot]); sessions[slot] = NULL; diff --git a/src/smtp.c b/src/smtp.c index e8c8938..5c4522e 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -18,7 +18,7 @@ void process_smtp_command(struct smtp_session *session, char *buf, struct config *cfg){ char response[SMALLBUFSIZE]; - if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "processing command: *%s*", buf); + if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "(fd: %d) processing command: *%s*", session->net.socket, buf); if(strncasecmp(buf, SMTP_CMD_HELO, strlen(SMTP_CMD_HELO)) == 0){ process_command_helo(session, response, sizeof(response)); @@ -46,7 +46,8 @@ return; } - if(session->cfg->enable_chunking == 1 && strncasecmp(buf, SMTP_CMD_BDAT, strlen(SMTP_CMD_BDAT)) == 0){ + /* Support only BDAT xxxx LAST command */ + if(session->cfg->enable_chunking == 1 && strncasecmp(buf, SMTP_CMD_BDAT, strlen(SMTP_CMD_BDAT)) == 0 && strncasecmp(buf, "LAST", strlen(SMTP_CMD_BDAT)) == 0){ get_bdat_size_to_read(session, buf); return; }