rawlog.c revision b8d232d88018c5cafd2f3be5a181d318137a45f2
/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "network.h"
#include "write-full.h"
#include "istream.h"
#include "ostream.h"
#include "process-title.h"
#include "restrict-access.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define MAX_PROXY_INPUT_SIZE 4096
#define OUTBUF_THRESHOLD 1024
#define TIMESTAMP_WAIT_TIME 5
#define TIMESTAMP_FORMAT "* OK [RAWLOG TIMESTAMP] %Y-%m-%d %H:%M:%S\n"
enum rawlog_flags {
RAWLOG_FLAG_LOG_INPUT = 0x01,
RAWLOG_FLAG_LOG_OUTPUT = 0x02,
RAWLOG_FLAG_LOG_TIMESTAMPS = 0x04,
RAWLOG_FLAG_LOG_BOUNDARIES = 0X10
};
struct rawlog_proxy {
struct istream *server_input;
enum rawlog_flags flags;
unsigned int last_out_lf:1;
};
{
i_error("close(in) failed: %m");
}
i_error("close(out) failed: %m");
}
i_error("close(client_in_fd) failed: %m");
i_error("close(client_out_fd) failed: %m");
i_error("close(server_fd) failed: %m");
}
{
return;
/* failed, disable logging */
i_error("write(in) failed: %m");
}
}
{
char buf[256];
return;
if (proxy->last_out_lf &&
i_fatal("strftime() failed");
i_fatal("Can't write to log file: %m");
}
/* failed, disable logging */
i_error("write(out) failed: %m");
}
}
{
unsigned char buf[OUTBUF_THRESHOLD];
/* client's output buffer is already quite full.
don't send more until we're below threshold. */
return;
}
if (ret > 0) {
} else if (ret <= 0)
}
{
unsigned char buf[OUTBUF_THRESHOLD];
/* proxy's output buffer is already quite full.
don't send more until we're below threshold. */
return;
}
if (ret > 0) {
} else if (ret < 0)
}
{
return 1;
}
/* there's again space in proxy's output buffer, so we can
read more from client. */
}
return 1;
}
{
return 1;
}
/* there's again space in client's output buffer, so we can
read more from proxy. */
}
return 1;
}
{
const char *fname;
char timestamp[50];
i_fatal("strftime() failed");
return;
}
}
return;
}
}
}
static struct rawlog_proxy *
{
struct rawlog_proxy *proxy;
return proxy;
}
{
int sfd[2];
if (chroot_dir != NULL)
home = ".";
/* see if we want rawlog */
return;
}
return;
if (chroot_dir != NULL) {
/* we'll chroot soon. skip over the chroot in the path. */
}
i_fatal("socketpair() failed: %m");
if (pid < 0)
i_fatal("fork() failed: %m");
if (pid > 0) {
/* parent */
i_fatal("dup2(sfd, 0)");
i_fatal("dup2(sfd, 1)");
return;
}
ioloop = io_loop_create();
lib_deinit();
exit(0);
}
{
char *executable, *p;
enum rawlog_flags flags;
lib_init();
argc--;
argv++;
else {
argc = 0;
break;
}
argc--;
argv++;
}
if (argc < 1)
i_fatal("Usage: rawlog [-i | -o] [-b] <binary> <arguments>");
executable = argv[0];
/* hide the executable path, it's ugly */
/* not reached */
return FATAL_EXEC;
}