/*
 * General logging functions.
 *
 * Copyright 2000-2008 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>

#include <sys/time.h>

#include <common/config.h>
#include <common/compat.h>
#include <common/standard.h>
#include <common/time.h>

#include <types/global.h>
#include <types/log.h>

#include <proto/log.h>
#include <proto/stream_interface.h>

const char *log_facilities[NB_LOG_FACILITIES] = {
	"kern", "user", "mail", "daemon",
	"auth", "syslog", "lpr", "news",
	"uucp", "cron", "auth2", "ftp",
	"ntp", "audit", "alert", "cron2",
	"local0", "local1", "local2", "local3",
	"local4", "local5", "local6", "local7"
};


const char *log_levels[NB_LOG_LEVELS] = {
	"emerg", "alert", "crit", "err",
	"warning", "notice", "info", "debug"
};

const char sess_term_cond[10] = "-cCsSPRIDK";	/* normal, CliTo, CliErr, SrvTo, SrvErr, PxErr, Resource, Internal, Down, Killed */
const char sess_fin_state[8]  = "-RCHDLQT";	/* cliRequest, srvConnect, srvHeader, Data, Last, Queue, Tarpit */


/* log_format   */
struct logformat_type {
	char *name;
	int type;
	int mode;
	int (*config_callback)(struct logformat_node *node, struct proxy *curproxy);
};

int prepare_addrsource(struct logformat_node *node, struct proxy *curproxy);

/* log_format variable names */
static const struct logformat_type logformat_keywords[] = {
	{ "o", LOG_GLOBAL, PR_MODE_TCP, NULL },  /* global option */
	{ "Ci", LOG_CLIENTIP, PR_MODE_TCP, NULL },  /* client ip */
	{ "Cp", LOG_CLIENTPORT, PR_MODE_TCP, NULL }, /* client port */
	{ "Bp", LOG_SOURCEPORT, PR_MODE_TCP, prepare_addrsource }, /* backend source port */
	{ "Bi", LOG_SOURCEIP, PR_MODE_TCP, prepare_addrsource }, /* backend source ip */
	{ "t", LOG_DATE, PR_MODE_TCP, NULL },      /* date */
	{ "T", LOG_DATEGMT, PR_MODE_TCP, NULL },   /* date GMT */
	{ "ms", LOG_MS, PR_MODE_TCP, NULL },       /* accept date millisecond */
	{ "f", LOG_FRONTEND, PR_MODE_TCP, NULL },  /* frontend */
	{ "b", LOG_BACKEND, PR_MODE_TCP, NULL },   /* backend */
	{ "s", LOG_SERVER, PR_MODE_TCP, NULL },    /* server */
	{ "B", LOG_BYTES, PR_MODE_TCP, NULL },     /* bytes read */
	{ "Tq", LOG_TQ, PR_MODE_HTTP, NULL },       /* Tq */
	{ "Tw", LOG_TW, PR_MODE_TCP, NULL },       /* Tw */
	{ "Tc", LOG_TC, PR_MODE_TCP, NULL },       /* Tc */
	{ "Tr", LOG_TR, PR_MODE_HTTP, NULL },       /* Tr */
	{ "Tt", LOG_TT, PR_MODE_TCP, NULL },       /* Tt */
	{ "st", LOG_STATUS, PR_MODE_HTTP, NULL },   /* status code */
	{ "cc", LOG_CCLIENT, PR_MODE_HTTP, NULL },  /* client cookie */
	{ "cs", LOG_CSERVER, PR_MODE_HTTP, NULL },  /* server cookie */
	{ "ts", LOG_TERMSTATE, PR_MODE_TCP, NULL },/* terminaison state */
	{ "tsc", LOG_TERMSTATE_CK, PR_MODE_HTTP, NULL },/* terminaison state with cookie status */
	{ "ac", LOG_ACTCONN, PR_MODE_TCP, NULL },  /* actconn */
	{ "fc", LOG_FECONN, PR_MODE_TCP, NULL },   /* feconn */
	{ "bc", LOG_BECONN, PR_MODE_TCP, NULL },   /* beconn */
	{ "sc", LOG_SRVCONN, PR_MODE_TCP, NULL },  /* srv_conn */
	{ "rc", LOG_RETRIES, PR_MODE_TCP, NULL },  /* retries */
	{ "sq", LOG_SRVQUEUE, PR_MODE_TCP, NULL  }, /* srv_queue */
	{ "bq", LOG_BCKQUEUE, PR_MODE_TCP, NULL }, /* backend_queue */
	{ "hr", LOG_HDRREQUEST, PR_MODE_HTTP, NULL }, /* header request */
	{ "hs", LOG_HDRRESPONS, PR_MODE_HTTP, NULL },  /* header response */
	{ "hrl", LOG_HDRREQUESTLIST, PR_MODE_HTTP, NULL }, /* header request list */
	{ "hsl", LOG_HDRRESPONSLIST, PR_MODE_HTTP, NULL },  /* header response list */
	{ "r", LOG_REQ, PR_MODE_HTTP, NULL },  /* request */
	{ 0, 0, 0, NULL }
};

char default_http_log_format[] = "%Ci:%Cp [%t] %f %b/%s %Tq/%Tw/%Tc/%Tr/%Tt %st %B %cc %cs %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"; // default format
char clf_http_log_format[] = "%{+Q}o %{-Q}Ci - - [%T] %r %st %B \"\" \"\" %Cp %ms %f %b %s %Tq %Tw %Tc %Tr %Tt %tsc %ac %fc %bc %sc %rc %sq %bq %cc %cs %hrl %hsl";
char default_tcp_log_format[] = "%Ci:%Cp [%t] %f %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq";
char *log_format = NULL;

/* This is a global syslog line, common to all outgoing messages. It begins
 * with the syslog tag and the date that are updated by update_log_hdr().
 */
static char logline[MAX_SYSLOG_LEN];

struct logformat_var_args {
	char *name;
	int mask;
};

struct logformat_var_args var_args_list[] = {
// global
	{ "M", LOG_OPT_MANDATORY },
	{ "Q", LOG_OPT_QUOTE },
	{  0,  0 }
};

/*
 * callback used to configure addr source retrieval
 */
int prepare_addrsource(struct logformat_node *node, struct proxy *curproxy)
{
	curproxy->options2 |= PR_O2_SRC_ADDR;

	return 0;
}


/*
 * Parse args in a logformat_var
 */
int parse_logformat_var_args(char *args, struct logformat_node *node)
{
	int i = 0;
	int end = 0;
	int flags = 0;  // 1 = +  2 = -
	char *sp = NULL; // start pointer

	if (args == NULL)
		return 1;

	while (1) {
		if (*args == '\0')
			end = 1;

		if (*args == '+') {
			// add flag
			sp = args + 1;
			flags = 1;
		}
		if (*args == '-') {
			// delete flag
			sp = args + 1;
			flags = 2;
		}

		if (*args == '\0' || *args == ',') {
			*args = '\0';
			for (i = 0; var_args_list[i].name; i++) {
				if (strcmp(sp, var_args_list[i].name) == 0) {
					if (flags == 1) {
						node->options |= var_args_list[i].mask;
						break;
					} else if (flags == 2) {
						node->options &= ~var_args_list[i].mask;
						break;
					}
				}
			}
			sp = NULL;
			if (end)
				break;
		}
	args++;
	}
	return 0;
}

/*
 * Parse a variable '%varname' or '%{args}varname' in logformat
 *
 */
int parse_logformat_var(char *str, size_t len, struct proxy *curproxy, int *defoptions)
{
	int i, j;
	char *arg = NULL; // arguments
	int fparam = 0;
	char *name = NULL;
	struct logformat_node *node = NULL;
	char varname[255] = { 0 }; // variable name

	for (i = 1; i < len; i++) { // escape first char %
		if (!arg && str[i] == '{') {
			arg = str + i;
			fparam = 1;
		} else if (arg && str[i] == '}') {
			char *tmp = arg;
			arg = calloc(str + i - tmp, 1); // without {}
			strncpy(arg, tmp + 1, str + i - tmp - 1); // copy without { and }
			arg[str + i - tmp - 1] = '\0';
			fparam = 0;
		} else if (!name && !fparam) {
			strncpy(varname, str + i, len - i + 1);
			varname[len - i] = '\0';
			for (j = 0; logformat_keywords[j].name; j++) { // search a log type
				if (strcmp(varname, logformat_keywords[j].name) == 0) {
					if (!((logformat_keywords[j].mode == PR_MODE_HTTP) && (curproxy->mode == PR_MODE_TCP))) {
						node = calloc(1, sizeof(struct logformat_node));
						node->type = logformat_keywords[j].type;
						node->options = *defoptions;
						node->arg = arg;
						parse_logformat_var_args(node->arg, node);
						if (node->type == LOG_GLOBAL) {
							*defoptions = node->options;
							free(node);
						} else {
							if (logformat_keywords[j].config_callback != NULL) {
								if (logformat_keywords[j].config_callback(node, curproxy) != 0) {
									return -1;
								 }
							}
							LIST_ADDQ(&curproxy->logformat, &node->list);
						}
						return 0;
					} else {
						Warning("Warning: No such variable name '%s' in this log mode\n", varname);
						if (arg)
							free(arg);
						return -1;
					}
				}
			}
			Warning("Warning: No such variable name '%s' in logformat\n", varname);
			if (arg)
				free(arg);
			return -1;
		}
	}
	return -1;
}

/*
 *  push to the logformat linked list
 *
 *  start: start pointer
 *  end: end text pointer
 *  type: string type
 *
 *  LOG_TEXT: copy chars from start to end excluding end.
 *
*/
void add_to_logformat_list(char *start, char *end, int type, struct proxy *curproxy)
{
	char *str;

	if (type == LOG_TEXT) { /* type text */
		struct logformat_node *node = calloc(1, sizeof(struct logformat_node));

		str = calloc(end - start + 1, 1);
		strncpy(str, start, end - start);

		str[end - start] = '\0';
		node->arg = str;
		node->type = LOG_TEXT; // type string
		LIST_ADDQ(&curproxy->logformat, &node->list);
	} else if (type == LOG_SEPARATOR) {
		struct logformat_node *node = calloc(1, sizeof(struct logformat_node));
		node->type = LOG_SEPARATOR;
		LIST_ADDQ(&curproxy->logformat, &node->list);
	}
}

/*
 * Parse the log_format string and fill a linked list.
 * Variable name are preceded by % and composed by characters [a-zA-Z0-9]* : %varname
 * You can set arguments using { } : %{many arguments}varname
 */
void parse_logformat_string(char *str, struct proxy *curproxy)
{
	char *sp = str; /* start pointer */
	int cformat = -1; /* current token format : LOG_TEXT, LOG_SEPARATOR, LOG_VARIABLE */
	int pformat = -1; /* previous token format */
	struct logformat_node *tmplf, *back;
	int options = 0;

	/* flush the list first. */
	list_for_each_entry_safe(tmplf, back, &curproxy->logformat, list) {
		LIST_DEL(&tmplf->list);
		free(tmplf);
	}

	while (1) {

		// push the variable only if formats are different, not
		// within a variable, and not the first iteration
		if ((cformat != pformat && cformat != -1 && pformat != -1) || *str == '\0') {
			if (((pformat != LF_STARTVAR && cformat != LF_VAR) &&
			    (pformat != LF_STARTVAR && cformat != LF_STARG) &&
			    (pformat != LF_STARG && cformat !=  LF_VAR)) || *str == '\0') {
				if (pformat > LF_VAR) // unfinished string
					pformat = LF_TEXT;
				if (pformat == LF_VAR)
					parse_logformat_var(sp, str - sp, curproxy, &options);
				else
					add_to_logformat_list(sp, str, pformat, curproxy);
				sp = str;
				if (*str == '\0')
					break;
			    }
		}

		if (cformat != -1)
			str++; // consume the string, except on the first tour

		pformat = cformat;

		if (*str == '\0') {
			cformat = LF_STARTVAR; // for breaking in all cases
			continue;
		}

		if (pformat == LF_STARTVAR) { // after a %
			if ( (*str >= 'a' && *str <= 'z') || // parse varname
			     (*str >= 'A' && *str <= 'Z') ||
			     (*str >= '0' && *str <= '9')) {
				cformat = LF_VAR; // varname
				continue;
			} else if (*str == '{') {
				cformat = LF_STARG; // variable arguments
				continue;
			} else { // another unexpected token
				pformat = LF_TEXT; // redefine the format of the previous token to TEXT
				cformat = LF_TEXT;
				continue;
			}

		} else if (pformat == LF_VAR) { // after a varname
			if ( (*str >= 'a' && *str <= 'z') || // parse varname
			     (*str >= 'A' && *str <= 'Z') ||
			     (*str >= '0' && *str <= '9')) {
				cformat = LF_VAR;
				continue;
			}
		} else if (pformat  == LF_STARG) { // inside variable arguments
			if (*str == '}') { // end of varname
				cformat = LF_EDARG;
				continue;
			} else { // all tokens are acceptable within { }
				cformat = LF_STARG;
				continue;
			}
		} else if (pformat == LF_EDARG) { //  after arguments
			if ( (*str >= 'a' && *str <= 'z') || // parse a varname
			     (*str >= 'A' && *str <= 'Z') ||
			     (*str >= '0' && *str <= '9')) {
				cformat = LF_VAR;
				continue;
			} else { // if no varname after arguments, transform in TEXT
				pformat = LF_TEXT;
				cformat = LF_TEXT;
			}
		}

		// others tokens that don't match previous conditions
		if (*str == '%') {
			cformat = LF_STARTVAR;
		} else if (*str == ' ') {
			cformat = LF_SEPARATOR;
		} else {
			cformat = LF_TEXT;
		}
	}
}

/*
 * Displays the message on stderr with the date and pid. Overrides the quiet
 * mode during startup.
 */
void Alert(const char *fmt, ...)
{
	va_list argp;
	struct tm tm;

	if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
		va_start(argp, fmt);

		get_localtime(date.tv_sec, &tm);
		fprintf(stderr, "[ALERT] %03d/%02d%02d%02d (%d) : ",
			tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
		vfprintf(stderr, fmt, argp);
		fflush(stderr);
		va_end(argp);
	}
}


/*
 * Displays the message on stderr with the date and pid.
 */
void Warning(const char *fmt, ...)
{
	va_list argp;
	struct tm tm;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
		va_start(argp, fmt);

		get_localtime(date.tv_sec, &tm);
		fprintf(stderr, "[WARNING] %03d/%02d%02d%02d (%d) : ",
			tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
		vfprintf(stderr, fmt, argp);
		fflush(stderr);
		va_end(argp);
	}
}

/*
 * Displays the message on <out> only if quiet mode is not set.
 */
void qfprintf(FILE *out, const char *fmt, ...)
{
	va_list argp;

	if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
		va_start(argp, fmt);
		vfprintf(out, fmt, argp);
		fflush(out);
		va_end(argp);
	}
}

/*
 * returns log level for <lev> or -1 if not found.
 */
int get_log_level(const char *lev)
{
	int level;

	level = NB_LOG_LEVELS - 1;
	while (level >= 0 && strcmp(log_levels[level], lev))
		level--;

	return level;
}


/*
 * returns log facility for <fac> or -1 if not found.
 */
int get_log_facility(const char *fac)
{
	int facility;

	facility = NB_LOG_FACILITIES - 1;
	while (facility >= 0 && strcmp(log_facilities[facility], fac))
		facility--;

	return facility;
}

/*
 * Write a string in the log string
 * Take cares of mandatory and quote options
 *
 * Return the adress of the \0 character, or NULL on error
 */
char *logformat_write_string(char *dst, char *src, size_t size, struct logformat_node *node)
{
	int n;

	if (src == NULL || *src == '\0') {
		if (node->options & LOG_OPT_QUOTE) {
			if (size > 2) {
				*(dst++) = '"';
				*(dst++) = '"';
				*dst = '\0';
				node->options |= LOG_OPT_WRITTEN;
			} else {
				dst = NULL;
				return dst;
			}
		} else {
			if (size > 1) {
				*(dst++) = '-';
				*dst = '\0';
				node->options |= LOG_OPT_WRITTEN;
			} else { // error no space available
				dst = NULL;
				return dst;
			}
		}
	} else {
		if (node->options & LOG_OPT_QUOTE) {
			if (size-- > 1 ) {
				*(dst++) = '"';
			} else {
				dst = NULL;
				return NULL;
			}
			n = strlcpy2(dst, src, size);
			size -= n;
			dst += n;
			if (size > 1) {
				*(dst++) = '"';
				*dst = '\0';
			} else {
				dst = NULL;
			}
		} else {
			dst += strlcpy2(dst, src, size);
		}
	}
	return dst;
}

/* Re-generate the syslog header at the beginning of logline once a second and
 * return the pointer to the first character after the header.
 */
static char *update_log_hdr()
{
	static long tvsec;
	static char *dataptr = NULL; /* backup of last end of header, NULL first time */

	if (unlikely(date.tv_sec != tvsec || dataptr == NULL)) {
		/* this string is rebuild only once a second */
		struct tm tm;
		int hdr_len;

		tvsec = date.tv_sec;
		get_localtime(tvsec, &tm);

		hdr_len = snprintf(logline, MAX_SYSLOG_LEN,
				   "<<<<>%s %2d %02d:%02d:%02d %s%s[%d]: ",
				   monthname[tm.tm_mon],
				   tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
				   global.log_send_hostname ? global.log_send_hostname : "",
				   global.log_tag, pid);
		/* WARNING: depending upon implementations, snprintf may return
		 * either -1 or the number of bytes that would be needed to store
		 * the total message. In both cases, we must adjust it.
		 */
		if (hdr_len < 0 || hdr_len > MAX_SYSLOG_LEN)
			hdr_len = MAX_SYSLOG_LEN;

		dataptr = logline + hdr_len;
	}

	return dataptr;
}

/*
 * This function adds a header to the message and sends the syslog message
 * using a printf format string. It expects an LF-terminated message.
 */
void send_log(struct proxy *p, int level, const char *format, ...)
{
	va_list argp;
	char *dataptr;
	int  data_len;

	if (level < 0 || format == NULL)
		return;

	dataptr = update_log_hdr(); /* update log header and skip it */
	data_len = dataptr - logline;

	va_start(argp, format);
	data_len += vsnprintf(dataptr, logline + sizeof(logline) - dataptr, format, argp);
	if (data_len < 0 || data_len > MAX_SYSLOG_LEN)
		data_len =  MAX_SYSLOG_LEN;
	va_end(argp);

	__send_log(p, level, logline, data_len);
}

/*
 * This function sends a syslog message.
 * It doesn't care about errors nor does it report them.
 * It overrides the last byte (message[size-1]) with an LF character.
 */
void __send_log(struct proxy *p, int level, char *message, size_t size)
{
	static int logfdunix = -1;	/* syslog to AF_UNIX socket */
	static int logfdinet = -1;	/* syslog to AF_INET socket */
	static char *dataptr = NULL;
	int fac_level;
	struct list *logsrvs = NULL;
	struct logsrv *tmp = NULL;
	int nblogger;
	char *log_ptr;

	dataptr = message;

	if (p == NULL) {
		if (!LIST_ISEMPTY(&global.logsrvs)) {
			logsrvs = &global.logsrvs;
		}
	} else {
		if (!LIST_ISEMPTY(&p->logsrvs)) {
			logsrvs = &p->logsrvs;
		}
	}

	if (!logsrvs)
		return;

	message[size - 1] = '\n';

	/* Lazily set up syslog sockets for protocol families of configured
	 * syslog servers. */
	nblogger = 0;
	list_for_each_entry(tmp, logsrvs, list) {
		const struct logsrv *logsrv = tmp;
		int proto, *plogfd;

		if (logsrv->addr.ss_family == AF_UNIX) {
			proto = 0;
			plogfd = &logfdunix;
		} else {
			proto = IPPROTO_UDP;
			plogfd = &logfdinet;
		}
		if (*plogfd >= 0) {
			/* socket already created. */
			continue;
		}
		if ((*plogfd = socket(logsrv->addr.ss_family, SOCK_DGRAM,
				proto)) < 0) {
			Alert("socket for logger #%d failed: %s (errno=%d)\n",
				nblogger + 1, strerror(errno), errno);
			return;
		}
		/* we don't want to receive anything on this socket */
		setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
		/* does nothing under Linux, maybe needed for others */
		shutdown(*plogfd, SHUT_RD);
		nblogger++;
	}

	/* Send log messages to syslog server. */
	nblogger = 0;
	list_for_each_entry(tmp, logsrvs, list) {
		const struct logsrv *logsrv = tmp;
		int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
			&logfdunix : &logfdinet;
		int sent;

		/* we can filter the level of the messages that are sent to each logger */
		if (level > logsrv->level)
			continue;

		/* For each target, we may have a different facility.
		 * We can also have a different log level for each message.
		 * This induces variations in the message header length.
		 * Since we don't want to recompute it each time, nor copy it every
		 * time, we only change the facility in the pre-computed header,
		 * and we change the pointer to the header accordingly.
		 */
		fac_level = (logsrv->facility << 3) + MAX(level, logsrv->minlvl);
		log_ptr = dataptr + 3; /* last digit of the log level */
		do {
			*log_ptr = '0' + fac_level % 10;
			fac_level /= 10;
			log_ptr--;
		} while (fac_level && log_ptr > dataptr);
		*log_ptr = '<';

		sent = sendto(*plogfd, log_ptr, size + log_ptr - dataptr,
			      MSG_DONTWAIT | MSG_NOSIGNAL,
			      (struct sockaddr *)&logsrv->addr, get_addr_len(&logsrv->addr));
		if (sent < 0) {
			Alert("sendto logger #%d failed: %s (errno=%d)\n",
				nblogger, strerror(errno), errno);
		}
		nblogger++;
	}
}

extern fd_set hdr_encode_map[];
extern fd_set url_encode_map[];


const char sess_cookie[8]     = "NIDVEOU7";	/* No cookie, Invalid cookie, cookie for a Down server, Valid cookie, Expired cookie, Old cookie, Unused, unknown */
const char sess_set_cookie[8] = "NPDIRU67";	/* No set-cookie, Set-cookie found and left unchanged (passive),
						   Set-cookie Deleted, Set-Cookie Inserted, Set-cookie Rewritten,
						   Set-cookie Updated, unknown, unknown */

#define LOGCHAR(x) do { \
			if (tmplog < logline + MAX_SYSLOG_LEN - 1) { \
				*(tmplog++) = (x);                     \
			} else {                                       \
				goto out;                              \
			}                                              \
		} while(0)

/*
 * send a log for the session when we have enough info about it.
 * Will not log if the frontend has no log defined.
 */
void sess_log(struct session *s)
{
	char pn[INET6_ADDRSTRLEN];
	char sn[INET6_ADDRSTRLEN];
	struct proxy *fe = s->fe;
	struct proxy *be = s->be;
	struct proxy *prx_log;
	struct http_txn *txn = &s->txn;
	int tolog, level, err;
	char *uri;
	const char *svid;
	struct tm tm;
	int t_request;
	int hdr;
	int last_isspace = 1;
	char *tmplog;
	struct logformat_node *tmp;

	/* if we don't want to log normal traffic, return now */
	err = (s->flags & (SN_ERR_MASK | SN_REDISP)) ||
		(s->req->cons->conn_retries != be->conn_retries) ||
		((s->fe->mode == PR_MODE_HTTP) && txn->status >= 500);
	if (!err && (fe->options2 & PR_O2_NOLOGNORM))
		return;

	if (LIST_ISEMPTY(&fe->logsrvs))
		return;
	prx_log = fe;

	if (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn)) == AF_UNIX)
		snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);

	if (be->options2 & PR_O2_SRC_ADDR) {
	      if (addr_to_str(&s->req->cons->addr.from, sn, sizeof(sn)) == AF_UNIX)
		snprintf(sn, sizeof(sn), "unix:%d", s->listener->luid);
	}

	/* FIXME: let's limit ourselves to frontend logging for now. */
	tolog = fe->to_log;

	if (!(tolog & LW_SVID))
		svid = "-";
	else switch (s->target.type) {
	case TARG_TYPE_SERVER:
		svid = s->target.ptr.s->id;
		break;
	case TARG_TYPE_APPLET:
		svid = s->target.ptr.a->name;
		break;
	default:
		svid = "<NOSRV>";
		break;
	}

	t_request = -1;
	if (tv_isge(&s->logs.tv_request, &s->logs.tv_accept))
		t_request = tv_ms_elapsed(&s->logs.tv_accept, &s->logs.tv_request);

	level = LOG_INFO;
	if (err && (fe->options2 & PR_O2_LOGERRORS))
		level = LOG_ERR;

	/* fill logbuffer */

	tmplog = update_log_hdr(); /* update log header and skip it */

	list_for_each_entry(tmp, &fe->logformat, list) {
		char *src = NULL;
		switch (tmp->type) {

			case LOG_SEPARATOR:
				if (!last_isspace) {
					LOGCHAR(' ');
					last_isspace = 1;
					*tmplog = '\0';
				}
				break;

			case LOG_TEXT: // text
				src = tmp->arg;
				tmplog += strlcpy2(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline));
				if (tmplog > logline + MAX_SYSLOG_LEN - 2)
					goto out;
				last_isspace = 0;
				break;

			case LOG_CLIENTIP:  // %Ci
				src = (s->req->prod->addr.from.ss_family == AF_UNIX) ? "unix" : pn;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_CLIENTPORT:  // %Cp
				tmplog = ltoa_o((s->req->prod->addr.from.ss_family == AF_UNIX) ? s->listener->luid : get_host_port(&s->req->prod->addr.from),
				                tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_SOURCEIP:  // Bi
				src = (s->req->cons->addr.from.ss_family == AF_UNIX) ? "unix" : sn;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_SOURCEPORT:  // %Bp
				tmplog = ltoa_o((s->req->cons->addr.from.ss_family == AF_UNIX) ? s->listener->luid : get_host_port(&s->req->cons->addr.from),
				                tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_DATE: // %t
				get_localtime(s->logs.accept_date.tv_sec, &tm);
				tmplog = date2str_log(tmplog, &tm, &(s->logs.accept_date), MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_DATEGMT: // %T
				get_gmtime(s->logs.accept_date.tv_sec, &tm);
				tmplog = gmt2str_log(tmplog, &tm, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_MS: // %ms
				if ((MAX_SYSLOG_LEN - (tmplog - logline)) < 4) {
					tmplog = NULL;
					goto out;
				}
				tmplog = utoa_pad((unsigned int)s->logs.accept_date.tv_usec/1000,
						  tmplog, 4);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_FRONTEND: // %f
				src = fe->id;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_BACKEND: // %b
				src = be->id;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_SERVER: // %s
				src = (char *)svid;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TQ: // %Tq
				tmplog = ltoa_o(t_request, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TW: // %Tw
				tmplog = ltoa_o((s->logs.t_queue >= 0) ? s->logs.t_queue - t_request : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TC: // %Tc
				tmplog = ltoa_o((s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TR: // %Tr
				tmplog = ltoa_o((s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TT:  // %Tt
				if (!(tolog & LW_BYTES))
					*(tmplog++) = '+';
				tmplog = ltoa_o(s->logs.t_close, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_STATUS: // %st
				tmplog = ltoa_o(txn->status, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_BYTES: // %B
				if (!(tolog & LW_BYTES))
					*(tmplog++) = '+';
				tmplog = lltoa(s->logs.bytes_out, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_CCLIENT: // %cc
				src = txn->cli_cookie;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_CSERVER: // %cs
				src = txn->srv_cookie;
				tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_TERMSTATE: // %ts
				LOGCHAR(sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT]);
				LOGCHAR(sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT]);
				*tmplog = '\0';
				last_isspace = 0;
				break;

			case LOG_TERMSTATE_CK: // %tsc, same as TS with cookie state (for mode HTTP)
				LOGCHAR(sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT]);
				LOGCHAR(sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT]);
				LOGCHAR((be->options & PR_O_COOK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-');
				LOGCHAR((be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-');
				*tmplog = '\0';
				last_isspace = 0;
				break;

			case LOG_ACTCONN: // %ac
				tmplog = ltoa_o(actconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_FECONN:  // %fc
				tmplog = ltoa_o(fe->feconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_BECONN:  // %bc
				tmplog = ltoa_o(be->beconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_SRVCONN:  // %sc
				tmplog = ultoa_o(target_srv(&s->target) ? target_srv(&s->target)->cur_sess : 0, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_RETRIES:  // %rq
				if (s->flags & SN_REDISP)
					*(tmplog++) = '+';
				tmplog = ltoa_o((s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_SRVQUEUE: // %sq
				tmplog = ltoa_o(s->logs.srv_queue_size, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_BCKQUEUE:  // %bq
				tmplog = ltoa_o(s->logs.prx_queue_size, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
				if (!tmplog)
					goto out;
				last_isspace = 0;
				break;

			case LOG_HDRREQUEST: // %hr
				/* request header */
				if (fe->to_log & LW_REQHDR && txn->req.cap) {
					if (tmp->options & LOG_OPT_QUOTE)
						LOGCHAR('"');
					LOGCHAR('{');
					for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
						if (hdr)
							LOGCHAR('|');
						if (txn->req.cap[hdr] != NULL) {
							tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
									       '#', hdr_encode_map, txn->req.cap[hdr]);
							if (*tmplog != '\0')
								goto out;
						}
					}
					LOGCHAR('}');
					if (tmp->options & LOG_OPT_QUOTE)
						LOGCHAR('"');
					last_isspace = 0;
				}
				*tmplog = '\0';
				break;

			case LOG_HDRREQUESTLIST: // %hrl
				/* request header list */
				if (fe->to_log & LW_REQHDR && txn->req.cap) {
					for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
						if (hdr > 0)
							LOGCHAR(' ');
						if (tmp->options & LOG_OPT_QUOTE)
							LOGCHAR('"');
						if (txn->req.cap[hdr] != NULL) {
							tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
									       '#', hdr_encode_map, txn->req.cap[hdr]);
							if (*tmplog != '\0')
								goto out;

						} else if (!(tmp->options & LOG_OPT_QUOTE))
							LOGCHAR('-');
						if (tmp->options & LOG_OPT_QUOTE)
							LOGCHAR('"');
						*tmplog = '\0';
						last_isspace = 0;
					}
				}
				break;

			case LOG_HDRRESPONS: // %hs
				/* response header */
				if (fe->to_log & LW_RSPHDR &&
				    txn->rsp.cap) {
					if (tmp->options & LOG_OPT_QUOTE)
						LOGCHAR('"');
					LOGCHAR('{');
					for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
						if (hdr)
							LOGCHAR('|');
						if (txn->rsp.cap[hdr] != NULL) {
							tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
									       '#', hdr_encode_map, txn->rsp.cap[hdr]);
							if (*tmplog != '\0')
								goto out;
						}
					}
					LOGCHAR('}');
					last_isspace = 0;
					if (tmp->options & LOG_OPT_QUOTE)
						LOGCHAR('"');
				}
				*tmplog = '\0';
				break;

			case LOG_HDRRESPONSLIST: // %hsl
				/* response header list */
				if (fe->to_log & LW_RSPHDR && txn->rsp.cap) {
					for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
						if (hdr > 0)
							LOGCHAR(' ');
						if (tmp->options & LOG_OPT_QUOTE)
							LOGCHAR('"');
						if (txn->rsp.cap[hdr] != NULL) {
							tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
									       '#', hdr_encode_map, txn->rsp.cap[hdr]);
							if (*tmplog != '\0')
								goto out;
						} else if (!(tmp->options & LOG_OPT_QUOTE))
							LOGCHAR('-');
						if (tmp->options & LOG_OPT_QUOTE)
							LOGCHAR('"');
						*tmplog = '\0';
						last_isspace = 0;
					}
				}
				break;

			case LOG_REQ: // %r
				/* Request */
				if (tmp->options & LOG_OPT_QUOTE)
					LOGCHAR('"');
				uri = txn->uri ? txn->uri : "<BADREQ>";
				tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
						       '#', url_encode_map, uri);
				if (*tmplog != '\0')
					goto out;
				if (tmp->options & LOG_OPT_QUOTE)
					LOGCHAR('"');
				*tmplog = '\0';
				last_isspace = 0;
				break;
		}
	}

out:

	if (tmplog == NULL) // if previous error
		tmplog = logline + MAX_SYSLOG_LEN - 1;

	__send_log(prx_log, level, logline, tmplog - logline + 1);
	s->logs.logwait = 0;

}





/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
