2012-06-01 14:25:49 +02:00
/*
* reindex . c , SJ
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/time.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <time.h>
# include <locale.h>
# include <syslog.h>
# include <getopt.h>
# include <piler.h>
extern char * optarg ;
extern int optind ;
int progressbar = 0 ;
void usage ( ) {
printf ( " \n usage: reindex \n \n " ) ;
printf ( " [-c|--config <config file>] \n " ) ;
printf ( " -f <from id> \n " ) ;
printf ( " -t <to id> \n " ) ;
2012-11-30 12:27:18 +01:00
printf ( " -a \n " ) ;
2012-06-01 14:25:49 +02:00
printf ( " [-p] \n " ) ;
exit ( 0 ) ;
}
2012-10-29 10:22:31 +01:00
void p_clean_exit ( char * msg , int rc ) {
2012-06-01 14:25:49 +02:00
if ( msg ) printf ( " error: %s \n " , msg ) ;
exit ( rc ) ;
}
2013-05-05 11:57:14 +02:00
uint64 get_max_meta_id ( struct session_data * sdata , struct __data * data ) {
2012-11-30 12:27:18 +01:00
char s [ SMALLBUFSIZE ] ;
uint64 id = 0 ;
snprintf ( s , sizeof ( s ) - 1 , " SELECT MAX(`id`) FROM %s " , SQL_METADATA_TABLE ) ;
2013-05-05 11:57:14 +02:00
if ( prepare_sql_statement ( sdata , & ( data - > stmt_generic ) , s ) = = ERR ) return id ;
p_bind_init ( data ) ;
if ( p_exec_query ( sdata , data - > stmt_generic , data ) = = ERR ) goto ENDE ;
p_bind_init ( data ) ;
data - > sql [ data - > pos ] = ( char * ) & id ; data - > type [ data - > pos ] = TYPE_LONGLONG ; data - > len [ data - > pos ] = sizeof ( uint64 ) ; data - > pos + + ;
p_store_results ( sdata , data - > stmt_generic , data ) ;
p_fetch_results ( data - > stmt_generic ) ;
p_free_results ( data - > stmt_generic ) ;
ENDE :
close_prepared_statement ( data - > stmt_generic ) ;
2012-11-30 12:27:18 +01:00
return id ;
}
2012-08-23 10:23:58 +02:00
uint64 retrieve_email_by_metadata_id ( struct session_data * sdata , struct __data * data , uint64 from_id , uint64 to_id , struct __config * cfg ) {
2012-06-01 14:25:49 +02:00
FILE * f ;
char filename [ SMALLBUFSIZE ] ;
char s [ SMALLBUFSIZE ] ;
int rc = 0 ;
uint64 stored_id = 0 , reindexed = 0 ;
struct _state state ;
2012-06-01 14:54:13 +02:00
snprintf ( s , sizeof ( s ) - 1 , " SELECT `id`, `piler_id`, `arrived`, `sent` FROM %s WHERE (id BETWEEN %llu AND %llu) AND `deleted`=0 " , SQL_METADATA_TABLE , from_id , to_id ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
if ( prepare_sql_statement ( sdata , & ( data - > stmt_generic ) , s ) = = ERR ) return reindexed ;
p_bind_init ( data ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
if ( p_exec_query ( sdata , data - > stmt_generic , data ) = = ERR ) goto ENDE ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
p_bind_init ( data ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
data - > sql [ data - > pos ] = ( char * ) & stored_id ; data - > type [ data - > pos ] = TYPE_LONGLONG ; data - > len [ data - > pos ] = sizeof ( uint64 ) ; data - > pos + + ;
data - > sql [ data - > pos ] = sdata - > ttmpfile ; data - > type [ data - > pos ] = TYPE_STRING ; data - > len [ data - > pos ] = RND_STR_LEN + 2 ; data - > pos + + ;
data - > sql [ data - > pos ] = ( char * ) & ( sdata - > now ) ; data - > type [ data - > pos ] = TYPE_LONG ; data - > len [ data - > pos ] = sizeof ( unsigned long ) ; data - > pos + + ;
data - > sql [ data - > pos ] = ( char * ) & ( sdata - > sent ) ; data - > type [ data - > pos ] = TYPE_LONG ; data - > len [ data - > pos ] = sizeof ( unsigned long ) ; data - > pos + + ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
p_store_results ( sdata , data - > stmt_generic , data ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
while ( p_fetch_results ( data - > stmt_generic ) = = OK ) {
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
if ( stored_id > 0 ) {
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
snprintf ( filename , sizeof ( filename ) - 1 , " %llu.eml " , stored_id ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
f = fopen ( filename , " w " ) ;
if ( f ) {
rc = retrieve_email_from_archive ( sdata , data , f , cfg ) ;
fclose ( f ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
if ( rc ) {
printf ( " cannot retrieve: %s \n " , filename ) ;
unlink ( filename ) ;
continue ;
}
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
snprintf ( sdata - > filename , SMALLBUFSIZE - 1 , " %s " , filename ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
state = parse_message ( sdata , 0 , data , cfg ) ;
post_parse ( sdata , & state , cfg ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
rc = store_index_data ( sdata , & state , data , stored_id , cfg ) ;
2012-06-01 14:25:49 +02:00
2013-05-05 11:57:14 +02:00
if ( rc = = OK ) reindexed + + ;
else printf ( " failed to add to %s table: %s \n " , SQL_SPHINX_TABLE , filename ) ;
unlink ( filename ) ;
if ( progressbar & & reindexed % 100 = = 0 ) printf ( " . " ) ;
2012-06-01 14:25:49 +02:00
}
2013-05-05 11:57:14 +02:00
else printf ( " cannot open: %s \n " , filename ) ;
2012-06-01 14:25:49 +02:00
}
2013-05-05 11:57:14 +02:00
2012-06-01 14:25:49 +02:00
}
2013-05-05 11:57:14 +02:00
p_free_results ( data - > stmt_generic ) ;
ENDE :
close_prepared_statement ( data - > stmt_generic ) ;
2012-06-01 14:25:49 +02:00
if ( progressbar ) printf ( " \n " ) ;
return reindexed ;
}
int main ( int argc , char * * argv ) {
2012-11-30 12:27:18 +01:00
int c , all = 0 ;
2012-06-01 14:25:49 +02:00
uint64 from_id = 0 , to_id = 0 , n = 0 ;
2012-08-23 10:23:58 +02:00
char * configfile = CONFIG_FILE , * folder = NULL ;
2012-06-01 14:25:49 +02:00
struct session_data sdata ;
2012-08-23 10:23:58 +02:00
struct __data data ;
2012-06-01 14:25:49 +02:00
struct __config cfg ;
while ( 1 ) {
2012-11-30 12:27:18 +01:00
c = getopt ( argc , argv , " c:f:t:F:pahv? " ) ;
2012-06-01 14:25:49 +02:00
if ( c = = - 1 ) break ;
switch ( c ) {
case ' c ' :
configfile = optarg ;
break ;
case ' f ' :
from_id = strtoull ( optarg , NULL , 10 ) ;
break ;
case ' t ' :
to_id = strtoull ( optarg , NULL , 10 ) ;
break ;
2012-11-30 12:27:18 +01:00
case ' a ' :
all = 1 ;
break ;
2012-08-23 10:23:58 +02:00
case ' F ' :
folder = optarg ;
break ;
2012-06-01 14:25:49 +02:00
case ' p ' :
progressbar = 1 ;
break ;
default :
usage ( ) ;
break ;
}
}
2012-11-30 12:27:18 +01:00
if ( all = = 0 & & ( from_id < = 0 | | to_id < = 0 ) ) usage ( ) ;
2012-06-01 14:25:49 +02:00
( void ) openlog ( " reindex " , LOG_PID , LOG_MAIL ) ;
2013-09-11 09:19:29 +02:00
srand ( getpid ( ) ) ;
2012-06-01 14:25:49 +02:00
cfg = read_config ( configfile ) ;
if ( read_key ( & cfg ) ) {
printf ( " %s \n " , ERR_READING_KEY ) ;
return 1 ;
}
2012-08-23 10:23:58 +02:00
data . folder = 0 ;
2012-09-03 17:12:02 +02:00
data . recursive_folder_names = 0 ;
2014-01-13 13:06:10 +01:00
2013-08-14 14:24:30 +02:00
inithash ( data . mydomains ) ;
initrules ( data . archiving_rules ) ;
initrules ( data . retention_rules ) ;
2012-08-23 10:23:58 +02:00
2014-02-19 15:16:20 +01:00
init_session_data ( & sdata , & cfg ) ;
if ( open_database ( & sdata , & cfg ) = = ERR ) {
p_clean_exit ( " cannot connect to mysql server " , 1 ) ;
}
2012-08-23 10:23:58 +02:00
if ( folder ) {
2013-01-28 13:40:44 +01:00
data . folder = get_folder_id ( & sdata , & data , folder , 0 ) ;
2012-08-23 10:23:58 +02:00
if ( data . folder = = 0 ) {
printf ( " error: could not get folder id for '%s' \n " , folder ) ;
return 0 ;
}
}
2012-06-01 14:25:49 +02:00
2013-01-06 22:16:21 +01:00
load_mydomains ( & sdata , & data , & cfg ) ;
2012-06-01 14:25:49 +02:00
2012-11-30 12:27:18 +01:00
if ( all = = 1 ) {
from_id = 1 ;
2013-05-05 11:57:14 +02:00
to_id = get_max_meta_id ( & sdata , & data ) ;
2012-11-30 12:27:18 +01:00
}
2012-08-23 10:23:58 +02:00
n = retrieve_email_by_metadata_id ( & sdata , & data , from_id , to_id , & cfg ) ;
2012-06-01 14:25:49 +02:00
printf ( " put %llu messages to %s table for reindexing \n " , n , SQL_SPHINX_TABLE ) ;
2013-08-14 14:24:30 +02:00
clearhash ( data . mydomains ) ;
2013-07-12 22:54:45 +02:00
2013-04-28 14:18:09 +02:00
close_database ( & sdata ) ;
2012-06-01 14:25:49 +02:00
return 0 ;
}