summaryrefslogtreecommitdiff
path: root/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'message.c')
-rw-r--r--message.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/message.c b/message.c
index 3e79605..8eceb4b 100644
--- a/message.c
+++ b/message.c
@@ -727,7 +727,7 @@ int processservermessage(SSL *server_ssl, char *str, struct client *clients, int
// Process an IRC message that came from a client.
// Return 1 if we processed it, or 0 if we didn't.
int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int sourcefd, struct ircdstate *ircdstate,
- struct channel *channels, struct settings *settings, char tokens[MAXTOKENS][MAXDATASIZE], int counter) {
+ struct channel *channels, struct settings *settings, char tokens[MAXTOKENS][MAXDATASIZE], int counter, struct clientcodes *clientcodes) {
// PASS received? User is trying to log in, check their password.
if (strncasecmp(tokens[0], "PASS", strlen(tokens[0])) == 0) {
if (checkpassword(tokens[1], settings)) {
@@ -751,7 +751,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
}
} else {
debugprint(DEBUG_SOME, "Password rejected, disconnecting fd %d.\n", sourcefd);
- disconnectclient(sourcefd, clients, ircdstate, settings);
+ disconnectclient(sourcefd, clients, ircdstate, settings, clientcodes);
// Alert other clients about the failed authentication
char alertmsg[MAXDATASIZE];
if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client with fd %d has failed to authenticate.", ircdstate->ircnick, sourcefd)) {
@@ -828,7 +828,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
// Tell the client to go away if we aren't registered with the real server yet as defined by the last greeting not being set yet
if (!strlen(ircdstate->greeting004)) {
sendtoclient(sourcefd, "Sorry, we aren't registered with a real IRC server yet.", clients, settings, 0);
- disconnectclient(sourcefd, clients, ircdstate, settings);
+ disconnectclient(sourcefd, clients, ircdstate, settings, clientcodes);
return 1;
}
@@ -865,6 +865,8 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REHASH\" (To reload settings from the configuration file, see README for which settings can be reloaded.)", ircdstate->ircnick);
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER CLIENTCODE [clientcode]\" (To set an identifier for the current client for auto replaying just what this client has missed.)", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER QUIT [quit message]\" (To quit blabouncer, optionally sending [quit message] to the server.)", ircdstate->ircnick);
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1039,7 +1041,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
// A client has QUIT, so disconnect (close) them and don't do anything else for now - TODO: Let another clients know with a NOTICE or something
if (strncasecmp(tokens[0], "QUIT", strlen(tokens[0])) == 0) {
debugprint(DEBUG_FULL, "Client QUIT found from fd %d and it is: %s with length %zd! Disconnecting that fd.\n", sourcefd, tokens[0], strlen(tokens[0]));
- disconnectclient(sourcefd, clients, ircdstate, settings);
+ disconnectclient(sourcefd, clients, ircdstate, settings, clientcodes);
return 1;
}
@@ -1160,7 +1162,7 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
char outgoingmsg[MAXDATASIZE];
debugprint(DEBUG_FULL, "Client BLABOUNCER found and it is: %s with length %zd!\n", tokens[1], strlen(tokens[1]));
// REPLAY received, send the requested length of replay time to the client
- if (strncasecmp(tokens[1], "REPLAY", strlen("REPLAY")) == 0) {
+ if (strncasecmp(tokens[1], "REPLAY", strlen("REPLAY")) == 0 && counter == 3) {
debugprint(DEBUG_FULL, "Client BLABOUNCER REPLAY (custom blabouncer command) found and it is: %s with length %zd!\n", tokens[1], strlen(tokens[1]));
// Split the request into days:hours:minutes:seconds
@@ -1283,6 +1285,51 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
}
return 1;
+ // CLIENTCODE received, set the provided string as the client code for handling auto replays for when this client code is next seen
+ } else if (strncasecmp(tokens[1], "CLIENTCODE", strlen("CLIENTCODE")) == 0 && counter == 3) {
+ debugprint(DEBUG_FULL, "Client BLABOUNCER CLIENTCODE found and it is: %s %s! Setting as this client's client code.\n", tokens[1], tokens[2]);
+
+ // Make sure replaymode = "perclient" is set
+ if (strcmp(settings->replaymode, "perclient")) {
+ debugprint(DEBUG_SOME, "CLIENTCODE requested but replaymode not set to \"perclient\".\n");
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :CLIENTCODE requested but replaymode not set to \"perclient\".", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ return 1;
+ }
+
+ // Make sure the client code length is good
+ if (strlen(tokens[2]) < 1 || strlen(tokens[2]) > CLIENTCODELEN - 1) {
+ debugprint(DEBUG_SOME, "Invalid CLIENTODE length.\n");
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Invalid CLIENTODE length. Must be 1 to %d characters.", ircdstate->ircnick, CLIENTCODELEN - 1);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ return 1;
+ }
+
+ // Register the client code (if it doesn't already exist)
+ int ret = addclientcode(sourcefd, tokens[2], clientcodes, clients);
+ if (ret == -1) {
+ // Something went wrong
+ debugprint(DEBUG_CRIT, "error: addclientcode() returned 0.\n");
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Problem registering client code.", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ return 1;
+ } else if (ret == 0) {
+ // If it did already exist, do a replay of everything since this client code last disconnected
+ int codetime = getclientcodetime(tokens[2], clientcodes);
+ if (!codetime) {
+ debugprint(DEBUG_CRIT, "Error finding last disconnect time of this client code!\n");
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Error finding last disconnect time of this client code!", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ return 1;
+ }
+ if (!doreplay(sourcefd, time(NULL) - codetime, clients, settings, ircdstate, channels)) {
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Unable to read replay log file!", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ return 1;
+ }
+ }
+
+ return 1;
// Unrecognised BLABOUNCER command received, send some help instructions
} else {
debugprint(DEBUG_SOME, "Client BLABOUNCER unrecognised command found and it is: %s with length %zd! Sending a help message.\n", tokens[1], strlen(tokens[1]));
@@ -1292,6 +1339,8 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REHASH\" (To reload settings from the configuration file, see README for which settings can be reloaded.)", ircdstate->ircnick);
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
+ snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER CLIENTCODE [clientcode]\" (To set an identifier for the current client for auto replaying just what this client has missed.)", ircdstate->ircnick);
+ sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER QUIT [quit message]\" (To quit blabouncer, optionally sending [quit message] to the server.)", ircdstate->ircnick);
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
return 1;