From a850d03599e3f90ee16f78814c702eabae4416f2 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Wed, 25 Dec 2019 17:34:19 -0500 Subject: Insert MOTDs into the database --- database.h | 7 +++++++ litterbox.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/database.h b/database.h index 3d88757..fa0dc10 100644 --- a/database.h +++ b/database.h @@ -210,6 +210,13 @@ static inline int dbVersion(void) { static const char *InitSQL = SQL( BEGIN TRANSACTION; + CREATE TABLE motds ( + time DATETIME NOT NULL, + network TEXT NOT NULL, + motd TEXT NOT NULL, + UNIQUE (network, motd) + ); + CREATE TABLE contexts ( context INTEGER PRIMARY KEY, network TEXT NOT NULL, diff --git a/litterbox.c b/litterbox.c index 964a6ea..ff110d4 100644 --- a/litterbox.c +++ b/litterbox.c @@ -28,6 +28,7 @@ #include "database.h" static struct { + sqlite3_stmt *motd; sqlite3_stmt *context; sqlite3_stmt *topic; sqlite3_stmt *event; @@ -35,14 +36,11 @@ static struct { } insert; static void prepare(void) { - const char *CreateJoins = SQL( - CREATE TEMPORARY TABLE joins ( - nick TEXT NOT NULL, - channel TEXT NOT NULL, - UNIQUE (nick, channel) - ); + const char *InsertMOTD = SQL( + INSERT OR IGNORE INTO motds (time, network, motd) + VALUES (coalesce(datetime(:time), datetime('now')), :network, :motd); ); - dbExec(CreateJoins); + dbPersist(&insert.motd, InsertMOTD); const char *InsertContext = SQL( INSERT OR IGNORE INTO contexts (network, name, query) @@ -71,6 +69,15 @@ static void prepare(void) { ); dbPersist(&insert.event, InsertEvent); + const char *CreateJoins = SQL( + CREATE TEMPORARY TABLE joins ( + nick TEXT NOT NULL, + channel TEXT NOT NULL, + UNIQUE (nick, channel) + ); + ); + dbExec(CreateJoins); + const char *InsertEvents = SQL( INSERT INTO events (time, type, context, name, target, message) SELECT @@ -88,12 +95,19 @@ static void prepare(void) { } static void bindNetwork(const char *network) { + dbBindTextCopy(insert.motd, ":network", network); dbBindTextCopy(insert.context, ":network", network); dbBindTextCopy(insert.topic, ":network", network); dbBindTextCopy(insert.event, ":network", network); dbBindTextCopy(insert.events, ":network", network); } +static void insertMOTD(const char *time, const char *motd) { + dbBindText(insert.motd, ":time", time); + dbBindText(insert.motd, ":motd", motd); + dbRun(insert.motd); +} + static void insertContext(const char *context, bool query) { dbBindText(insert.context, ":context", context); dbBindInt(insert.context, ":query", query); @@ -310,6 +324,41 @@ static void handleReplyISupport(struct Message *msg) { } } +static struct { + char *buf; + size_t cap, len; +} motd; + +static void handleReplyMOTDStart(struct Message *msg) { + (void)msg; + motd.len = 0; + motd.cap = 80; + motd.buf = malloc(motd.cap); + if (!motd.buf) err(EX_OSERR, "malloc"); +} + +static void handleReplyMOTD(struct Message *msg) { + require(msg, false, 2); + char *line = msg->params[1]; + if (!strncmp(line, "- ", 2)) line += 2; + size_t len = strlen(line); + if (motd.len + len + 1 > motd.cap) { + motd.cap *= 2; + motd.buf = realloc(motd.buf, motd.cap); + if (!motd.buf) err(EX_OSERR, "realloc"); + } + memcpy(&motd.buf[motd.len], line, len); + motd.len += len; + motd.buf[motd.len++] = '\n'; +} + +static void handleReplyEndOfMOTD(struct Message *msg) { + motd.buf[motd.len - 1] = '\0'; + insertMOTD(msg->time, motd.buf); + free(motd.buf); + memset(&motd, 0, sizeof(motd)); +} + static void handlePrivmsg(struct Message *msg) { require(msg, true, 2); @@ -438,6 +487,9 @@ static const struct { { "331", true, handleReplyTopic }, { "332", true, handleReplyTopic }, { "353", true, handleReplyNames }, + { "372", false, handleReplyMOTD }, + { "375", false, handleReplyMOTDStart }, + { "376", true, handleReplyEndOfMOTD }, { "CAP", false, handleCap }, { "JOIN", true, handleJoin }, { "KICK", true, handleKick }, -- cgit 1.4.1