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;
+}