summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2024-03-29 17:34:14 +0000
committerLuke Bratch <luke@bratch.co.uk>2024-03-29 17:34:14 +0000
commit8f317a7182e8b61b42c1be83c4760098b1098c6d (patch)
tree00c599163a2650c4f49f0ed87638d3c1a8e38cfe
parentbd7a7d2ce18babb041492762b3e55fdbad670d5c (diff)
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).
-rw-r--r--README3
-rw-r--r--message.c55
2 files changed, 58 insertions, 0 deletions
diff --git a/README b/README
index 0aae39f..7381b49 100644
--- a/README
+++ b/README
@@ -44,6 +44,9 @@ Once connected to blabouncer with an IRC client, you can use the following speci
"BLABOUNCER REHASH" (To reload settings from the configuration file, see above for details.)
"BLABOUNCER CLIENTCODE [clientcode]" (To set an identifier for the current client for auto replaying just
what this client has missed.)
+"BLABOUNCER LISTCLIENTS" (To list all connected clients and their authentication status.)
+"BLABOUNCER DISCONNECT [FD]" (To disconnect a client with file descriptor number [FD] (see LISTCLIENTS
+output).)
"BLABOUNCER VERSION" (To show the current blabouncer version.)
Blabouncer commands are all prefixed with BLABOUNCER which you can usually send using "/QUOTE BLABOUNCER".
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);
@@ -1484,6 +1488,53 @@ int processclientmessage(SSL *server_ssl, char *str, struct client *clients, int
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 {
// Debug and NOTICE an unrecognised command error unless the command was "HELP"
@@ -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);