diff --git a/src/archive.c b/src/archive.c index e4117830..0d4d74f4 100644 --- a/src/archive.c +++ b/src/archive.c @@ -228,9 +228,9 @@ int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, return 1; } - snprintf(filename, sizeof(filename)-1, "%s/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, *(sdata->ttmpfile+8), *(sdata->ttmpfile+9), *(sdata->ttmpfile+10), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, *(sdata->ttmpfile+8), *(sdata->ttmpfile+9), *(sdata->ttmpfile+10), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile); if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, *(sdata->ttmpfile+RND_STR_LEN-6), *(sdata->ttmpfile+RND_STR_LEN-5), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, *(sdata->ttmpfile+RND_STR_LEN-6), *(sdata->ttmpfile+RND_STR_LEN-5), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile); } if(attachments == 0){ @@ -252,10 +252,10 @@ int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, buffer = p + strlen(pointer); if(strlen(ptr_arr[i].piler_id) == RND_STR_LEN){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, ptr_arr[i].piler_id[8], ptr_arr[i].piler_id[9], ptr_arr[i].piler_id[10], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, ptr_arr[i].piler_id[8], ptr_arr[i].piler_id[9], ptr_arr[i].piler_id[10], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id); if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, ptr_arr[i].piler_id[RND_STR_LEN-6], ptr_arr[i].piler_id[RND_STR_LEN-5], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, ptr_arr[i].piler_id[RND_STR_LEN-6], ptr_arr[i].piler_id[RND_STR_LEN-5], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id); } retrieve_file_from_archive(filename, WRITE_TO_STDOUT, NULL, dest, cfg); diff --git a/src/config.h b/src/config.h index 58251e1a..eb34dd42 100644 --- a/src/config.h +++ b/src/config.h @@ -13,7 +13,7 @@ #define VERSION "0.1.23-master-branch" -#define BUILD 763 +#define BUILD 767 #define HOSTID "mailarchiver" diff --git a/src/dirs.c b/src/dirs.c index 8347e71a..e4067884 100644 --- a/src/dirs.c +++ b/src/dirs.c @@ -17,7 +17,7 @@ void createdir(char *path, uid_t uid, gid_t gid, mode_t mode); void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid){ - char *p; + char *p, s[SMALLBUFSIZE]; p = strrchr(cfg->workdir, '/'); if(p){ @@ -35,6 +35,9 @@ void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid){ } createdir(cfg->queuedir, uid, gid, 0700); + snprintf(s, sizeof(s)-1, "%s/%02x", cfg->queuedir, cfg->server_id); + createdir(s, uid, gid, 0700); + p = strrchr(cfg->pidfile, '/'); if(p){ *p = '\0'; diff --git a/src/message.c b/src/message.c index d08964bb..a5f52d08 100644 --- a/src/message.c +++ b/src/message.c @@ -136,8 +136,6 @@ uint64 get_metaid_by_messageid(struct session_data *sdata, struct __data *data, uint64 id=0; MYSQL_BIND bind[1]; - if(prepare_a_mysql_statement(sdata, &(data->stmt_get_meta_id_by_message_id), SQL_PREPARED_STMT_GET_META_ID_BY_MESSAGE_ID) == ERR) return id; - memset(bind, 0, sizeof(bind)); bind[0].buffer_type = MYSQL_TYPE_STRING; @@ -173,7 +171,6 @@ uint64 get_metaid_by_messageid(struct session_data *sdata, struct __data *data, mysql_stmt_fetch(data->stmt_get_meta_id_by_message_id); CLOSE: - mysql_stmt_close(data->stmt_get_meta_id_by_message_id); return id; } @@ -187,9 +184,6 @@ int store_recipients(struct session_data *sdata, struct __data *data, char *to, unsigned long len[3]; - if(prepare_a_mysql_statement(sdata, &(data->stmt_insert_into_rcpt_table), SQL_PREPARED_STMT_INSERT_INTO_RCPT_TABLE) == ERR) return ERR; - - p = to; do { p = split_str(p, " ", puf, sizeof(puf)-1); @@ -216,7 +210,6 @@ int store_recipients(struct session_data *sdata, struct __data *data, char *to, bind[2].is_null = 0; len[2] = strlen(q); bind[2].length = &len[2]; - if(mysql_stmt_bind_param(data->stmt_insert_into_rcpt_table, bind)){ syslog(LOG_PRIORITY, "%s: %s.mysql_stmt_bind_param() error: %s", sdata->ttmpfile, SQL_RECIPIENT_TABLE, mysql_stmt_error(data->stmt_insert_into_rcpt_table)); ret = ERR; @@ -235,8 +228,6 @@ int store_recipients(struct session_data *sdata, struct __data *data, char *to, CLOSE: - mysql_stmt_close(data->stmt_insert_into_rcpt_table); - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: added %d recipients", sdata->ttmpfile, n); return ret; diff --git a/src/mysql.c b/src/mysql.c index e66910cc..184d212e 100644 --- a/src/mysql.c +++ b/src/mysql.c @@ -36,3 +36,21 @@ void insert_offset(struct session_data *sdata, int server_id){ } +int create_prepared_statements(struct session_data *sdata, struct __data *data){ + int rc = OK; + + data->stmt_get_meta_id_by_message_id = NULL; + data->stmt_insert_into_rcpt_table = NULL; + + if(prepare_a_mysql_statement(sdata, &(data->stmt_get_meta_id_by_message_id), SQL_PREPARED_STMT_GET_META_ID_BY_MESSAGE_ID) == ERR) rc = ERR; + if(prepare_a_mysql_statement(sdata, &(data->stmt_insert_into_rcpt_table), SQL_PREPARED_STMT_INSERT_INTO_RCPT_TABLE) == ERR) rc = ERR; + + return rc; +} + + +void close_prepared_statements(struct __data *data){ + if(data->stmt_get_meta_id_by_message_id) mysql_stmt_close(data->stmt_get_meta_id_by_message_id); + if(data->stmt_insert_into_rcpt_table) mysql_stmt_close(data->stmt_insert_into_rcpt_table); +} + diff --git a/src/piler.h b/src/piler.h index f9f79890..6e1f752f 100644 --- a/src/piler.h +++ b/src/piler.h @@ -65,5 +65,8 @@ int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *de void load_mydomains(struct session_data *sdata, struct __data *data, struct __config *cfg); +int create_prepared_statements(struct session_data *sdata, struct __data *data); +void close_prepared_statements(struct __data *data); + #endif /* _PILER_H */ diff --git a/src/pileraget.c b/src/pileraget.c index 3f97d47d..a4ac20d8 100644 --- a/src/pileraget.c +++ b/src/pileraget.c @@ -44,9 +44,9 @@ int main(int argc, char **argv){ return 1; } - snprintf(filename, sizeof(filename)-1, "%s/%c%c%c/%c%c/%c%c/%s.a%d", cfg.queuedir, argv[1][8], argv[1][9], argv[1][10], argv[1][RND_STR_LEN-4], argv[1][RND_STR_LEN-3], argv[1][RND_STR_LEN-2], argv[1][RND_STR_LEN-1], argv[1], atoi(argv[2])); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.a%d", cfg.queuedir, cfg.server_id, argv[1][8], argv[1][9], argv[1][10], argv[1][RND_STR_LEN-4], argv[1][RND_STR_LEN-3], argv[1][RND_STR_LEN-2], argv[1][RND_STR_LEN-1], argv[1], atoi(argv[2])); if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.a%d", cfg.queuedir, argv[1][RND_STR_LEN-6], argv[1][RND_STR_LEN-5], argv[1][RND_STR_LEN-4], argv[1][RND_STR_LEN-3], argv[1][RND_STR_LEN-2], argv[1][RND_STR_LEN-1], argv[1], atoi(argv[2])); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.a%d", cfg.queuedir, cfg.server_id, argv[1][RND_STR_LEN-6], argv[1][RND_STR_LEN-5], argv[1][RND_STR_LEN-4], argv[1][RND_STR_LEN-3], argv[1][RND_STR_LEN-2], argv[1][RND_STR_LEN-1], argv[1], atoi(argv[2])); } retrieve_file_from_archive(filename, WRITE_TO_STDOUT, NULL, stdout, &cfg); diff --git a/src/pilerimport.c b/src/pilerimport.c index fbb39ec8..35295a90 100644 --- a/src/pilerimport.c +++ b/src/pilerimport.c @@ -484,6 +484,11 @@ int main(int argc, char **argv){ mysql_real_query(&(sdata.mysql), "SET NAMES utf8", strlen("SET NAMES utf8")); mysql_real_query(&(sdata.mysql), "SET CHARACTER SET utf8", strlen("SET CHARACTER SET utf8")); + if(create_prepared_statements(&sdata, &data) == ERR){ + rc = ERR; + goto ENDE; + } + setlocale(LC_CTYPE, cfg.locale); (void) openlog("pilerimport", LOG_PID, LOG_MAIL); @@ -524,6 +529,9 @@ int main(int argc, char **argv){ free_rule(data.archiving_rules); free_rule(data.retention_rules); +ENDE: + close_prepared_statements(&data); + mysql_close(&(sdata.mysql)); if(quiet == 0) printf("\n"); diff --git a/src/pilerpurge.c b/src/pilerpurge.c index 1197edc3..4485f473 100644 --- a/src/pilerpurge.c +++ b/src/pilerpurge.c @@ -60,10 +60,10 @@ int remove_message_frame_files(char *s, char *update_meta_sql, struct session_da p = split(p, ' ', puf, sizeof(puf)-1); if(strlen(puf) == RND_STR_LEN){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, puf[8], puf[9], puf[10], puf[RND_STR_LEN-4], puf[RND_STR_LEN-3], puf[RND_STR_LEN-2], puf[RND_STR_LEN-1], puf); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, puf[8], puf[9], puf[10], puf[RND_STR_LEN-4], puf[RND_STR_LEN-3], puf[RND_STR_LEN-2], puf[RND_STR_LEN-1], puf); if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, puf[RND_STR_LEN-6], puf[RND_STR_LEN-5], puf[RND_STR_LEN-4], puf[RND_STR_LEN-3], puf[RND_STR_LEN-2], puf[RND_STR_LEN-1], puf); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, puf[RND_STR_LEN-6], puf[RND_STR_LEN-5], puf[RND_STR_LEN-4], puf[RND_STR_LEN-3], puf[RND_STR_LEN-2], puf[RND_STR_LEN-1], puf); } if(dryrun == 1){ @@ -129,9 +129,9 @@ int remove_attachments(char *in, struct session_data *sdata, struct __config *cf while((row = mysql_fetch_row(res))){ if(!row[0]) continue; - snprintf(filename, sizeof(filename)-1, "%s/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, row[0][8], row[0][9], row[0][10], row[0][RND_STR_LEN-4], row[0][RND_STR_LEN-3], row[0][RND_STR_LEN-2], row[0][RND_STR_LEN-1], row[0], atoi(row[1])); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, row[0][8], row[0][9], row[0][10], row[0][RND_STR_LEN-4], row[0][RND_STR_LEN-3], row[0][RND_STR_LEN-2], row[0][RND_STR_LEN-1], row[0], atoi(row[1])); if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, row[0][RND_STR_LEN-6], row[0][RND_STR_LEN-5], row[0][RND_STR_LEN-4], row[0][RND_STR_LEN-3], row[0][RND_STR_LEN-2], row[0][RND_STR_LEN-1], row[0], atoi(row[1])); + snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, row[0][RND_STR_LEN-6], row[0][RND_STR_LEN-5], row[0][RND_STR_LEN-4], row[0][RND_STR_LEN-3], row[0][RND_STR_LEN-2], row[0][RND_STR_LEN-1], row[0], atoi(row[1])); } if(dryrun == 1){ diff --git a/src/session.c b/src/session.c index 8af4324d..c8b7d92b 100644 --- a/src/session.c +++ b/src/session.c @@ -79,8 +79,16 @@ int handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){ syslog(LOG_PRIORITY, "%s", ERR_MYSQL_CONNECT); #endif + if(db_conn == 1 && create_prepared_statements(&sdata, data) == ERR){ + close_prepared_statements(data); + mysql_close(&(sdata.mysql)); + db_conn = 0; + } + + if(db_conn == 0){ send(new_sd, SMTP_RESP_421_ERR_TMP, strlen(SMTP_RESP_421_ERR_TMP), 0); + syslog(LOG_PRIORITY, "cannot make prepared statement"); return 0; } @@ -562,6 +570,7 @@ QUITTING: update_counters(&sdata, data, &counters, cfg); #ifdef NEED_MYSQL + close_prepared_statements(data); mysql_close(&(sdata.mysql)); #endif diff --git a/src/store.c b/src/store.c index a0691f49..75b280c2 100644 --- a/src/store.c +++ b/src/store.c @@ -114,7 +114,7 @@ int store_file(struct session_data *sdata, char *filename, int startpos, int len p = strchr(filename, '.'); if(p) *p = '\0'; - snprintf(s, sizeof(s)-1, "%s/%c%c%c/%c%c/%c%c/%s", cfg->queuedir, filename[8], filename[9], filename[10], filename[RND_STR_LEN-4], filename[RND_STR_LEN-3], filename[RND_STR_LEN-2], filename[RND_STR_LEN-1], filename); + snprintf(s, sizeof(s)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s", cfg->queuedir, cfg->server_id, filename[8], filename[9], filename[10], filename[RND_STR_LEN-4], filename[RND_STR_LEN-3], filename[RND_STR_LEN-2], filename[RND_STR_LEN-1], filename); if(p){ *p = '.'; @@ -188,7 +188,7 @@ int remove_stored_message_files(struct session_data *sdata, struct _state *state if(state->n_attachments > 0){ for(i=1; i<=state->n_attachments; i++){ - snprintf(s, sizeof(s)-1, "%s/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, sdata->ttmpfile[8], sdata->ttmpfile[9], sdata->ttmpfile[10], sdata->ttmpfile[RND_STR_LEN-4], sdata->ttmpfile[RND_STR_LEN-3], sdata->ttmpfile[RND_STR_LEN-2], sdata->ttmpfile[RND_STR_LEN-1], sdata->ttmpfile, i); + snprintf(s, sizeof(s)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, sdata->ttmpfile[8], sdata->ttmpfile[9], sdata->ttmpfile[10], sdata->ttmpfile[RND_STR_LEN-4], sdata->ttmpfile[RND_STR_LEN-3], sdata->ttmpfile[RND_STR_LEN-2], sdata->ttmpfile[RND_STR_LEN-1], sdata->ttmpfile, i); if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: unlinking %s", sdata->ttmpfile, s); @@ -196,7 +196,7 @@ int remove_stored_message_files(struct session_data *sdata, struct _state *state } } - snprintf(s, sizeof(s)-1, "%s/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, sdata->ttmpfile[8], sdata->ttmpfile[9], sdata->ttmpfile[10], sdata->ttmpfile[RND_STR_LEN-4], sdata->ttmpfile[RND_STR_LEN-3], sdata->ttmpfile[RND_STR_LEN-2], sdata->ttmpfile[RND_STR_LEN-1], sdata->ttmpfile); + snprintf(s, sizeof(s)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, sdata->ttmpfile[8], sdata->ttmpfile[9], sdata->ttmpfile[10], sdata->ttmpfile[RND_STR_LEN-4], sdata->ttmpfile[RND_STR_LEN-3], sdata->ttmpfile[RND_STR_LEN-2], sdata->ttmpfile[RND_STR_LEN-1], sdata->ttmpfile); if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: unlinking %s", sdata->ttmpfile, s);