diff --git a/configure b/configure index 8bf81927..1698ca39 100755 --- a/configure +++ b/configure @@ -673,6 +673,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -751,6 +752,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1003,6 +1005,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1140,7 +1151,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1293,6 +1304,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -4866,7 +4878,7 @@ echo; echo CFLAGS="$static -O2 -Wall -g" LIBS="$antispam_libs $sunos_libs " -OBJS="dirs.o base64.o misc.o counters.o cfg.o sig.o decoder.o hash.o parser.o parser_utils.o rules.o smtp.o session.o bdat.o message.o attachment.o digest.o store.o archive.o tai.o import.o import_maildir.o import_mailbox.o import_pop3.o import_imap.o import_gui.o imap.o pop3.o extract.o mydomains.o $objs" +OBJS="dirs.o base64.o misc.o counters.o cfg.o sig.o decoder.o hash.o parser.o parser_utils.o rules.o smtp.o session.o bdat.o message.o attachment.o digest.o store.o archive.o tai.o import.o import_maildir.o import_mailbox.o import_pop3.o import_imap.o imap.o pop3.o extract.o mydomains.o $objs" ac_config_files="$ac_config_files Makefile src/Makefile etc/Makefile util/Makefile init.d/Makefile unit_tests/Makefile contrib/imap/Makefile" diff --git a/configure.in b/configure.in index cc6f09bc..9cde7be0 100644 --- a/configure.in +++ b/configure.in @@ -544,7 +544,7 @@ echo; echo CFLAGS="$static -O2 -Wall -g" LIBS="$antispam_libs $sunos_libs " -OBJS="dirs.o base64.o misc.o counters.o cfg.o sig.o decoder.o hash.o parser.o parser_utils.o rules.o smtp.o session.o bdat.o message.o attachment.o digest.o store.o archive.o tai.o import.o import_maildir.o import_mailbox.o import_pop3.o import_imap.o import_gui.o imap.o pop3.o extract.o mydomains.o $objs" +OBJS="dirs.o base64.o misc.o counters.o cfg.o sig.o decoder.o hash.o parser.o parser_utils.o rules.o smtp.o session.o bdat.o message.o attachment.o digest.o store.o archive.o tai.o import.o import_maildir.o import_mailbox.o import_pop3.o import_imap.o imap.o pop3.o extract.o mydomains.o $objs" AC_CONFIG_FILES([Makefile src/Makefile etc/Makefile util/Makefile init.d/Makefile unit_tests/Makefile contrib/imap/Makefile]) AC_OUTPUT diff --git a/src/archive.c b/src/archive.c index 17196a3a..628387ca 100644 --- a/src/archive.c +++ b/src/archive.c @@ -131,7 +131,7 @@ int inf(unsigned char *in, int len, int mode, char **buffer, FILE *dest){ } -int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct __config *cfg){ +int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct config *cfg){ int rc=0, n, olen, tlen, len, fd=-1; unsigned char *s=NULL, *addr=NULL, inbuf[REALLYBIGBUFSIZE]; struct stat st; @@ -234,7 +234,7 @@ CLEANUP: } -int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, FILE *dest, struct __config *cfg){ +int retrieve_email_from_archive(struct session_data *sdata, struct data *data, FILE *dest, struct config *cfg){ int i, attachments; char *buffer=NULL, *saved_buffer, *p, filename[SMALLBUFSIZE], pointer[SMALLBUFSIZE]; struct ptr_array ptr_arr[MAX_ATTACHMENTS]; diff --git a/src/attachment.c b/src/attachment.c index 08d1ac87..8e243191 100644 --- a/src/attachment.c +++ b/src/attachment.c @@ -16,7 +16,7 @@ #include -int store_attachments(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg){ +int store_attachments(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg){ uint64 id=0; int i, rc=1, found, affected_rows; @@ -91,7 +91,7 @@ CLOSE: } -int query_attachment_pointers(struct session_data *sdata, struct __data *data, uint64 ptr, char *piler_id, int *id){ +int query_attachment_pointers(struct session_data *sdata, struct data *data, uint64 ptr, char *piler_id, int *id){ int rc=0; if(prepare_sql_statement(sdata, &(data->stmt_get_attachment_pointer), SQL_PREPARED_STMT_GET_ATTACHMENT_POINTER) == ERR) return rc; @@ -120,7 +120,7 @@ int query_attachment_pointers(struct session_data *sdata, struct __data *data, u } -int query_attachments(struct session_data *sdata, struct __data *data, struct ptr_array *ptr_arr){ +int query_attachments(struct session_data *sdata, struct data *data, struct ptr_array *ptr_arr){ int i, rc, id, attachments=0; uint64 ptr; diff --git a/src/av.h b/src/av.h index 7439e30f..883e4ff7 100644 --- a/src/av.h +++ b/src/av.h @@ -20,6 +20,6 @@ #define CLAMD_RESP_INFECTED "FOUND" #define CLAMD_RESP_ERROR "ERROR" -int clamd_scan(char *tmpfile, struct __config *cfg); +int clamd_scan(char *tmpfile, struct config *cfg); #endif /* _AV_H */ diff --git a/src/avir.c b/src/avir.c index d9da95bf..4bc29349 100644 --- a/src/avir.c +++ b/src/avir.c @@ -10,7 +10,7 @@ #include -int do_av_check(char *filename, struct __config *cfg){ +int do_av_check(char *filename, struct config *cfg){ int rav = AVIR_OK; if(clamd_scan(filename, cfg) == AV_VIRUS) rav = AVIR_VIRUS; diff --git a/src/bdat.c b/src/bdat.c index 14e90294..1773206f 100644 --- a/src/bdat.c +++ b/src/bdat.c @@ -78,7 +78,7 @@ void process_bdat(struct smtp_session *session, char *readbuf, int readlen){ session->bdat_bytes_to_read -= readlen; if(session->fd != -1){ - write(session->fd, readbuf, readlen); + if(write(session->fd, readbuf, readlen) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); session->tot_len += readlen; if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_INFO, "%s: wrote %d bytes, %d bytes to go", session->ttmpfile, readlen, session->bdat_bytes_to_read); diff --git a/src/cfg.c b/src/cfg.c index f8e0df73..27e21db2 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -59,60 +59,60 @@ struct _parse_rule { struct _parse_rule config_parse_rules[] = { - { "archive_emails_not_having_message_id", "integer", (void*) int_parser, offsetof(struct __config, archive_emails_not_having_message_id), "0", sizeof(int)}, - { "archive_only_mydomains", "integer", (void*) int_parser, offsetof(struct __config, archive_only_mydomains), "0", sizeof(int)}, - { "backlog", "integer", (void*) int_parser, offsetof(struct __config, backlog), "20", sizeof(int)}, - { "cipher_list", "string", (void*) string_parser, offsetof(struct __config, cipher_list), "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS", MAXVAL-1}, - { "clamd_addr", "string", (void*) string_parser, offsetof(struct __config, clamd_addr), "", MAXVAL-1}, - { "clamd_port", "integer", (void*) int_parser, offsetof(struct __config, clamd_port), "0", sizeof(int)}, - { "clamd_socket", "string", (void*) string_parser, offsetof(struct __config, clamd_socket), CLAMD_SOCKET, MAXVAL-1}, - { "debug", "integer", (void*) int_parser, offsetof(struct __config, debug), "0", sizeof(int)}, - { "default_retention_days", "integer", (void*) int_parser, offsetof(struct __config, default_retention_days), "2557", sizeof(int)}, - { "enable_chunking", "integer", (void*) int_parser, offsetof(struct __config, enable_chunking), "0", sizeof(int)}, - { "enable_cjk", "integer", (void*) int_parser, offsetof(struct __config, enable_cjk), "0", sizeof(int)}, - { "enable_folders", "integer", (void*) int_parser, offsetof(struct __config, enable_folders), "0", sizeof(int)}, - { "encrypt_messages", "integer", (void*) int_parser, offsetof(struct __config, encrypt_messages), "1", sizeof(int)}, - { "extra_to_field", "string", (void*) string_parser, offsetof(struct __config, extra_to_field), "", MAXVAL-1}, - { "extract_attachments", "integer", (void*) int_parser, offsetof(struct __config, extract_attachments), "1", sizeof(int)}, - { "helper_timeout", "integer", (void*) int_parser, offsetof(struct __config, helper_timeout), "20", sizeof(int)}, - { "hostid", "string", (void*) string_parser, offsetof(struct __config, hostid), HOSTID, MAXVAL-1}, - { "iv", "string", (void*) string_parser, offsetof(struct __config, iv), "", MAXVAL-1}, - { "listen_addr", "string", (void*) string_parser, offsetof(struct __config, listen_addr), "0.0.0.0", MAXVAL-1}, - { "listen_port", "integer", (void*) int_parser, offsetof(struct __config, listen_port), "25", sizeof(int)}, - { "locale", "string", (void*) string_parser, offsetof(struct __config, locale), "", MAXVAL-1}, - { "max_connections", "integer", (void*) int_parser, offsetof(struct __config, max_connections), "64", sizeof(int)}, - { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct __config, max_requests_per_child), "1000", sizeof(int)}, - { "memcached_servers", "string", (void*) string_parser, offsetof(struct __config, memcached_servers), "127.0.0.1", MAXVAL-1}, - { "memcached_to_db_interval", "integer", (void*) int_parser, offsetof(struct __config, memcached_to_db_interval), "900", sizeof(int)}, - { "memcached_ttl", "integer", (void*) int_parser, offsetof(struct __config, memcached_ttl), "86400", sizeof(int)}, - { "min_message_size", "integer", (void*) int_parser, offsetof(struct __config, min_message_size), "100", sizeof(int)}, - { "min_word_len", "integer", (void*) int_parser, offsetof(struct __config, min_word_len), "1", sizeof(int)}, - { "mmap_dedup_test", "integer", (void*) int_parser, offsetof(struct __config, mmap_dedup_test), "0", sizeof(int)}, - { "mysqlcharset", "string", (void*) string_parser, offsetof(struct __config, mysqlcharset), "utf8mb4", 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}, - { "mysqluser", "string", (void*) string_parser, offsetof(struct __config, mysqluser), "piler", MAXVAL-1}, - { "mysqlpwd", "string", (void*) string_parser, offsetof(struct __config, mysqlpwd), "", MAXVAL-1}, - { "mysqldb", "string", (void*) string_parser, offsetof(struct __config, mysqldb), "piler", MAXVAL-1}, - { "mysql_connect_timeout", "integer", (void*) int_parser, offsetof(struct __config, mysql_connect_timeout), "2", sizeof(int)}, - { "number_of_worker_processes", "integer", (void*) int_parser, offsetof(struct __config, number_of_worker_processes), "2", sizeof(int)}, - { "pemfile", "string", (void*) string_parser, offsetof(struct __config, pemfile), "", MAXVAL-1}, - { "pidfile", "string", (void*) string_parser, offsetof(struct __config, pidfile), PIDFILE, MAXVAL-1}, - { "piler_header_field", "string", (void*) string_parser, offsetof(struct __config, piler_header_field), "X-piler-id:", MAXVAL-1}, - { "process_rcpt_to_addresses", "integer", (void*) int_parser, offsetof(struct __config, process_rcpt_to_addresses), "0", sizeof(int)}, - { "queuedir", "string", (void*) string_parser, offsetof(struct __config, queuedir), QUEUE_DIR, MAXVAL-1}, - { "server_id", "integer", (void*) int_parser, offsetof(struct __config, server_id), "0", sizeof(int)}, - { "smtp_timeout", "integer", (void*) int_parser, offsetof(struct __config, smtp_timeout), "60", sizeof(int)}, - { "spam_header_line", "string", (void*) string_parser, offsetof(struct __config, spam_header_line), "", MAXVAL-1}, - { "syslog_recipients", "integer", (void*) int_parser, offsetof(struct __config, syslog_recipients), "0", sizeof(int)}, - { "tls_enable", "integer", (void*) int_parser, offsetof(struct __config, tls_enable), "0", sizeof(int)}, - { "tweak_sent_time_offset", "integer", (void*) int_parser, offsetof(struct __config, tweak_sent_time_offset), "0", sizeof(int)}, - { "update_counters_to_memcached", "integer", (void*) int_parser, offsetof(struct __config, update_counters_to_memcached), "0", sizeof(int)}, - { "username", "string", (void*) string_parser, offsetof(struct __config, username), "piler", MAXVAL-1}, - { "use_antivirus", "integer", (void*) int_parser, offsetof(struct __config, use_antivirus), "1", sizeof(int)}, - { "verbosity", "integer", (void*) int_parser, offsetof(struct __config, verbosity), "1", sizeof(int)}, - { "workdir", "string", (void*) string_parser, offsetof(struct __config, workdir), WORK_DIR, MAXVAL-1}, + { "archive_emails_not_having_message_id", "integer", (void*) int_parser, offsetof(struct config, archive_emails_not_having_message_id), "0", sizeof(int)}, + { "archive_only_mydomains", "integer", (void*) int_parser, offsetof(struct config, archive_only_mydomains), "0", sizeof(int)}, + { "backlog", "integer", (void*) int_parser, offsetof(struct config, backlog), "20", sizeof(int)}, + { "cipher_list", "string", (void*) string_parser, offsetof(struct config, cipher_list), "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS", MAXVAL-1}, + { "clamd_addr", "string", (void*) string_parser, offsetof(struct config, clamd_addr), "", MAXVAL-1}, + { "clamd_port", "integer", (void*) int_parser, offsetof(struct config, clamd_port), "0", sizeof(int)}, + { "clamd_socket", "string", (void*) string_parser, offsetof(struct config, clamd_socket), CLAMD_SOCKET, MAXVAL-1}, + { "debug", "integer", (void*) int_parser, offsetof(struct config, debug), "0", sizeof(int)}, + { "default_retention_days", "integer", (void*) int_parser, offsetof(struct config, default_retention_days), "2557", sizeof(int)}, + { "enable_chunking", "integer", (void*) int_parser, offsetof(struct config, enable_chunking), "0", sizeof(int)}, + { "enable_cjk", "integer", (void*) int_parser, offsetof(struct config, enable_cjk), "0", sizeof(int)}, + { "enable_folders", "integer", (void*) int_parser, offsetof(struct config, enable_folders), "0", sizeof(int)}, + { "encrypt_messages", "integer", (void*) int_parser, offsetof(struct config, encrypt_messages), "1", sizeof(int)}, + { "extra_to_field", "string", (void*) string_parser, offsetof(struct config, extra_to_field), "", MAXVAL-1}, + { "extract_attachments", "integer", (void*) int_parser, offsetof(struct config, extract_attachments), "1", sizeof(int)}, + { "helper_timeout", "integer", (void*) int_parser, offsetof(struct config, helper_timeout), "20", sizeof(int)}, + { "hostid", "string", (void*) string_parser, offsetof(struct config, hostid), HOSTID, MAXVAL-1}, + { "iv", "string", (void*) string_parser, offsetof(struct config, iv), "", MAXVAL-1}, + { "listen_addr", "string", (void*) string_parser, offsetof(struct config, listen_addr), "0.0.0.0", MAXVAL-1}, + { "listen_port", "integer", (void*) int_parser, offsetof(struct config, listen_port), "25", sizeof(int)}, + { "locale", "string", (void*) string_parser, offsetof(struct config, locale), "", MAXVAL-1}, + { "max_connections", "integer", (void*) int_parser, offsetof(struct config, max_connections), "64", sizeof(int)}, + { "max_requests_per_child", "integer", (void*) int_parser, offsetof(struct config, max_requests_per_child), "1000", sizeof(int)}, + { "memcached_servers", "string", (void*) string_parser, offsetof(struct config, memcached_servers), "127.0.0.1", MAXVAL-1}, + { "memcached_to_db_interval", "integer", (void*) int_parser, offsetof(struct config, memcached_to_db_interval), "900", sizeof(int)}, + { "memcached_ttl", "integer", (void*) int_parser, offsetof(struct config, memcached_ttl), "86400", sizeof(int)}, + { "min_message_size", "integer", (void*) int_parser, offsetof(struct config, min_message_size), "100", sizeof(int)}, + { "min_word_len", "integer", (void*) int_parser, offsetof(struct config, min_word_len), "1", sizeof(int)}, + { "mmap_dedup_test", "integer", (void*) int_parser, offsetof(struct config, mmap_dedup_test), "0", sizeof(int)}, + { "mysqlcharset", "string", (void*) string_parser, offsetof(struct config, mysqlcharset), "utf8mb4", 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}, + { "mysqluser", "string", (void*) string_parser, offsetof(struct config, mysqluser), "piler", MAXVAL-1}, + { "mysqlpwd", "string", (void*) string_parser, offsetof(struct config, mysqlpwd), "", MAXVAL-1}, + { "mysqldb", "string", (void*) string_parser, offsetof(struct config, mysqldb), "piler", MAXVAL-1}, + { "mysql_connect_timeout", "integer", (void*) int_parser, offsetof(struct config, mysql_connect_timeout), "2", sizeof(int)}, + { "number_of_worker_processes", "integer", (void*) int_parser, offsetof(struct config, number_of_worker_processes), "2", sizeof(int)}, + { "pemfile", "string", (void*) string_parser, offsetof(struct config, pemfile), "", MAXVAL-1}, + { "pidfile", "string", (void*) string_parser, offsetof(struct config, pidfile), PIDFILE, MAXVAL-1}, + { "piler_header_field", "string", (void*) string_parser, offsetof(struct config, piler_header_field), "X-piler-id:", MAXVAL-1}, + { "process_rcpt_to_addresses", "integer", (void*) int_parser, offsetof(struct config, process_rcpt_to_addresses), "0", sizeof(int)}, + { "queuedir", "string", (void*) string_parser, offsetof(struct config, queuedir), QUEUE_DIR, MAXVAL-1}, + { "server_id", "integer", (void*) int_parser, offsetof(struct config, server_id), "0", sizeof(int)}, + { "smtp_timeout", "integer", (void*) int_parser, offsetof(struct config, smtp_timeout), "60", sizeof(int)}, + { "spam_header_line", "string", (void*) string_parser, offsetof(struct config, spam_header_line), "", MAXVAL-1}, + { "syslog_recipients", "integer", (void*) int_parser, offsetof(struct config, syslog_recipients), "0", sizeof(int)}, + { "tls_enable", "integer", (void*) int_parser, offsetof(struct config, tls_enable), "0", sizeof(int)}, + { "tweak_sent_time_offset", "integer", (void*) int_parser, offsetof(struct config, tweak_sent_time_offset), "0", sizeof(int)}, + { "update_counters_to_memcached", "integer", (void*) int_parser, offsetof(struct config, update_counters_to_memcached), "0", sizeof(int)}, + { "username", "string", (void*) string_parser, offsetof(struct config, username), "piler", MAXVAL-1}, + { "use_antivirus", "integer", (void*) int_parser, offsetof(struct config, use_antivirus), "1", sizeof(int)}, + { "verbosity", "integer", (void*) int_parser, offsetof(struct config, verbosity), "1", sizeof(int)}, + { "workdir", "string", (void*) string_parser, offsetof(struct config, workdir), WORK_DIR, MAXVAL-1}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -122,7 +122,7 @@ struct _parse_rule config_parse_rules[] = * parse configfile */ -int parse_config_file(char *configfile, struct __config *target_cfg, struct _parse_rule *rules){ +int parse_config_file(char *configfile, struct config *target_cfg, struct _parse_rule *rules){ char line[MAXVAL], *chpos; FILE *f; @@ -162,7 +162,7 @@ int parse_config_file(char *configfile, struct __config *target_cfg, struct _par } -int load_default_config(struct __config *cfg, struct _parse_rule *rules){ +int load_default_config(struct config *cfg, struct _parse_rule *rules){ int i=0; while(rules[i].name){ @@ -178,12 +178,12 @@ int load_default_config(struct __config *cfg, struct _parse_rule *rules){ * read configuration file variables */ -struct __config read_config(char *configfile){ - struct __config cfg; +struct config read_config(char *configfile){ + struct config cfg; /* reset config structure and fill it with defaults */ - memset((char *)&cfg, 0, sizeof(struct __config)); + memset((char *)&cfg, 0, sizeof(struct config)); load_default_config(&cfg, config_parse_rules); @@ -202,7 +202,7 @@ struct __config read_config(char *configfile){ * print a single configuration item as key=value */ -void print_config_item(struct __config *cfg, struct _parse_rule *rules, int i){ +void print_config_item(struct config *cfg, struct _parse_rule *rules, int i){ int j; float f; char *p, buf[MAXVAL]; @@ -237,7 +237,7 @@ void print_config_item(struct __config *cfg, struct _parse_rule *rules, int i){ * print all known configuration items */ -void print_config_all(struct __config *cfg, char *key){ +void print_config_all(struct config *cfg, char *key){ int i=0; struct _parse_rule *rules; @@ -261,7 +261,7 @@ void print_config_all(struct __config *cfg, char *key){ * print all configuration items found in configfile */ -void print_config(char *configfile, struct __config *cfg){ +void print_config(char *configfile, struct config *cfg){ FILE *f; char line[MAXVAL], *chpos, previtem[MAXVAL]; struct _parse_rule *rules; diff --git a/src/cfg.h b/src/cfg.h index 29b81081..9bf7df84 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -7,7 +7,7 @@ #include "config.h" -struct __config { +struct config { int server_id; char username[MAXVAL]; diff --git a/src/clamd.c b/src/clamd.c index a2dda47c..e5a7d17d 100644 --- a/src/clamd.c +++ b/src/clamd.c @@ -18,7 +18,7 @@ #include -int clamd_scan(char *tmpfile, struct __config *cfg){ +int clamd_scan(char *tmpfile, struct config *cfg){ int s, n; char *p, *q, buf[MAXBUFSIZE], scan_cmd[SMALLBUFSIZE]; struct sockaddr_un server; diff --git a/src/config.h b/src/config.h index a9cd3a49..dd1419df 100644 --- a/src/config.h +++ b/src/config.h @@ -11,7 +11,7 @@ #define VERSION "1.3.0-epoll" -#define BUILD 978 +#define BUILD 979 #define HOSTID "mailarchiver" diff --git a/src/counters.c b/src/counters.c index 10ecb1a6..4a214863 100644 --- a/src/counters.c +++ b/src/counters.c @@ -11,7 +11,7 @@ #include -struct counters load_counters(struct session_data *sdata, struct __data *data){ +struct counters load_counters(struct session_data *sdata, struct data *data){ char buf[SMALLBUFSIZE]; struct counters counters; @@ -47,7 +47,7 @@ struct counters load_counters(struct session_data *sdata, struct __data *data){ } -void update_counters(struct session_data *sdata, struct __data *data, struct counters *counters, struct __config *cfg){ +void update_counters(struct session_data *sdata, struct data *data, struct counters *counters, struct config *cfg){ char buf[MAXBUFSIZE]; #ifdef HAVE_MEMCACHED unsigned long long mc, rcvd; diff --git a/src/defs.h b/src/defs.h index 89f89974..b0025f97 100644 --- a/src/defs.h +++ b/src/defs.h @@ -99,6 +99,16 @@ struct node { }; +struct net { + int socket; + int use_ssl; + int starttls; + int timeout; + SSL_CTX *ctx; + SSL *ssl; +}; + + struct rule { #ifdef HAVE_TRE regex_t from; @@ -295,6 +305,21 @@ struct import { int timeout; int cap_uidplus; long total_size; + int dryrun; + int tot_msgs; + int port; + int seq; + char *server; + char *username; + char *password; + char *database; + char *skiplist; + char *folder_imap; + char *folder_name; + char *directory; + char *mboxdir; + char *folder; + char filename[SMALLBUFSIZE]; time_t started, updated, finished; }; @@ -308,7 +333,7 @@ struct licence { }; -struct __data { +struct data { int folder, quiet; char recursive_folder_names; char starttls[TINYBUFSIZE]; @@ -355,8 +380,8 @@ struct __data { #ifdef HAVE_MEMCACHED struct memcached_server memc; #endif - SSL_CTX *ctx; - SSL *ssl; + + struct net *net; }; @@ -385,12 +410,8 @@ struct smtp_session { int bdat_rounds; int bdat_last_round; int bdat_bytes_to_read; - int socket; - struct __config *cfg; - SSL_CTX *ctx; - SSL *ssl; - int use_ssl; - int starttls; + struct config *cfg; + struct net net; }; #endif /* _DEFS_H */ diff --git a/src/digest.c b/src/digest.c index 8a490829..6f373ad2 100644 --- a/src/digest.c +++ b/src/digest.c @@ -33,7 +33,7 @@ int search_header_end(char *p, int n){ } -int make_digests(struct session_data *sdata, struct __config *cfg){ +int make_digests(struct session_data *sdata, struct config *cfg){ int i=0, n, fd, offset=3, hdr_len=0, len=0; char *body=NULL; unsigned char buf[BIGBUFSIZE], md[DIGEST_LENGTH], md2[DIGEST_LENGTH]; diff --git a/src/dirs.c b/src/dirs.c index 56e0e6e6..6d40b505 100644 --- a/src/dirs.c +++ b/src/dirs.c @@ -13,10 +13,25 @@ #include -void createdir(char *path, uid_t uid, gid_t gid, mode_t mode); +void createdir(char *path, uid_t uid, gid_t gid, mode_t mode){ + struct stat st; + + if(strlen(path) > 2){ + if(path[strlen(path)-1] == '/') path[strlen(path)-1] = '\0'; + + if(stat(path, &st)){ + if(mkdir(path, mode) == 0){ + if(chown(path, uid, gid)) + syslog(LOG_PRIORITY, "ERROR: createdir(): chown() failed on %s", path); + syslog(LOG_PRIORITY, "created directory: *%s*", path); + } + else syslog(LOG_PRIORITY, "ERROR: could not create directory: *%s*", path); + } + } +} -void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid){ +void check_and_create_directories(struct config *cfg, uid_t uid, gid_t gid){ char *p, s[SMALLBUFSIZE]; int i; @@ -56,23 +71,3 @@ void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid){ } } - - -void createdir(char *path, uid_t uid, gid_t gid, mode_t mode){ - struct stat st; - - if(strlen(path) > 2){ - if(path[strlen(path)-1] == '/') path[strlen(path)-1] = '\0'; - - if(stat(path, &st)){ - if(mkdir(path, mode) == 0){ - chown(path, uid, gid); - syslog(LOG_PRIORITY, "created directory: *%s*", path); - } - else syslog(LOG_PRIORITY, "could not create directory: *%s*", path); - } - - } -} - - diff --git a/src/extract.c b/src/extract.c index 01ac1d15..7942f381 100644 --- a/src/extract.c +++ b/src/extract.c @@ -99,7 +99,7 @@ int extract_opendocument(struct session_data *sdata, struct parser_state *state, } -int unzip_file(struct session_data *sdata, struct parser_state *state, char *filename, int *rec, struct __config *cfg){ +int unzip_file(struct session_data *sdata, struct parser_state *state, char *filename, int *rec, struct config *cfg){ int errorp, i=0, len=0, fd; char *p, extracted_filename[SMALLBUFSIZE], buf[MAXBUFSIZE]; struct zip *z; @@ -132,7 +132,7 @@ int unzip_file(struct session_data *sdata, struct parser_state *state, char *fil zf = zip_fopen_index(z, i, 0); if(zf){ while((len = zip_fread(zf, buf, sizeof(buf))) > 0){ - write(fd, buf, len); + if(write(fd, buf, len) == -1) syslog(LOG_PRIORITY, "ERROR: error writing to fd in %s", __func__); } zip_fclose(zf); } @@ -169,7 +169,7 @@ int unzip_file(struct session_data *sdata, struct parser_state *state, char *fil #ifdef HAVE_TNEF -int extract_tnef(struct session_data *sdata, struct parser_state *state, char *filename, struct __config *cfg){ +int extract_tnef(struct session_data *sdata, struct parser_state *state, char *filename, struct config *cfg){ int rc=0, n, rec=1; char tmpdir[BUFLEN], buf[SMALLBUFSIZE]; struct dirent **namelist; @@ -216,7 +216,7 @@ void kill_helper(){ } -void extract_attachment_content(struct session_data *sdata, struct parser_state *state, char *filename, char *type, int *rec, struct __config *cfg){ +void extract_attachment_content(struct session_data *sdata, struct parser_state *state, char *filename, char *type, int *rec, struct config *cfg){ int link[2], n; pid_t pid; char outbuf[MAXBUFSIZE]; diff --git a/src/imap.c b/src/imap.c index 95e083ac..f063a7ae 100644 --- a/src/imap.c +++ b/src/imap.c @@ -23,9 +23,6 @@ #include -void update_import_job_stat(struct session_data *sdata, struct __data *data); - - int get_message_length_from_imap_answer(char *s){ char *p, *q; int len=0; @@ -54,18 +51,18 @@ int get_message_length_from_imap_answer(char *s){ } -int read_response(int sd, char *buf, int buflen, int *seq, struct __data *data, int use_ssl){ +int read_response(char *buf, int buflen, struct data *data){ int i=0, n, len=0, rc=0; char puf[MAXBUFSIZE], tagok[SMALLBUFSIZE], tagno[SMALLBUFSIZE], tagbad[SMALLBUFSIZE]; - snprintf(tagok, sizeof(tagok)-1, "A%d OK", *seq); - snprintf(tagno, sizeof(tagno)-1, "A%d NO", *seq); - snprintf(tagbad, sizeof(tagbad)-1, "A%d BAD", *seq); + snprintf(tagok, sizeof(tagok)-1, "A%d OK", data->import->seq); + snprintf(tagno, sizeof(tagno)-1, "A%d NO", data->import->seq); + snprintf(tagbad, sizeof(tagbad)-1, "A%d BAD", data->import->seq); memset(buf, 0, buflen); while(!strstr(buf, tagok)){ - n = recvtimeoutssl(sd, puf, sizeof(puf), data->import->timeout, use_ssl, data->ssl); + n = recvtimeoutssl(data->net, puf, sizeof(puf)); if(n + len < buflen) strncat(buf, puf, n); else goto END; @@ -87,28 +84,104 @@ int read_response(int sd, char *buf, int buflen, int *seq, struct __data *data, END: - (*seq)++; + (data->import->seq)++; return rc; } -int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sdata, struct __data *data, int use_ssl, int dryrun, struct __config *cfg){ - int rc=ERR, i, n, messages=0, len, readlen, fd, nreads, readpos, finished, msglen, msg_written_len, tagoklen, tagbadlen, result; - char *p, tag[SMALLBUFSIZE], tagok[SMALLBUFSIZE], tagbad[SMALLBUFSIZE], buf[MAXBUFSIZE], puf[MAXBUFSIZE], filename[SMALLBUFSIZE]; +int connect_to_imap_server(struct data *data){ + int n; + char buf[MAXBUFSIZE]; + X509* server_cert; + char *str; - /* imap cmd: SELECT */ + data->import->cap_uidplus = 0; + + if(data->net->use_ssl == 1){ + SSL_library_init(); + SSL_load_error_strings(); + + #if OPENSSL_VERSION_NUMBER < 0x10100000L + data->net->ctx = SSL_CTX_new(TLSv1_client_method()); + #else + data->net->ctx = SSL_CTX_new(TLS_client_method()); + #endif + CHK_NULL(data->net->ctx, "internal SSL error"); + + data->net->ssl = SSL_new(data->net->ctx); + CHK_NULL(data->net->ssl, "internal ssl error"); + + SSL_set_fd(data->net->ssl, data->net->socket); + n = SSL_connect(data->net->ssl); + CHK_SSL(n, "internal ssl error"); + + printf("Cipher: %s\n", SSL_get_cipher(data->net->ssl)); + + server_cert = SSL_get_peer_certificate(data->net->ssl); + CHK_NULL(server_cert, "server cert error"); + + str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0); + CHK_NULL(str, "error in server cert"); + printf("server cert:\n\t subject: %s\n", str); + OPENSSL_free(str); + + str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0); + CHK_NULL(str, "error in server cert"); + printf("\t issuer: %s\n\n", str); + OPENSSL_free(str); + + X509_free(server_cert); + } + + + recvtimeoutssl(data->net, buf, sizeof(buf)); + + + /* imap cmd: LOGIN */ + + snprintf(buf, sizeof(buf)-1, "A%d LOGIN %s \"%s\"\r\n", data->import->seq, data->import->username, data->import->password); + + write1(data->net, buf, strlen(buf)); + if(read_response(buf, sizeof(buf), data) == 0){ + printf("login failed, server reponse: %s\n", buf); + return ERR; + } + + if(strstr(buf, "UIDPLUS")){ + data->import->cap_uidplus = 1; + } + else { + + /* run the CAPABILITY command if the reply doesn't contain the UIDPLUS capability */ + + snprintf(buf, sizeof(buf)-1, "A%d CAPABILITY\r\n", data->import->seq); + + write1(data->net, buf, strlen(buf)); + read_response(buf, sizeof(buf), data); + + if(strstr(buf, "UIDPLUS")) data->import->cap_uidplus = 1; + } + + + return OK; +} + + +int imap_select_cmd_on_folder(char *folder, struct data *data){ + int messages=0; + char *p, buf[MAXBUFSIZE]; if(strchr(folder, '"')) - snprintf(buf, sizeof(buf)-1, "A%d SELECT %s\r\n", *seq, folder); + snprintf(buf, sizeof(buf)-1, "A%d SELECT %s\r\n", data->import->seq, folder); else - snprintf(buf, sizeof(buf)-1, "A%d SELECT \"%s\"\r\n", *seq, folder); + snprintf(buf, sizeof(buf)-1, "A%d SELECT \"%s\"\r\n", data->import->seq, folder); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - if(read_response(sd, buf, sizeof(buf), seq, data, use_ssl) == 0){ + write1(data->net, buf, strlen(buf)); + if(read_response(buf, sizeof(buf), data) == 0){ trimBuffer(buf); - printf("select cmd error: %s\n", buf); - return rc; + printf("ERROR: select cmd error: %s\n", buf); + return messages; } p = strstr(buf, " EXISTS"); @@ -123,184 +196,198 @@ int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sda printf("found %d messages\n", messages); - if(messages <= 0) return OK; + data->import->total_messages += messages; + return messages; +} + + +int imap_download_email(struct data *data, int i){ + int fd, len, result, tagoklen, tagbadlen; + int n, readlen=0, nreads=0, readpos=0, finished=0, msglen=0, msg_written_len=0; + char *p, buf[MAXBUFSIZE], puf[MAXBUFSIZE], tag[SMALLBUFSIZE], tagok[SMALLBUFSIZE], tagbad[SMALLBUFSIZE]; + + data->import->processed_messages++; + + snprintf(data->import->filename, SMALLBUFSIZE-1, "%d-imap-%d.txt", getpid(), data->import->processed_messages); + + unlink(data->import->filename); + + fd = open(data->import->filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + if(fd == -1){ + printf("cannot open: %s\n", data->import->filename); + return ERR; + } + + snprintf(tag, sizeof(tag)-1, "A%d", data->import->seq); + snprintf(tagok, sizeof(tagok)-1, "A%d OK", (data->import->seq)++); + snprintf(tagbad, sizeof(tagbad)-1, "%s BAD", tag); + + tagoklen = strlen(tagok); + tagbadlen = strlen(tagbad); + + snprintf(buf, sizeof(buf)-1, "%s FETCH %d (BODY.PEEK[])\r\n", tag, i); + write1(data->net, buf, strlen(buf)); + + while((n = recvtimeoutssl(data->net, &buf[readpos], sizeof(buf)-readpos)) > 0){ + + readlen += n; + + if(strchr(buf, '\n')){ + readpos = 0; + p = &buf[0]; + do { + nreads++; + memset(puf, 0, sizeof(puf)); + p = split(p, '\n', puf, sizeof(puf)-1, &result); + len = strlen(puf); + + if(result == 1){ + // process a complete line + + if(nreads == 1){ + + if(strcasestr(puf, " FETCH ")){ + msglen = get_message_length_from_imap_answer(puf); + + if(msglen == 0){ + finished = 1; + break; + } + continue; + } + + if(strcasestr(puf, " BYE")){ + printf("imap server sent BYE response: '%s'\n", puf); + close(fd); + unlink(data->import->filename); + return ERR; + } + + } + + if(len > 0 && msg_written_len < msglen){ + if(write(fd, puf, len) == -1) printf("ERROR: writing to fd\n"); + if(write(fd, "\n", 1) == -1) printf("ERROR: writing to fd\n"); + msg_written_len += len + 1; + } + + if(strncmp(puf, tagok, tagoklen) == 0){ + finished = 1; + break; + } + + if(strncmp(puf, tagbad, tagbadlen) == 0){ + printf("ERROR happened reading the message!\n"); + finished = 1; + break; + } + + } + else { + // prepend the last incomplete line back to 'buf' + + snprintf(buf, sizeof(buf)-2, "%s", puf); + readpos = len; + break; + } + + } while(p); + + + } + else { + readpos += n; + } + + if(finished == 1) break; + } + + close(fd); + + if(msglen > 10) return OK; + + return ERR; +} + + +void imap_delete_message(struct data *data, int i){ + char buf[SMALLBUFSIZE]; + + snprintf(buf, sizeof(buf)-1, "A%d STORE %d +FLAGS.SILENT (\\Deleted)\r\n", data->import->seq, i); + write1(data->net, buf, strlen(buf)); + read_response(buf, sizeof(buf), data); +} + + +void imap_move_message_to_folder(struct data *data, int i){ + int tagoklen; + char buf[SMALLBUFSIZE], tagok[SMALLBUFSIZE]; + + snprintf(tagok, sizeof(tagok)-1, "A%d OK", data->import->seq); + tagoklen = strlen(tagok); + + snprintf(buf, sizeof(buf)-1, "A%d COPY %d %s\r\n", data->import->seq, i, data->import->move_folder); + write1(data->net, buf, strlen(buf)); + read_response(buf, sizeof(buf), data); + + if(strncmp(buf, tagok, tagoklen) == 0){ + snprintf(buf, sizeof(buf)-1, "A%d STORE %d +FLAGS.SILENT (\\Deleted)\r\n", data->import->seq, i); + write1(data->net, buf, strlen(buf)); + read_response(buf, sizeof(buf), data); + } +} + + +void imap_expunge_message(struct data *data){ + char buf[SMALLBUFSIZE]; + + snprintf(buf, sizeof(buf)-1, "A%d EXPUNGE\r\n", data->import->seq); + write1(data->net, buf, strlen(buf)); + read_response(buf, sizeof(buf), data); +} + + +int process_imap_folder(char *folder, struct session_data *sdata, struct data *data, struct config *cfg){ + int rc=ERR, i, messages=0; + + messages = imap_select_cmd_on_folder(folder, data); + + if(messages <= 0) return OK; if(data->recursive_folder_names == 1){ data->folder = get_folder_id(sdata, data, folder, 0); if(data->folder == ERR_FOLDER) data->folder = add_new_folder(sdata, data, folder, 0); } - - data->import->total_messages += messages; - for(i=data->import->start_position; i<=messages; i++){ + if(imap_download_email(data, i) == OK){ + if(data->quiet == 0){ printf("processed: %7d [%3d%%]\r", data->import->processed_messages, 100*i/messages); fflush(stdout); } + + if(data->import->dryrun == 0){ + rc = import_message(sdata, data, cfg); + + if(data->import->remove_after_import == 1 && rc == OK){ + imap_delete_message(data, i); + } + + if(data->import->move_folder && data->import->cap_uidplus == 1){ + imap_move_message_to_folder(data, i); + } + } + + if(data->import->download_only == 0) unlink(data->import->filename); + } /* whether to quit after processing a batch of messages */ if(data->import->batch_processing_limit > 0 && data->import->processed_messages >= data->import->batch_processing_limit){ break; } - - data->import->processed_messages++; - if(data->quiet == 0){ printf("processed: %7d [%3d%%]\r", data->import->processed_messages, 100*i/messages); fflush(stdout); } - - snprintf(tag, sizeof(tag)-1, "A%d", *seq); - snprintf(tagok, sizeof(tagok)-1, "A%d OK", (*seq)++); - snprintf(tagbad, sizeof(tagbad)-1, "%s BAD", tag); - - tagoklen = strlen(tagok); - tagbadlen = strlen(tagbad); - - snprintf(buf, sizeof(buf)-1, "%s FETCH %d (BODY.PEEK[])\r\n", tag, i); - - snprintf(filename, sizeof(filename)-1, "%d-imap-%d.txt", getpid(), data->import->processed_messages); - unlink(filename); - - fd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); - if(fd == -1){ - printf("cannot open: %s\n", filename); - return rc; - } - - - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - - readlen = 0; - nreads = 0; - readpos = 0; - finished = 0; - msglen = 0; - msg_written_len = 0; - - while((n = recvtimeoutssl(sd, &buf[readpos], sizeof(buf)-readpos, data->import->timeout, use_ssl, data->ssl)) > 0){ - - readlen += n; - - if(strchr(buf, '\n')){ - readpos = 0; - p = &buf[0]; - do { - nreads++; - memset(puf, 0, sizeof(puf)); - p = split(p, '\n', puf, sizeof(puf)-1, &result); - len = strlen(puf); - - if(result == 1){ - // process a complete line - - if(nreads == 1){ - - if(strcasestr(puf, " FETCH ")){ - msglen = get_message_length_from_imap_answer(puf); - - if(msglen == 0){ - finished = 1; - break; - } - continue; - } - - if(strcasestr(puf, " BYE")){ - printf("imap server sent BYE response: '%s'\n", puf); - close(fd); - unlink(filename); - return ERR; - } - - } - - if(len > 0 && msg_written_len < msglen){ - write(fd, puf, len); - write(fd, "\n", 1); - msg_written_len += len + 1; - } - - if(strncmp(puf, tagok, tagoklen) == 0){ - finished = 1; - break; - } - - if(strncmp(puf, tagbad, tagbadlen) == 0){ - printf("ERROR happened reading the message!\n"); - finished = 1; - break; - } - - } - else { - // prepend the last incomplete line back to 'buf' - - snprintf(buf, sizeof(buf)-2, "%s", puf); - readpos = len; - break; - } - - } while(p); - - - - } - else { - readpos += n; - } - - if(finished == 1) break; - } - - - close(fd); - - if(dryrun == 0 && msglen > 10){ - rc = import_message(filename, sdata, data, cfg); - - if(data->import->processed_messages % 100 == 0){ - time(&(data->import->updated)); - update_import_job_stat(sdata, data); - } - } - else rc = OK; - - - if(rc == ERR) printf("error importing '%s'\n", filename); - else { - - if(data->import->remove_after_import == 1 && dryrun == 0){ - snprintf(buf, sizeof(buf)-1, "A%d STORE %d +FLAGS.SILENT (\\Deleted)\r\n", *seq, i); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - read_response(sd, buf, sizeof(buf), seq, data, use_ssl); - } - - - if(data->import->move_folder && data->import->cap_uidplus == 1 && dryrun == 0){ - - snprintf(tagok, sizeof(tagok)-1, "A%d OK", *seq); - tagoklen = strlen(tagok); - - snprintf(buf, sizeof(buf)-1, "A%d COPY %d %s\r\n", *seq, i, data->import->move_folder); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - read_response(sd, buf, sizeof(buf), seq, data, use_ssl); - - if(strncmp(buf, tagok, tagoklen) == 0){ - snprintf(buf, sizeof(buf)-1, "A%d STORE %d +FLAGS.SILENT (\\Deleted)\r\n", *seq, i); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - read_response(sd, buf, sizeof(buf), seq, data, use_ssl); - - } - } - - - - if(data->import->download_only == 0) unlink(filename); - } - - } - if((data->import->remove_after_import == 1 || data->import->move_folder) && dryrun == 0){ - snprintf(buf, sizeof(buf)-1, "A%d EXPUNGE\r\n", *seq); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - read_response(sd, buf, sizeof(buf), seq, data, use_ssl); + if((data->import->remove_after_import == 1 || data->import->move_folder) && data->import->dryrun == 0){ + imap_expunge_message(data); } @@ -310,96 +397,15 @@ int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sda } -int connect_to_imap_server(int sd, int *seq, char *username, char *password, struct __data *data, int use_ssl){ - int n; - char buf[MAXBUFSIZE]; - X509* server_cert; - char *str; - - data->import->cap_uidplus = 0; - - if(use_ssl == 1){ - - SSL_library_init(); - SSL_load_error_strings(); - - #if OPENSSL_VERSION_NUMBER < 0x10100000L - data->ctx = SSL_CTX_new(TLSv1_client_method()); - #else - data->ctx = SSL_CTX_new(TLS_client_method()); - #endif - CHK_NULL(data->ctx, "internal SSL error"); - - data->ssl = SSL_new(data->ctx); - CHK_NULL(data->ssl, "internal ssl error"); - - SSL_set_fd(data->ssl, sd); - n = SSL_connect(data->ssl); - CHK_SSL(n, "internal ssl error"); - - printf("Cipher: %s\n", SSL_get_cipher(data->ssl)); - - server_cert = SSL_get_peer_certificate(data->ssl); - CHK_NULL(server_cert, "server cert error"); - - //if(verbose){ - str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0); - CHK_NULL(str, "error in server cert"); - printf("server cert:\n\t subject: %s\n", str); - OPENSSL_free(str); - - str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0); - CHK_NULL(str, "error in server cert"); - printf("\t issuer: %s\n\n", str); - OPENSSL_free(str); - //} - - X509_free(server_cert); - } - - - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); - - - /* imap cmd: LOGIN */ - - snprintf(buf, sizeof(buf)-1, "A%d LOGIN %s \"%s\"\r\n", *seq, username, password); - - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - if(read_response(sd, buf, sizeof(buf), seq, data, use_ssl) == 0){ - printf("login failed, server reponse: %s\n", buf); - return ERR; - } - - if(strstr(buf, "UIDPLUS")){ - data->import->cap_uidplus = 1; - } - else { - - /* run the CAPABILITY command if the reply doesn't contain the UIDPLUS capability */ - - snprintf(buf, sizeof(buf)-1, "A%d CAPABILITY\r\n", *seq); - - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - read_response(sd, buf, sizeof(buf), seq, data, use_ssl); - - if(strstr(buf, "UIDPLUS")) data->import->cap_uidplus = 1; - } - - - return OK; -} - - -void send_imap_close(int sd, int *seq, struct __data *data, int use_ssl){ +void send_imap_close(struct data *data){ char puf[SMALLBUFSIZE]; - snprintf(puf, sizeof(puf)-1, "A%d CLOSE\r\n", *seq); + snprintf(puf, sizeof(puf)-1, "A%d CLOSE\r\n", data->import->seq); - write1(sd, puf, strlen(puf), use_ssl, data->ssl); + write1(data->net, puf, strlen(puf)); } -int list_folders(int sd, int *seq, int use_ssl, char *folder_name, struct __data *data){ +int list_folders(struct data *data){ char *p, *q, *r, *buf, *ruf, tag[SMALLBUFSIZE], tagok[SMALLBUFSIZE], puf[MAXBUFSIZE]; char attrs[SMALLBUFSIZE], folder[SMALLBUFSIZE]; int len=MAXBUFSIZE+3, pos=0, n, rc=ERR, fldrlen=0, result; @@ -411,18 +417,18 @@ int list_folders(int sd, int *seq, int use_ssl, char *folder_name, struct __data memset(buf, 0, len); - snprintf(tag, sizeof(tag)-1, "A%d", *seq); snprintf(tagok, sizeof(tagok)-1, "A%d OK", (*seq)++); - if(folder_name == NULL) + snprintf(tag, sizeof(tag)-1, "A%d", data->import->seq); snprintf(tagok, sizeof(tagok)-1, "A%d OK", (data->import->seq)++); + if(data->import->folder_name == NULL) snprintf(puf, sizeof(puf)-1, "%s LIST \"\" \"*\"\r\n", tag); else - snprintf(puf, sizeof(puf)-1, "%s LIST \"%s\" \"*\"\r\n", tag, folder_name); + snprintf(puf, sizeof(puf)-1, "%s LIST \"%s\" \"*\"\r\n", tag, data->import->folder_name); - write1(sd, puf, strlen(puf), use_ssl, data->ssl); + write1(data->net, puf, strlen(puf)); p = NULL; while(1){ - n = recvtimeoutssl(sd, puf, sizeof(puf), data->import->timeout, use_ssl, data->ssl); + n = recvtimeoutssl(data->net, puf, sizeof(puf)); if(n < 0) return ERR; if(pos + n >= len){ @@ -522,5 +528,3 @@ ENDE_FOLDERS: return rc; } - - diff --git a/src/import.c b/src/import.c index 1b973f0a..33f49262 100644 --- a/src/import.c +++ b/src/import.c @@ -18,7 +18,7 @@ #include -int import_message(char *filename, struct session_data *sdata, struct __data *data, struct __config *cfg){ +int import_message(struct session_data *sdata, struct data *data, struct config *cfg){ int rc=ERR; char *p, *rule, newpath[SMALLBUFSIZE]; struct stat st; @@ -33,12 +33,12 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da sdata->num_of_rcpt_to = 1; } - if(cfg->verbosity > 1) printf("processing: %s\n", filename); + if(cfg->verbosity > 1) printf("processing: %s\n", data->import->filename); - if(strcmp(filename, "-") == 0){ + if(strcmp(data->import->filename, "-") == 0){ if(read_from_stdin(sdata) == ERR){ - printf("error reading from stdin\n"); + printf("ERROR: error reading from stdin\n"); return rc; } @@ -47,17 +47,17 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da } else { - if(stat(filename, &st) != 0){ - printf("cannot stat() %s\n", filename); + if(stat(data->import->filename, &st) != 0){ + printf("ERROR: cannot stat() %s\n", data->import->filename); return rc; } if(S_ISREG(st.st_mode) == 0){ - printf("%s is not a file\n", filename); + printf("ERROR: %s is not a file\n", data->import->filename); return rc; } - snprintf(sdata->filename, SMALLBUFSIZE-1, "%s", filename); + snprintf(sdata->filename, SMALLBUFSIZE-1, "%s", data->import->filename); sdata->tot_len = st.st_size; } @@ -81,14 +81,14 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da rule = check_againt_ruleset(data->archiving_rules, &state, sdata->tot_len, sdata->spam_message); if(rule){ - if(data->quiet == 0) printf("discarding %s by archiving policy: %s\n", filename, rule); + if(data->quiet == 0) printf("discarding %s by archiving policy: %s\n", data->import->filename, rule); rc = OK; } else { make_digests(sdata, cfg); if(sdata->hdr_len < 10){ - printf("%s: invalid message, hdr_len: %d\n", filename, sdata->hdr_len); + printf("%s: invalid message, hdr_len: %d\n", data->import->filename, sdata->hdr_len); return ERR; } @@ -98,7 +98,7 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da unlink(sdata->tmpframe); - if(strcmp(filename, "-") == 0) unlink(sdata->ttmpfile); + if(strcmp(data->import->filename, "-") == 0) unlink(sdata->ttmpfile); switch(rc) { @@ -118,32 +118,32 @@ int import_message(char *filename, struct session_data *sdata, struct __data *da counters.c_duplicate = 1; update_counters(sdata, data, &counters, cfg); - if(data->quiet == 0) printf("duplicate: %s (duplicate id: %llu)\n", filename, sdata->duplicate_id); + if(data->quiet == 0) printf("duplicate: %s (duplicate id: %llu)\n", data->import->filename, sdata->duplicate_id); break; default: - printf("failed to import: %s (id: %s)\n", filename, sdata->ttmpfile); + printf("failed to import: %s (id: %s)\n", data->import->filename, sdata->ttmpfile); break; } if(rc != OK && data->import->failed_folder){ - p = strrchr(filename, '/'); + p = strrchr(data->import->filename, '/'); if(p) p++; else - p = filename; + p = data->import->filename; snprintf(newpath, sizeof(newpath)-2, "%s/%s", data->import->failed_folder, p); - if(rename(filename, newpath)) - printf("cannot move %s to %s\n", filename, newpath); + if(rename(data->import->filename, newpath)) + printf("cannot move %s to %s\n", data->import->filename, newpath); } return rc; } -int get_folder_id(struct session_data *sdata, struct __data *data, char *foldername, int parent_id){ +int get_folder_id(struct session_data *sdata, struct data *data, char *foldername, int parent_id){ int id=ERR_FOLDER; if(prepare_sql_statement(sdata, &(data->stmt_get_folder_id), SQL_PREPARED_STMT_GET_FOLDER_ID) == ERR) return id; @@ -168,7 +168,7 @@ int get_folder_id(struct session_data *sdata, struct __data *data, char *foldern } -int add_new_folder(struct session_data *sdata, struct __data *data, char *foldername, int parent_id){ +int add_new_folder(struct session_data *sdata, struct data *data, char *foldername, int parent_id){ int id=ERR_FOLDER; if(foldername == NULL) return id; @@ -187,15 +187,3 @@ int add_new_folder(struct session_data *sdata, struct __data *data, char *folder return id; } - - -void update_import_job_stat(struct session_data *sdata, struct __data *data){ - char buf[SMALLBUFSIZE]; - - snprintf(buf, sizeof(buf)-1, "update import set status=%d, started=%ld, updated=%ld, finished=%ld, total=%d, imported=%d where id=%d", data->import->status, data->import->started, data->import->updated, data->import->finished, data->import->total_messages, data->import->processed_messages, data->import->import_job_id); - - p_query(sdata, buf); -} - - - diff --git a/src/import.h b/src/import.h index e52bfa24..1659deb1 100644 --- a/src/import.h +++ b/src/import.h @@ -6,24 +6,21 @@ #define _IMPORT_H -int import_message(char *filename, struct session_data *sdata, struct __data *data, struct __config *cfg); -void update_import_job_stat(struct session_data *sdata, struct __data *data); +int import_message(struct session_data *sdata, struct data *data, struct config *cfg); -int read_gui_import_data(struct session_data *sdata, struct __data *data, char *folder_imap, char *skiplist, int dryrun, struct __config *cfg); +int import_from_maildir(struct session_data *sdata, struct data *data, struct config *cfg); +int import_from_mailbox(char *mailbox, struct session_data *sdata, struct data *data, struct config *cfg); +int import_mbox_from_dir(char *directory, struct session_data *sdata, struct data *data, struct config *cfg); +void import_from_pop3_server(struct session_data *sdata, struct data *data, struct config *cfg); +int import_from_imap_server(struct session_data *sdata, struct data *data, struct config *cfg); -int import_from_maildir(char *directory, struct session_data *sdata, struct __data *data, int *tot_msgs, struct __config *cfg); -int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data *data, struct __config *cfg); -int import_mbox_from_dir(char *directory, struct session_data *sdata, struct __data *data, int *tot_msgs, struct __config *cfg); -int import_from_pop3_server(char *server, char *username, char *password, int port, struct session_data *sdata, struct __data *data, int dryrun, struct __config *cfg); -int import_from_imap_server(char *server, char *username, char *password, int port, struct session_data *sdata, struct __data *data, char *folder_imap, char *skiplist, int dryrun, struct __config *cfg); +int connect_to_pop3_server(struct data *data); +void process_pop3_emails(struct session_data *sdata, struct data *data, struct config *cfg); -int connect_to_pop3_server(int sd, char *username, char *password, struct __data *data, int use_ssl); -int process_pop3_emails(int sd, struct session_data *sdata, struct __data *data, int use_ssl, int dryrun, struct __config *cfg); - -int connect_to_imap_server(int sd, int *seq, char *username, char *password, struct __data *data, int use_ssl); -int list_folders(int sd, int *seq, int use_ssl, char *folder_name, struct __data *data); -int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sdata, struct __data *data, int use_ssl, int dryrun, struct __config *cfg); -void send_imap_close(int sd, int *seq, struct __data *data, int use_ssl); +int connect_to_imap_server(struct data *data); +int list_folders(struct data *data); +int process_imap_folder(char *folder, struct session_data *sdata, struct data *data, struct config *cfg); +void send_imap_close(struct data *data); #endif /* _IMPORT_H */ diff --git a/src/import_gui.c b/src/import_gui.c deleted file mode 100644 index 749a9e9b..00000000 --- a/src/import_gui.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * import_gui.c, SJ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int read_gui_import_data(struct session_data *sdata, struct __data *data, char *folder_imap, char *skiplist, int dryrun, struct __config *cfg){ - int rc=ERR; - char s_type[SMALLBUFSIZE], s_username[SMALLBUFSIZE], s_password[SMALLBUFSIZE], s_server[SMALLBUFSIZE]; - - memset(s_type, 0, sizeof(s_type)); - memset(s_username, 0, sizeof(s_username)); - memset(s_password, 0, sizeof(s_password)); - memset(s_server, 0, sizeof(s_server)); - - if(prepare_sql_statement(sdata, &(data->stmt_generic), SQL_PREPARED_STMT_GET_GUI_IMPORT_JOBS) == ERR) return ERR; - - p_bind_init(data); - - if(p_exec_query(sdata, data->stmt_generic, data) == OK){ - - p_bind_init(data); - - data->sql[data->pos] = (char *)&(data->import->import_job_id); data->type[data->pos] = TYPE_LONG; data->len[data->pos] = sizeof(int); data->pos++; - data->sql[data->pos] = &s_type[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s_type)-2; data->pos++; - data->sql[data->pos] = &s_username[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s_username)-2; data->pos++; - data->sql[data->pos] = &s_password[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s_password)-2; data->pos++; - data->sql[data->pos] = &s_server[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s_server)-2; data->pos++; - - p_store_results(data->stmt_generic, data); - - if(p_fetch_results(data->stmt_generic) == OK) rc = OK; - - p_free_results(data->stmt_generic); - } - - close_prepared_statement(data->stmt_generic); - - data->import->processed_messages = 0; - data->import->total_messages = 0; - - time(&(data->import->started)); - data->import->status = 1; - update_import_job_stat(sdata, data); - - if(strcmp(s_type, "pop3") == 0){ - rc = import_from_pop3_server(s_server, s_username, s_password, 110, sdata, data, dryrun, cfg); - } - - if(strcmp(s_type, "imap") == 0){ - rc = import_from_imap_server(s_server, s_username, s_password, 143, sdata, data, folder_imap, skiplist, dryrun, cfg); - } - - update_import_job_stat(sdata, data); - - // don't set error in case of a problem, because it - // will scare users looking at the gui progressbar - - return rc; -} - - diff --git a/src/import_imap.c b/src/import_imap.c index ef3b0988..79876c74 100644 --- a/src/import_imap.c +++ b/src/import_imap.c @@ -22,49 +22,52 @@ #include -int import_from_imap_server(char *server, char *username, char *password, int port, struct session_data *sdata, struct __data *data, char *folder_imap, char *skiplist, int dryrun, struct __config *cfg){ - int i, rc=ERR, ret=OK, sd, seq=1, skipmatch, use_ssl=0; +int import_from_imap_server(struct session_data *sdata, struct data *data, struct config *cfg){ + int i, rc=ERR, ret=OK, skipmatch; char port_string[8], puf[SMALLBUFSIZE]; struct addrinfo hints, *res; struct node *q; + data->net->use_ssl = 0; + data->import->seq = 1; inithash(data->imapfolders); - snprintf(port_string, sizeof(port_string)-1, "%d", port); + snprintf(port_string, sizeof(port_string)-1, "%d", data->import->port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - if((rc = getaddrinfo(server, port_string, &hints, &res)) != 0){ - printf("getaddrinfo for '%s': %s\n", server, gai_strerror(rc)); + if((rc = getaddrinfo(data->import->server, port_string, &hints, &res)) != 0){ + printf("getaddrinfo for '%s': %s\n", data->import->server, gai_strerror(rc)); return ERR; } - if(port == 993) use_ssl = 1; + if(data->import->port == 993) data->net->use_ssl = 1; - if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ + if((data->net->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ printf("cannot create socket\n"); ret = ERR; goto ENDE_IMAP; } - if(connect(sd, res->ai_addr, res->ai_addrlen) == -1){ + if(connect(data->net->socket, res->ai_addr, res->ai_addrlen) == -1){ printf("connect()\n"); ret = ERR; goto ENDE_IMAP; } - if(connect_to_imap_server(sd, &seq, username, password, data, use_ssl) == ERR){ - close(sd); + if(connect_to_imap_server(data) == ERR){ + close(data->net->socket); ret = ERR; goto ENDE_IMAP; } - if(list_folders(sd, &seq, use_ssl, folder_imap, data) == ERR) goto ENDE_IMAP; + if(list_folders(data) == ERR) goto ENDE_IMAP; + for(i=0;iimapfolders[i]; @@ -74,9 +77,9 @@ int import_from_imap_server(char *server, char *username, char *password, int po skipmatch = 0; - if(skiplist && strlen(skiplist) > 0){ + if(data->import->skiplist && strlen(data->import->skiplist) > 0){ snprintf(puf, sizeof(puf)-1, "%s,", (char *)q->str); - if(strstr(skiplist, puf)) skipmatch = 1; + if(strstr(data->import->skiplist, puf)) skipmatch = 1; } if(skipmatch == 1){ @@ -85,7 +88,7 @@ int import_from_imap_server(char *server, char *username, char *password, int po else { if(data->quiet == 0) printf("processing folder: %s... ", (char *)q->str); - if(process_imap_folder(sd, &seq, q->str, sdata, data, use_ssl, dryrun, cfg) == ERR) ret = ERR; + if(process_imap_folder(q->str, sdata, data, cfg) == ERR) ret = ERR; } } @@ -95,9 +98,9 @@ int import_from_imap_server(char *server, char *username, char *password, int po } } - send_imap_close(sd, &seq, data, use_ssl); + send_imap_close(data); - close_connection(sd, data, use_ssl); + close_connection(data->net); ENDE_IMAP: freeaddrinfo(res); @@ -108,5 +111,3 @@ ENDE_IMAP: return ret; } - - diff --git a/src/import_mailbox.c b/src/import_mailbox.c index 79e1a05c..c3885f48 100644 --- a/src/import_mailbox.c +++ b/src/import_mailbox.c @@ -22,10 +22,10 @@ #include -int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data *data, struct __config *cfg){ +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, ret=OK; - char buf[MAXBUFSIZE], fname[SMALLBUFSIZE]; + char buf[MAXBUFSIZE]; time_t t; @@ -44,18 +44,18 @@ int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data if(f){ fclose(f); f = NULL; - rc = import_message(fname, sdata, data, cfg); + rc = import_message(sdata, data, cfg); if(rc == ERR){ - printf("error importing: '%s'\n", fname); + printf("error importing: '%s'\n", data->import->filename); ret = ERR; } - else unlink(fname); + else unlink(data->import->filename); - if(data->quiet == 0){ printf("processed: %7d\r", tot_msgs); fflush(stdout); } + if(data->quiet == 0){ printf("processed: %7d\r", data->import->tot_msgs); fflush(stdout); } } - snprintf(fname, sizeof(fname)-1, "%ld-%d", t, tot_msgs); - f = fopen(fname, "w+"); + snprintf(data->import->filename, sizeof(data->import->filename)-1, "%ld-%d", t, data->import->tot_msgs); + f = fopen(data->import->filename, "w+"); continue; } @@ -64,14 +64,14 @@ int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data if(f){ fclose(f); - rc = import_message(fname, sdata, data, cfg); + rc = import_message(sdata, data, cfg); if(rc == ERR){ - printf("error importing: '%s'\n", fname); + printf("ERROR: error importing: '%s'\n", data->import->filename); ret = ERR; } - else unlink(fname); + else unlink(data->import->filename); - if(data->quiet == 0){ printf("processed: %7d\r", tot_msgs); fflush(stdout); } + if(data->quiet == 0){ printf("processed: %7d\r", data->import->tot_msgs); fflush(stdout); } } fclose(F); @@ -80,7 +80,7 @@ int import_from_mailbox(char *mailbox, struct session_data *sdata, struct __data } -int import_mbox_from_dir(char *directory, struct session_data *sdata, struct __data *data, int *tot_msgs, struct __config *cfg){ +int import_mbox_from_dir(char *directory, struct session_data *sdata, struct data *data, struct config *cfg){ DIR *dir; struct dirent *de; int rc=ERR, ret=OK, i=0; @@ -103,7 +103,7 @@ int import_mbox_from_dir(char *directory, struct session_data *sdata, struct __d if(stat(fname, &st) == 0){ if(S_ISDIR(st.st_mode)){ folder = data->folder; - rc = import_mbox_from_dir(fname, sdata, data, tot_msgs, cfg); + rc = import_mbox_from_dir(fname, sdata, data, cfg); data->folder = folder; if(rc == ERR) ret = ERR; } @@ -127,7 +127,7 @@ int import_mbox_from_dir(char *directory, struct session_data *sdata, struct __d } rc = import_from_mailbox(fname, sdata, data, cfg); - if(rc == OK) (*tot_msgs)++; + if(rc == OK) (data->import->tot_msgs)++; else ret = ERR; i++; diff --git a/src/import_maildir.c b/src/import_maildir.c index 97607903..dc4e3f7a 100644 --- a/src/import_maildir.c +++ b/src/import_maildir.c @@ -22,17 +22,17 @@ #include -int import_from_maildir(char *directory, struct session_data *sdata, struct __data *data, int *tot_msgs, struct __config *cfg){ +int import_from_maildir(struct session_data *sdata, struct data *data, struct config *cfg){ DIR *dir; struct dirent *de; int rc=ERR, ret=OK, i=0; int folder; - char *p, fname[SMALLBUFSIZE]; + char *p; struct stat st; - dir = opendir(directory); + dir = opendir(data->import->directory); if(!dir){ - printf("cannot open directory: %s\n", directory); + printf("cannot open directory: %s\n", data->import->directory); return ERR; } @@ -40,12 +40,13 @@ int import_from_maildir(char *directory, struct session_data *sdata, struct __da 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); + snprintf(data->import->filename, SMALLBUFSIZE-1, "%s/%s", data->import->directory, de->d_name); - if(stat(fname, &st) == 0){ + if(stat(data->import->filename, &st) == 0){ if(S_ISDIR(st.st_mode)){ folder = data->folder; - rc = import_from_maildir(fname, sdata, data, tot_msgs, cfg); + data->import->directory = data->import->filename; + rc = import_from_maildir(sdata, data, cfg); data->folder = folder; if(rc == ERR) ret = ERR; } @@ -53,10 +54,10 @@ int import_from_maildir(char *directory, struct session_data *sdata, struct __da if(S_ISREG(st.st_mode)){ if(i == 0 && data->recursive_folder_names == 1){ - p = strrchr(directory, '/'); + p = strrchr(data->import->directory, '/'); if(p) p++; else { - printf("invalid directory name: '%s'\n", directory); + printf("ERROR: invalid directory name: '%s'\n", data->import->directory); return ERR; } @@ -75,28 +76,28 @@ int import_from_maildir(char *directory, struct session_data *sdata, struct __da } - rc = import_message(fname, sdata, data, cfg); + rc = import_message(sdata, data, cfg); - if(rc == OK) (*tot_msgs)++; + if(rc == OK) (data->import->tot_msgs)++; else if(rc == ERR){ - printf("error importing: '%s'\n", fname); + printf("ERROR: error importing: '%s'\n", data->import->filename); ret = ERR; } - if(data->import->remove_after_import == 1 && rc != ERR) unlink(fname); + if(data->import->remove_after_import == 1 && rc != ERR) unlink(data->import->filename); i++; - if(data->quiet == 0){ printf("processed: %7d\r", *tot_msgs); fflush(stdout); } + if(data->quiet == 0){ printf("processed: %7d\r", data->import->tot_msgs); fflush(stdout); } } else { - printf("%s is not a file\n", fname); + printf("%s is not a file\n", data->import->filename); } } } else { - printf("cannot stat() %s\n", fname); + printf("cannot stat() %s\n", data->import->filename); } } @@ -104,5 +105,3 @@ int import_from_maildir(char *directory, struct session_data *sdata, struct __da return ret; } - - diff --git a/src/import_pop3.c b/src/import_pop3.c index 0209035a..a324ba22 100644 --- a/src/import_pop3.c +++ b/src/import_pop3.c @@ -22,50 +22,46 @@ #include -int import_from_pop3_server(char *server, char *username, char *password, int port, struct session_data *sdata, struct __data *data, int dryrun, struct __config *cfg){ - int rc, ret=OK, sd, use_ssl=0; +void import_from_pop3_server(struct session_data *sdata, struct data *data, struct config *cfg){ + int rc; char port_string[8]; struct addrinfo hints, *res; - snprintf(port_string, sizeof(port_string)-1, "%d", port); + data->net->use_ssl = 0; + + snprintf(port_string, sizeof(port_string)-1, "%d", data->import->port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - if((rc = getaddrinfo(server, port_string, &hints, &res)) != 0){ - printf("getaddrinfo for '%s': %s\n", server, gai_strerror(rc)); - return ERR; + if((rc = getaddrinfo(data->import->server, port_string, &hints, &res)) != 0){ + printf("getaddrinfo for '%s': %s\n", data->import->server, gai_strerror(rc)); + return; } - if(port == 995) use_ssl = 1; + if(data->import->port == 995) data->net->use_ssl = 1; - if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ + if((data->net->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ printf("cannot create socket\n"); - ret = ERR; goto ENDE_POP3; } - if(connect(sd, res->ai_addr, res->ai_addrlen) == -1){ + if(connect(data->net->socket, res->ai_addr, res->ai_addrlen) == -1){ printf("connect()\n"); - ret = ERR; goto ENDE_POP3; } - if(connect_to_pop3_server(sd, username, password, data, use_ssl) == ERR){ - close(sd); - ret = ERR; + if(connect_to_pop3_server(data) == ERR){ + close(data->net->socket); goto ENDE_POP3; } - if(process_pop3_emails(sd, sdata, data, use_ssl, dryrun, cfg) == ERR) ret = ERR; + process_pop3_emails(sdata, data, cfg); - close_connection(sd, data, use_ssl); + close_connection(data->net); ENDE_POP3: freeaddrinfo(res); - - return ret; } - diff --git a/src/message.c b/src/message.c index 91ec381f..28825836 100644 --- a/src/message.c +++ b/src/message.c @@ -17,7 +17,7 @@ #include -int store_index_data(struct session_data *sdata, struct parser_state *state, struct __data *data, uint64 id, struct __config *cfg){ +int store_index_data(struct session_data *sdata, struct parser_state *state, struct data *data, uint64 id, struct config *cfg){ int rc=ERR; char *subj; @@ -64,7 +64,7 @@ int store_index_data(struct session_data *sdata, struct parser_state *state, str } -uint64 get_metaid_by_messageid(struct session_data *sdata, struct __data *data, char *message_id, char *piler_id){ +uint64 get_metaid_by_messageid(struct session_data *sdata, struct data *data, char *message_id, char *piler_id){ uint64 id=0; if(prepare_sql_statement(sdata, &(data->stmt_get_meta_id_by_message_id), SQL_PREPARED_STMT_GET_META_ID_BY_MESSAGE_ID) == ERR) return id; @@ -91,7 +91,7 @@ uint64 get_metaid_by_messageid(struct session_data *sdata, struct __data *data, } -int store_recipients(struct session_data *sdata, struct __data *data, char *to, uint64 id, struct __config *cfg){ +int store_recipients(struct session_data *sdata, struct data *data, char *to, uint64 id, struct config *cfg){ int ret=OK, n=0; char *p, *q, puf[SMALLBUFSIZE]; @@ -138,7 +138,7 @@ void remove_recipients(struct session_data *sdata, uint64 id){ } -int store_folder_id(struct session_data *sdata, struct __data *data, uint64 id){ +int store_folder_id(struct session_data *sdata, struct data *data, uint64 id){ int rc = ERR; if(data->folder == ERR_FOLDER) return rc; @@ -166,7 +166,7 @@ void remove_folder_id(struct session_data *sdata, uint64 id){ } -int update_metadata_reference(struct session_data *sdata, struct parser_state *state, struct __data *data, char *ref, struct __config *cfg){ +int update_metadata_reference(struct session_data *sdata, struct parser_state *state, struct data *data, char *ref, struct config *cfg){ int ret = ERR; if(prepare_sql_statement(sdata, &(data->stmt_update_metadata_reference), SQL_PREPARED_STMT_UPDATE_METADATA_REFERENCE) == ERR) return ret; @@ -186,7 +186,7 @@ int update_metadata_reference(struct session_data *sdata, struct parser_state *s } -int store_meta_data(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg){ +int store_meta_data(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg){ int rc, ret=ERR, result; char *subj, *p, s[MAXBUFSIZE], s2[SMALLBUFSIZE], vcode[2*DIGEST_LENGTH+1], ref[2*DIGEST_LENGTH+1]; uint64 id=0; @@ -280,7 +280,7 @@ void remove_stripped_attachments(struct parser_state *state){ } -int process_message(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg){ +int process_message(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg){ int rc, fd; char piler_id[SMALLBUFSIZE]; diff --git a/src/misc.c b/src/misc.c index 9bd25d7e..bf3f35e3 100644 --- a/src/misc.c +++ b/src/misc.c @@ -422,13 +422,13 @@ int recvtimeout(int s, char *buf, int len, int timeout){ } -int write1(int sd, void *buf, int buflen, int use_ssl, SSL *ssl){ +int write1(struct net *net, void *buf, int buflen){ int n; - if(use_ssl == 1) - n = SSL_write(ssl, buf, buflen); + if(net->use_ssl == 1) + n = SSL_write(net->ssl, buf, buflen); else - n = send(sd, buf, buflen, 0); + n = send(net->socket, buf, buflen, 0); return n; } @@ -489,26 +489,26 @@ int ssl_read_timeout(SSL *ssl, void *buf, int len, int timeout){ } -int recvtimeoutssl(int s, char *buf, int len, int timeout, int use_ssl, SSL *ssl){ +int recvtimeoutssl(struct net *net, char *buf, int len){ memset(buf, 0, len); - if(use_ssl == 1){ - return ssl_read_timeout(ssl, buf, len-1, timeout); + if(net->use_ssl == 1){ + return ssl_read_timeout(net->ssl, buf, len-1, net->timeout); } else { - return recvtimeout(s, buf, len-1, timeout); + return recvtimeout(net->socket, buf, len-1, net->timeout); } } -void close_connection(int sd, struct __data *data, int use_ssl){ - close(sd); +void close_connection(struct net *net){ + close(net->socket); - if(use_ssl == 1){ - SSL_shutdown(data->ssl); - SSL_free(data->ssl); - SSL_CTX_free(data->ctx); + if(net->use_ssl == 1){ + SSL_shutdown(net->ssl); + SSL_free(net->ssl); + SSL_CTX_free(net->ctx); ERR_free_strings(); } } @@ -544,7 +544,7 @@ int drop_privileges(struct passwd *pwd){ } -void init_session_data(struct session_data *sdata, struct __config *cfg){ +void init_session_data(struct session_data *sdata, struct config *cfg){ int i; diff --git a/src/misc.h b/src/misc.h index 95450021..ff58cdcb 100644 --- a/src/misc.h +++ b/src/misc.h @@ -32,14 +32,14 @@ void create_id(char *id, unsigned char server_id); int get_random_bytes(unsigned char *buf, int len, unsigned char server_id); int readFromEntropyPool(int fd, void *_s, ssize_t n); int recvtimeout(int s, char *buf, int len, int timeout); -int write1(int sd, void *buf, int buflen, int use_ssl, SSL *ssl); -int recvtimeoutssl(int s, char *buf, int len, int timeout, int use_ssl, SSL *ssl); -void close_connection(int sd, struct __data *data, int use_ssl); +int write1(struct net *net, void *buf, int buflen); +int recvtimeoutssl(struct net *net, char *buf, int len); +void close_connection(struct net *net); void write_pid_file(char *pidfile); int drop_privileges(struct passwd *pwd); -void init_session_data(struct session_data *sdata, struct __config *cfg); +void init_session_data(struct session_data *sdata, struct config *cfg); int read_from_stdin(struct session_data *sdata); void strtolower(char *s); diff --git a/src/mydomains.c b/src/mydomains.c index 3e7e3d93..0048de5b 100644 --- a/src/mydomains.c +++ b/src/mydomains.c @@ -10,7 +10,7 @@ #include -void load_mydomains(struct session_data *sdata, struct __data *data, struct __config *cfg){ +void load_mydomains(struct session_data *sdata, struct data *data, struct config *cfg){ int rc; char s[SMALLBUFSIZE]; @@ -46,7 +46,7 @@ void load_mydomains(struct session_data *sdata, struct __data *data, struct __co } -int is_email_address_on_my_domains(char *email, struct __data *data){ +int is_email_address_on_my_domains(char *email, struct data *data){ int rc=0; char *q, *s; diff --git a/src/mysql.c b/src/mysql.c index 54124efe..91addb05 100644 --- a/src/mysql.c +++ b/src/mysql.c @@ -9,7 +9,7 @@ #include -int open_database(struct session_data *sdata, struct __config *cfg){ +int open_database(struct session_data *sdata, struct config *cfg){ int rc=1; char buf[BUFLEN]; @@ -38,7 +38,7 @@ void close_database(struct session_data *sdata){ } -void p_bind_init(struct __data *data){ +void p_bind_init(struct data *data){ int i; data->pos = 0; @@ -56,7 +56,7 @@ void p_query(struct session_data *sdata, char *s){ } -int p_exec_query(struct session_data *sdata, MYSQL_STMT *stmt, struct __data *data){ +int p_exec_query(struct session_data *sdata, MYSQL_STMT *stmt, struct data *data){ MYSQL_BIND bind[MAX_SQL_VARS]; unsigned long length[MAX_SQL_VARS]; int i, ret=ERR; @@ -127,7 +127,7 @@ int p_exec_query(struct session_data *sdata, MYSQL_STMT *stmt, struct __data *da } -int p_store_results(MYSQL_STMT *stmt, struct __data *data){ +int p_store_results(MYSQL_STMT *stmt, struct data *data){ MYSQL_BIND bind[MAX_SQL_VARS]; int i, ret=ERR; diff --git a/src/parser.c b/src/parser.c index c11c1488..73e14746 100644 --- a/src/parser.c +++ b/src/parser.c @@ -16,7 +16,7 @@ #include -struct parser_state parse_message(struct session_data *sdata, int take_into_pieces, struct __data *data, struct __config *cfg){ +struct parser_state parse_message(struct session_data *sdata, int take_into_pieces, struct data *data, struct config *cfg){ FILE *f; int i; unsigned int len; @@ -84,7 +84,7 @@ struct parser_state parse_message(struct session_data *sdata, int take_into_piec } if(take_into_pieces == 1 && state.writebufpos > 0){ - write(state.mfd, writebuffer, state.writebufpos); + if(write(state.mfd, writebuffer, state.writebufpos) == -1) syslog(LOG_PRIORITY, "ERROR: %s: write(), %s, %d, %s", sdata->ttmpfile, __func__, __LINE__, __FILE__); memset(writebuffer, 0, sizeof(writebuffer)); state.writebufpos = 0; } @@ -99,7 +99,7 @@ struct parser_state parse_message(struct session_data *sdata, int take_into_piec } -void post_parse(struct session_data *sdata, struct parser_state *state, struct __config *cfg){ +void post_parse(struct session_data *sdata, struct parser_state *state, struct config *cfg){ int i, rec=0; unsigned int len; char *p; @@ -171,7 +171,7 @@ void storno_attachment(struct parser_state *state){ } -int parse_line(char *buf, struct parser_state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct __data *data, struct __config *cfg){ +int parse_line(char *buf, struct parser_state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct data *data, struct config *cfg){ char *p, *q, puf[SMALLBUFSIZE]; unsigned char b64buffer[MAXBUFSIZE]; char tmpbuf[MAXBUFSIZE]; @@ -224,16 +224,16 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata if(state->message_state == MSG_BODY && state->fd != -1 && is_substr_in_hash(state->boundaries, buf) == 0){ //n = write(state->fd, buf, len); // WRITE if(len + state->abufpos > abuffersize-1){ - write(state->fd, abuffer, state->abufpos); + if(write(state->fd, abuffer, state->abufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); if(state->b64fd != -1){ abuffer[state->abufpos] = '\0'; if(state->base64 == 1){ n64 = base64_decode_attachment_buffer(abuffer, &b64buffer[0], sizeof(b64buffer)); - write(state->b64fd, b64buffer, n64); + if(write(state->b64fd, b64buffer, n64) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); } else { - write(state->b64fd, abuffer, state->abufpos); + if(write(state->b64fd, abuffer, state->abufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); } } @@ -247,7 +247,9 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata state->saved_size += len; //n = write(state->mfd, buf, len); // WRITE if(len + state->writebufpos > writebuffersize-1){ - write(state->mfd, writebuffer, state->writebufpos); state->writebufpos = 0; memset(writebuffer, 0, writebuffersize); + if(write(state->mfd, writebuffer, state->writebufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); + state->writebufpos = 0; + memset(writebuffer, 0, writebuffersize); } memcpy(writebuffer+state->writebufpos, buf, len); state->writebufpos += len; } @@ -296,9 +298,12 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata //n = write(state->mfd, puf, strlen(puf)); // WRITE writelen = strlen(puf); if(writelen + state->writebufpos > writebuffersize-1){ - write(state->mfd, writebuffer, state->writebufpos); state->writebufpos = 0; memset(writebuffer, 0, writebuffersize); + if(write(state->mfd, writebuffer, state->writebufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); + state->writebufpos = 0; + memset(writebuffer, 0, writebuffersize); } - memcpy(writebuffer+state->writebufpos, puf, writelen); state->writebufpos += writelen; + memcpy(writebuffer+state->writebufpos, puf, writelen); + state->writebufpos += writelen; } } @@ -588,16 +593,16 @@ int parse_line(char *buf, struct parser_state *state, struct session_data *sdata if(state->has_to_dump == 1){ if(take_into_pieces == 1 && state->fd != -1){ if(state->abufpos > 0){ - write(state->fd, abuffer, state->abufpos); + if(write(state->fd, abuffer, state->abufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); if(state->b64fd != -1){ abuffer[state->abufpos] = '\0'; if(state->base64 == 1){ n64 = base64_decode_attachment_buffer(abuffer, &b64buffer[0], sizeof(b64buffer)); - write(state->b64fd, b64buffer, n64); + if(write(state->b64fd, b64buffer, n64) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); } else { - write(state->b64fd, abuffer, state->abufpos); + if(write(state->b64fd, abuffer, state->abufpos) == -1) syslog(LOG_PRIORITY, "ERROR: write(), %s, %d, %s", __func__, __LINE__, __FILE__); } } diff --git a/src/parser.h b/src/parser.h index f448d6f9..b6565667 100644 --- a/src/parser.h +++ b/src/parser.h @@ -9,9 +9,9 @@ #include "config.h" #include "defs.h" -struct parser_state parse_message(struct session_data *sdata, int take_into_pieces, struct __data *data, struct __config *cfg); -void post_parse(struct session_data *sdata, struct parser_state *state, struct __config *cfg); -int parse_line(char *buf, struct parser_state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct __data *data, struct __config *cfg); +struct parser_state parse_message(struct session_data *sdata, int take_into_pieces, struct data *data, struct config *cfg); +void post_parse(struct session_data *sdata, struct parser_state *state, struct config *cfg); +int parse_line(char *buf, struct parser_state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct data *data, struct config *cfg); void init_state(struct parser_state *state); time_t parse_date_header(char *s); diff --git a/src/piler-smtp.c b/src/piler-smtp.c index 182365a4..a3b56393 100644 --- a/src/piler-smtp.c +++ b/src/piler-smtp.c @@ -36,7 +36,7 @@ int num_connections = 0; int listenerfd = -1; char *configfile = CONFIG_FILE; -struct __config cfg; +struct config cfg; struct passwd *pwd; struct smtp_session *session, **sessions=NULL; @@ -270,8 +270,8 @@ int main(int argc, char **argv){ while(1){ memset(readbuf, 0, sizeof(readbuf)); - if(session->use_ssl == 1) - readlen = SSL_read(session->ssl, (char*)&readbuf[0], sizeof(readbuf)-1); + if(session->net.use_ssl == 1) + readlen = SSL_read(session->net.ssl, (char*)&readbuf[0], sizeof(readbuf)-1); else readlen = read(events[i].data.fd, (char*)&readbuf[0], sizeof(readbuf)-1); diff --git a/src/piler.c b/src/piler.c index 2d9dc0df..9bf265a3 100644 --- a/src/piler.c +++ b/src/piler.c @@ -34,8 +34,8 @@ extern int optind; int quit = 0; int received_sighup = 0; char *configfile = CONFIG_FILE; -struct __config cfg; -struct __data data; +struct config cfg; +struct data data; struct passwd *pwd; struct child children[MAXCHILDREN]; @@ -87,7 +87,7 @@ void child_sighup_handler(int sig){ } -int process_email(char *filename, struct session_data *sdata, struct __data *data, int size, struct __config *cfg){ +int process_email(char *filename, struct session_data *sdata, struct data *data, int size, struct config *cfg){ int rc; char tmpbuf[SMALLBUFSIZE]; char *status=S_STATUS_UNDEF; @@ -187,7 +187,7 @@ int process_email(char *filename, struct session_data *sdata, struct __data *dat } -int process_dir(char *directory, struct session_data *sdata, struct __data *data, struct __config *cfg){ +int process_dir(char *directory, struct session_data *sdata, struct data *data, struct config *cfg){ DIR *dir; struct dirent *de; int tot_msgs=0; diff --git a/src/piler.h b/src/piler.h index 5ee0316b..cd29103d 100644 --- a/src/piler.h +++ b/src/piler.h @@ -27,47 +27,47 @@ #include "memc.h" #endif -int read_key(struct __config *cfg); +int read_key(struct config *cfg); void insert_offset(struct session_data *sdata, int server_id); void tear_down_client(int n); -int do_av_check(char *filename, struct __config *cfg); +int do_av_check(char *filename, struct config *cfg); -int make_digests(struct session_data *sdata, struct __config *cfg); +int make_digests(struct session_data *sdata, struct config *cfg); void digest_file(char *filename, char *digest); void digest_string(char *s, char *digest); void remove_stripped_attachments(struct parser_state *state); -int process_message(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg); -int reimport_message(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg); -int store_file(struct session_data *sdata, char *filename, int len, struct __config *cfg); -int remove_stored_message_files(struct session_data *sdata, struct parser_state *state, struct __config *cfg); -int store_attachments(struct session_data *sdata, struct parser_state *state, struct __data *data, struct __config *cfg); -int query_attachments(struct session_data *sdata, struct __data *data, struct ptr_array *ptr_arr); +int process_message(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg); +int reimport_message(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg); +int store_file(struct session_data *sdata, char *filename, int len, struct config *cfg); +int remove_stored_message_files(struct session_data *sdata, struct parser_state *state, struct config *cfg); +int store_attachments(struct session_data *sdata, struct parser_state *state, struct data *data, struct config *cfg); +int query_attachments(struct session_data *sdata, struct data *data, struct ptr_array *ptr_arr); -struct __config read_config(char *configfile); +struct config read_config(char *configfile); -void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid); +void check_and_create_directories(struct config *cfg, uid_t uid, gid_t gid); -void update_counters(struct session_data *sdata, struct __data *data, struct counters *counters, struct __config *cfg); +void update_counters(struct session_data *sdata, struct data *data, struct counters *counters, struct config *cfg); -int retrieve_email_from_archive(struct session_data *sdata, struct __data *data, FILE *dest, struct __config *cfg); -int file_from_archive_to_network(char *filename, int sd, int tls_enable, struct __data *data, struct __config *cfg); +int retrieve_email_from_archive(struct session_data *sdata, struct data *data, FILE *dest, struct config *cfg); +int file_from_archive_to_network(char *filename, int sd, int tls_enable, struct data *data, struct config *cfg); -int get_folder_id(struct session_data *sdata, struct __data *data, char *foldername, int parent_id); -int add_new_folder(struct session_data *sdata, struct __data *data, char *foldername, int parent_id); +int get_folder_id(struct session_data *sdata, struct data *data, char *foldername, int parent_id); +int add_new_folder(struct session_data *sdata, struct data *data, char *foldername, int parent_id); -int store_index_data(struct session_data *sdata, struct parser_state *state, struct __data *data, uint64 id, struct __config *cfg); +int store_index_data(struct session_data *sdata, struct parser_state *state, struct data *data, uint64 id, struct config *cfg); -void extract_attachment_content(struct session_data *sdata, struct parser_state *state, char *filename, char *type, int *rec, struct __config *cfg); +void extract_attachment_content(struct session_data *sdata, struct parser_state *state, char *filename, char *type, int *rec, struct config *cfg); -int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct __config *cfg); +int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct config *cfg); -void load_mydomains(struct session_data *sdata, struct __data *data, struct __config *cfg); -int is_email_address_on_my_domains(char *email, struct __data *data); +void load_mydomains(struct session_data *sdata, struct data *data, struct config *cfg); +int is_email_address_on_my_domains(char *email, struct data *data); -int start_new_session(struct smtp_session **sessions, int socket, int *num_connections, struct __config *cfg); +int start_new_session(struct smtp_session **sessions, int socket, int *num_connections, struct config *cfg); void tear_down_session(struct smtp_session **sessions, int slot, int *num_connections); struct smtp_session *get_session_by_socket(struct smtp_session **sessions, int max_connections, int socket); void handle_data(struct smtp_session *session, char *readbuf, int readlen); diff --git a/src/pileraget.c b/src/pileraget.c index b576f2cb..d926c7f8 100644 --- a/src/pileraget.c +++ b/src/pileraget.c @@ -22,7 +22,7 @@ int main(int argc, char **argv){ #ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT struct stat st; #endif - struct __config cfg; + struct config cfg; if(argc < 3){ diff --git a/src/pilerconf.c b/src/pilerconf.c index 019b4461..bc9071ee 100644 --- a/src/pilerconf.c +++ b/src/pilerconf.c @@ -12,13 +12,13 @@ extern char *optarg; extern int optind; -void print_config_all(struct __config *cfg, char *key); -void print_config(char *configfile, struct __config *cfg); +void print_config_all(struct config *cfg, char *key); +void print_config(char *configfile, struct config *cfg); int main(int argc, char **argv){ int i, print_from_file=0; char *configfile=CONFIG_FILE, *query=NULL; - struct __config cfg; + struct config cfg; while((i = getopt(argc, argv, "c:q:nh?")) > 0){ switch(i){ diff --git a/src/pilerexport.c b/src/pilerexport.c index 3983ff1e..111f6273 100644 --- a/src/pilerexport.c +++ b/src/pilerexport.c @@ -30,7 +30,7 @@ char *index_list = "main1,dailydelta1,delta1"; regex_t regexp; -int export_emails_matching_to_query(struct session_data *sdata, struct __data *data, char *s, struct __config *cfg); +int export_emails_matching_to_query(struct session_data *sdata, struct data *data, char *s, struct config *cfg); void usage(){ @@ -151,7 +151,7 @@ int append_string_to_buffer(char **buffer, char *str){ } -uint64 run_query(struct session_data *sdata, struct session_data *sdata2, struct __data *data, char *where_condition, uint64 last_id, int *num, struct __config *cfg){ +uint64 run_query(struct session_data *sdata, struct session_data *sdata2, struct data *data, char *where_condition, uint64 last_id, int *num, struct config *cfg){ MYSQL_RES *res; MYSQL_ROW row; int rc=0; @@ -212,7 +212,7 @@ uint64 get_total_found(struct session_data *sdata){ } -void export_emails_matching_id_list(struct session_data *sdata, struct session_data *sdata2, struct __data *data, char *where_condition, struct __config *cfg){ +void export_emails_matching_id_list(struct session_data *sdata, struct session_data *sdata2, struct data *data, char *where_condition, struct config *cfg){ int n; uint64 count=0, last_id=0, total_found=0; @@ -335,7 +335,7 @@ int build_query_from_args(char *from, char *to, char *fromdomain, char *todomain } -int export_emails_matching_to_query(struct session_data *sdata, struct __data *data, char *s, struct __config *cfg){ +int export_emails_matching_to_query(struct session_data *sdata, struct data *data, char *s, struct config *cfg){ FILE *f; uint64 id, n=0; char digest[SMALLBUFSIZE], bodydigest[SMALLBUFSIZE]; @@ -416,8 +416,8 @@ int main(int argc, char **argv){ char *configfile=CONFIG_FILE; char *to=NULL, *from=NULL, *todomain=NULL, *fromdomain=NULL, *where_condition=NULL; struct session_data sdata, sdata2; - struct __data data; - struct __config cfg; + struct data data; + struct config cfg; if(regcomp(®exp, "^([\\+a-z0-9_\\.@\\-]+)$", REG_ICASE | REG_EXTENDED)){ diff --git a/src/pilerget.c b/src/pilerget.c index a41c94a8..837b2103 100644 --- a/src/pilerget.c +++ b/src/pilerget.c @@ -19,8 +19,8 @@ int main(int argc, char **argv){ int readkey=1; struct session_data sdata; - struct __data data; - struct __config cfg; + struct data data; + struct config cfg; if(argc < 2){ diff --git a/src/pilerimport.c b/src/pilerimport.c index 4a1333f1..19d855f5 100644 --- a/src/pilerimport.c +++ b/src/pilerimport.c @@ -30,9 +30,6 @@ extern char *optarg; extern int optind; -int dryrun=0; -int import_from_gui=0; - void usage(){ printf("\nusage: pilerimport\n\n"); @@ -65,13 +62,14 @@ void usage(){ int main(int argc, char **argv){ - int i, c, rc=0, n_mbox=0, tot_msgs=0, port=143; - char *configfile=CONFIG_FILE, *emlfile=NULL, *mboxdir=NULL, *mbox[MBOX_ARGS], *directory=NULL; - char *imapserver=NULL, *pop3server=NULL, *username=NULL, *password=NULL, *skiplist=SKIPLIST, *folder=NULL, *folder_imap=NULL; + int i, c, n_mbox=0; + char *configfile=CONFIG_FILE, *mbox[MBOX_ARGS]; + char *imapserver=NULL, *pop3server=NULL; struct session_data sdata; - struct __config cfg; - struct __data data; + struct config cfg; + struct data data; struct import import; + struct net net; for(i=0; ifilename, SMALLBUFSIZE-1, "%s", optarg); break; case 'd' : - directory = optarg; + data.import->directory = optarg; break; case 'm' : @@ -163,40 +177,42 @@ int main(int argc, char **argv){ break; case 'M' : - mboxdir = optarg; + data.import->mboxdir = optarg; break; case 'i' : imapserver = optarg; + data.import->server = optarg; break; case 'K' : pop3server = optarg; - if(port == 143) port = 110; + data.import->server = optarg; + if(data.import->port == 143) data.import->port = 110; break; case 'u' : - username = optarg; + data.import->username = optarg; break; case 'p' : - password = optarg; + data.import->password = optarg; break; case 'P' : - port = atoi(optarg); + data.import->port = atoi(optarg); break; case 'x' : - skiplist = optarg; + data.import->skiplist = optarg; break; case 'F' : - folder = optarg; + data.import->folder = optarg; break; case 'f' : - folder_imap = optarg; + data.import->folder_imap = optarg; break; case 'R' : @@ -217,7 +233,7 @@ int main(int argc, char **argv){ case 'o' : data.import->download_only = 1; - dryrun = 1; + data.import->dryrun = 1; break; case 'b' : @@ -241,12 +257,8 @@ int main(int argc, char **argv){ data.import->extra_recipient = optarg; break; - case 'G' : - import_from_gui = 1; - break; - case 'D' : - dryrun = 1; + data.import->dryrun = 1; break; case 'q' : @@ -265,8 +277,7 @@ int main(int argc, char **argv){ } - - if(!mbox[0] && !mboxdir && !emlfile && !directory && !imapserver && !pop3server && import_from_gui == 0) usage(); + if(!mbox[0] && !data.import->mboxdir && !data.import->filename && !data.import->directory && !imapserver && !pop3server) usage(); if(data.import->failed_folder && !can_i_write_directory(data.import->failed_folder)){ printf("cannot write failed directory '%s'\n", data.import->failed_folder); @@ -277,7 +288,7 @@ int main(int argc, char **argv){ cfg = read_config(configfile); - if((data.recursive_folder_names == 1 || folder) && cfg.enable_folders == 0){ + if((data.recursive_folder_names == 1 || data.import->folder) && cfg.enable_folders == 0){ printf("please set enable_folders=1 in piler.conf to use the folder options\n"); return ERR; } @@ -304,15 +315,15 @@ int main(int argc, char **argv){ memcached_init(&(data.memc), cfg.memcached_servers, 11211); #endif - if(folder){ - data.folder = get_folder_id(&sdata, &data, folder, 0); + if(data.import->folder){ + data.folder = get_folder_id(&sdata, &data, data.import->folder, 0); if(data.folder == ERR_FOLDER){ - data.folder = add_new_folder(&sdata, &data, folder, 0); + data.folder = add_new_folder(&sdata, &data, data.import->folder, 0); } if(data.folder == ERR_FOLDER){ - printf("error: cannot get/add folder '%s'\n", folder); + printf("ERROR: cannot get/add folder '%s'\n", data.import->folder); close_database(&sdata); return 0; } @@ -325,18 +336,17 @@ int main(int argc, char **argv){ load_mydomains(&sdata, &data, &cfg); - if(emlfile) rc = import_message(emlfile, &sdata, &data, &cfg); + if(data.import->filename[0] != '\0') import_message(&sdata, &data, &cfg); if(mbox[0]){ for(i=0; imboxdir) import_mbox_from_dir(data.import->mboxdir, &sdata, &data, &cfg); + if(data.import->directory) import_from_maildir(&sdata, &data, &cfg); + if(imapserver) import_from_imap_server(&sdata, &data, &cfg); + if(pop3server) import_from_pop3_server(&sdata, &data, &cfg); clearrules(data.archiving_rules); clearrules(data.retention_rules); @@ -348,7 +358,5 @@ int main(int argc, char **argv){ if(data.quiet == 0) printf("\n"); - return rc; + return 0; } - - diff --git a/src/pilerpurge.c b/src/pilerpurge.c deleted file mode 100644 index 656491a6..00000000 --- a/src/pilerpurge.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * pilerpurge.c, SJ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -extern char *optarg; -extern int optind; - -int dryrun = 0; -unsigned long purged_size=0; - -#define NUMBER_OF_ATTACHMENTS_TO_REMOVE_IN_ONE_ROUND 100 - -#define SQL_STMT_SELECT_PURGE_FROM_OPTION_TABLE "SELECT `value` FROM `" SQL_OPTION_TABLE "` WHERE `key`='enable_purge'" -#define SQL_STMT_DELETE_FROM_META_TABLE "UPDATE `" SQL_METADATA_TABLE "` SET `deleted`=1 WHERE `id` IN (" -#define SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID "UPDATE `" SQL_METADATA_TABLE "` SET `deleted`=1 WHERE `piler_id` IN ('" -#define SQL_STMT_SELECT_NON_REFERENCED_ATTACHMENTS "SELECT `piler_id`, `attachment_id`, `i` FROM `" SQL_ATTACHMENTS_VIEW "` WHERE `refcount`=0 AND `piler_id` IN ('" -#define SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE "DELETE FROM `" SQL_ATTACHMENT_TABLE "` WHERE `id` IN (" - - -int is_purge_allowed(struct session_data *sdata, struct __data *data){ - int rc=0; - - if(prepare_sql_statement(sdata, &(data->stmt_generic), SQL_STMT_SELECT_PURGE_FROM_OPTION_TABLE) == ERR) return rc; - - - p_bind_init(data); - - if(p_exec_query(sdata, data->stmt_generic, data) == OK){ - - p_bind_init(data); - - data->sql[data->pos] = (char *)&rc; data->type[data->pos] = TYPE_LONG; data->len[data->pos] = sizeof(int); data->pos++; - - p_store_results(data->stmt_generic, data); - p_fetch_results(data->stmt_generic); - p_free_results(data->stmt_generic); - } - - close_prepared_statement(data->stmt_generic); - - return rc; -} - - -int remove_message_frame_files(char *s, char *update_meta_sql, struct session_data *sdata, struct __config *cfg){ - char *p, puf[SMALLBUFSIZE], filename[SMALLBUFSIZE]; - int n=0, result; -#ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT - struct stat st; -#endif - - p = s; - do { - p = split(p, ' ', puf, sizeof(puf)-1, &result); - - if(strlen(puf) == RND_STR_LEN){ - 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); - - #ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT - if(stat(filename, &st)){ - 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); - } - #endif - - if(dryrun == 1){ - n++; - printf("removing messagefile: %s\n", filename); - } - else { - if(unlink(filename) == 0) n++; - } - - } - } while(p); - - - update_meta_sql[strlen(update_meta_sql)-1] = ')'; - - if(dryrun == 1){ - printf("update metadata query: *%s*\n\n", update_meta_sql); - } else { - p_query(sdata, update_meta_sql); - } - - - return n; -} - - -int remove_attachments(char *in, struct session_data *sdata, struct __data *data, struct __config *cfg){ - char filename[SMALLBUFSIZE]; - char *a, buf[NUMBER_OF_ATTACHMENTS_TO_REMOVE_IN_ONE_ROUND*(RND_STR_LEN+1)+10], update_meta_sql[strlen(SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID)+NUMBER_OF_ATTACHMENTS_TO_REMOVE_IN_ONE_ROUND*(RND_STR_LEN+3)+10], delete_attachment_stmt[MAXBUFSIZE]; - char piler_id[SMALLBUFSIZE], i[BUFLEN]; - int n=0, m=0, len, attachment_id=0, piler_id_len; - unsigned int blen=0, ulen=0, dlen=0; -#ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT - struct stat st; -#endif - - if(strlen(in) < 10) return 0; - - len = strlen(SQL_STMT_SELECT_NON_REFERENCED_ATTACHMENTS) + strlen(in) + 2; - - a = malloc(len); - if(!a) return 0; - - memset(a, 0, len); - - in[strlen(in)-2] = ')'; - in[strlen(in)-1] = '\0'; - snprintf(a, len-1, "%s%s", SQL_STMT_SELECT_NON_REFERENCED_ATTACHMENTS, in); - - if(prepare_sql_statement(sdata, &(data->stmt_select_non_referenced_attachments), a) == ERR){ free(a); return n; } - - if(dryrun == 1) printf("attachment select sql: *%s*\n\n", a); - - memset(buf, 0, sizeof(buf)); - memset(update_meta_sql, 0, sizeof(update_meta_sql)); - memset(delete_attachment_stmt, 0, sizeof(delete_attachment_stmt)); - - snprintf(update_meta_sql, sizeof(update_meta_sql)-1, "%s", SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID); - ulen = strlen(SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID); - - snprintf(delete_attachment_stmt, sizeof(delete_attachment_stmt)-1, "%s", SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE); - dlen = strlen(SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE); - - p_bind_init(data); - if(p_exec_query(sdata, data->stmt_select_non_referenced_attachments, data) == ERR) goto ENDE; - - - p_bind_init(data); - - data->sql[data->pos] = &piler_id[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(piler_id)-2; data->pos++; - data->sql[data->pos] = (char *)&attachment_id; data->type[data->pos] = TYPE_LONG; data->len[data->pos] = sizeof(int); data->pos++; - data->sql[data->pos] = &i[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(i)-2; data->pos++; - - p_store_results(data->stmt_select_non_referenced_attachments, data); - - while(p_fetch_results(data->stmt_select_non_referenced_attachments) == OK){ - - piler_id_len = strlen(piler_id); - - if(piler_id_len != RND_STR_LEN || attachment_id <= 0){ - printf("invalid piler_id: '%s.a%d'\n", piler_id, attachment_id); - continue; - } - - snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, piler_id[8], piler_id[9], piler_id[10], piler_id[RND_STR_LEN-4], piler_id[RND_STR_LEN-3], piler_id[RND_STR_LEN-2], piler_id[RND_STR_LEN-1], piler_id, attachment_id); - #ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT - if(stat(filename, &st)){ - snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, cfg->server_id, piler_id[RND_STR_LEN-6], piler_id[RND_STR_LEN-5], piler_id[RND_STR_LEN-4], piler_id[RND_STR_LEN-3], piler_id[RND_STR_LEN-2], piler_id[RND_STR_LEN-1], piler_id, attachment_id); - } - #endif - - if(dryrun == 1){ - printf("removing attachment: *%s*\n", filename); - } else { - unlink(filename); - } - - - if(strlen(i) > 0){ - if(dlen > sizeof(delete_attachment_stmt) - 200){ - - delete_attachment_stmt[dlen-1] = ')'; - if(dryrun == 1){ - printf("delete sql: *%s*\n", delete_attachment_stmt); - } else { - p_query(sdata, delete_attachment_stmt); - } - - memset(delete_attachment_stmt, 0, sizeof(delete_attachment_stmt)); - snprintf(delete_attachment_stmt, sizeof(delete_attachment_stmt)-1, "%s", SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE); - dlen = strlen(SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE); - } - - memcpy(&delete_attachment_stmt[dlen], i, strlen(i)); dlen += strlen(i); - memcpy(&delete_attachment_stmt[dlen], ",", 1); dlen++; - } - - - if(attachment_id == 1){ - - m++; - - if(m >= NUMBER_OF_ATTACHMENTS_TO_REMOVE_IN_ONE_ROUND){ - if(ulen > strlen(SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID)+10){ - update_meta_sql[ulen-2] = ')'; - update_meta_sql[ulen-1] = '\0'; - } - - n += remove_message_frame_files(buf, update_meta_sql, sdata, cfg); - - memset(buf, 0, sizeof(buf)); - memset(update_meta_sql, 0, sizeof(update_meta_sql)); - - snprintf(update_meta_sql, sizeof(update_meta_sql)-1, "%s", SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID); - - ulen = strlen(SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID); - blen = 0; - - m = 0; - } - - memcpy(&buf[blen], piler_id, piler_id_len); blen += piler_id_len; - memcpy(&buf[blen], " ", 1); blen++; - - memcpy(&update_meta_sql[ulen], piler_id, piler_id_len); ulen += piler_id_len; - memcpy(&update_meta_sql[ulen], "','", 3); ulen += 3; - } - - } - - p_free_results(data->stmt_select_non_referenced_attachments); - - if(ulen > strlen(SQL_STMT_DELETE_FROM_META_TABLE_BY_PILER_ID)+10){ - - update_meta_sql[ulen-2] = ')'; - update_meta_sql[ulen-1] = '\0'; - - n += remove_message_frame_files(buf, update_meta_sql, sdata, cfg); - } - - if(dlen > strlen(SQL_STMT_DELETE_FROM_ATTACHMENT_TABLE)){ - delete_attachment_stmt[dlen-1] = ')'; - if(dryrun == 1){ - printf("delete sql: *%s*\n", delete_attachment_stmt); - } else { - p_query(sdata, delete_attachment_stmt); - } - - } - -ENDE: - free(a); - - close_prepared_statement(data->stmt_select_non_referenced_attachments); - - return n; -} - - -int purge_messages_round1(struct session_data *sdata, struct __data *data, char *attachment_condition, struct __config *cfg){ - int purged=0, size; - unsigned int blen=0, ulen=0; - char id[BUFLEN], s[SMALLBUFSIZE], buf[MAXBUFSIZE], update_meta_sql[MAXBUFSIZE]; - - memset(buf, 0, sizeof(buf)); - memset(update_meta_sql, 0, sizeof(update_meta_sql)); - - snprintf(update_meta_sql, sizeof(update_meta_sql)-1, "%s", SQL_STMT_DELETE_FROM_META_TABLE); - ulen = strlen(SQL_STMT_DELETE_FROM_META_TABLE); - - snprintf(s, sizeof(s)-1, "SELECT `id`, `piler_id`, `size` FROM `%s` WHERE `deleted`=0 AND `retained` < %ld AND %s AND id NOT IN (SELECT id FROM `%s` WHERE `to` IN (SELECT email FROM `%s`)) AND id NOT IN (SELECT id FROM `%s` WHERE `from` IN (SELECT email FROM `%s`))", SQL_METADATA_TABLE, sdata->now, attachment_condition, SQL_RECIPIENT_TABLE, SQL_LEGAL_HOLD_TABLE, SQL_METADATA_TABLE, SQL_LEGAL_HOLD_TABLE); - - if(dryrun == 1) printf("purge sql: *%s*\n", s); - - if(prepare_sql_statement(sdata, &(data->stmt_select_from_meta_table), s) == ERR) return purged; - - p_bind_init(data); - - if(p_exec_query(sdata, data->stmt_select_from_meta_table, data) == OK){ - - p_bind_init(data); - - data->sql[data->pos] = &id[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(id)-2; data->pos++; - data->sql[data->pos] = &s[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s)-2; data->pos++; - data->sql[data->pos] = (char *)&size; data->type[data->pos] = TYPE_LONG; data->len[data->pos] = sizeof(int); data->pos++; - - p_store_results(data->stmt_select_from_meta_table, data); - - while(p_fetch_results(data->stmt_select_from_meta_table) == OK){ - - memcpy(&update_meta_sql[ulen], id, strlen(id)); ulen += strlen(id); - memcpy(&update_meta_sql[ulen], ",", 1); ulen++; - - purged_size += size; - - if(blen >= sizeof(buf)-RND_STR_LEN-2-1){ - - purged += remove_message_frame_files(buf, update_meta_sql, sdata, cfg); - - memset(buf, 0, sizeof(buf)); - memset(update_meta_sql, 0, sizeof(update_meta_sql)); - - snprintf(update_meta_sql, sizeof(update_meta_sql)-1, "%s", SQL_STMT_DELETE_FROM_META_TABLE); - - blen = 0; - ulen = strlen(SQL_STMT_DELETE_FROM_META_TABLE); - } - - memcpy(&buf[blen], s, strlen(s)); blen += strlen(s); - memcpy(&buf[blen], " ", 1); blen++; - - } - - p_free_results(data->stmt_select_from_meta_table); - - if(strlen(buf) > 5 && strlen(update_meta_sql) > strlen(SQL_STMT_DELETE_FROM_META_TABLE)+5){ - purged += remove_message_frame_files(buf, update_meta_sql, sdata, cfg); - } - - } - - close_prepared_statement(data->stmt_select_from_meta_table); - - return purged; -} - - -int purge_messages_with_attachments(struct session_data *sdata, struct __data *data, struct __config *cfg){ - int purged=0, size; - unsigned int idlist_len=0; - char s[SMALLBUFSIZE], idlist[MAXBUFSIZE]; - - memset(idlist, 0, sizeof(idlist)); - - snprintf(s, sizeof(s)-1, "SELECT `piler_id`, `size` FROM `%s` WHERE `deleted`=0 AND `retained` < %ld AND attachments > 0", SQL_METADATA_TABLE, sdata->now); - - if(dryrun == 1) printf("purge sql: *%s*\n", s); - - if(prepare_sql_statement(sdata, &(data->stmt_select_from_meta_table), s) == ERR) return purged; - - p_bind_init(data); - if(p_exec_query(sdata, data->stmt_select_from_meta_table, data) == OK){ - - p_bind_init(data); - - data->sql[data->pos] = &s[0]; data->type[data->pos] = TYPE_STRING; data->len[data->pos] = sizeof(s)-2; data->pos++; - data->sql[data->pos] = (char *)&size; data->type[data->pos] = TYPE_LONG; data->len[data->pos] = sizeof(int); data->pos++; - - p_store_results(data->stmt_select_from_meta_table, data); - - while(p_fetch_results(data->stmt_select_from_meta_table) == OK){ - memcpy(&idlist[idlist_len], s, strlen(s)); idlist_len += strlen(s); - memcpy(&idlist[idlist_len], "','", 3); idlist_len += 3; - - purged_size += size; - - if(idlist_len >= sizeof(idlist)-2*RND_STR_LEN){ - purged += remove_attachments(idlist, sdata, data, cfg); - - memset(idlist, 0, sizeof(idlist)); - idlist_len = 0; - } - } - - p_free_results(data->stmt_select_from_meta_table); - - if(idlist_len > 5){ - purged += remove_attachments(idlist, sdata, data, cfg); - } - - } - - close_prepared_statement(data->stmt_select_from_meta_table); - - return purged; -} - - -int main(int argc, char **argv){ - int i, purged=0; - char *configfile=CONFIG_FILE, buf[SMALLBUFSIZE]; - struct session_data sdata; - struct __data data; - struct __config cfg; - - - while((i = getopt(argc, argv, "c:dh?")) > 0){ - switch(i){ - - case 'c' : - configfile = optarg; - break; - - case 'd' : - dryrun = 1; - break; - - case 'h' : - case '?' : - default : - break; - } - } - - - - (void) openlog("pilerpurge", LOG_PID, LOG_MAIL); - - cfg = read_config(configfile); - - - if(open_database(&sdata, &cfg) == ERR) return 0; - - - setlocale(LC_CTYPE, cfg.locale); - - init_session_data(&sdata, &cfg); - - i = is_purge_allowed(&sdata, &data); - if(i == 1){ - purged += purge_messages_round1(&sdata, &data, "attachments=0", &cfg); - purged += purge_messages_with_attachments(&sdata, &data, &cfg); - purged += purge_messages_round1(&sdata, &data, "attachments > 0", &cfg); - - syslog(LOG_INFO, "purged %d messages, %ld bytes", purged, purged_size); - } - else printf("purge is not allowed by configuration, enable_purge=%d\n", i); - - - if(purged_size > 100){ - snprintf(buf, sizeof(buf)-1, "UPDATE `%s` SET size = size - %ld", SQL_COUNTER_TABLE, purged_size); - - if(dryrun == 0) p_query(&sdata, buf); - } - - - close_database(&sdata); - - return 0; -} - - diff --git a/src/pop3.c b/src/pop3.c index 7daf3425..83eb4433 100644 --- a/src/pop3.c +++ b/src/pop3.c @@ -23,9 +23,6 @@ #include -void update_import_job_stat(struct session_data *sdata, struct __data *data); - - int is_last_complete_pop3_packet(char *s, int len){ if(*(s+len-5) == '\r' && *(s+len-4) == '\n' && *(s+len-3) == '.' && *(s+len-2) == '\r' && *(s+len-1) == '\n'){ @@ -36,35 +33,35 @@ int is_last_complete_pop3_packet(char *s, int len){ } -int connect_to_pop3_server(int sd, char *username, char *password, struct __data *data, int use_ssl){ +int connect_to_pop3_server(struct data *data){ int n; char buf[MAXBUFSIZE]; X509* server_cert; char *str; - if(use_ssl == 1){ + if(data->net->use_ssl == 1){ SSL_library_init(); SSL_load_error_strings(); #if OPENSSL_VERSION_NUMBER < 0x10100000L - data->ctx = SSL_CTX_new(TLSv1_client_method()); + data->net->ctx = SSL_CTX_new(TLSv1_client_method()); #else - data->ctx = SSL_CTX_new(TLS_client_method()); + data->net->ctx = SSL_CTX_new(TLS_client_method()); #endif - CHK_NULL(data->ctx, "internal SSL error"); + CHK_NULL(data->net->ctx, "internal SSL error"); - data->ssl = SSL_new(data->ctx); - CHK_NULL(data->ssl, "internal ssl error"); + data->net->ssl = SSL_new(data->net->ctx); + CHK_NULL(data->net->ssl, "internal ssl error"); - SSL_set_fd(data->ssl, sd); - n = SSL_connect(data->ssl); + SSL_set_fd(data->net->ssl, data->net->socket); + n = SSL_connect(data->net->ssl); CHK_SSL(n, "internal ssl error"); - printf("Cipher: %s\n", SSL_get_cipher(data->ssl)); + printf("Cipher: %s\n", SSL_get_cipher(data->net->ssl)); - server_cert = SSL_get_peer_certificate(data->ssl); + server_cert = SSL_get_peer_certificate(data->net->ssl); CHK_NULL(server_cert, "server cert error"); str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0); @@ -79,19 +76,19 @@ int connect_to_pop3_server(int sd, char *username, char *password, struct __data } - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); + recvtimeoutssl(data->net, buf, sizeof(buf)); - snprintf(buf, sizeof(buf)-1, "USER %s\r\n", username); + snprintf(buf, sizeof(buf)-1, "USER %s\r\n", data->import->username); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); + write1(data->net, buf, strlen(buf)); + recvtimeoutssl(data->net, buf, sizeof(buf)); - snprintf(buf, sizeof(buf)-1, "PASS %s\r\n", password); + snprintf(buf, sizeof(buf)-1, "PASS %s\r\n", data->import->password); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); + write1(data->net, buf, strlen(buf)); + recvtimeoutssl(data->net, buf, sizeof(buf)); if(strncmp(buf, "+OK", 3) == 0) return OK; @@ -101,18 +98,15 @@ int connect_to_pop3_server(int sd, char *username, char *password, struct __data } -int process_pop3_emails(int sd, struct session_data *sdata, struct __data *data, int use_ssl, int dryrun, struct __config *cfg){ - int i=0, rc=ERR, n, pos, readlen, fd, lastpos, nreads; - char *p, buf[MAXBUFSIZE], filename[SMALLBUFSIZE]; - char aggrbuf[3*MAXBUFSIZE]; +void get_number_of_total_messages(struct data *data){ + char *p, buf[MAXBUFSIZE]; - data->import->processed_messages = 0; data->import->total_messages = 0; snprintf(buf, sizeof(buf)-1, "STAT\r\n"); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); + write1(data->net, buf, strlen(buf)); - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); + recvtimeoutssl(data->net, buf, sizeof(buf)); if(strncmp(buf, "+OK ", 4) == 0){ p = strchr(&buf[4], ' '); @@ -121,103 +115,119 @@ int process_pop3_emails(int sd, struct session_data *sdata, struct __data *data, data->import->total_messages = atoi(&buf[4]); } } - else return ERR; + else { + printf("ERROR: '%s'", buf); + } +} - if(data->quiet == 0) printf("found %d messages\n", data->import->total_messages); +int pop3_download_email(struct data *data, int i){ + int n, fd, pos=0, readlen=0, lastpos=0, nreads=0; + char *p, buf[MAXBUFSIZE]; + char aggrbuf[3*MAXBUFSIZE]; - if(data->import->total_messages <= 0) return OK; + data->import->processed_messages++; - for(i=data->import->start_position; i<=data->import->total_messages; i++){ - data->import->processed_messages++; - if(data->quiet == 0){ printf("processed: %7d [%3d%%]\r", data->import->processed_messages, 100*i/data->import->total_messages); fflush(stdout); } + snprintf(data->import->filename, SMALLBUFSIZE-1, "pop3-tmp-%d-%d.txt", getpid(), i); + unlink(data->import->filename); + fd = open(data->import->filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + if(fd == -1){ + printf("cannot open: %s\n", data->import->filename); + return ERR; + } - snprintf(buf, sizeof(buf)-1, "RETR %d\r\n", i); + snprintf(buf, sizeof(buf)-1, "RETR %d\r\n", i); + write1(data->net, buf, strlen(buf)); - snprintf(filename, sizeof(filename)-1, "pop3-tmp-%d-%d.txt", getpid(), i); - unlink(filename); + memset(aggrbuf, 0, sizeof(aggrbuf)); + + while((n = recvtimeoutssl(data->net, buf, sizeof(buf))) > 0){ + nreads++; + readlen += n; + + if(nreads == 1){ + + if(strncmp(buf, "+OK", 3) == 0){ + p = strchr(&buf[3], '\n'); + if(p){ + *p = '\0'; + pos = strlen(buf)+1; + *p = '\n'; + } + } + else { printf("error: %s", buf); return ERR; } - fd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); - if(fd == -1){ - printf("cannot open: %s\n", filename); - return rc; } - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - - readlen = 0; - pos = 0; - nreads = 0; - - memset(aggrbuf, 0, sizeof(aggrbuf)); - lastpos = 0; - - - while((n = recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl)) > 0){ - nreads++; - readlen += n; + if((uint)(lastpos + 1 + n) < sizeof(aggrbuf)){ if(nreads == 1){ - - if(strncmp(buf, "+OK", 3) == 0){ - p = strchr(&buf[3], '\n'); - if(p){ - *p = '\0'; - pos = strlen(buf)+1; - *p = '\n'; - } - } - else { printf("error: %s", buf); return ERR; } - - } - - if(lastpos + 1 + n < sizeof(aggrbuf)){ - - if(nreads == 1){ - memcpy(aggrbuf+lastpos, buf+pos, n-pos); - lastpos += n-pos; - } - else { - memcpy(aggrbuf+lastpos, buf, n); - lastpos += n; - } + memcpy(aggrbuf+lastpos, buf+pos, n-pos); + lastpos += n-pos; } else { - write(fd, aggrbuf, sizeof(buf)); - - memmove(aggrbuf, aggrbuf+sizeof(buf), lastpos-sizeof(buf)); - lastpos -= sizeof(buf); - memcpy(aggrbuf+lastpos, buf, n); lastpos += n; } + } + else { + if(write(fd, aggrbuf, sizeof(buf)) == -1) printf("ERROR: writing to fd\n"); - if(is_last_complete_pop3_packet(aggrbuf, lastpos) == 1){ - write(fd, aggrbuf, lastpos-3); - break; + memmove(aggrbuf, aggrbuf+sizeof(buf), lastpos-sizeof(buf)); + lastpos -= sizeof(buf); + + memcpy(aggrbuf+lastpos, buf, n); + lastpos += n; + } + + if(is_last_complete_pop3_packet(aggrbuf, lastpos) == 1){ + if(write(fd, aggrbuf, lastpos-3) == -1) printf("ERROR: writing to fd\n"); + break; + } + } + + close(fd); + + return OK; +} + + +void pop3_delete_message(struct data *data, int i){ + char buf[SMALLBUFSIZE]; + + snprintf(buf, sizeof(buf)-1, "DELE %d\r\n", i); + write1(data->net, buf, strlen(buf)); + recvtimeoutssl(data->net, buf, sizeof(buf)); +} + + +void process_pop3_emails(struct session_data *sdata, struct data *data, struct config *cfg){ + int i=0, rc=ERR; + char buf[MAXBUFSIZE]; + + data->import->processed_messages = 0; + + get_number_of_total_messages(data); + + if(data->quiet == 0) printf("found %d messages\n", data->import->total_messages); + + if(data->import->total_messages <= 0) return; + + for(i=data->import->start_position; i<=data->import->total_messages; i++){ + if(pop3_download_email(data, i) == OK){ + if(data->quiet == 0){ printf("processed: %7d [%3d%%]\r", data->import->processed_messages, 100*i/data->import->total_messages); fflush(stdout); } + + if(data->import->dryrun == 0){ + rc = import_message(sdata, data, cfg); + + if(data->import->remove_after_import == 1 && rc == OK){ + pop3_delete_message(data, i); + } } - - } - - close(fd); - - if(dryrun == 0) rc = import_message(filename, sdata, data, cfg); - else rc = OK; - - if(dryrun == 0 && rc == OK && data->import->remove_after_import == 1){ - snprintf(buf, sizeof(buf)-1, "DELE %d\r\n", i); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); - recvtimeoutssl(sd, buf, sizeof(buf), data->import->timeout, use_ssl, data->ssl); } - if(i % 100 == 0){ - time(&(data->import->updated)); - update_import_job_stat(sdata, data); - } - - if(data->import->download_only == 0) unlink(filename); - + if(data->import->download_only == 0) unlink(data->import->filename); /* whether to quit after processing a batch of messages */ @@ -228,16 +238,7 @@ int process_pop3_emails(int sd, struct session_data *sdata, struct __data *data, snprintf(buf, sizeof(buf)-1, "QUIT\r\n"); - write1(sd, buf, strlen(buf), use_ssl, data->ssl); + write1(data->net, buf, strlen(buf)); if(data->quiet == 0) printf("\n"); - - time(&(data->import->finished)); - data->import->status = 2; - update_import_job_stat(sdata, data); - - - return OK; } - - diff --git a/src/reindex.c b/src/reindex.c index e4d966e8..472b1a63 100644 --- a/src/reindex.c +++ b/src/reindex.c @@ -42,7 +42,7 @@ void p_clean_exit(char *msg, int rc){ } -uint64 get_max_meta_id(struct session_data *sdata, struct __data *data){ +uint64 get_max_meta_id(struct session_data *sdata, struct data *data){ char s[SMALLBUFSIZE]; uint64 id=0; @@ -72,7 +72,7 @@ uint64 get_max_meta_id(struct session_data *sdata, struct __data *data){ } -uint64 retrieve_email_by_metadata_id(struct session_data *sdata, struct __data *data, uint64 from_id, uint64 to_id, struct __config *cfg){ +uint64 retrieve_email_by_metadata_id(struct session_data *sdata, struct data *data, uint64 from_id, uint64 to_id, struct config *cfg){ FILE *f; char filename[SMALLBUFSIZE]; char s[SMALLBUFSIZE]; @@ -164,8 +164,8 @@ int main(int argc, char **argv){ uint64 from_id=0, to_id=0, n=0; char *configfile=CONFIG_FILE, *folder=NULL; struct session_data sdata; - struct __data data; - struct __config cfg; + struct data data; + struct config cfg; while(1){ diff --git a/src/rules.c b/src/rules.c index f212d2cd..7a95bd41 100644 --- a/src/rules.c +++ b/src/rules.c @@ -10,7 +10,7 @@ #include "rules.h" -void load_rules(struct session_data *sdata, struct __data *data, struct node *xhash[], char *table){ +void load_rules(struct session_data *sdata, struct data *data, struct node *xhash[], char *table){ char s[SMALLBUFSIZE]; struct rule_cond rule_cond; @@ -78,7 +78,7 @@ void load_rules(struct session_data *sdata, struct __data *data, struct node *xh } -int append_rule(struct node *xhash[], struct rule_cond *rule_cond, struct __data *data){ +int append_rule(struct node *xhash[], struct rule_cond *rule_cond, struct data *data){ struct node *q, *Q=NULL, *node; struct rule *rule; int rc=0; @@ -116,7 +116,7 @@ int append_rule(struct node *xhash[], struct rule_cond *rule_cond, struct __data } -struct rule *create_rule_item(struct rule_cond *rule_cond, struct __data *data){ +struct rule *create_rule_item(struct rule_cond *rule_cond, struct data *data){ struct rule *h=NULL; char empty = '\0'; int len; @@ -248,7 +248,7 @@ char *check_againt_ruleset(struct node *xhash[], struct parser_state *state, int } -time_t query_retain_period(struct __data *data, struct parser_state *state, int size, int spam, struct __config *cfg){ +time_t query_retain_period(struct data *data, struct parser_state *state, int size, int spam, struct config *cfg){ size_t nmatch=0; struct rule *p; struct node *q; @@ -316,7 +316,7 @@ time_t query_retain_period(struct __data *data, struct parser_state *state, int } -int get_folder_id_by_rule(struct __data *data, struct parser_state *state, int size, int spam, struct __config *cfg){ +int get_folder_id_by_rule(struct data *data, struct parser_state *state, int size, int spam, struct config *cfg){ size_t nmatch=0; struct rule *p; struct node *q; diff --git a/src/rules.h b/src/rules.h index 48019ad6..dbae4103 100644 --- a/src/rules.h +++ b/src/rules.h @@ -7,12 +7,12 @@ #include "defs.h" -void load_rules(struct session_data *sdata, struct __data *data, struct node *xhash[], char *table); -int append_rule(struct node *xhash[], struct rule_cond *rule_cond, struct __data *data); -struct rule *create_rule_item(struct rule_cond *rule_cond, struct __data *data); +void load_rules(struct session_data *sdata, struct data *data, struct node *xhash[], char *table); +int append_rule(struct node *xhash[], struct rule_cond *rule_cond, struct data *data); +struct rule *create_rule_item(struct rule_cond *rule_cond, struct data *data); char *check_againt_ruleset(struct node *xhash[], struct parser_state *state, int size, int spam); -time_t query_retain_period(struct __data *data, struct parser_state *state, int size, int spam, struct __config *cfg); -int get_folder_id_by_rule(struct __data *data, struct parser_state *state, int size, int spam, struct __config *cfg); +time_t query_retain_period(struct data *data, struct parser_state *state, int size, int spam, struct config *cfg); +int get_folder_id_by_rule(struct data *data, struct parser_state *state, int size, int spam, struct config *cfg); int check_size_rule(int message_size, int size, char *_size); int check_spam_rule(int is_spam, int spam); int check_attachment_rule(struct parser_state *state, struct rule *rule); diff --git a/src/session.c b/src/session.c index fefa9ad8..b4af56fb 100644 --- a/src/session.c +++ b/src/session.c @@ -6,7 +6,7 @@ int get_session_slot(struct smtp_session **sessions, int max_connections); -void init_smtp_session(struct smtp_session *session, int slot, int sd, struct __config *cfg); +void init_smtp_session(struct smtp_session *session, int slot, int sd, struct config *cfg); #ifdef HAVE_LIBWRAP @@ -28,7 +28,7 @@ int is_blocked_by_tcp_wrappers(int sd){ #endif -int start_new_session(struct smtp_session **sessions, int socket, int *num_connections, struct __config *cfg){ +int start_new_session(struct smtp_session **sessions, int socket, int *num_connections, struct config *cfg){ char smtp_banner[SMALLBUFSIZE]; int slot; @@ -37,7 +37,7 @@ int start_new_session(struct smtp_session **sessions, int socket, int *num_conne */ if(*num_connections >= cfg->max_connections){ - syslog(LOG_PRIORITY, "too many connections (%d), cannot accept socket %d", *num_connections, socket); + syslog(LOG_PRIORITY, "ERROR: too many connections (%d), cannot accept socket %d", *num_connections, socket); send(socket, SMTP_RESP_421_ERR_ALL_PORTS_ARE_BUSY, strlen(SMTP_RESP_421_ERR_ALL_PORTS_ARE_BUSY), 0); close(socket); return -1; @@ -93,30 +93,30 @@ struct smtp_session *get_session_by_socket(struct smtp_session **sessions, int m int i; for(i=0; isocket == socket) return sessions[i]; + if(sessions[i] && sessions[i]->net.socket == socket) return sessions[i]; } return NULL; } -void init_smtp_session(struct smtp_session *session, int slot, int sd, struct __config *cfg){ +void init_smtp_session(struct smtp_session *session, int slot, int sd, struct config *cfg){ struct sockaddr_in addr; socklen_t addr_size = sizeof(struct sockaddr_in); char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; session->slot = slot; - session->socket = sd; session->buflen = 0; session->protocol_state = SMTP_STATE_INIT; session->cfg = cfg; - session->use_ssl = 0; // use SSL/TLS - session->starttls = 0; // SSL/TLS communication is active (1) or not (0) - session->ctx = NULL; - session->ssl = NULL; + session->net.socket = sd; + session->net.use_ssl = 0; // use SSL/TLS + session->net.starttls = 0; // SSL/TLS communication is active (1) or not (0) + session->net.ctx = NULL; + session->net.ssl = NULL; memset(session->buf, 0, SMALLBUFSIZE); memset(session->remote_host, 0, INET6_ADDRSTRLEN); @@ -125,7 +125,7 @@ void init_smtp_session(struct smtp_session *session, int slot, int sd, struct __ time(&(session->lasttime)); - if(getpeername(sd, (struct sockaddr *)&addr, &addr_size) == 0 && + if(getpeername(session->net.socket, (struct sockaddr *)&addr, &addr_size) == 0 && getnameinfo((struct sockaddr *)&addr, addr_size, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0){ snprintf(session->remote_host, INET6_ADDRSTRLEN-1, "%s", hbuf); } @@ -136,12 +136,12 @@ void free_smtp_session(struct smtp_session *session){ if(session){ - if(session->use_ssl == 1){ - SSL_shutdown(session->ssl); - SSL_free(session->ssl); + if(session->net.use_ssl == 1){ + SSL_shutdown(session->net.ssl); + SSL_free(session->net.ssl); } - if(session->ctx) SSL_CTX_free(session->ctx); + if(session->net.ctx) SSL_CTX_free(session->net.ctx); free(session); } @@ -151,7 +151,7 @@ void free_smtp_session(struct smtp_session *session){ void tear_down_session(struct smtp_session **sessions, int slot, int *num_connections){ syslog(LOG_PRIORITY, "disconnected from %s", sessions[slot]->remote_host); - close(sessions[slot]->socket); + close(sessions[slot]->net.socket); free_smtp_session(sessions[slot]); sessions[slot] = NULL; diff --git a/src/smtp.c b/src/smtp.c index 256747f8..5d679691 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -61,7 +61,7 @@ void process_smtp_command(struct smtp_session *session, char *buf){ return; } - if(session->cfg->tls_enable == 1 && strncasecmp(buf, SMTP_CMD_STARTTLS, strlen(SMTP_CMD_STARTTLS)) == 0 && session->use_ssl == 0){ + if(session->cfg->tls_enable == 1 && strncasecmp(buf, SMTP_CMD_STARTTLS, strlen(SMTP_CMD_STARTTLS)) == 0 && session->net.use_ssl == 0){ process_command_starttls(session); return; } @@ -89,20 +89,26 @@ void process_data(struct smtp_session *session, char *readbuf, int readlen){ pos = searchStringInBuffer(&puf[0], len, SMTP_CMD_PERIOD, 5); if(pos > 0){ - write(session->fd, puf, pos); - session->tot_len += pos; - process_command_period(session); + if(write(session->fd, puf, pos) != -1){ + session->tot_len += pos; + process_command_period(session); + } + else syslog(LOG_PRIORITY, "ERROR: process_data(): failed to write %d bytes", pos); } else { n = search_char_backward(&puf[0], len, '\r'); if(n == -1 || len - n > 4){ - write(session->fd, puf, len); - session->tot_len += len; + if(write(session->fd, puf, len) != -1){ + session->tot_len += len; + } + else syslog(LOG_PRIORITY, "ERROR: process_data(): failed to write %d bytes", len); } else { - write(session->fd, puf, n); - session->tot_len += n; + if(write(session->fd, puf, n) != -1){ + session->tot_len += n; + } + else syslog(LOG_PRIORITY, "process_data(): failed to write %d bytes", n); snprintf(session->buf, SMALLBUFSIZE-1, "%s", &puf[n]); session->buflen = len - n; @@ -117,7 +123,7 @@ void wait_for_ssl_accept(struct smtp_session *session){ if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "waiting for ssl handshake"); - rc = SSL_accept(session->ssl); + rc = SSL_accept(session->net.ssl); // Since we use non-blocking IO, SSL_accept() is likely to return with -1 // "In this case a call to SSL_get_error() with the return value of SSL_accept() @@ -125,20 +131,20 @@ void wait_for_ssl_accept(struct smtp_session *session){ // // In this case we may proceed. - if(rc == 1 || SSL_get_error(session->ssl, rc) == SSL_ERROR_WANT_READ){ - session->use_ssl = 1; + if(rc == 1 || SSL_get_error(session->net.ssl, rc) == SSL_ERROR_WANT_READ){ + session->net.use_ssl = 1; } - if(session->cfg->verbosity >= _LOG_DEBUG || session->use_ssl == 0){ + if(session->cfg->verbosity >= _LOG_DEBUG || session->net.use_ssl == 0){ ERR_error_string_n(ERR_get_error(), ssl_error, SMALLBUFSIZE); syslog(LOG_PRIORITY, "SSL_accept() result, rc=%d, errorcode: %d, error text: %s", - rc, SSL_get_error(session->ssl, rc), ssl_error); + rc, SSL_get_error(session->net.ssl, rc), ssl_error); } } void send_smtp_response(struct smtp_session *session, char *buf){ - write1(session->socket, buf, strlen(buf), session->use_ssl, session->ssl); + write1(&(session->net), buf, strlen(buf)); if(session->cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "sent: %s", buf); } @@ -159,7 +165,7 @@ void process_command_ehlo_lhlo(struct smtp_session *session, char *buf, int bufl if(session->protocol_state == SMTP_STATE_INIT) session->protocol_state = SMTP_STATE_HELO; // if tls is not started, but it's enabled in the config - if(session->use_ssl == 0 && session->cfg->tls_enable == 1) snprintf(extensions, sizeof(extensions)-1, "%s", SMTP_EXTENSION_STARTTLS); + if(session->net.use_ssl == 0 && session->cfg->tls_enable == 1) snprintf(extensions, sizeof(extensions)-1, "%s", SMTP_EXTENSION_STARTTLS); if(session->cfg->enable_chunking == 1) strncat(extensions, SMTP_EXTENSION_CHUNKING, sizeof(extensions)-strlen(extensions)-2); snprintf(buf, buflen-1, SMTP_RESP_250_EXTENSIONS, session->cfg->hostid, extensions); @@ -170,27 +176,27 @@ void process_command_ehlo_lhlo(struct smtp_session *session, char *buf, int bufl int init_ssl(struct smtp_session *session){ #if OPENSSL_VERSION_NUMBER < 0x10100000L - session->ctx = SSL_CTX_new(TLSv1_server_method()); + session->net.ctx = SSL_CTX_new(TLSv1_server_method()); #else - session->ctx = SSL_CTX_new(TLS_server_method()); + session->net.ctx = SSL_CTX_new(TLS_server_method()); #endif - if(session->ctx == NULL){ + if(session->net.ctx == NULL){ syslog(LOG_PRIORITY, "SSL ctx is null"); return 0; } - if(SSL_CTX_set_cipher_list(session->ctx, session->cfg->cipher_list) == 0){ + if(SSL_CTX_set_cipher_list(session->net.ctx, session->cfg->cipher_list) == 0){ syslog(LOG_PRIORITY, "failed to set cipher list: '%s'", session->cfg->cipher_list); return 0; } - if(SSL_CTX_use_PrivateKey_file(session->ctx, session->cfg->pemfile, SSL_FILETYPE_PEM) != 1){ + if(SSL_CTX_use_PrivateKey_file(session->net.ctx, session->cfg->pemfile, SSL_FILETYPE_PEM) != 1){ syslog(LOG_PRIORITY, "cannot load private key from %s", session->cfg->pemfile); return 0; } - if(SSL_CTX_use_certificate_file(session->ctx, session->cfg->pemfile, SSL_FILETYPE_PEM) != 1){ + if(SSL_CTX_use_certificate_file(session->net.ctx, session->cfg->pemfile, SSL_FILETYPE_PEM) != 1){ syslog(LOG_PRIORITY, "cannot load certificate from %s", session->cfg->pemfile); return 0; } @@ -204,17 +210,17 @@ void process_command_starttls(struct smtp_session *session){ if(init_ssl(session) == 1){ - session->ssl = SSL_new(session->ctx); - if(session->ssl){ + session->net.ssl = SSL_new(session->net.ctx); + if(session->net.ssl){ - SSL_set_options(session->ssl, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); + SSL_set_options(session->net.ssl, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); - if(SSL_set_fd(session->ssl, session->socket) == 1){ - session->starttls = 1; + if(SSL_set_fd(session->net.ssl, session->net.socket) == 1){ + session->net.starttls = 1; send_smtp_response(session, SMTP_RESP_220_READY_TO_START_TLS); session->protocol_state = SMTP_STATE_INIT; - if(session->starttls == 1 && session->use_ssl == 0) + if(session->net.starttls == 1 && session->net.use_ssl == 0) wait_for_ssl_accept(session); return; @@ -230,7 +236,7 @@ void process_command_mail_from(struct smtp_session *session, char *buf){ memset(session->mailfrom, 0, SMALLBUFSIZE); if(session->protocol_state != SMTP_STATE_HELO && session->protocol_state != SMTP_STATE_PERIOD && session->protocol_state != SMTP_STATE_BDAT){ - send(session->socket, SMTP_RESP_503_ERR, strlen(SMTP_RESP_503_ERR), 0); + send(session->net.socket, SMTP_RESP_503_ERR, strlen(SMTP_RESP_503_ERR), 0); } else { memset(&(session->ttmpfile[0]), 0, SMALLBUFSIZE); diff --git a/src/sql.h b/src/sql.h index 692cfa1e..353e0f07 100644 --- a/src/sql.h +++ b/src/sql.h @@ -6,15 +6,15 @@ #define _SQL_H -int open_database(struct session_data *sdata, struct __config *cfg); +int open_database(struct session_data *sdata, struct config *cfg); void close_database(struct session_data *sdata); int prepare_sql_statement(struct session_data *sdata, MYSQL_STMT **stmt, char *s); void p_query(struct session_data *sdata, char *s); -int p_exec_query(struct session_data *sdata, MYSQL_STMT *stmt, struct __data *data); -int p_store_results(MYSQL_STMT *stmt, struct __data *data); +int p_exec_query(struct session_data *sdata, MYSQL_STMT *stmt, struct data *data); +int p_store_results(MYSQL_STMT *stmt, struct data *data); int p_fetch_results(MYSQL_STMT *stmt); void p_free_results(MYSQL_STMT *stmt); -void p_bind_init(struct __data *data); +void p_bind_init(struct data *data); uint64 p_get_insert_id(MYSQL_STMT *stmt); int p_get_affected_rows(MYSQL_STMT *stmt); void close_prepared_statement(MYSQL_STMT *stmt); diff --git a/src/store.c b/src/store.c index dff21d88..2cfc5e4b 100644 --- a/src/store.c +++ b/src/store.c @@ -20,7 +20,7 @@ #include -int read_key(struct __config *cfg){ +int read_key(struct config *cfg){ int fd, n; fd = open(KEYFILE, O_RDONLY); @@ -39,7 +39,7 @@ int read_key(struct __config *cfg){ } -int store_file(struct session_data *sdata, char *filename, int len, struct __config *cfg){ +int store_file(struct session_data *sdata, char *filename, int len, struct config *cfg){ int ret=0, rc, fd, n; char *addr, *p, *p0, *p1, *p2, s[SMALLBUFSIZE]; struct stat st; @@ -212,7 +212,7 @@ ENDE: } -int remove_stored_message_files(struct session_data *sdata, struct parser_state *state, struct __config *cfg){ +int remove_stored_message_files(struct session_data *sdata, struct parser_state *state, struct config *cfg){ int i; char s[SMALLBUFSIZE]; diff --git a/src/tai.c b/src/tai.c index 4a4f1631..344ee094 100644 --- a/src/tai.c +++ b/src/tai.c @@ -8,9 +8,8 @@ static char hex[16] = "0123456789abcdef"; void tai_pack(char *s, struct tai *t){ - unsigned long long x; + uint64 x = t->x; - x = t->x; s[7] = x & 255; x >>= 8; s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; @@ -33,6 +32,7 @@ void taia_pack(char *s, struct taia *t){ s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; s[4] = x; + x = t->nano; s[3] = x & 255; x >>= 8; s[2] = x & 255; x >>= 8; @@ -43,8 +43,10 @@ void taia_pack(char *s, struct taia *t){ void taia_now(struct taia *t){ struct timeval now; + gettimeofday(&now,(struct timezone *) 0); - t->sec.x = 4611686018427387914ULL + (uint64) now.tv_sec; + + t->sec.x = 4611686018427387914ULL + (uint64)now.tv_sec; t->nano = 1000 * now.tv_usec + 500; t->atto = 0; } @@ -55,7 +57,7 @@ void tai_timestamp(char *s){ char nowpack[TAI_PACK]; int i; - now.x = 4611686018427387914ULL + (unsigned long long) time((long *) 0); + now.x = 4611686018427387914ULL + (uint64)time((long *) 0); tai_pack(nowpack, &now); @@ -66,4 +68,3 @@ void tai_timestamp(char *s){ *(s+2*TAI_PACK) = '\0'; } - diff --git a/src/test.c b/src/test.c index f85e53cf..d10d98ed 100644 --- a/src/test.c +++ b/src/test.c @@ -21,8 +21,8 @@ int main(int argc, char **argv){ struct stat st; struct session_data sdata; struct parser_state state; - struct __config cfg; - struct __data data; + struct config cfg; + struct data data; struct import import; char *rule; diff --git a/unit_tests/check_digest.c b/unit_tests/check_digest.c index ddaead29..bab35dce 100644 --- a/unit_tests/check_digest.c +++ b/unit_tests/check_digest.c @@ -64,12 +64,12 @@ static void test_digest_file(){ } -static void test_make_digests(struct __config *cfg){ +static void test_make_digests(struct config *cfg){ unsigned int i; int j; struct session_data sdata; struct parser_state state; - struct __data data; + struct data data; struct stat st; @@ -120,7 +120,7 @@ static void test_make_digests(struct __config *cfg){ int main(){ - struct __config cfg; + struct config cfg; (void) openlog("digest_test", LOG_PID, LOG_MAIL); diff --git a/unit_tests/check_mydomains.c b/unit_tests/check_mydomains.c index 2ef1eed6..5ec627f9 100644 --- a/unit_tests/check_mydomains.c +++ b/unit_tests/check_mydomains.c @@ -28,7 +28,7 @@ struct emails { }; -static void fill_domain_table(struct __config *cfg){ +static void fill_domain_table(struct config *cfg){ unsigned int i; char buf[SMALLBUFSIZE]; struct session_data sdata; @@ -49,7 +49,7 @@ static void fill_domain_table(struct __config *cfg){ } -static void restore_domain_table(struct __config *cfg){ +static void restore_domain_table(struct config *cfg){ unsigned int i; char buf[SMALLBUFSIZE]; struct session_data sdata; @@ -70,10 +70,10 @@ static void restore_domain_table(struct __config *cfg){ } -static void test_mydomains(struct __config *cfg){ +static void test_mydomains(struct config *cfg){ unsigned int i; struct session_data sdata; - struct __data data; + struct data data; struct emails emails[] = { {"ajaja@aaaa.fu ", 1}, {"ajahahah@aaa.fu ", 0}, @@ -113,7 +113,7 @@ static void test_mydomains(struct __config *cfg){ int main(){ - struct __config cfg; + struct config cfg; if(!can_i_write_directory(NULL)) __fatal("cannot write current directory!"); diff --git a/unit_tests/check_parser.c b/unit_tests/check_parser.c index 97e3cb30..f4606cae 100644 --- a/unit_tests/check_parser.c +++ b/unit_tests/check_parser.c @@ -25,13 +25,13 @@ struct parser_test { }; -static void test_parser(struct __config *cfg){ +static void test_parser(struct config *cfg){ unsigned int i; int j; struct stat st; struct session_data sdata; struct parser_state state; - struct __data data; + struct data data; struct parser_test tests[] = { {"1.eml", "", "játékok birodalma játékbolt hirlevel@jatekokbirodalma.hu hirlevel jatekokbirodalma hu ", "jatekokbirodalma.hu", "architerv m sj@acts.hu sj acts hu ", "acts.hu ", "", "BLACK FRIDAY - Hihetetlen kedvezmények csak 1 napig november 27-én", 2}, @@ -103,7 +103,7 @@ static void test_parser(struct __config *cfg){ int main(){ - struct __config cfg; + struct config cfg; if(!can_i_write_directory(NULL)) __fatal("cannot write current directory!"); diff --git a/unit_tests/check_parser_utils.c b/unit_tests/check_parser_utils.c index 56b3a99c..25b80fb2 100644 --- a/unit_tests/check_parser_utils.c +++ b/unit_tests/check_parser_utils.c @@ -32,7 +32,7 @@ static void test_parse_date_header(){ int dst_fix = 0; time_t t = time(NULL); struct tm lt = {0}; - struct __config cfg; + struct config cfg; struct date_test date_test[] = { {"Date: Mon, 02 Nov 2015 09:39:31 -0000", 1446457171}, {"Date: Mon, 2 Nov 2015 10:39:45 +0100", 1446457185}, diff --git a/unit_tests/check_rules.c b/unit_tests/check_rules.c index b745243d..b2053089 100644 --- a/unit_tests/check_rules.c +++ b/unit_tests/check_rules.c @@ -35,7 +35,7 @@ struct rule_query rules[] = { }; -static void fill_rule_table(struct __config *cfg){ +static void fill_rule_table(struct config *cfg){ unsigned int i; struct session_data sdata; @@ -55,7 +55,7 @@ static void fill_rule_table(struct __config *cfg){ } -static void restore_rule_table(struct __config *cfg){ +static void restore_rule_table(struct config *cfg){ unsigned int i; char buf[SMALLBUFSIZE]; struct session_data sdata; @@ -77,13 +77,13 @@ static void restore_rule_table(struct __config *cfg){ -static void test_archiving_rule(struct __config *cfg){ +static void test_archiving_rule(struct config *cfg){ unsigned int i; int j; char *rule; struct session_data sdata; struct parser_state state; - struct __data data; + struct data data; struct stat st; struct rule_test rule_test[] = { {"1.eml", "domain=,from=hirlevel@jatekokbirodalma.hu,to=,subject=,body=,size0,att.name=,att.type=,att.size0,spam=-1", 0}, @@ -157,7 +157,7 @@ static void test_archiving_rule(struct __config *cfg){ int main(){ - struct __config cfg; + struct config cfg; if(!can_i_write_directory(NULL)) __fatal("cannot write current directory!"); diff --git a/unit_tests/smtp.c b/unit_tests/smtp.c index 073a3224..ca003bde 100644 --- a/unit_tests/smtp.c +++ b/unit_tests/smtp.c @@ -26,9 +26,6 @@ extern int optind; char *testmessage = "From: aaa@aaa.fu\nTo: bela@aaa.fu\nMessage-Id: ajajajaja\nSubject: this is a test\n\nAaaaaa."; -int connect_to_smtp_server(char *server, int port, int timeout, int use_ssl, struct __data *data); - - void usage(){ printf("\nusage: smtp\n\n"); printf(" -s SMTP server\n"); @@ -39,156 +36,14 @@ void usage(){ } -void send_smtp_command(int sd, char *cmd, char *buf, int buflen, int timeout, int use_ssl, struct __data *data){ - if(data == NULL || cmd == NULL) return; - - printf("sent: %s", cmd); - write1(sd, cmd, strlen(cmd), use_ssl, data->ssl); - recvtimeoutssl(sd, buf, buflen, timeout, use_ssl, data->ssl); - printf("rcvd: %s", buf); - -} - - -static void test_smtp_commands_one_at_a_time(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int sd; - char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; - - sd = connect_to_smtp_server(server, port, timeout, use_ssl, data); - - send_smtp_command(sd, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); - - send_smtp_command(sd, "MAIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); - - send_smtp_command(sd, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "RCPT"); - - send_smtp_command(sd, "DATA\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "354 ", 4) == 0 && "DATA"); - - snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\n", testmessage); - - send_smtp_command(sd, sendbuf, recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "PERIOD"); - - send_smtp_command(sd, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); - - close(sd); -} - - -static void test_smtp_commands_pipelining(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int sd; - char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; - - sd = connect_to_smtp_server(server, port, timeout, use_ssl, data); - - send_smtp_command(sd, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); - - send_smtp_command(sd, "MAIL FROM: \r\nRCPT TO: \r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); - - snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\nQUIT\r\n", testmessage); - - send_smtp_command(sd, sendbuf, recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT"); - - close(sd); -} - - -static void test_smtp_commands_with_reset_command(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int sd; - char recvbuf[MAXBUFSIZE]; - - sd = connect_to_smtp_server(server, port, timeout, use_ssl, data); - - send_smtp_command(sd, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); - - send_smtp_command(sd, "MAIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); - - send_smtp_command(sd, "RSET\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "RSET"); - - send_smtp_command(sd, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "503 ", 4) == 0 && "RCPT"); - - send_smtp_command(sd, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); - - close(sd); -} - - -static void test_smtp_commands_partial_command(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int sd; - char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; - - sd = connect_to_smtp_server(server, port, timeout, use_ssl, data); - - send_smtp_command(sd, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); - - write1(sd, "M", 1, use_ssl, data->ssl); - printf("sent: M\n"); - - send_smtp_command(sd, "AIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); - - send_smtp_command(sd, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "RCPT"); - - send_smtp_command(sd, "DATA\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "354 ", 4) == 0 && "DATA"); - - snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\n", testmessage); - - send_smtp_command(sd, sendbuf, recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "PERIOD"); - - send_smtp_command(sd, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); - - close(sd); -} - - -static void test_smtp_commands_partial_command_pipelining(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int sd; - char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; - - sd = connect_to_smtp_server(server, port, timeout, use_ssl, data); - - send_smtp_command(sd, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); - - write1(sd, "M", 1, use_ssl, data->ssl); - printf("sent: M\n"); - - send_smtp_command(sd, "AIL FROM: \r\nRCPT TO: \r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); - - snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\nQUIT\r\n", testmessage); - - send_smtp_command(sd, sendbuf, recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data); - assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT"); - - close(sd); -} - - -int connect_to_smtp_server(char *server, int port, int timeout, int use_ssl, struct __data *data){ - int rc, sd = -1; +void connect_to_smtp_server(char *server, int port, struct data *data){ + int rc; char port_string[8], buf[MAXBUFSIZE]; struct addrinfo hints, *res; - if(data == NULL) return sd; + data->net->socket = -1; + + if(data == NULL) return; snprintf(port_string, sizeof(port_string)-1, "%d", port); @@ -198,33 +53,179 @@ int connect_to_smtp_server(char *server, int port, int timeout, int use_ssl, str if((rc = getaddrinfo(server, port_string, &hints, &res)) != 0){ printf("getaddrinfo for '%s': %s\n", server, gai_strerror(rc)); - return sd; + return; } - if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ + if((data->net->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1){ printf("cannot create socket\n"); goto ENDE; } - if(connect(sd, res->ai_addr, res->ai_addrlen) == -1){ + if(connect(data->net->socket, res->ai_addr, res->ai_addrlen) == -1){ printf("connect()\n"); goto ENDE; } - recvtimeoutssl(sd, buf, sizeof(buf), timeout, use_ssl, data->ssl); + recvtimeoutssl(data->net, buf, sizeof(buf)); printf("rcvd: %s", buf); ENDE: freeaddrinfo(res); +} - return sd; + +void send_smtp_command(struct net *net, char *cmd, char *buf, int buflen){ + if(net == NULL || cmd == NULL) return; + + if(net->socket == -1){ + printf("not connected to remote host\n"); + return; + } + + printf("sent: %s", cmd); + write1(net, cmd, strlen(cmd)); + recvtimeoutssl(net, buf, buflen); + printf("rcvd: %s", buf); +} + + +static void test_smtp_commands_one_at_a_time(char *server, int port, struct data *data){ + char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; + + connect_to_smtp_server(server, port, data); + + send_smtp_command(data->net, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); + + send_smtp_command(data->net, "MAIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); + + send_smtp_command(data->net, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "RCPT"); + + send_smtp_command(data->net, "DATA\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "354 ", 4) == 0 && "DATA"); + + snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\n", testmessage); + + send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "PERIOD"); + + send_smtp_command(data->net, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); + + close(data->net->socket); +} + + +static void test_smtp_commands_pipelining(char *server, int port, struct data *data){ + char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; + + connect_to_smtp_server(server, port, data); + + send_smtp_command(data->net, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); + + send_smtp_command(data->net, "MAIL FROM: \r\nRCPT TO: \r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); + + snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\nQUIT\r\n", testmessage); + + send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT"); + + close(data->net->socket); +} + + +static void test_smtp_commands_with_reset_command(char *server, int port, struct data *data){ + char recvbuf[MAXBUFSIZE]; + + connect_to_smtp_server(server, port, data); + + send_smtp_command(data->net, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); + + send_smtp_command(data->net, "MAIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); + + send_smtp_command(data->net, "RSET\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "RSET"); + + send_smtp_command(data->net, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "503 ", 4) == 0 && "RCPT"); + + send_smtp_command(data->net, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); + + close(data->net->socket); +} + + +static void test_smtp_commands_partial_command(char *server, int port, struct data *data){ + char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; + + connect_to_smtp_server(server, port, data); + + send_smtp_command(data->net, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); + + write1(data->net, "M", 1); + printf("sent: M\n"); + + send_smtp_command(data->net, "AIL FROM: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); + + send_smtp_command(data->net, "RCPT TO: \r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "RCPT"); + + send_smtp_command(data->net, "DATA\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "354 ", 4) == 0 && "DATA"); + + snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\n", testmessage); + + send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "PERIOD"); + + send_smtp_command(data->net, "QUIT\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "221 ", 4) == 0 && "QUIT"); + + close(data->net->socket); +} + + +static void test_smtp_commands_partial_command_pipelining(char *server, int port, struct data *data){ + char recvbuf[MAXBUFSIZE], sendbuf[MAXBUFSIZE]; + + connect_to_smtp_server(server, port, data); + + send_smtp_command(data->net, "HELO aaaa.fu\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "HELO"); + + write1(data->net, "M", 1); + printf("sent: M\n"); + + send_smtp_command(data->net, "AIL FROM: \r\nRCPT TO: \r\nDATA\r\n", recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL"); + + snprintf(sendbuf, sizeof(sendbuf)-1, "%s\r\n.\r\nQUIT\r\n", testmessage); + + send_smtp_command(data->net, sendbuf, recvbuf, sizeof(recvbuf)-1); + assert(strncmp(recvbuf, "250 ", 4) == 0 && "QUIT"); + + close(data->net->socket); } int main(int argc, char **argv){ - int c, port=25, timeout=10, use_ssl; + int c, port=25; char *server=NULL; - struct __data data; + struct data data; + struct net net; + + net.timeout = 10; + net.use_ssl = 0; + net.ssl = NULL; while(1){ @@ -259,7 +260,7 @@ int main(int argc, char **argv){ break; case 't' : - timeout = atoi(optarg); + net.timeout = atoi(optarg); break; case 'h' : @@ -275,14 +276,13 @@ int main(int argc, char **argv){ if(!server) usage(); - use_ssl = 0; - data.ssl = NULL; + data.net = &net; - test_smtp_commands_one_at_a_time(server, port, timeout, use_ssl, &data); - test_smtp_commands_pipelining(server, port, timeout, use_ssl, &data); - test_smtp_commands_with_reset_command(server, port, timeout, use_ssl, &data); - test_smtp_commands_partial_command(server, port, timeout, use_ssl, &data); - test_smtp_commands_partial_command_pipelining(server, port, timeout, use_ssl, &data); + test_smtp_commands_one_at_a_time(server, port, &data); + test_smtp_commands_pipelining(server, port, &data); + test_smtp_commands_with_reset_command(server, port, &data); + test_smtp_commands_partial_command(server, port, &data); + test_smtp_commands_partial_command_pipelining(server, port, &data);