mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-12-24 04:20:12 +01:00
src: refactoring
Signed-off-by: Janos SUTO <sj@acts.hu>
This commit is contained in:
parent
5bb52be2fd
commit
950211687f
16
configure
vendored
16
configure
vendored
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
2
src/av.h
2
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 */
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
|
124
src/cfg.c
124
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;
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
struct __config {
|
||||
struct config {
|
||||
int server_id;
|
||||
char username[MAXVAL];
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#define VERSION "1.3.0-epoll"
|
||||
|
||||
#define BUILD 978
|
||||
#define BUILD 979
|
||||
|
||||
#define HOSTID "mailarchiver"
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
39
src/defs.h
39
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 */
|
||||
|
@ -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];
|
||||
|
39
src/dirs.c
39
src/dirs.c
@ -13,10 +13,25 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
550
src/imap.c
550
src/imap.c
@ -23,9 +23,6 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
50
src/import.c
50
src/import.c
@ -18,7 +18,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
27
src/import.h
27
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 */
|
||||
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* import_gui.c, SJ
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
#include <getopt.h>
|
||||
#include <syslog.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -22,49 +22,52 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;i<MAXHASH;i++){
|
||||
q = data->imapfolders[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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,10 +22,10 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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++;
|
||||
|
@ -22,17 +22,17 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,50 +22,46 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
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];
|
||||
|
||||
|
30
src/misc.c
30
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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
31
src/parser.c
31
src/parser.c
@ -16,7 +16,7 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
44
src/piler.h
44
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);
|
||||
|
@ -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){
|
||||
|
@ -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){
|
||||
|
@ -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)){
|
||||
|
@ -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){
|
||||
|
@ -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; i<MBOX_ARGS; i++) mbox[i] = NULL;
|
||||
|
||||
@ -87,10 +85,27 @@ int main(int argc, char **argv){
|
||||
import.extra_recipient = import.move_folder = import.failed_folder = NULL;
|
||||
import.start_position = 1;
|
||||
import.download_only = 0;
|
||||
import.timeout = 30;
|
||||
import.dryrun = 0;
|
||||
import.port = 143;
|
||||
import.server = NULL;
|
||||
import.username = NULL;
|
||||
import.password = NULL;
|
||||
import.database = NULL;
|
||||
import.skiplist = SKIPLIST;
|
||||
import.folder_imap = NULL;
|
||||
memset(import.filename, 0, SMALLBUFSIZE);
|
||||
import.directory = NULL;
|
||||
import.mboxdir = NULL;
|
||||
import.tot_msgs = 0;
|
||||
import.folder = NULL;
|
||||
|
||||
data.import = &import;
|
||||
|
||||
net.socket = -1;
|
||||
net.timeout = 30;
|
||||
|
||||
data.net = &net;
|
||||
|
||||
inithash(data.mydomains);
|
||||
initrules(data.archiving_rules);
|
||||
initrules(data.retention_rules);
|
||||
@ -124,7 +139,6 @@ int main(int argc, char **argv){
|
||||
{"failed-folder", required_argument, 0, 'j' },
|
||||
{"move-folder", required_argument, 0, 'g' },
|
||||
{"only-download",no_argument, 0, 'o' },
|
||||
{"gui-import", no_argument, 0, 'G' },
|
||||
{"dry-run", no_argument, 0, 'D' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{0,0,0,0}
|
||||
@ -132,9 +146,9 @@ int main(int argc, char **argv){
|
||||
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "c:m:M:e:d:i:K:u:p:P:x:F:f:a:b:t:s:g:j:GDRroqh?", long_options, &option_index);
|
||||
c = getopt_long(argc, argv, "c:m:M:e:d:i:K:u:p:P:x:F:f:a:b:t:s:g:j:DRroqh?", long_options, &option_index);
|
||||
#else
|
||||
c = getopt(argc, argv, "c:m:M:e:d:i:K:u:p:P:x:F:f:a:b:t:s:g:j:GDRroqh?");
|
||||
c = getopt(argc, argv, "c:m:M:e:d:i:K:u:p:P:x:F:f:a:b:t:s:g:j:DRroqh?");
|
||||
#endif
|
||||
|
||||
if(c == -1) break;
|
||||
@ -146,11 +160,11 @@ int main(int argc, char **argv){
|
||||
break;
|
||||
|
||||
case 'e' :
|
||||
emlfile = optarg;
|
||||
snprintf(data.import->filename, 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; i<n_mbox; i++){
|
||||
rc = import_from_mailbox(mbox[i], &sdata, &data, &cfg);
|
||||
import_from_mailbox(mbox[i], &sdata, &data, &cfg);
|
||||
}
|
||||
}
|
||||
if(mboxdir) rc = import_mbox_from_dir(mboxdir, &sdata, &data, &tot_msgs, &cfg);
|
||||
if(directory) rc = import_from_maildir(directory, &sdata, &data, &tot_msgs, &cfg);
|
||||
if(imapserver && username && password) rc = import_from_imap_server(imapserver, username, password, port, &sdata, &data, folder_imap, skiplist, dryrun, &cfg);
|
||||
if(pop3server && username && password) rc = import_from_pop3_server(pop3server, username, password, port, &sdata, &data, dryrun, &cfg);
|
||||
if(import_from_gui == 1) rc = read_gui_import_data(&sdata, &data, folder_imap, skiplist, dryrun, &cfg);
|
||||
if(data.import->mboxdir) 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;
|
||||
}
|
||||
|
||||
|
||||
|
439
src/pilerpurge.c
439
src/pilerpurge.c
@ -1,439 +0,0 @@
|
||||
/*
|
||||
* pilerpurge.c, SJ
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
#include <syslog.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
229
src/pop3.c
229
src/pop3.c
@ -23,9 +23,6 @@
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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){
|
||||
|
10
src/rules.c
10
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;
|
||||
|
10
src/rules.h
10
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);
|
||||
|
@ -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; i<max_connections; i++){
|
||||
if(sessions[i] && sessions[i]->socket == 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;
|
||||
|
62
src/smtp.c
62
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);
|
||||
|
@ -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);
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
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];
|
||||
|
||||
|
11
src/tai.c
11
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';
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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", "<ajahhdddhjdhddh@jatekokbirodalma.hu>", "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!");
|
||||
|
||||
|
@ -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},
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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> 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: <sender@aaa.fu>\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data);
|
||||
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||
|
||||
send_smtp_command(sd, "RCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\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: <archive@aaa.fu>\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: <sender@aaa.fu>\r\n", recvbuf, sizeof(recvbuf)-1, timeout, use_ssl, data);
|
||||
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||
|
||||
send_smtp_command(sd, "RCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\r\n", recvbuf, sizeof(recvbuf)-1);
|
||||
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||
|
||||
send_smtp_command(data->net, "RCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\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: <archive@aaa.fu>\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: <sender@aaa.fu>\r\n", recvbuf, sizeof(recvbuf)-1);
|
||||
assert(strncmp(recvbuf, "250 ", 4) == 0 && "MAIL");
|
||||
|
||||
send_smtp_command(data->net, "RCPT TO: <archive@aaa.fu>\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: <sender@aaa.fu>\r\nRCPT TO: <archive@aaa.fu>\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);
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user