[dovecot-cvs] dovecot/src/imap rawlog.c,NONE,1.1 rawlog.h,NONE,1.1 Makefile.am,1.3,1.4 client.h,1.3,1.4 main.c,1.5,1.6

cras at procontrol.fi cras at procontrol.fi
Tue Oct 29 08:29:19 EET 2002


Update of /home/cvs/dovecot/src/imap
In directory danu:/tmp/cvs-serv14547/src/imap

Modified Files:
	Makefile.am client.h main.c 
Added Files:
	rawlog.c rawlog.h 
Log Message:
--with-rawlog: Build support for logging traffic of user sessions. If
user's home directory contains "rawlog" directory, the input and output
traffic is written to YYYYMMDD-hhmmss-pid.in and .out files. This was made
for debugging purposes.



--- NEW FILE: rawlog.c ---
/* Copyright (C) 2002 Timo Sirainen */

#include "lib.h"

#ifdef BUILD_RAWLOG

#include "ioloop.h"
#include "rawlog.h"
#include "write-full.h"

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>

static IOLoop ioloop;
static int client_in, client_out, imap_in, imap_out;
static int log_in, log_out;

static void copy(int in, int out, int log)
{
	char buf[1024];
	ssize_t r_ret, s_ret;

	r_ret = read(in, buf, sizeof(buf));
	if (r_ret <= 0) {
		if (r_ret < 0)
			i_error("imap_in: read() failed: %m");

		/* disconnected */
		io_loop_stop(ioloop);
		return;
	}

	if (write_full(log, buf, r_ret) < 0)
		i_fatal("Can't write to log file: %m");

	do {
		s_ret = write(out, buf, r_ret);
		if (s_ret <= 0) {
			if (r_ret < 0)
				i_error("imap_in: write() failed: %m");

			/* disconnected */
			io_loop_stop(ioloop);
			return;
		}
		r_ret -= s_ret;
	} while (r_ret > 0);
}

static void imap_input(void *context __attr_unused__, int fd __attr_unused__,
		       IO io __attr_unused__)
{
	copy(imap_in, client_out, log_out);
}

static void client_input(void *context __attr_unused__, int fd __attr_unused__,
			 IO io __attr_unused__)
{
	copy(client_in, imap_out, log_in);
}

void rawlog_open(int *hin, int *hout)
{
	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;

	home = getenv("HOME");
	if (home == NULL)
		home = ".";

	/* see if we want rawlog */
	path = t_strconcat(home, "/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-%d.in", path, timestamp, 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-%d.out", path, timestamp, 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");

	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]);

	/* 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

--- NEW FILE: rawlog.h ---
#ifndef __RAWLOG_H
#define __RAWLOG_H

void rawlog_open(int *hin, int *hout);

#endif

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/imap/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Makefile.am	19 Oct 2002 14:51:59 -0000	1.3
+++ Makefile.am	29 Oct 2002 06:29:17 -0000	1.4
@@ -51,10 +51,12 @@
 	commands.c \
 	commands-util.c \
 	mailbox-sync.c \
-	main.c
+	main.c \
+	rawlog.c
 
 noinst_HEADERS = \
 	client.h \
 	commands.h \
 	commands-util.h \
-	common.h
+	common.h \
+	rawlog.h

Index: client.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/client.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- client.h	19 Oct 2002 14:51:59 -0000	1.3
+++ client.h	29 Oct 2002 06:29:17 -0000	1.4
@@ -28,6 +28,7 @@
 	unsigned int cmd_error:1;
 	unsigned int cmd_uid:1; /* used UID command */
 	unsigned int sync_flags_send_uid:1;
+	unsigned int rawlog:1;
 	unsigned int inbuf_skip_line:1; /* skip all the data until we've
 					   found a new line */
 };

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/main.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- main.c	13 Oct 2002 23:49:11 -0000	1.5
+++ main.c	29 Oct 2002 06:29:17 -0000	1.6
@@ -3,6 +3,7 @@
 #include "common.h"
 #include "ioloop.h"
 #include "lib-signals.h"
+#include "rawlog.h"
 #include "restrict-access.h"
 
 #include <stdlib.h>
@@ -21,8 +22,12 @@
 	Client *client;
 	MailStorage *storage;
 	const char *logfile, *mail, *tag;
+	int hin, hout;
+
+	hin = 0; hout = 1;
 
 	lib_init_signals(sig_quit);
+	rawlog_open(&hin, &hout);
 
 	i_snprintf(log_prefix, sizeof(log_prefix), "imap(%s)", getenv("USER"));
 
@@ -70,7 +75,7 @@
 				"autodetection failed (home %s)", home);
 		}
 	} else {
-		client = client_create(0, 1, storage);
+		client = client_create(hin, hout, storage);
 
 		tag = getenv("LOGIN_TAG");
 		if (tag == NULL || *tag == '\0')




More information about the dovecot-cvs mailing list