mirror of
				https://bitbucket.org/jsuto/piler.git
				synced 2025-11-04 09:52:26 +01:00 
			
		
		
		
	
							
								
								
									
										63
									
								
								src/bdat.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								src/bdat.c
									
									
									
									
									
								
							@@ -21,8 +21,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void reset_bdat_counters(struct smtp_session *session){
 | 
					void reset_bdat_counters(struct smtp_session *session){
 | 
				
			||||||
   session->bdat_rounds = 0;
 | 
					 | 
				
			||||||
   session->bdat_last_round = 0;
 | 
					 | 
				
			||||||
   session->bdat_bytes_to_read = 0;
 | 
					   session->bdat_bytes_to_read = 0;
 | 
				
			||||||
   session->bad = 0;
 | 
					   session->bad = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -31,17 +29,12 @@ void reset_bdat_counters(struct smtp_session *session){
 | 
				
			|||||||
void get_bdat_size_to_read(struct smtp_session *session, char *buf){
 | 
					void get_bdat_size_to_read(struct smtp_session *session, char *buf){
 | 
				
			||||||
   char *p;
 | 
					   char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   session->bdat_rounds++;
 | 
					 | 
				
			||||||
   session->bdat_bytes_to_read = 0;
 | 
					   session->bdat_bytes_to_read = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   session->protocol_state = SMTP_STATE_BDAT;
 | 
					   session->protocol_state = SMTP_STATE_BDAT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   // determine if this is the last BDAT command
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   p = strcasestr(buf, " LAST");
 | 
					   p = strcasestr(buf, " LAST");
 | 
				
			||||||
   if(p){
 | 
					   if(p){
 | 
				
			||||||
      session->bdat_last_round = 1;
 | 
					 | 
				
			||||||
      syslog(LOG_INFO, "%s: BDAT LAST", session->ttmpfile);
 | 
					 | 
				
			||||||
      *p = '\0';
 | 
					      *p = '\0';
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,12 +54,11 @@ void get_bdat_size_to_read(struct smtp_session *session, char *buf){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void process_bdat(struct smtp_session *session, char *readbuf, int readlen, struct config *cfg){
 | 
					void process_bdat(struct smtp_session *session, char *readbuf, int readlen, struct config *cfg){
 | 
				
			||||||
   int i;
 | 
					 | 
				
			||||||
   char buf[SMALLBUFSIZE];
 | 
					   char buf[SMALLBUFSIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   if(readlen <= 0) return;
 | 
					   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);
 | 
					      session->fd = open(session->ttmpfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
 | 
				
			||||||
      if(session->fd == -1){
 | 
					      if(session->fd == -1){
 | 
				
			||||||
         syslog(LOG_PRIORITY, "%s: %s", ERR_OPEN_TMP_FILE, session->ttmpfile);
 | 
					         syslog(LOG_PRIORITY, "%s: %s", ERR_OPEN_TMP_FILE, session->ttmpfile);
 | 
				
			||||||
@@ -81,7 +73,7 @@ void process_bdat(struct smtp_session *session, char *readbuf, int readlen, stru
 | 
				
			|||||||
      if(write(session->fd, readbuf, readlen) != -1){
 | 
					      if(write(session->fd, readbuf, readlen) != -1){
 | 
				
			||||||
         session->tot_len += readlen;
 | 
					         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__);
 | 
					      else syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__);
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
@@ -94,45 +86,36 @@ void process_bdat(struct smtp_session *session, char *readbuf, int readlen, stru
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      close(session->fd);
 | 
					      close(session->fd);
 | 
				
			||||||
      unlink(session->ttmpfile);
 | 
					      unlink(session->ttmpfile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      session->fd = 1;
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   if(session->bdat_bytes_to_read == 0){
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if(session->bdat_last_round == 1){
 | 
					   // If there's nothing more to read, then send response to smtp client
 | 
				
			||||||
         if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_INFO, "%s: read all bdat data in %d rounds", session->ttmpfile, session->bdat_rounds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
         // send back the smtp answers
 | 
					   if(session->bdat_bytes_to_read <= 0){
 | 
				
			||||||
         for(i=0; i<session->bdat_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);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  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, SMTP_RESP_421_ERR_WRITE_FAILED);
 | 
				
			||||||
                  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 {
 | 
				
			||||||
               }
 | 
					         fsync(session->fd);
 | 
				
			||||||
               else send_smtp_response(session, SMTP_RESP_250_BDAT);
 | 
					         close(session->fd);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
         }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
         // 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;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
         session->fd = -1;
 | 
					         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 {
 | 
					      // technically we are not in the PERIOD state, but it's good enough
 | 
				
			||||||
         // this is not the last BDAT round, let's go back
 | 
					      // to quit the BDAT processing state
 | 
				
			||||||
         // after the rcpt state, and wait for the next
 | 
					      session->protocol_state = SMTP_STATE_PERIOD;
 | 
				
			||||||
         // BDAT command
 | 
					 | 
				
			||||||
         session->protocol_state = SMTP_STATE_RCPT_TO;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define VERSION "1.3.5-pre1"
 | 
					#define VERSION "1.3.5-pre1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BUILD 995
 | 
					#define BUILD 996
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HOSTID "mailarchiver"
 | 
					#define HOSTID "mailarchiver"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -393,8 +393,6 @@ struct smtp_session {
 | 
				
			|||||||
   int buflen;
 | 
					   int buflen;
 | 
				
			||||||
   int last_data_char;
 | 
					   int last_data_char;
 | 
				
			||||||
   int tot_len;
 | 
					   int tot_len;
 | 
				
			||||||
   int bdat_rounds;
 | 
					 | 
				
			||||||
   int bdat_last_round;
 | 
					 | 
				
			||||||
   int bdat_bytes_to_read;
 | 
					   int bdat_bytes_to_read;
 | 
				
			||||||
   int num_of_rcpt_to;
 | 
					   int num_of_rcpt_to;
 | 
				
			||||||
   struct config *cfg;
 | 
					   struct config *cfg;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -163,6 +163,13 @@ void tear_down_session(struct smtp_session **sessions, int slot, int *num_connec
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
   close(sessions[slot]->net.socket);
 | 
					   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]);
 | 
					   free_smtp_session(sessions[slot]);
 | 
				
			||||||
   sessions[slot] = NULL;
 | 
					   sessions[slot] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
void process_smtp_command(struct smtp_session *session, char *buf, struct config *cfg){
 | 
					void process_smtp_command(struct smtp_session *session, char *buf, struct config *cfg){
 | 
				
			||||||
   char response[SMALLBUFSIZE];
 | 
					   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){
 | 
					   if(strncasecmp(buf, SMTP_CMD_HELO, strlen(SMTP_CMD_HELO)) == 0){
 | 
				
			||||||
      process_command_helo(session, response, sizeof(response));
 | 
					      process_command_helo(session, response, sizeof(response));
 | 
				
			||||||
@@ -46,7 +46,8 @@ void process_smtp_command(struct smtp_session *session, char *buf, struct config
 | 
				
			|||||||
      return;
 | 
					      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);
 | 
					      get_bdat_size_to_read(session, buf);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user