Mercurial > dovecot > core-2.2
changeset 1694:0fae24674a9a HEAD
Separated rawlog into it's own binary.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 21 Aug 2003 02:24:29 +0300 |
parents | 552514c014cc |
children | 587f7911b93d |
files | configure.in src/Makefile.am src/imap/Makefile.am src/imap/main.c src/imap/rawlog.c src/imap/rawlog.h src/util/.cvsignore src/util/Makefile.am src/util/rawlog.c |
diffstat | 9 files changed, 225 insertions(+), 205 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Thu Aug 21 01:12:44 2003 +0300 +++ b/configure.in Thu Aug 21 02:24:29 2003 +0300 @@ -139,12 +139,6 @@ fi, want_cyrus_sasl2=no) -AC_ARG_WITH(rawlog, -[ --with-rawlog Build support for logging user traffic], - if test x$withval = xyes; then - AC_DEFINE(BUILD_RAWLOG,, Build with rawlogging feature) - fi) - AC_ARG_WITH(ssl, [ --with-ssl=[gnutls|openssl] Build with GNUTLS (default) or OpenSSL], if test x$withval = xno; then @@ -1122,6 +1116,7 @@ src/master/Makefile src/pop3/Makefile src/pop3-login/Makefile +src/util/Makefile stamp.h dovecot.spec)
--- a/src/Makefile.am Thu Aug 21 01:12:44 2003 +0300 +++ b/src/Makefile.am Thu Aug 21 02:24:29 2003 +0300 @@ -2,4 +2,4 @@ POP3D = pop3-login pop3 endif -SUBDIRS = lib lib-settings lib-charset lib-mail lib-imap lib-index lib-storage auth master login-common imap-login imap $(POP3D) +SUBDIRS = lib lib-settings lib-charset lib-mail lib-imap lib-index lib-storage auth master login-common imap-login imap $(POP3D) util
--- a/src/imap/Makefile.am Thu Aug 21 01:12:44 2003 +0300 +++ b/src/imap/Makefile.am Thu Aug 21 02:24:29 2003 +0300 @@ -70,8 +70,7 @@ imap-thread.c \ mail-storage-callbacks.c \ main.c \ - namespace.c \ - rawlog.c + namespace.c noinst_HEADERS = \ @@ -84,5 +83,4 @@ imap-search.h \ imap-sort.h \ imap-thread.h \ - namespace.h \ - rawlog.h + namespace.h
--- a/src/imap/main.c Thu Aug 21 01:12:44 2003 +0300 +++ b/src/imap/main.c Thu Aug 21 02:24:29 2003 +0300 @@ -5,7 +5,6 @@ #include "ostream.h" #include "str.h" #include "lib-signals.h" -#include "rawlog.h" #include "restrict-access.h" #include "fd-close-on-exec.h" #include "process-title.h" @@ -88,7 +87,6 @@ { struct client *client; const char *user, *str; - int hin, hout; lib_init_signals(sig_quit); @@ -103,9 +101,6 @@ capability_string = str_new(default_pool, sizeof(CAPABILITY_STRING)+32); str_append(capability_string, CAPABILITY_STRING); - hin = 0; hout = 1; - rawlog_open(&hin, &hout); - mail_storage_init(); mail_storage_register_all(); clients_init(); @@ -132,7 +127,7 @@ MAILBOX_OPEN_MMAP_INVALIDATE : 0; namespace_pool = pool_alloconly_create("namespaces", 1024); - client = client_create(hin, hout, namespace_init(namespace_pool, user)); + client = client_create(0, 1, namespace_init(namespace_pool, user)); o_stream_cork(client->output); if (IS_STANDALONE()) {
--- a/src/imap/rawlog.c Thu Aug 21 01:12:44 2003 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -/* Copyright (C) 2002 Timo Sirainen */ - -#include "lib.h" -#include "rawlog.h" - -#ifdef BUILD_RAWLOG - -#include "ioloop.h" -#include "network.h" -#include "write-full.h" -#include "process-title.h" - -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#define TIMESTAMP_WAIT_TIME 5 -#define TIMESTAMP_FORMAT "* OK [RAWLOG TIMESTAMP] %Y-%m-%d %H:%M:%S\n" - -static struct ioloop *ioloop; -static int client_in, client_out, imap_in, imap_out; -static int log_in, log_out; - -static time_t last_write = 0; -static int last_lf = TRUE; - -static void copy(int in, int out, int log) -{ - struct tm *tm; - char buf[1024]; - ssize_t r_ret, s_ret; - - if (last_lf && ioloop_time - last_write > TIMESTAMP_WAIT_TIME) { - tm = localtime(&ioloop_time); - - if (strftime(buf, sizeof(buf), TIMESTAMP_FORMAT, tm) <= 0) - i_fatal("strftime() failed"); - if (write_full(log, buf, strlen(buf)) < 0) - i_fatal("Can't write to log file: %m"); - } - - net_set_nonblock(in, TRUE); - do { - r_ret = net_receive(in, buf, sizeof(buf)); - } while (r_ret == 0); - - if (r_ret < 0) { - if (r_ret == -1) - i_error("imap_in: net_receive() failed: %m"); - - /* disconnected */ - io_loop_stop(ioloop); - return; - } - - last_lf = buf[r_ret-1] == '\n'; - if (write_full(log, buf, r_ret) < 0) - i_fatal("Can't write to log file: %m"); - - net_set_nonblock(out, FALSE); - do { - s_ret = net_transmit(out, buf, r_ret); - if (s_ret < 0) { - if (s_ret == -1) - i_error("imap_in: net_transmit() failed: %m"); - - /* disconnected */ - io_loop_stop(ioloop); - return; - } - r_ret -= s_ret; - } while (r_ret > 0); - - last_write = time(NULL); -} - -static void imap_input(void *context __attr_unused__) -{ - copy(imap_in, client_out, log_out); -} - -static void client_input(void *context __attr_unused__) -{ - copy(client_in, imap_out, log_in); -} - -void rawlog_open(int *hin, int *hout) -{ - struct io *io_imap, *io_client; - const char *home, *path, *fname; - char timestamp[50]; - struct tm *tm; - struct stat st; - int sfd[2]; - pid_t pid, parent_pid; - - home = getenv("HOME"); - if (home == NULL) - home = "."; - - /* see if we want rawlog */ - path = t_strconcat(home, "/dovecot.rawlog", NULL); - if (stat(path, &st) < 0) { - if (errno != ENOENT) - i_warning("stat() failed for %s: %m", path); - return; - } - - /* yes, open the files. Do it before forking to make sure we don't - unneededly do it. */ - tm = localtime(&ioloop_time); - if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) <= 0) - i_fatal("strftime() failed"); - - fname = t_strdup_printf("%s/%s-%s.in", path, timestamp, - dec2str(getpid())); - log_in = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); - if (log_in == -1) { - i_warning("rawlog_open: open() failed for %s: %m", fname); - return; - } - - fname = t_strdup_printf("%s/%s-%s.out", path, timestamp, - dec2str(getpid())); - log_out = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); - if (log_out == -1) { - i_warning("rawlog_open: open() failed for %s: %m", fname); - close(log_in); - return; - } - - /* we need to fork the rawlog writer to separate process since - imap process does blocking writes. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0) - i_fatal("socketpair() failed: %m"); - - parent_pid = getpid(); - - pid = fork(); - if (pid < 0) - i_fatal("fork() failed: %m"); - - if (pid > 0) { - /* parent */ - close(log_in); close(log_out); - close(*hin); close(*hout); - close(sfd[0]); - *hin = *hout = sfd[1]; - return; - } - close(sfd[1]); - - process_title_set(t_strdup_printf("[%s:%s rawlog]", getenv("USER"), - dec2str(parent_pid))); - - /* child */ - client_in = *hin; - client_out = *hout; - imap_in = sfd[0]; - imap_out = sfd[0]; - - ioloop = io_loop_create(system_pool); - io_imap = io_add(imap_in, IO_READ, imap_input, NULL); - io_client = io_add(client_in, IO_READ, client_input, NULL); - - io_loop_run(ioloop); - - io_remove(io_imap); - io_remove(io_client); - io_loop_destroy(ioloop); - - lib_deinit(); - exit(0); -} - -#else -void rawlog_open(int *hin __attr_unused__, int *hout __attr_unused__) -{ -} -#endif
--- a/src/imap/rawlog.h Thu Aug 21 01:12:44 2003 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -#ifndef __RAWLOG_H -#define __RAWLOG_H - -void rawlog_open(int *hin, int *hout); - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util/.cvsignore Thu Aug 21 02:24:29 2003 +0300 @@ -0,0 +1,9 @@ +*.la +*.lo +*.o +.deps +.libs +Makefile +Makefile.in +so_locations +rawlog
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util/Makefile.am Thu Aug 21 02:24:29 2003 +0300 @@ -0,0 +1,10 @@ +bin_PROGRAMS = rawlog + +INCLUDES = \ + -I$(top_srcdir)/src/lib + +rawlog_LDADD = \ + ../lib/liblib.a + +rawlog_SOURCES = \ + rawlog.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util/rawlog.c Thu Aug 21 02:24:29 2003 +0300 @@ -0,0 +1,201 @@ +/* Copyright (C) 2002-2003 Timo Sirainen */ + +#include "lib.h" + +#include "ioloop.h" +#include "network.h" +#include "write-full.h" +#include "process-title.h" + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/socket.h> + +#define TIMESTAMP_WAIT_TIME 5 +#define TIMESTAMP_FORMAT "* OK [RAWLOG TIMESTAMP] %Y-%m-%d %H:%M:%S\n" + +static struct ioloop *ioloop; +static int client_in, client_out, imap_in, imap_out; +static int log_in, log_out; + +static time_t last_write = 0; +static int last_lf = TRUE; + +static void copy(int in, int out, int log) +{ + struct tm *tm; + char buf[1024]; + ssize_t r_ret, s_ret; + + if (last_lf && ioloop_time - last_write > TIMESTAMP_WAIT_TIME) { + tm = localtime(&ioloop_time); + + if (strftime(buf, sizeof(buf), TIMESTAMP_FORMAT, tm) <= 0) + i_fatal("strftime() failed"); + if (write_full(log, buf, strlen(buf)) < 0) + i_fatal("Can't write to log file: %m"); + } + + net_set_nonblock(in, TRUE); + do { + r_ret = net_receive(in, buf, sizeof(buf)); + } while (r_ret == 0); + + if (r_ret < 0) { + if (r_ret == -1) + i_error("imap_in: net_receive() failed: %m"); + + /* disconnected */ + io_loop_stop(ioloop); + return; + } + + last_lf = buf[r_ret-1] == '\n'; + if (write_full(log, buf, r_ret) < 0) + i_fatal("Can't write to log file: %m"); + + net_set_nonblock(out, FALSE); + do { + s_ret = net_transmit(out, buf, r_ret); + if (s_ret < 0) { + if (s_ret == -1) + i_error("imap_in: net_transmit() failed: %m"); + + /* disconnected */ + io_loop_stop(ioloop); + return; + } + r_ret -= s_ret; + } while (r_ret > 0); + + last_write = time(NULL); +} + +static void imap_input(void *context __attr_unused__) +{ + copy(imap_in, client_out, log_out); +} + +static void client_input(void *context __attr_unused__) +{ + copy(client_in, imap_out, log_in); +} + +static void rawlog_open(void) +{ + struct io *io_imap, *io_client; + const char *home, *path, *fname; + char timestamp[50]; + struct tm *tm; + struct stat st; + int sfd[2]; + pid_t pid, parent_pid; + + home = getenv("HOME"); + if (home == NULL) + home = "."; + + /* see if we want rawlog */ + path = t_strconcat(home, "/dovecot.rawlog", NULL); + if (stat(path, &st) < 0) { + if (errno != ENOENT) + i_warning("stat() failed for %s: %m", path); + return; + } + + /* yes, open the files. Do it before forking to make sure we don't + unneededly do it. */ + tm = localtime(&ioloop_time); + if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) <= 0) + i_fatal("strftime() failed"); + + fname = t_strdup_printf("%s/%s-%s.in", path, timestamp, + dec2str(getpid())); + log_in = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (log_in == -1) { + i_warning("rawlog_open: open() failed for %s: %m", fname); + return; + } + + fname = t_strdup_printf("%s/%s-%s.out", path, timestamp, + dec2str(getpid())); + log_out = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (log_out == -1) { + i_warning("rawlog_open: open() failed for %s: %m", fname); + close(log_in); + return; + } + + /* we need to fork the rawlog writer to separate process since + imap process does blocking writes. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0) + i_fatal("socketpair() failed: %m"); + + parent_pid = getpid(); + + pid = fork(); + if (pid < 0) + i_fatal("fork() failed: %m"); + + if (pid > 0) { + /* parent */ + close(log_in); close(log_out); + close(sfd[0]); + if (dup2(sfd[1], 0) < 0) + i_fatal("dup2(sfd, 0)"); + if (dup2(sfd[1], 1) < 0) + i_fatal("dup2(sfd, 1)"); + return; + } + close(sfd[1]); + + process_title_set(t_strdup_printf("[%s:%s rawlog]", getenv("USER"), + dec2str(parent_pid))); + + /* child */ + client_in = 0; + client_out = 1; + imap_in = sfd[0]; + imap_out = sfd[0]; + + ioloop = io_loop_create(system_pool); + io_imap = io_add(imap_in, IO_READ, imap_input, NULL); + io_client = io_add(client_in, IO_READ, client_input, NULL); + + io_loop_run(ioloop); + + io_remove(io_imap); + io_remove(io_client); + io_loop_destroy(ioloop); + + lib_deinit(); + exit(0); +} + +int main(int argc, char *argv[], char *envp[]) +{ + char *executable, *p; + + lib_init(); + process_title_init(argv, envp); + + if (argc < 2) + i_fatal("Usage: rawlog <binary> <arguments>"); + + rawlog_open(); + + argv++; + executable = argv[0]; + + /* hide path, it's ugly */ + p = strrchr(argv[0], '/'); + if (p != NULL) argv[0] = p+1; + execv(executable, argv); + + i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable); + + /* not reached */ + return FATAL_EXEC; +}