From 8f317a7182e8b61b42c1be83c4760098b1098c6d Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Fri, 29 Mar 2024 17:34:14 +0000 Subject: Implement BLABOUNCER commands LISTCLIENTS and DISCONNECT. BLABOUNCER LISTCLIENTS: List all connected clients and their authentication status. BLABOUNCER DISCONNECT [FD]: Disconnect a client with file descriptor number [FD] (see LISTCLIENTS output). --- message.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'message.c') diff --git a/message.c b/message.c index 3eb35bd..c45f56b 100644 --- a/message.c +++ b/message.c @@ -1003,6 +1003,10 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int 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 LISTCLIENTS\" (To list all connected clients and their authentication status.)", ircdstate->ircnick); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER DISCONNECT [FD]\" (To disconnect a client with file descriptor number [FD] (see LISTCLIENTS output).)", 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); snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER VERSION\" (To show the current blabouncer version.)", ircdstate->ircnick); @@ -1483,6 +1487,53 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int debugprint(DEBUG_SOME, "Client BLABOUNCER VERSION found and it is: %s with length %zd!\n", tokens[1], strlen(tokens[1])); snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :This is blabouncer version %s!", ircdstate->ircnick, VERSION); sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + return 1; + // LISTCLIENTS received, send list of connected clients and their authentication status + } else if (strncasecmp(tokens[1], "LISTCLIENTS", strlen("LISTCLIENTS")) == 0) { + debugprint(DEBUG_SOME, "Client BLABOUNCER LISTCLIENTS found and it is: %s with length %zd!\n", tokens[1], strlen(tokens[1])); + + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :There are %d blabouncer client(s) connected:", ircdstate->ircnick, numclients(clients)); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + + int clientcount = 0; + + // Loop through each client in clients struct... + for (int i = 0; i < MAXCLIENTS; i++) { + // ...and if they have a file descriptor... + if (clients[i].fd) { + // ... then tell the requesting client about them + clientcount++; + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :#%d: File descriptor: %d, authenticated: %d, IP: %s.", ircdstate->ircnick, clientcount, clients[i].fd, clients[i].authed, clients[i].remoteip); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + } + } + + return 1; + // DISCONNECT received, attempt to disconnect the client with the provided file descriptor number + } else if (strncasecmp(tokens[1], "DISCONNECT", strlen("DISCONNECT")) == 0 && counter == 3) { + debugprint(DEBUG_FULL, "Client BLABOUNCER DISCONNECT found and it is: %s %s!\n", tokens[1], tokens[2], tokens[2]); + + // Convert requested fd string to an integer, base 10 + int fdint = strtol(tokens[2], NULL, 10); + debugprint(DEBUG_FULL, "processclientmessage(): BLABOUNCER DISCONNECT attempting to disconnect fd %d.\n", fdint); + + // Try to find the requested client + int clientindex = arrindex(clients, fdint); + + // Give up if we can't find the requested client + if (clientindex < 0) { + debugprint(DEBUG_SOME, "processclientmessage(): warning: arrindex() returned %d trying to find the requested fd %d by BLABOUNCER DISCONNECT, returning.\n", clientindex, fdint); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :warning: couldn't find requested FD %d to disconnect.", ircdstate->ircnick, fdint); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + return 1; + } + + // Try to disconnect the client + debugprint(DEBUG_SOME, "processclientmessage(): BLABOUNCER DISCONNECT disconnecting client with fd %d, IP %s.\n", fdint, clients[clientindex].remoteip); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Disconnecting client with FD %d, IP %s.", ircdstate->ircnick, fdint, clients[clientindex].remoteip); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + disconnectclient(fdint, clients, ircdstate, settings, clientcodes); + return 1; // Unrecognised BLABOUNCER command received (or a BLABOUNCER HELP command), send some help instructions } else { @@ -1498,6 +1549,10 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int 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 LISTCLIENTS\" (To list all connected clients and their authentication status.)", ircdstate->ircnick); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER DISCONNECT [FD]\" (To disconnect a client with file descriptor number [FD] (see LISTCLIENTS output).)", 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); snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER VERSION\" (To show the current blabouncer version.)", ircdstate->ircnick); -- cgit v1.2.3