From 00ca1b50bdf84edd5386ffbb16656f7b456cfbdb Mon Sep 17 00:00:00 2001
From: Thomas Vigouroux <tomvig38@gmail.com>
Date: Thu, 7 Oct 2021 16:16:02 +0200
Subject: [PATCH] Allow customizing the timestamp format

---
 src/bip.c      | 33 +++++++++++++++++++++++++--------
 src/conf.y     |  8 +++++++-
 src/defaults.h |  4 +++-
 src/irc.h      |  9 ++++++++-
 src/lex.l      |  3 ++-
 src/log.c      |  4 ++--
 6 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/src/bip.c b/src/bip.c
index cbce24b..3caf6b9 100644
--- a/src/bip.c
+++ b/src/bip.c
@@ -625,12 +625,22 @@ static int get_tuple_nvalue(list_t *tuple_l, int lex)
 	return -1;
 }
 
+enum BLTimestamp lex_backlog_timestamp(char * tdata) {
+	if (strcmp(tdata, "time") == 0) {
+		return BLTSTime;
+	} else if (strcmp(tdata, "datetime") == 0) {
+		return BLTSDateTime;
+	} else {
+		return BLTSNone;
+	}
+}
+
 struct historical_directives {
 	int always_backlog;
 	int backlog;
 	int bl_msg_only;
 	int backlog_lines;
-	int backlog_no_timestamp;
+	enum BLTimestamp backlog_timestamp;
 	int blreset_on_talk;
 };
 
@@ -658,7 +668,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
 		u->always_backlog = DEFAULT_ALWAYS_BACKLOG;
 		u->bl_msg_only = DEFAULT_BL_MSG_ONLY;
 		u->backlog_lines = DEFAULT_BACKLOG_LINES;
-		u->backlog_no_timestamp = DEFAULT_BACKLOG_NO_TIMESTAMP;
+		u->backlog_timestamp = DEFAULT_BACKLOG_TIMESTAMP;
 		u->blreset_on_talk = DEFAULT_BLRESET_ON_TALK;
 		u->blreset_connection = DEFAULT_BLRESET_CONNECTION;
 		u->bip_use_notice = DEFAULT_BIP_USE_NOTICE;
@@ -668,7 +678,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
 	u->always_backlog = hds->always_backlog;
 	u->bl_msg_only = hds->bl_msg_only;
 	u->backlog_lines = hds->backlog_lines;
-	u->backlog_no_timestamp = hds->backlog_no_timestamp;
+	u->backlog_timestamp = hds->backlog_timestamp;
 	u->blreset_on_talk = hds->blreset_on_talk;
 
 	while ((t = list_remove_first(data))) {
@@ -706,7 +716,10 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
 			u->backlog_lines = t->ndata;
 			break;
 		case LEX_BACKLOG_NO_TIMESTAMP:
-			u->backlog_no_timestamp = t->ndata;
+			u->backlog_timestamp = t->ndata ? BLTSNone : BLTSTime;
+			break;
+		case LEX_BACKLOG_TIMESTAMP:
+			u->backlog_timestamp = lex_backlog_timestamp(t->pdata);
 			break;
 		case LEX_BLRESET_ON_TALK:
 			u->blreset_on_talk = t->ndata;
@@ -929,7 +942,7 @@ int fireup(bip_t *bip, FILE *conf)
 	SET_HV(hds.backlog, BACKLOG);
 	SET_HV(hds.bl_msg_only, BL_MSG_ONLY);
 	SET_HV(hds.backlog_lines, BACKLOG_LINES);
-	SET_HV(hds.backlog_no_timestamp, BACKLOG_NO_TIMESTAMP);
+	SET_HV(hds.backlog_timestamp, BACKLOG_TIMESTAMP);
 	SET_HV(hds.blreset_on_talk, BLRESET_ON_TALK);
 #undef SET_HV
 
@@ -1010,7 +1023,10 @@ int fireup(bip_t *bip, FILE *conf)
 			hds.backlog_lines = t->ndata;
 			break;
 		case LEX_BACKLOG_NO_TIMESTAMP:
-			hds.backlog_no_timestamp = t->ndata;
+			hds.backlog_timestamp = t->ndata ? BLTSNone : BLTSTime;
+			break;
+		case LEX_BACKLOG_TIMESTAMP:
+			hds.backlog_timestamp = lex_backlog_timestamp(t->pdata);
 			break;
 		case LEX_BLRESET_ON_TALK:
 			hds.blreset_on_talk = t->ndata;
@@ -1352,9 +1368,10 @@ noroom:
 		   STRORNULL(u->default_nick), STRORNULL(u->default_username),
 		   STRORNULL(u->default_realname));
 	if (u->backlog) {
-		bip_notify(ic, "Backlog enabled, lines: %d, no timestamp: %s,"
+		bip_notify(ic, "Backlog enabled, lines: %d, timestamp: %s,"
 			"  messages only: %s", u->backlog_lines,
-			bool2text(u->backlog_no_timestamp),
+			u->backlog_timestamp == BLTSNone ? "none" :
+				(u->backlog_timestamp == BLTSTime ? "time" : "datetime"),
 			bool2text(u->bl_msg_only));
 		bip_notify(ic, "always backlog: %s, reset on talk: %s",
 			bool2text(u->always_backlog),
diff --git a/src/conf.y b/src/conf.y
index 29ef504..3cf56cb 100644
--- a/src/conf.y
+++ b/src/conf.y
@@ -68,7 +68,7 @@ struct tuple *tuple_l_new(int type, void *p)
 
 %}
 
-%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_SSL_CLIENT_CERTFILE  LEX_CIPHERS LEX_CSS_CIPHERS LEX_DEFAULT_CIPHERS LEX_DH_PARAM LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_WRITE_OIDENTD LEX_OIDENTD_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_BLRESET_CONNECTION LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER
+%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_SSL_CLIENT_CERTFILE  LEX_CIPHERS LEX_CSS_CIPHERS LEX_DEFAULT_CIPHERS LEX_DH_PARAM LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_TIMESTAMP LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_WRITE_OIDENTD LEX_OIDENTD_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_BLRESET_CONNECTION LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER
 
 %union {
 	int number;
@@ -113,6 +113,9 @@ command:
            | LEX_BACKLOG_LINES LEX_EQ LEX_INT {
 	           $$ = tuple_i_new(LEX_BACKLOG_LINES, $3);
 		  }
+           | LEX_BACKLOG_TIMESTAMP LEX_EQ LEX_STRING {
+	       $$ = tuple_s_new(LEX_BACKLOG_TIMESTAMP, $3);
+	       }
            | LEX_BACKLOG_NO_TIMESTAMP LEX_EQ LEX_BOOL {
 	       $$ = tuple_i_new(LEX_BACKLOG_NO_TIMESTAMP, $3);
 	       }
@@ -168,6 +171,9 @@ usr_command:
            | LEX_BACKLOG_LINES LEX_EQ LEX_INT {
 	           $$ = tuple_i_new(LEX_BACKLOG_LINES, $3);
 		  }
+           | LEX_BACKLOG_TIMESTAMP LEX_EQ LEX_STRING {
+	       $$ = tuple_s_new(LEX_BACKLOG_TIMESTAMP, $3);
+	       }
            | LEX_BACKLOG_NO_TIMESTAMP LEX_EQ LEX_BOOL {
 	       $$ = tuple_i_new(LEX_BACKLOG_NO_TIMESTAMP, $3);
 	       }
diff --git a/src/defaults.h b/src/defaults.h
index 126dca9..eaf915d 100644
--- a/src/defaults.h
+++ b/src/defaults.h
@@ -14,11 +14,13 @@
 #ifndef DEFAULTS_H
 #define DEFAULTS_H
 
+#include "irc.h"
+
 #define DEFAULT_BACKLOG 1
 #define DEFAULT_ALWAYS_BACKLOG 0
 #define DEFAULT_BL_MSG_ONLY 0
 #define DEFAULT_BACKLOG_LINES 10
-#define DEFAULT_BACKLOG_NO_TIMESTAMP 0
+#define DEFAULT_BACKLOG_TIMESTAMP BLTSTime
 #define DEFAULT_BLRESET_ON_TALK 0
 #define DEFAULT_BLRESET_CONNECTION 0
 #define DEFAULT_LOG 1
diff --git a/src/irc.h b/src/irc.h
index 7969072..9320b9b 100644
--- a/src/irc.h
+++ b/src/irc.h
@@ -54,6 +54,12 @@ struct channel {
 #define IRC_TYPE_LOGING_CLIENT (2)
 #define IRC_TYPE_TRUST_CLIENT (3)
 
+enum BLTimestamp {
+	BLTSNone = 0,
+	BLTSTime,
+	BLTSDateTime,
+};
+
 struct bipuser {
 	/** client connection static data **/
 
@@ -74,10 +80,11 @@ struct bipuser {
 	int backlog_lines;
 	int always_backlog:1;
 	int bl_msg_only:1;
-	int backlog_no_timestamp:1;
 	int blreset_on_talk:1;
 	int blreset_connection:1;
 
+	enum BLTimestamp backlog_timestamp;
+
 #ifdef HAVE_LIBSSL
 	int ssl_check_mode;
 	char *ssl_check_store;
diff --git a/src/lex.l b/src/lex.l
index 45db3e5..80e68d9 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -90,7 +90,8 @@ list_t *parse_conf(FILE *file, int *err)
 "log_root"		{ return LEX_LOG_ROOT; }
 "log_format"		{ return LEX_LOG_FORMAT; }
 "backlog_lines"		{ return LEX_BACKLOG_LINES; }
-"backlog_no_timestamp"	{ return LEX_BACKLOG_NO_TIMESTAMP; }
+"backlog_timestamp"		{ return LEX_BACKLOG_TIMESTAMP; }
+"backlog_no_timestamp"		{ return LEX_BACKLOG_NO_TIMESTAMP; }
 "backlog"		{ return LEX_BACKLOG; }
 "backlog_always"	{ return LEX_ALWAYS_BACKLOG; }
 "backlog_msg_only"	{ return LEX_BL_MSG_ONLY; }
diff --git a/src/log.c b/src/log.c
index 9fbe526..c6f04d9 100644
--- a/src/log.c
+++ b/src/log.c
@@ -853,7 +853,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
 	if (!p || !p[0] || !p[1])
 		return _log_wrap(dest, buf);
 	p++;
-	sots = p;
+	sots = logdata->user->backlog_timestamp == BLTSDateTime ? buf : p;
 	p = strchr(p, ' ');
 	if (!p || !p[0] || !p[1])
 		return _log_wrap(dest, buf);
@@ -937,7 +937,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
 		strcpy(p, PMSG_ARROW);
 		p += strlen(PMSG_ARROW);
 	}
-	if (logdata->user->backlog_no_timestamp == 0) {
+	if (logdata->user->backlog_timestamp != BLTSNone) {
 		memcpy(p, sots, lots);
 		p += lots;
 		*p++ = '>';
-- 
2.33.0

