diff --git a/src/config.h b/src/config.h index b02c8df..84012c6 100644 --- a/src/config.h +++ b/src/config.h @@ -13,7 +13,7 @@ #define VERSION "0.1.21" -#define BUILD 713 +#define BUILD 716 #define HOSTID "mailarchiver" diff --git a/src/defs.h b/src/defs.h index 151b27b..0751f16 100644 --- a/src/defs.h +++ b/src/defs.h @@ -152,6 +152,7 @@ struct list *boundaries; struct list *rcpt; struct list *rcpt_domain; + struct list *journal_recipient; int n_attachments; struct attachment attachments[MAX_ATTACHMENTS]; @@ -159,9 +160,11 @@ char reference[SMALLBUFSIZE]; char b_from[SMALLBUFSIZE], b_from_domain[SMALLBUFSIZE], b_to[MAXBUFSIZE], b_to_domain[SMALLBUFSIZE], b_subject[MAXBUFSIZE], b_body[BIGBUFSIZE]; + char b_journal_to[MAXBUFSIZE]; int bodylen; int tolen; + int journaltolen; }; diff --git a/src/list.c b/src/list.c index 25894a5..74a7b81 100644 --- a/src/list.c +++ b/src/list.c @@ -56,7 +56,7 @@ p = list; while(p != NULL){ - if(strcasecmp(p->s, s) == 0) return 1; + if(strcmp(p->s, s) == 0) return 1; p = p->r; } diff --git a/src/message.c b/src/message.c index 2b0dc20..7553d95 100644 --- a/src/message.c +++ b/src/message.c @@ -206,7 +206,59 @@ } -int store_recipients(struct session_data *sdata, char *to, uint64 id, struct __config *cfg){ +uint64 get_metaid_by_messageid(struct session_data *sdata, char *message_id, struct __config *cfg){ + unsigned long len=0; + uint64 id=0; + char s[SMALLBUFSIZE]; + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + + snprintf(s, sizeof(s)-1, "SELECT id FROM %s WHERE message_id=?", SQL_METADATA_TABLE); + + if(prepare_a_mysql_statement(sdata, &stmt, s) == ERR) return id; + + memset(bind, 0, sizeof(bind)); + + bind[0].buffer_type = MYSQL_TYPE_STRING; + bind[0].buffer = message_id; + bind[0].is_null = 0; + len = strlen(message_id); bind[0].length = &len; + + if(mysql_stmt_bind_param(stmt, bind)){ + goto CLOSE; + } + + if(mysql_stmt_execute(stmt)){ + goto CLOSE; + } + + memset(bind, 0, sizeof(bind)); + + bind[0].buffer_type = MYSQL_TYPE_LONGLONG; + bind[0].buffer = (char *)&id; + bind[0].is_null = 0; + bind[0].length = 0; + + + if(mysql_stmt_bind_result(stmt, bind)){ + goto CLOSE; + } + + + if(mysql_stmt_store_result(stmt)){ + goto CLOSE; + } + + mysql_stmt_fetch(stmt); + +CLOSE: + mysql_stmt_close(stmt); + + return id; +} + + +int store_recipients(struct session_data *sdata, char *to, uint64 id, int log_errors, struct __config *cfg){ int ret=OK, n=0; char *p, *q, s[SMALLBUFSIZE], puf[SMALLBUFSIZE]; @@ -248,7 +300,7 @@ } - if(mysql_stmt_execute(stmt)){ + if(mysql_stmt_execute(stmt) && log_errors == 1){ syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_execute error: *%s*", sdata->ttmpfile, SQL_RECIPIENT_TABLE, mysql_error(&(sdata->mysql))); ret = ERR; } @@ -353,7 +405,7 @@ else { id = mysql_stmt_insert_id(stmt); - rc = store_recipients(sdata, state->b_to, id, cfg); + rc = store_recipients(sdata, state->b_to, id, 1, cfg); if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: stored recipients, rc=%d", sdata->ttmpfile, rc); @@ -377,11 +429,19 @@ int process_message(struct session_data *sdata, struct _state *state, struct __data *data, struct __config *cfg){ int i, rc; + uint64 id=0; /* discard if existing message_id */ if(is_existing_message_id(sdata, state, data, cfg) == 1){ for(i=1; i<=state->n_attachments; i++) unlink(state->attachments[i].internalname); + + if(strlen(state->b_journal_to) > 0){ + id = get_metaid_by_messageid(sdata, state->message_id, cfg); + if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: trying to add journal rcpt (%s) to id=%llu for message-id: '%s'", sdata->ttmpfile, state->b_journal_to, id, state->message_id); + store_recipients(sdata, state->b_journal_to, id, 0, cfg); + } + return ERR_EXISTS; } diff --git a/src/misc.c b/src/misc.c index 16a7632..5e444ce 100644 --- a/src/misc.c +++ b/src/misc.c @@ -452,6 +452,11 @@ } +void strtolower(char *s){ + for(; *s; s++) *s = tolower(*s); +} + + #ifndef _GNU_SOURCE char *strcasestr(const char *s, const char *find){ char c, sc; diff --git a/src/misc.h b/src/misc.h index 7c4cdef..483b372 100644 --- a/src/misc.h +++ b/src/misc.h @@ -31,6 +31,7 @@ int is_email_address_on_my_domains(char *email, struct __config *cfg); void init_session_data(struct session_data *sdata); int read_from_stdin(struct session_data *sdata); +void strtolower(char *s); #ifndef _GNU_SOURCE char *strcasestr(const char *s, const char *find); diff --git a/src/parser.c b/src/parser.c index 399fe0a..b666caa 100644 --- a/src/parser.c +++ b/src/parser.c @@ -112,6 +112,7 @@ free_list(state->boundaries); free_list(state->rcpt); free_list(state->rcpt_domain); + free_list(state->journal_recipient); trimBuffer(state->b_subject); fixupEncodedHeaderLine(state->b_subject); @@ -608,6 +609,15 @@ } } else if((state->message_state == MSG_TO || state->message_state == MSG_CC || state->message_state == MSG_RECIPIENT) && state->is_1st_header == 1 && state->tolen < MAXBUFSIZE-len-1){ + strtolower(puf); + + if(state->message_state == MSG_RECIPIENT && is_string_on_list(state->journal_recipient, puf) == 0){ + append_list(&(state->journal_recipient), puf); + memcpy(&(state->b_journal_to[state->journaltolen]), puf, len); + memcpy(&(state->b_journal_to[state->journaltolen]), puf, len); + if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: journal rcpt: '%s'", sdata->ttmpfile, puf); + } + if(is_string_on_list(state->rcpt, puf) == 0){ append_list(&(state->rcpt), puf); @@ -634,6 +644,7 @@ } } + } else if(state->message_state == MSG_BODY && len >= cfg->min_word_len && state->bodylen < BIGBUFSIZE-len-1){ memcpy(&(state->b_body[state->bodylen]), puf, len); diff --git a/src/parser_utils.c b/src/parser_utils.c index c77c118..88c818b 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -69,6 +69,7 @@ state->boundaries = NULL; state->rcpt = NULL; state->rcpt_domain = NULL; + state->journal_recipient = NULL; state->n_attachments = 0; @@ -91,9 +92,11 @@ memset(state->b_to_domain, 0, SMALLBUFSIZE); memset(state->b_subject, 0, MAXBUFSIZE); memset(state->b_body, 0, BIGBUFSIZE); + memset(state->b_journal_to, 0, MAXBUFSIZE); state->tolen = 0; state->bodylen = 0; + state->journaltolen = 0; }