diff --git a/etc/example.conf b/etc/example.conf index d31c8d7..e6b81b4 100644 --- a/etc/example.conf +++ b/etc/example.conf @@ -38,6 +38,10 @@ workdir=/var/spool/piler/tmp +; comma separated list of your domains. piler uses this information to determine +; the direction of the given email +mydomains= + ; ; memcached stuff ; diff --git a/etc/sphinx.conf b/etc/sphinx.conf index 50bf719..f18f5b4 100644 --- a/etc/sphinx.conf +++ b/etc/sphinx.conf @@ -11,12 +11,13 @@ sql_pass = sphinx sql_query_pre = SET NAMES utf8 - sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `attachments`, `deleted` FROM sph_index \ + sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments`, `deleted` FROM sph_index \ WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) sql_attr_uint = size sql_attr_uint = arrived sql_attr_uint = sent + sql_attr_uint = direction sql_attr_uint = attachments sql_attr_bool = deleted @@ -33,12 +34,13 @@ sql_query_pre = SET NAMES utf8 sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM sph_index sql_query_post_index = DELETE FROM sph_index WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1) - sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `attachments`, `deleted` FROM sph_index \ + sql_query = SELECT id, `from`, `to`, `subject`, `arrived`, `sent`, `body`, `size`, `direction`, `attachments`, `deleted` FROM sph_index \ WHERE id <= (SELECT max_doc_id FROM sph_counter WHERE counter_id=1) sql_attr_uint = size sql_attr_uint = arrived sql_attr_uint = sent + sql_attr_uint = direction sql_attr_uint = attachments sql_attr_bool = deleted diff --git a/src/cfg.c b/src/cfg.c index 2b8b829..a7512b6 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -72,6 +72,7 @@ { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct __config, max_requests_per_child), "200", sizeof(int)}, { "memcached_servers", "string", (void*) string_parser, offsetof(struct __config, memcached_servers), "127.0.0.1", MAXVAL-1}, { "memcached_ttl", "integer", (void*) int_parser, offsetof(struct __config, memcached_ttl), "86400", sizeof(int)}, + { "mydomains", "string", (void*) string_parser, offsetof(struct __config, mydomains), "", MAXVAL-1}, { "mysqlhost", "string", (void*) string_parser, offsetof(struct __config, mysqlhost), "", MAXVAL-1}, { "mysqlport", "integer", (void*) int_parser, offsetof(struct __config, mysqlport), "", sizeof(int)}, { "mysqlsocket", "string", (void*) string_parser, offsetof(struct __config, mysqlsocket), "/tmp/mysql.sock", MAXVAL-1}, diff --git a/src/cfg.h b/src/cfg.h index acb2b01..557b40c 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -44,6 +44,8 @@ unsigned char key[KEYLEN]; unsigned char iv[MAXVAL]; + char mydomains[MAXVAL]; + // mysql stuff char mysqlhost[MAXVAL]; diff --git a/src/config.h b/src/config.h index 34b7dd6..18e4478 100644 --- a/src/config.h +++ b/src/config.h @@ -94,6 +94,10 @@ #define AVIR_VIRUS 1 +#define DIRECTION_INCOMING 0 +#define DIRECTION_INTERNAL 1 +#define DIRECTION_OUTGOING 2 +#define DIRECTION_INTERNAL_AND_OUTGOING 3 #endif /* _CONFIG_H */ diff --git a/src/defs.h b/src/defs.h index 1c16044..efd8570 100644 --- a/src/defs.h +++ b/src/defs.h @@ -148,10 +148,13 @@ struct session_data { + char filename[SMALLBUFSIZE]; char ttmpfile[SMALLBUFSIZE], tmpframe[SMALLBUFSIZE], tre, restored_copy; char mailfrom[SMALLBUFSIZE], rcptto[MAX_RCPT_TO][SMALLBUFSIZE], client_addr[SMALLBUFSIZE]; char acceptbuf[SMALLBUFSIZE]; char attachments[SMALLBUFSIZE]; + char internal_sender, internal_recipient, external_recipient; + int direction; int fd, hdr_len, tot_len, num_of_rcpt_to, rav; int need_scan; float __acquire, __parsed, __av, __store, __compress, __encrypt; diff --git a/src/digest.c b/src/digest.c index 39a2205..6003048 100644 --- a/src/digest.c +++ b/src/digest.c @@ -44,7 +44,7 @@ SHA256_Init(&context2); - fd = open(sdata->ttmpfile, O_RDONLY); + fd = open(sdata->filename, O_RDONLY); if(fd == -1) return -1; while((n = read(fd, buf, sizeof(buf))) > 0){ diff --git a/src/message.c b/src/message.c index 144686e..ba5ca6c 100644 --- a/src/message.c +++ b/src/message.c @@ -131,7 +131,7 @@ } - snprintf(s, sizeof(s)-1, "INSERT INTO %s (`id`, `from`, `to`, `subject`, `body`, `arrived`, `sent`, `size`, `attachments`, `attachment_types`) values(%llu,?,?,?,?,%ld,%ld,%d,%d,?)", SQL_SPHINX_TABLE, id, sdata->now, sdata->sent, sdata->tot_len, state->n_attachments); + snprintf(s, sizeof(s)-1, "INSERT INTO %s (`id`, `from`, `to`, `subject`, `body`, `arrived`, `sent`, `size`, `direction`, `attachments`, `attachment_types`) values(%llu,?,?,?,?,%ld,%ld,%d,%d,%d,?)", SQL_SPHINX_TABLE, id, sdata->now, sdata->sent, sdata->tot_len, sdata->direction, state->n_attachments); if(mysql_stmt_prepare(stmt, s, strlen(s))){ @@ -169,7 +169,7 @@ bind[4].buffer_type = MYSQL_TYPE_STRING; bind[4].buffer = sdata->attachments; bind[4].is_null = 0; - len[4] = strlen(sdata->attachments); bind[4].length = &len[3]; + len[4] = strlen(sdata->attachments); bind[4].length = &len[4]; if(mysql_stmt_bind_param(stmt, bind)){ @@ -265,7 +265,7 @@ subj = state->b_subject; if(*subj == ' ') subj++; - snprintf(s, MAXBUFSIZE-1, "INSERT INTO %s (`from`,`subject`,`arrived`,`sent`,`size`,`hlen`,`attachments`,`piler_id`,`message_id`,`digest`,`bodydigest`) VALUES(?,?,%ld,%ld,%d,%d,%d,'%s',?,'%s','%s')", SQL_METADATA_TABLE, sdata->now, sdata->sent, sdata->tot_len, sdata->hdr_len, state->n_attachments, sdata->ttmpfile, sdata->digest, sdata->bodydigest); + snprintf(s, MAXBUFSIZE-1, "INSERT INTO %s (`from`,`subject`,`arrived`,`sent`,`size`,`hlen`,`direction`,`attachments`,`piler_id`,`message_id`,`digest`,`bodydigest`) VALUES(?,?,%ld,%ld,%d,%d,%d,%d,'%s',?,'%s','%s')", SQL_METADATA_TABLE, sdata->now, sdata->sent, sdata->tot_len, sdata->hdr_len, sdata->direction, state->n_attachments, sdata->ttmpfile, sdata->digest, sdata->bodydigest); if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: meta sql: *%s*", sdata->ttmpfile, s); diff --git a/src/misc.c b/src/misc.c index 77b889c..0b89741 100644 --- a/src/misc.c +++ b/src/misc.c @@ -341,6 +341,72 @@ } +int is_email_address_on_my_domains(char *email, struct __config *cfg){ + int rc=0; + char *p, *q=NULL; + + if(email == NULL || cfg->mydomains == NULL) return rc; + + p = strchr(email, '@'); + + if(!p) return rc; + + if(strlen(p) < 3) return rc; + + q = strrchr(p+1, ' '); + + if(q) *q = '\0'; + + if(strcasestr(cfg->mydomains, p+1)) rc = 1; + + if(q) *q = ' '; + + return rc; +} + + +void init_session_data(struct session_data *sdata){ + int i; + + + sdata->fd = -1; + + create_id(&(sdata->ttmpfile[0])); + unlink(sdata->ttmpfile); + + snprintf(sdata->filename, SMALLBUFSIZE-1, "%s", sdata->ttmpfile); + + snprintf(sdata->tmpframe, SMALLBUFSIZE-1, "%s.m", sdata->ttmpfile); + unlink(sdata->tmpframe); + + memset(sdata->mailfrom, 0, SMALLBUFSIZE); + snprintf(sdata->client_addr, SMALLBUFSIZE-1, "null"); + + memset(sdata->attachments, 0, SMALLBUFSIZE); + + sdata->restored_copy = 0; + + sdata->internal_sender = sdata->internal_recipient = sdata->external_recipient = 0; + sdata->direction = 0; + + sdata->hdr_len = 0; + sdata->tot_len = 0; + sdata->num_of_rcpt_to = 0; + + sdata->tre = '-'; + + sdata->rav = AVIR_OK; + + sdata->__acquire = sdata->__parsed = sdata->__av = sdata->__store = sdata->__compress = sdata->__encrypt = 0; + + + for(i=0; ircptto[i], 0, SMALLBUFSIZE); + + time(&(sdata->now)); + sdata->sent = sdata->now; +} + + #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 03d402a..df6439c 100644 --- a/src/misc.h +++ b/src/misc.h @@ -23,14 +23,12 @@ int get_random_bytes(unsigned char *buf, int len); int readFromEntropyPool(int fd, void *_s, size_t n); int recvtimeout(int s, char *buf, int len, int timeout); -int isValidClapfID(char *p); - -int isDottedIPv4Address(char *s); -int isEmailAddressOnList(char *list, char *tmpfile, char *email, struct __config *cfg); void write_pid_file(char *pidfile); int drop_privileges(struct passwd *pwd); +int is_email_address_on_my_domains(char *email, struct __config *cfg); +void init_session_data(struct session_data *sdata); #ifndef _GNU_SOURCE char *strcasestr(const char *s, const char *find); diff --git a/src/parser.c b/src/parser.c index 32d87ca..121ca11 100644 --- a/src/parser.c +++ b/src/parser.c @@ -18,13 +18,12 @@ struct _state parse_message(struct session_data *sdata, struct __config *cfg){ FILE *f; - char *p, buf[MAXBUFSIZE]; + char buf[MAXBUFSIZE]; struct _state state; - int i, len; init_state(&state); - f = fopen(sdata->ttmpfile, "r"); + f = fopen(sdata->filename, "r"); if(!f){ syslog(LOG_PRIORITY, "%s: cannot open", sdata->ttmpfile); return state; @@ -34,6 +33,7 @@ state.mfd = open(sdata->tmpframe, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); if(state.mfd == -1){ syslog(LOG_PRIORITY, "%s: cannot open frame file: %s", sdata->ttmpfile, sdata->tmpframe); + fclose(f); return state; } @@ -45,38 +45,52 @@ close(state.mfd); state.mfd = 0; fclose(f); - - free_list(state.boundaries); - free_list(state.rcpt); - - trimBuffer(state.b_subject); - fixupEncodedHeaderLine(state.b_subject); + return state; +} - for(i=1; i<=state.n_attachments; i++){ - digest_file(state.attachments[i].internalname, &(state.attachments[i].digest[0])); - fixupEncodedHeaderLine(state.attachments[i].filename); +void post_parse(struct session_data *sdata, struct _state *state, struct __config *cfg){ + int i, len; + char *p; - if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: attachment list: i:%d, name=*%s*, type: *%s*, size: %d, int.name: %s, digest: %s", sdata->ttmpfile, i, state.attachments[i].filename, state.attachments[i].type, state.attachments[i].size, state.attachments[i].internalname, state.attachments[i].digest); + free_list(state->boundaries); + free_list(state->rcpt); - p = determine_attachment_type(state.attachments[i].filename, state.attachments[i].type); - len = strlen(p); + trimBuffer(state->b_subject); + fixupEncodedHeaderLine(state->b_subject); - if(strlen(sdata->attachments) < SMALLBUFSIZE-len-1) memcpy(&(sdata->attachments[strlen(sdata->attachments)]), p, len); + + if(sdata->internal_sender == 0) sdata->direction = DIRECTION_INCOMING; + else { + if(sdata->internal_recipient == 1) sdata->direction = DIRECTION_INTERNAL; + if(sdata->external_recipient == 1) sdata->direction = DIRECTION_OUTGOING; + if(sdata->internal_recipient == 1 && sdata->external_recipient == 1) sdata->direction = DIRECTION_INTERNAL_AND_OUTGOING; } - if(state.message_id[0] == 0) snprintf(state.message_id, SMALLBUFSIZE-1, "null"); + for(i=1; i<=state->n_attachments; i++){ + digest_file(state->attachments[i].internalname, &(state->attachments[i].digest[0])); + fixupEncodedHeaderLine(state->attachments[i].filename); - len = strlen(state.b_from); - if(state.b_from[len-1] == ' ') state.b_from[len-1] = '\0'; + if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "%s: attachment list: i:%d, name=*%s*, type: *%s*, size: %d, int.name: %s, digest: %s", sdata->ttmpfile, i, state->attachments[i].filename, state->attachments[i].type, state->attachments[i].size, state->attachments[i].internalname, state->attachments[i].digest); - len = strlen(state.b_to); - if(state.b_to[len-1] == ' ') state.b_to[len-1] = '\0'; + p = determine_attachment_type(state->attachments[i].filename, state->attachments[i].type); + len = strlen(p); - syslog(LOG_PRIORITY, "%s: from=%s, to=%s, subj=%s, message-id=%s", sdata->ttmpfile, state.b_from, state.b_to, state.b_subject, state.message_id); + if(strlen(sdata->attachments) < SMALLBUFSIZE-len-1 && !strstr(sdata->attachments, p)) memcpy(&(sdata->attachments[strlen(sdata->attachments)]), p, len); + } - return state; + + if(state->message_id[0] == 0) snprintf(state->message_id, SMALLBUFSIZE-1, "null"); + + len = strlen(state->b_from); + if(state->b_from[len-1] == ' ') state->b_from[len-1] = '\0'; + + len = strlen(state->b_to); + if(state->b_to[len-1] == ' ') state->b_to[len-1] = '\0'; + + syslog(LOG_PRIORITY, "%s: from=%s, to=%s, subj=%s, message-id=%s", sdata->ttmpfile, state->b_from, state->b_to, state->b_subject, state->message_id); + } @@ -384,14 +398,20 @@ len = strlen(puf); - if(state->message_state == MSG_FROM && strchr(puf, '@') && strlen(puf) > 5 && state->is_1st_header == 1 && state->b_from[0] == '\0' && strlen(state->b_from) < SMALLBUFSIZE-len-1) + if(state->message_state == MSG_FROM && strchr(puf, '@') && strlen(puf) > 5 && state->is_1st_header == 1 && state->b_from[0] == '\0' && strlen(state->b_from) < SMALLBUFSIZE-len-1){ memcpy(&(state->b_from[strlen(state->b_from)]), puf, len); + if(is_email_address_on_my_domains(puf, cfg) == 1) sdata->internal_sender = 1; + } else if((state->message_state == MSG_TO || state->message_state == MSG_CC) && state->is_1st_header == 1 && strchr(puf, '@') && strlen(puf) > 5 && strlen(state->b_to) < SMALLBUFSIZE-len-1){ if(is_string_on_list(state->rcpt, puf) == 0){ append_list(&(state->rcpt), puf); memcpy(&(state->b_to[strlen(state->b_to)]), puf, len); + + if(is_email_address_on_my_domains(puf, cfg) == 1) sdata->internal_recipient = 1; + else sdata->external_recipient = 1; + } } else if(state->message_state == MSG_BODY && strlen(state->b_body) < BIGBUFSIZE-len-1) diff --git a/src/parser.h b/src/parser.h index 591e4bc..ba8b429 100644 --- a/src/parser.h +++ b/src/parser.h @@ -10,6 +10,7 @@ #include "defs.h" struct _state parse_message(struct session_data *sdata, struct __config *cfg); +void post_parse(struct session_data *sdata, struct _state *state, struct __config *cfg); int parse_line(char *buf, struct _state *state, struct session_data *sdata, struct __config *cfg); void init_state(struct _state *state); diff --git a/src/pilerget.c b/src/pilerget.c index d0a6d37..8fc1968 100644 --- a/src/pilerget.c +++ b/src/pilerget.c @@ -389,6 +389,8 @@ memset(sdata.ttmpfile, 0, sizeof(sdata.ttmpfile)); while((rc = read(0, sdata.ttmpfile, RND_STR_LEN+1)) > 0){ + snprintf(sdata.filename, SMALLBUFSIZE-1, "%s", sdata.ttmpfile); + trimBuffer(sdata.ttmpfile); id = get_id_by_piler_id(&sdata, &digest[0], &bodydigest[0], &cfg); @@ -420,6 +422,7 @@ } else { snprintf(sdata.ttmpfile, SMALLBUFSIZE-1, "%s", argv[1]); + snprintf(sdata.filename, SMALLBUFSIZE-1, "%s", sdata.ttmpfile); rc = retrieve_email_from_archive(&sdata, stdout, &cfg); } diff --git a/src/pilerimport.c b/src/pilerimport.c index 0cb4b7c..f037b32 100644 --- a/src/pilerimport.c +++ b/src/pilerimport.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -16,8 +16,12 @@ #include +extern char *optarg; +extern int optind; + + int import_message(char *filename, struct session_data *sdata, struct __data *data, struct __config *cfg){ - int i, rc=ERR; + int rc=ERR; char *rule; struct stat st; struct _state state; @@ -27,25 +31,32 @@ return rc; } + if(S_ISREG(st.st_mode) == 0){ + printf("%s is not a file\n", filename); + return rc; + } - create_id(&(sdata->ttmpfile[0])); - printf("a: %s\n", sdata->ttmpfile); - - link(filename, sdata->ttmpfile); - - sdata->num_of_rcpt_to = -1; - memset(sdata->rcptto[0], 0, SMALLBUFSIZE); - - time(&(sdata->now)); + init_session_data(sdata); + snprintf(sdata->filename, SMALLBUFSIZE-1, "%s", filename); + sdata->sent = 0; - sdata->hdr_len = 0; sdata->tot_len = st.st_size; - memset(sdata->attachments, 0, SMALLBUFSIZE); - - snprintf(sdata->tmpframe, SMALLBUFSIZE-1, "%s.m", sdata->ttmpfile); state = parse_message(sdata, cfg); + post_parse(sdata, &state, cfg); + + if(sdata->sent > sdata->now) sdata->sent = sdata->now; + + /*printf("message-id: %s\n", state.message_id); + printf("from: *%s*\n", state.b_from); + printf("to: *%s*\n", state.b_to); + printf("subject: *%s*\n", state.b_subject); + printf("attachments:%s\n", sdata->attachments); + printf("direction: %d\n", sdata->direction);*/ + + + rule = check_againt_ruleset(data->rules, &state, st.st_size); @@ -55,54 +66,157 @@ goto ENDE; } - - printf("message-id: %s\n", state.message_id); - printf("from: *%s*\n", state.b_from); - printf("to: *%s*\n", state.b_to); - printf("subject: *%s*\n", state.b_subject); - make_digests(sdata, cfg); - printf("hdr len: %d\n", sdata->hdr_len); - - printf("body digest: %s\n", sdata->bodydigest); - - for(i=1; i<=state.n_attachments; i++){ - printf("i:%d, name=*%s*, type: *%s*, size: %d, int.name: %s, digest: %s\n", i, state.attachments[i].filename, state.attachments[i].type, state.attachments[i].size, state.attachments[i].internalname, state.attachments[i].digest); - } - - printf("attachments:%s\n", sdata->attachments); - - printf("\n\n"); - rc = processMessage(sdata, &state, cfg); ENDE: - unlink(sdata->ttmpfile); unlink(sdata->tmpframe); - if(rc == ERR) return rc; + switch(rc) { + case OK: + printf("imported: %s\n", filename); + break; - if(rc == ERR_EXISTS) printf("discarding duplicate message: %s\n", sdata->ttmpfile); + case ERR_EXISTS: + printf("discarding duplicate message: %s\n", filename); + break; - - return OK; + default: + printf("failed to import: %s\n", filename); + break; + } + + printf("\n\n"); + + return rc; +} + + +int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data *data, struct __config *cfg){ + FILE *F, *f=NULL; + int rc=ERR, tot_msgs=0; + char buf[MAXBUFSIZE], fname[SMALLBUFSIZE]; + time_t t; + + + F = fopen(mailbox, "r"); + if(!F){ + printf("cannot open mailbox: %s\n", mailbox); + return rc; + } + + t = time(NULL); + + while(fgets(buf, sizeof(buf)-1, F)){ + + if(buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && buf[3] == 'm' && buf[4] == ' '){ + tot_msgs++; + if(f){ + fclose(f); + rc = import_message(fname, sdata, data, cfg); + unlink(fname); + } + + snprintf(fname, sizeof(fname)-1, "%ld-%d", t, tot_msgs); + f = fopen(fname, "w+"); + continue; + } + + if(f) fprintf(f, "%s", buf); + } + + if(f){ + fclose(f); + rc = import_message(fname, sdata, data, cfg); + unlink(fname); + } + + fclose(F); + + + return rc; +} + + +int import_from_maildir(char *directory, struct session_data *sdata, struct __data *data, struct __config *cfg){ + DIR *dir; + struct dirent *de; + int rc=ERR, tot_msgs=0; + char fname[SMALLBUFSIZE]; + + dir = opendir(directory); + if(!dir){ + printf("cannot open directory: %s\n", directory); + return rc; + } + + while((de = readdir(dir))){ + if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; + + snprintf(fname, sizeof(fname)-1, "%s/%s", directory, de->d_name); + + rc = import_message(fname, sdata, data, cfg); + + if(rc != ERR) tot_msgs++; + + } + closedir(dir); + + return rc; +} + + +void usage(){ + printf("usage: pilerimport -e -m -d \n"); + exit(0); } int main(int argc, char **argv){ - int rc; + int i, rc; + char *configfile=CONFIG_FILE, *mailbox=NULL, *emlfile=NULL, *directory=NULL; struct session_data sdata; struct __config cfg; struct __data data; - if(argc < 2){ - printf("usage: %s \n", argv[0]); - exit(1); + while((i = getopt(argc, argv, "c:m:e:d:h?")) > 0){ + switch(i){ + + case 'c' : + configfile = optarg; + break; + + case 'e' : + emlfile = optarg; + break; + + case 'd' : + directory = optarg; + break; + + case 'm' : + mailbox = optarg; + break; + + case 'h' : + case '?' : + usage(); + break; + + + default : + break; + } } - cfg = read_config(CONFIG_FILE); + + + if(!mailbox && !emlfile && !directory) usage(); + + + cfg = read_config(configfile); if(read_key(&cfg)){ printf("%s\n", ERR_READING_KEY); @@ -119,7 +233,6 @@ 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")); - printf("locale: %s\n", setlocale(LC_MESSAGES, cfg.locale)); setlocale(LC_CTYPE, cfg.locale); data.rules = NULL; @@ -128,7 +241,9 @@ - rc = import_message(argv[1], &sdata, &data, &cfg); + if(emlfile) rc = import_message(emlfile, &sdata, &data, &cfg); + if(mailbox) rc = import_from_mailbox(mailbox, &sdata, &data, &cfg); + if(directory) rc = import_from_maildir(directory, &sdata, &data, &cfg); diff --git a/src/session.c b/src/session.c index 582cbf8..766e631 100644 --- a/src/session.c +++ b/src/session.c @@ -36,7 +36,7 @@ state = SMTP_STATE_INIT; - initSessionData(&sdata); + init_session_data(&sdata); bzero(&counters, sizeof(counters)); @@ -141,7 +141,10 @@ gettimeofday(&tv1, &tz); + sstate = parse_message(&sdata, cfg); + post_parse(&sdata, &sstate, cfg); + gettimeofday(&tv2, &tz); sdata.__parsed = tvdiff(tv2, tv1); @@ -378,7 +381,7 @@ strncat(resp, SMTP_RESP_503_ERR, MAXBUFSIZE-1); } else { - sdata.fd = open(sdata.ttmpfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP); + sdata.fd = open(sdata.filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP); if(sdata.fd == -1){ syslog(LOG_PRIORITY, "%s: %s", ERR_OPEN_TMP_FILE, sdata.ttmpfile); strncat(resp, SMTP_RESP_451_ERR, MAXBUFSIZE-1); @@ -424,7 +427,7 @@ unlink(sdata.ttmpfile); unlink(sdata.tmpframe); - initSessionData(&sdata); + init_session_data(&sdata); state = SMTP_STATE_HELO; @@ -487,39 +490,3 @@ } -void initSessionData(struct session_data *sdata){ - int i; - - - sdata->fd = -1; - - create_id(&(sdata->ttmpfile[0])); - unlink(sdata->ttmpfile); - - snprintf(sdata->tmpframe, SMALLBUFSIZE-1, "%s.m", sdata->ttmpfile); - unlink(sdata->tmpframe); - - memset(sdata->mailfrom, 0, SMALLBUFSIZE); - snprintf(sdata->client_addr, SMALLBUFSIZE-1, "null"); - - memset(sdata->attachments, 0, SMALLBUFSIZE); - - sdata->restored_copy = 0; - - sdata->hdr_len = 0; - sdata->tot_len = 0; - sdata->num_of_rcpt_to = 0; - - sdata->tre = '-'; - - sdata->rav = AVIR_OK; - - sdata->__acquire = sdata->__parsed = sdata->__av = sdata->__store = sdata->__compress = sdata->__encrypt = 0; - - - for(i=0; ircptto[i], 0, SMALLBUFSIZE); - - time(&(sdata->now)); - sdata->sent = sdata->now; -} - diff --git a/src/test.c b/src/test.c index 250ac05..4c00931 100644 --- a/src/test.c +++ b/src/test.c @@ -56,18 +56,18 @@ load_archiving_rules(&sdata, &(data.rules)); rc = 0; + + init_session_data(&sdata); - sdata.num_of_rcpt_to = -1; - time(&(sdata.now)); sdata.sent = 0; sdata.tot_len = st.st_size; - memset(sdata.rcptto[0], 0, SMALLBUFSIZE); - memset(sdata.attachments, 0, SMALLBUFSIZE); + snprintf(sdata.ttmpfile, SMALLBUFSIZE-1, "%s", argv[1]); + snprintf(sdata.filename, SMALLBUFSIZE-1, "%s", argv[1]); snprintf(sdata.tmpframe, SMALLBUFSIZE-1, "%s.m", argv[1]); - state = parse_message(&sdata, &cfg); + post_parse(&sdata, &state, &cfg); printf("message-id: %s\n", state.message_id); printf("from: *%s*\n", state.b_from); @@ -93,6 +93,8 @@ printf("attachments:%s\n", sdata.attachments); + printf("direction: %d\n", sdata.direction); + printf("\n\n"); mysql_close(&(sdata.mysql)); diff --git a/util/db-mysql.sql b/util/db-mysql.sql index 569e819..c4f0bde 100644 --- a/util/db-mysql.sql +++ b/util/db-mysql.sql @@ -20,6 +20,7 @@ `sent` int not null, `body` text, `size` int default '0', + `direction` int default 0, `attachments` int default 0, `attachment_types` text(512) default null, primary key (`id`) @@ -36,6 +37,7 @@ `deleted` tinyint(1) default 0, `size` int default 0, `hlen` int default 0, + `direction` int default 0, `attachments` int default 0, `piler_id` char(36) not null, `message_id` char(128) character set 'latin1' not null, @@ -62,7 +64,7 @@ drop view if exists `messages`; -create view `messages` AS select `metadata`.`id` AS `id`,`metadata`.`piler_id` AS `piler_id`,`metadata`.`from` AS `from`,`rcpt`.`to` AS `to`,`metadata`.`subject` AS `subject`, `metadata`.`size` AS `size`, `metadata`.`arrived` AS `arrived` from (`metadata` join `rcpt`) where (`metadata`.`id` = `rcpt`.`id`); +create view `messages` AS select `metadata`.`id` AS `id`,`metadata`.`piler_id` AS `piler_id`,`metadata`.`from` AS `from`,`rcpt`.`to` AS `to`,`metadata`.`subject` AS `subject`, `metadata`.`size` AS `size`, `metadata`.`direction` AS `direction`, `metadata`.`arrived` AS `arrived` from (`metadata` join `rcpt`) where (`metadata`.`id` = `rcpt`.`id`); drop table if exists `attachment`; create table if not exists `attachment` ( @@ -150,7 +152,7 @@ create index `user_settings_idx` on `user_settings`(`username`); - +drop table if exists `user`; create table if not exists `user` ( `uid` int unsigned not null primary key, `gid` int unsigned not null, @@ -165,6 +167,7 @@ insert into `user` (`uid`, `gid`, `username`, `realname`, `password`, `policy_group`, `isadmin`, `domain`) values (0, 0, 'admin', 'built-in piler admin', '$1$PItc7d$zsUgON3JRrbdGS11t9JQW1', 0, 1, 'local'); +drop table if exists `email`; create table if not exists `email` ( `uid` int unsigned not null, `email` char(128) not null primary key @@ -190,6 +193,7 @@ ) ENGINE=InnoDB; +drop table if exists `domain`; create table if not exists `domain` ( `domain` char(64) not null primary key, `mapped` char(64) not null