2011-11-14 15:57:52 +01:00
/*
* message . c , SJ
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/socket.h>
# include <sys/stat.h>
2018-10-23 13:56:50 +02:00
# include <errno.h>
2011-11-14 15:57:52 +01:00
# include <fcntl.h>
# include <unistd.h>
# include <syslog.h>
# include <piler.h>
# include <zlib.h>
2017-08-08 15:34:45 +02:00
int store_index_data ( struct session_data * sdata , struct parser_state * state , struct data * data , uint64 id , struct config * cfg ) {
2015-09-03 14:41:52 +02:00
int rc = ERR ;
2013-01-27 23:42:45 +01:00
char * subj ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2011-12-03 23:05:00 +01:00
2015-09-03 14:41:52 +02:00
if ( data - > folder = = 0 ) {
data - > folder = get_folder_id_by_rule ( data , state , sdata - > tot_len , sdata - > spam_message , cfg ) ;
2015-08-28 22:50:28 +02:00
}
2011-11-28 14:21:14 +01:00
subj = state - > b_subject ;
if ( * subj = = ' ' ) subj + + ;
2011-11-14 15:57:52 +01:00
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_INSERT_INTO_SPHINX_TABLE ) = = ERR ) return rc ;
2011-11-14 15:57:52 +01:00
2011-12-03 23:05:00 +01:00
2011-12-05 17:18:03 +01:00
fix_email_address_for_sphinx ( state - > b_from ) ;
fix_email_address_for_sphinx ( state - > b_to ) ;
2012-01-14 09:53:26 +01:00
fix_email_address_for_sphinx ( state - > b_from_domain ) ;
fix_email_address_for_sphinx ( state - > b_to_domain ) ;
2011-12-05 17:18:03 +01:00
2011-12-03 23:05:00 +01:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2011-12-03 23:05:00 +01:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = ( char * ) & id ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_from ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_to ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_from_domain ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_to_domain ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = subj ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_body ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > now ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > sent ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > tot_len ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > direction ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & data - > folder ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & state - > n_attachments ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = sdata - > attachments ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
2011-12-03 23:05:00 +01:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) rc = OK ;
2018-01-23 20:02:50 +01:00
else syslog ( LOG_PRIORITY , " ERROR: %s failed to store index data for id=%llu, sql_errno=%d " , sdata - > ttmpfile , id , sdata - > sql_errno ) ;
2011-12-03 23:05:00 +01:00
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2012-01-29 09:02:21 +01:00
return rc ;
2011-12-03 23:05:00 +01:00
}
2018-09-29 08:43:50 +02:00
uint64 get_metaid_by_messageid ( struct session_data * sdata , char * message_id , char * piler_id ) {
2012-10-05 14:27:03 +02:00
uint64 id = 0 ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_GET_META_ID_BY_MESSAGE_ID ) = = ERR ) return id ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2017-08-11 19:44:36 +02:00
sql . sql [ sql . pos ] = message_id ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) {
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = ( char * ) & id ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . len [ sql . pos ] = sizeof ( uint64 ) ; sql . pos + + ;
sql . sql [ sql . pos ] = piler_id ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = RND_STR_LEN ; sql . pos + + ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
p_store_results ( & sql ) ;
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
p_fetch_results ( & sql ) ;
p_free_results ( & sql ) ;
2015-12-18 22:38:52 +01:00
}
2012-10-05 14:27:03 +02:00
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2013-06-29 15:43:16 +02:00
2012-10-05 14:27:03 +02:00
return id ;
}
2018-09-29 08:43:50 +02:00
int store_recipients ( struct session_data * sdata , char * to , uint64 id , struct config * cfg ) {
2018-01-23 20:02:50 +01:00
int rc = OK , n = 0 ;
2013-01-27 23:42:45 +01:00
char * p , * q , puf [ SMALLBUFSIZE ] ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2011-12-03 23:05:00 +01:00
2018-01-23 20:02:50 +01:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_INSERT_INTO_RCPT_TABLE ) = = ERR ) return ERR ;
2013-06-29 15:43:16 +02:00
2011-12-03 23:05:00 +01:00
p = to ;
do {
p = split_str ( p , " " , puf , sizeof ( puf ) - 1 ) ;
2012-01-09 23:15:39 +01:00
q = strchr ( puf , ' @ ' ) ;
if ( q & & strlen ( q ) > 3 & & does_it_seem_like_an_email_address ( puf ) = = 1 ) {
q + + ;
2011-12-03 23:05:00 +01:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2012-01-09 23:15:39 +01:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = ( char * ) & id ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . pos + + ;
sql . sql [ sql . pos ] = & puf [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = q ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
2013-01-27 23:42:45 +01:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = ERR ) {
2018-01-23 20:02:50 +01:00
if ( sdata - > sql_errno ! = ER_DUP_ENTRY ) {
syslog ( LOG_PRIORITY , " ERROR: %s: failed to add '%s' for id=%llu to rcpt table, sql_errno=%d " , sdata - > ttmpfile , puf , id , sdata - > sql_errno ) ;
rc = ERR ;
}
2011-12-03 23:05:00 +01:00
}
2012-09-04 14:49:56 +02:00
else n + + ;
2011-12-03 23:05:00 +01:00
}
} while ( p ) ;
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2012-01-29 09:02:21 +01:00
2018-01-23 20:02:50 +01:00
if ( cfg - > verbosity > = _LOG_DEBUG ) syslog ( LOG_PRIORITY , " %s: stored %d recipients, rc=%d " , sdata - > ttmpfile , n , rc ) ;
2012-09-04 14:49:56 +02:00
2018-01-23 20:02:50 +01:00
return rc ;
2011-11-14 15:57:52 +01:00
}
2018-01-23 20:02:50 +01:00
int store_folder_id ( struct session_data * sdata , struct data * data , uint64 id , struct config * cfg ) {
int rc = ERR ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2015-09-09 12:52:15 +02:00
2015-12-05 11:56:01 +01:00
if ( data - > folder = = ERR_FOLDER ) return rc ;
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_INSERT_FOLDER_MESSAGE ) = = ERR ) return rc ;
2015-09-09 12:52:15 +02:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2015-09-09 12:52:15 +02:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = ( char * ) & data - > folder ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & id ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . pos + + ;
2015-09-09 12:52:15 +02:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) rc = OK ;
close_prepared_statement ( & sql ) ;
2015-09-09 12:52:15 +02:00
2018-01-23 20:02:50 +01:00
if ( cfg - > verbosity > = _LOG_DEBUG ) syslog ( LOG_PRIORITY , " %s: stored folderdata, rc=%d " , sdata - > ttmpfile , rc ) ;
2016-04-05 21:10:09 +02:00
2018-01-23 20:02:50 +01:00
return rc ;
2016-04-05 21:10:09 +02:00
}
2018-09-29 08:43:50 +02:00
int update_metadata_reference ( struct session_data * sdata , struct parser_state * state , char * ref , struct config * cfg ) {
2013-05-05 11:57:14 +02:00
int ret = ERR ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2013-03-18 10:13:26 +01:00
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_UPDATE_METADATA_REFERENCE ) = = ERR ) return ret ;
2013-03-18 10:13:26 +01:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2013-03-18 10:13:26 +01:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = ref ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > reference ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
2013-03-18 10:13:26 +01:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) ret = OK ;
2013-03-18 10:13:26 +01:00
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2013-06-29 15:43:16 +02:00
2013-05-05 11:57:14 +02:00
if ( cfg - > verbosity > = _LOG_DEBUG ) syslog ( LOG_PRIORITY , " %s: updated meta reference for '%s', rc=%d " , sdata - > ttmpfile , state - > reference , ret ) ;
2013-03-18 10:13:26 +01:00
return ret ;
}
2017-08-08 15:34:45 +02:00
int store_meta_data ( struct session_data * sdata , struct parser_state * state , struct data * data , struct config * cfg ) {
2018-01-23 20:02:50 +01:00
int rc = ERR , result ;
2012-02-10 14:06:00 +01:00
char * subj , * p , s [ MAXBUFSIZE ] , s2 [ SMALLBUFSIZE ] , vcode [ 2 * DIGEST_LENGTH + 1 ] , ref [ 2 * DIGEST_LENGTH + 1 ] ;
2013-05-05 11:57:14 +02:00
uint64 id = 0 ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2011-12-03 23:05:00 +01:00
2011-11-28 14:21:14 +01:00
subj = state - > b_subject ;
if ( * subj = = ' ' ) subj + + ;
2012-02-19 22:59:47 +01:00
snprintf ( s , sizeof ( s ) - 1 , " %llu+%s%s%s%ld%ld%ld%d%d%d%d%s%s%s " , id , subj , state - > b_from , state - > message_id , sdata - > now , sdata - > sent , sdata - > retained , sdata - > tot_len , sdata - > hdr_len , sdata - > direction , state - > n_attachments , sdata - > ttmpfile , sdata - > digest , sdata - > bodydigest ) ;
2012-02-10 14:06:00 +01:00
2012-01-14 09:53:26 +01:00
digest_string ( s , & vcode [ 0 ] ) ;
2012-02-10 14:06:00 +01:00
memset ( ref , 0 , sizeof ( ref ) ) ;
2013-03-18 10:13:26 +01:00
if ( strlen ( state - > reference ) > 10 ) {
digest_string ( state - > reference , & ref [ 0 ] ) ;
2018-09-29 08:43:50 +02:00
update_metadata_reference ( sdata , state , & ref [ 0 ] , cfg ) ;
2013-03-18 10:13:26 +01:00
}
2012-02-10 14:06:00 +01:00
2012-01-14 09:53:26 +01:00
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , SQL_PREPARED_STMT_INSERT_INTO_META_TABLE ) = = ERR ) return ERR ;
2012-02-07 17:21:23 +01:00
memset ( s2 , 0 , sizeof ( s2 ) ) ;
2011-11-14 15:57:52 +01:00
2012-02-07 17:21:23 +01:00
p = state - > b_from ;
do {
memset ( s2 , 0 , sizeof ( s2 ) ) ;
2014-07-22 16:00:03 +02:00
p = split ( p , ' ' , s2 , sizeof ( s2 ) - 1 , & result ) ;
2012-02-07 17:21:23 +01:00
if ( s2 [ 0 ] = = ' \0 ' ) continue ;
if ( does_it_seem_like_an_email_address ( s2 ) = = 1 ) { break ; }
} while ( p ) ;
2011-11-14 15:57:52 +01:00
if ( strlen ( state - > b_to ) < 5 ) {
2012-01-09 23:15:39 +01:00
snprintf ( state - > b_to , SMALLBUFSIZE - 1 , " undisclosed-recipients@no.domain " ) ;
2011-11-14 15:57:52 +01:00
}
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
sql . sql [ sql . pos ] = & s2 [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > b_from_domain ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = subj ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > spam_message ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > now ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > sent ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > retained ; sql . type [ sql . pos ] = TYPE_LONGLONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > tot_len ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > hdr_len ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & sdata - > direction ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & state - > n_attachments ; sql . type [ sql . pos ] = TYPE_LONG ; sql . pos + + ;
sql . sql [ sql . pos ] = sdata - > ttmpfile ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = state - > message_id ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = & ref [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = sdata - > digest ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = sdata - > bodydigest ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
sql . sql [ sql . pos ] = & vcode [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . pos + + ;
2018-01-23 20:02:50 +01:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) {
2017-08-11 18:18:45 +02:00
id = p_get_insert_id ( & sql ) ;
2011-11-14 15:57:52 +01:00
2018-09-29 08:43:50 +02:00
if ( store_recipients ( sdata , state - > b_to , id , cfg ) = = OK ) {
2011-11-14 15:57:52 +01:00
2018-01-23 20:02:50 +01:00
if ( store_index_data ( sdata , state , data , id , cfg ) = = OK ) rc = OK ;
2012-01-09 23:15:39 +01:00
2018-01-23 20:02:50 +01:00
if ( cfg - > enable_folders = = 1 ) {
rc = store_folder_id ( sdata , data , id , cfg ) ;
}
}
2011-11-14 15:57:52 +01:00
2018-01-23 20:02:50 +01:00
// There were some sql errors, so we should rollback everything
if ( rc = = ERR ) {
rollback ( sdata , state , id , cfg ) ;
2015-09-09 12:52:15 +02:00
}
2018-01-23 20:02:50 +01:00
}
else {
syslog ( LOG_PRIORITY , " ERROR: %s storing metadata, sql_errno=%d " , sdata - > ttmpfile , sdata - > sql_errno ) ;
2011-12-03 23:05:00 +01:00
}
2011-11-14 15:57:52 +01:00
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2012-01-29 09:02:21 +01:00
2018-01-23 20:02:50 +01:00
if ( cfg - > verbosity > = _LOG_DEBUG ) syslog ( LOG_PRIORITY , " %s: stored metadata, rc=%d " , sdata - > ttmpfile , rc ) ;
return rc ;
}
void rollback ( struct session_data * sdata , struct parser_state * state , uint64 id , struct config * cfg ) {
char buf [ SMALLBUFSIZE ] ;
snprintf ( buf , sizeof ( buf ) - 2 , " DELETE FROM %s WHERE id=%llu " , SQL_SPHINX_TABLE , id ) ;
p_query ( sdata , buf ) ;
syslog ( LOG_PRIORITY , " ERROR: %s: rollback sql stmt=%s " , sdata - > ttmpfile , buf ) ;
snprintf ( buf , sizeof ( buf ) - 2 , " DELETE FROM %s WHERE id=%llu " , SQL_RECIPIENT_TABLE , id ) ;
p_query ( sdata , buf ) ;
syslog ( LOG_PRIORITY , " ERROR: %s: rollback sql stmt=%s " , sdata - > ttmpfile , buf ) ;
snprintf ( buf , sizeof ( buf ) - 2 , " DELETE FROM %s WHERE id=%llu " , SQL_METADATA_TABLE , id ) ;
p_query ( sdata , buf ) ;
syslog ( LOG_PRIORITY , " ERROR: %s: rollback sql stmt=%s " , sdata - > ttmpfile , buf ) ;
snprintf ( buf , sizeof ( buf ) - 2 , " DELETE FROM %s WHERE piler_id='%s' " , SQL_ATTACHMENT_TABLE , sdata - > ttmpfile ) ;
p_query ( sdata , buf ) ;
syslog ( LOG_PRIORITY , " ERROR: %s: rollback sql stmt=%s " , sdata - > ttmpfile , buf ) ;
if ( cfg - > enable_folders = = 1 ) {
snprintf ( buf , sizeof ( buf ) - 1 , " DELETE FROM " SQL_FOLDER_MESSAGE_TABLE " WHERE id=%llu " , id ) ;
p_query ( sdata , buf ) ;
syslog ( LOG_PRIORITY , " ERROR: %s: rollback sql stmt=%s " , sdata - > ttmpfile , buf ) ;
}
remove_stored_message_files ( sdata , state , cfg ) ;
2011-11-14 15:57:52 +01:00
}
2015-11-21 23:06:47 +01:00
void remove_stripped_attachments ( struct parser_state * state ) {
2012-12-15 21:25:36 +01:00
int i ;
for ( i = 1 ; i < = state - > n_attachments ; i + + ) unlink ( state - > attachments [ i ] . internalname ) ;
}
2017-08-08 15:34:45 +02:00
int process_message ( struct session_data * sdata , struct parser_state * state , struct data * data , struct config * cfg ) {
2018-01-23 20:02:50 +01:00
int fd ;
2016-04-05 21:10:09 +02:00
char piler_id [ SMALLBUFSIZE ] ;
2011-11-14 15:57:52 +01:00
/* discard if existing message_id */
2018-09-29 08:43:50 +02:00
sdata - > duplicate_id = get_metaid_by_messageid ( sdata , state - > message_id , piler_id ) ;
2013-01-27 23:42:45 +01:00
2013-11-12 14:51:31 +01:00
if ( sdata - > duplicate_id > 0 ) {
2012-12-15 21:25:36 +01:00
remove_stripped_attachments ( state ) ;
2012-10-05 14:27:03 +02:00
if ( strlen ( state - > b_journal_to ) > 0 ) {
2013-11-12 14:51:31 +01:00
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 , sdata - > duplicate_id , state - > message_id ) ;
2018-09-29 08:43:50 +02:00
store_recipients ( sdata , state - > b_journal_to , sdata - > duplicate_id , cfg ) ;
2012-10-05 14:27:03 +02:00
}
2011-11-14 15:57:52 +01:00
return ERR_EXISTS ;
}
2015-05-09 12:06:45 +02:00
fd = open ( state - > message_id_hash , O_CREAT | O_EXCL , S_IRUSR | S_IWUSR ) ;
2014-04-25 21:17:01 +02:00
if ( fd = = - 1 ) {
remove_stripped_attachments ( state ) ;
2018-10-23 13:56:50 +02:00
syslog ( LOG_PRIORITY , " %s: touch %s FAILED (%s), error: %s " , sdata - > ttmpfile , state - > message_id_hash , state - > message_id , strerror ( errno ) ) ;
2014-04-25 21:17:01 +02:00
return ERR_EXISTS ;
}
2014-05-06 10:22:29 +02:00
close ( fd ) ;
2014-04-25 21:17:01 +02:00
2015-05-06 12:22:15 +02:00
if ( cfg - > verbosity > = _LOG_DEBUG ) syslog ( LOG_PRIORITY , " %s: touch %s OK (%s) " , sdata - > ttmpfile , state - > message_id_hash , state - > message_id ) ;
2011-11-14 15:57:52 +01:00
2015-05-09 14:31:20 +02:00
if ( cfg - > mmap_dedup_test = = 1 & & data - > dedup ! = MAP_FAILED & & data - > child_serial > = 0 & & data - > child_serial < MAXCHILDREN ) {
if ( strstr ( data - > dedup , state - > message_id_hash ) ) {
2018-10-23 13:56:50 +02:00
if ( cfg - > verbosity > = _LOG_DEBUG ) {
syslog ( LOG_INFO , " %s: dedup string: %s " , sdata - > ttmpfile , data - > dedup ) ;
syslog ( LOG_INFO , " %s: message-id-hash=%s, serial=%d " , sdata - > ttmpfile , state - > message_id_hash , data - > child_serial ) ;
}
2015-05-09 14:31:20 +02:00
remove_stripped_attachments ( state ) ;
return ERR_EXISTS ;
}
memcpy ( data - > dedup + data - > child_serial * DIGEST_LENGTH * 2 , state - > message_id_hash , DIGEST_LENGTH * 2 ) ;
}
2018-01-23 20:02:50 +01:00
sdata - > retained + = query_retain_period ( data , state , sdata - > tot_len , sdata - > spam_message , cfg ) ;
2015-05-09 14:31:20 +02:00
2018-09-29 08:43:50 +02:00
if ( state - > n_attachments > 0 & & store_attachments ( sdata , state , cfg ) = = ERR ) return ERR ;
2011-11-19 21:25:44 +01:00
2018-01-23 20:02:50 +01:00
if ( store_file ( sdata , sdata - > tmpframe , 0 , cfg ) = = 0 ) {
syslog ( LOG_PRIORITY , " ERROR: %s: failed to store message: %s " , sdata - > ttmpfile , sdata - > tmpframe ) ;
2011-11-19 21:25:44 +01:00
return ERR ;
}
2011-11-14 15:57:52 +01:00
2018-01-23 20:02:50 +01:00
return store_meta_data ( sdata , state , data , cfg ) ;
2011-11-14 15:57:52 +01:00
}