summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2022-11-24 00:08:34 +0000
committerLuke Bratch <luke@bratch.co.uk>2022-11-24 00:08:34 +0000
commit2e665e03b6175b3f31f0ef1e058183417df1456e (patch)
tree32674c99ac25a3df5c166db89260c60e15764c10 /functions.c
parent680d8535a87be8aa0d5ef6432d1f87561ebfcb5f (diff)
Fix replaymode = "lastspoke" by using line numbers rather than time to calculate replay start point.
Introduce new function doreplaylastspoke() to achieve this, move doreplay() into replay.c as doreplaytime() and refactor common things into sanitisereplay().
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c132
1 files changed, 14 insertions, 118 deletions
diff --git a/functions.c b/functions.c
index 917f688..6d85d8e 100644
--- a/functions.c
+++ b/functions.c
@@ -873,110 +873,6 @@ int channelindex(struct channel *channels, int maxchannelcount, char *name) {
return -1;
}
-// Send the requested number of seconds worth of replay log lines to the requested client.
-// 'sourcefd' is the client to send to, and 'replayseconds' is the number of
-// seconds of replay log to replay.
-// Returns 1 for success or 0 for failure.
-int doreplay(int sourcefd, int replayseconds, struct client *clients, struct settings *settings, struct ircdstate *ircdstate, struct channel *channels) {
- char outgoingmsg[MAXDATASIZE];
-
- // Figure out how many lines to replay
- int numlines = replaylines(replayseconds, settings->basedir);
- debugprint(DEBUG_FULL, "Replay log lines: '%d'.\n", numlines);
-
- if (numlines < 0) {
- debugprint(DEBUG_CRIT, "Error getting number of replay lines.\n");
- return 0;
- } else if (numlines == 0) {
- snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :0 replay log lines found in the time requested, nothing to send.", ircdstate->ircnick);
- sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
- return 1;
- }
-
- // Announce the start
- snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Starting log replay....", ircdstate->ircnick);
- sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
-
- // Replay those lines!
- for (int i = 0; i < numlines; i++) {
- int ret = readreplayline(replayseconds, i, outgoingmsg, settings, ircdstate);
- if (ret == 0) {
- debugprint(DEBUG_CRIT, "Error requesting replay line.\n");
- return 0;
- } else if (ret == -1) {
- debugprint(DEBUG_FULL, "doreplay(): readreplayline() said to ignore replay line.\n");
- continue;
- }
-
- // Check if the replay line is a TOPIC, a JOIN, or a PART so we don't
- // replay those if we are not currently in the channel they are from
- // otherwise clients and state go a bit mad.
- // Never replay them if they are from us.
-
- // Copy to a temporary string
- char *strcopy = strdup(outgoingmsg);
- // Keep track of initial pointer for free()ing later
- char *strcopyPtr = strcopy;
-
- // Build array of each space-separated token
- char tokens[3][MAXDATASIZE];
- char *token;
-
- for (int j = 0; j < 3; j++) {
- // Try to split
- if ((token = strsep(&strcopy, " ")) == NULL) {
- debugprint(DEBUG_CRIT, "doreplay(): error splitting string on iteration '%d', returning!\n", j);
- return 0;
- }
- // Copy into the token array (strlen + 1 to get the NULL terminator)
- strncpy(tokens[j], token, strlen(token) + 1);
- }
-
- if (strncmp(tokens[1], "TOPIC", strlen("TOPIC")) == 0 ||
- strncmp(tokens[1], "JOIN", strlen("JOIN")) == 0 ||
- strncmp(tokens[1], "PART", strlen("PART")) == 0) {
- // Skip over colon if present in channel name
- int offset = 0;
- if (tokens[2][0] == ':') {
- offset = 1;
- }
-
- // To make sure it's not us
- extractnickfromprefix(tokens[0], 1);
-
- // Check if we're currently in this channel or if the log line is from us
- if (!inchannel(channels, ircdstate->maxchannelcount, tokens[2] + offset) ||
- ((strlen(tokens[0]) == strlen(ircdstate->ircnick)) && (strncmp(tokens[0], ircdstate->ircnick, strlen(tokens[0])) == 0))) {
- debugprint(DEBUG_FULL, "Not sending '%s' replay line '%s'.\n", tokens[1], outgoingmsg);
- free(strcopyPtr);
- continue;
- }
- }
-
- // Separate special check for if a NICK change is from us but it isn't our current nick
- if (strncmp(tokens[1], "NICK", strlen("NICK")) == 0) {
- extractnickfromprefix(tokens[0], 1);
-
- if ((strlen(tokens[0]) == strlen(ircdstate->ircnick)) && (strncmp(tokens[0], ircdstate->ircnick, strlen(tokens[0])) == 0)) {
- debugprint(DEBUG_FULL, "Not sending '%s' replay line '%s'.\n", tokens[1], outgoingmsg);
- free(strcopyPtr);
- continue;
- }
- }
-
- free(strcopyPtr);
-
- debugprint(DEBUG_FULL, "Sending replay line: '%s'.\n", outgoingmsg);
- sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
- }
-
- // Announce the end
- snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Log replay complete.", ircdstate->ircnick);
- sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
-
- return 1;
-}
-
// Send the auto replay to the requested client, where 'sourcefd' is the client
// to send to. The type of replay will depend on the user's settings.
// Returns 1 for success or 0 for failure.
@@ -989,9 +885,9 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings
// If replaymode = "time" then send whatever replayseconds is set to
if (!strncmp(settings->replaymode, "time", strlen("time"))) {
- debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"time\", calling doreplay() with '%d' seconds.\n", settings->replayseconds);
- if (!doreplay(sourcefd, settings->replayseconds, clients, settings, ircdstate, channels)) {
- debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n");
+ debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"time\", calling doreplaytime() with '%d' seconds.\n", settings->replayseconds);
+ if (!doreplaytime(sourcefd, settings->replayseconds, clients, settings, ircdstate, channels)) {
+ debugprint(DEBUG_SOME, "doautoreplay(): doreplaytime() returned 0, returning 0 to caller...\n");
return 0;
}
return 1;
@@ -999,15 +895,15 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings
// If replaymode = "lastspoke" then send whatever happened since the user's current nick last spoke
if (!strncmp(settings->replaymode, "lastspoke", strlen("lastspoke"))) {
- debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastspoke\".\n", settings->replayseconds);
- int secondsago = lastspokesecondsago(ircdstate->ircnick, settings->basedir);
- if (secondsago < 1) {
- debugprint(DEBUG_SOME, "doautoreplay(): lastspokesecondsago() returned < 1, returning 0 to caller...\n");
+ debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastspoke\", calling doreplaylastspoke().\n");
+ long linenumber = lastspokelinenumber(ircdstate->ircnick, settings->basedir);
+ if (linenumber < 1) {
+ debugprint(DEBUG_SOME, "doautoreplay(): lastspokelinenumber() returned < 1, returning 0 to caller...\n");
return 0;
}
- debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastspoke\", sending lines from '%d' seconds ago to sourcefd '%d'.\n", secondsago, sourcefd);
- if (!doreplay(sourcefd, secondsago, clients, settings, ircdstate, channels)) {
- debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n");
+ debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastspoke\", replaying from line '%ld' to sourcefd '%d'.\n", linenumber, sourcefd);
+ if (!doreplaylastspoke(sourcefd, linenumber, clients, settings, ircdstate, channels)) {
+ debugprint(DEBUG_SOME, "doautoreplay(): doreplaylastspoke() returned 0, returning 0 to caller...\n"); // CORRECT?
return 0;
}
return 1;
@@ -1016,8 +912,8 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings
// If replaymode = "noclients" and there is currently only one client connected, then send whatever happened since there were last no clients connected
if (!strncmp(settings->replaymode, "noclients", strlen("noclients")) && numclients(clients) == 1) {
debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"noclients\", sending '%d' seconds of replay.\n", time(NULL) - ircdstate->clientsnonetime);
- if (!doreplay(sourcefd, time(NULL) - ircdstate->clientsnonetime, clients, settings, ircdstate, channels)) {
- debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n");
+ if (!doreplaytime(sourcefd, time(NULL) - ircdstate->clientsnonetime, clients, settings, ircdstate, channels)) {
+ debugprint(DEBUG_SOME, "doautoreplay(): doreplaytime() returned 0, returning 0 to caller...\n");
return 0;
}
return 1;
@@ -1026,8 +922,8 @@ int doautoreplay(int sourcefd, struct client *clients, struct settings *settings
// If replaymode = "lastchange" then send whatever happened since the last client registration or disconnection
if (!strncmp(settings->replaymode, "lastchange", strlen("lastchange"))) {
debugprint(DEBUG_FULL, "doautoreplay(): replaymode = \"lastchange\", sending '%d' seconds of replay.\n", time(NULL) - ircdstate->clientchangetime);
- if (!doreplay(sourcefd, time(NULL) - ircdstate->clientchangetime, clients, settings, ircdstate, channels)) {
- debugprint(DEBUG_SOME, "doautoreplay(): doreplay() returned 0, returning 0 to caller...\n");
+ if (!doreplaytime(sourcefd, time(NULL) - ircdstate->clientchangetime, clients, settings, ircdstate, channels)) {
+ debugprint(DEBUG_SOME, "doautoreplay(): doreplaytime() returned 0, returning 0 to caller...\n");
return 0;
}
return 1;