diff options
author | Luke Bratch <luke@bratch.co.uk> | 2024-03-29 17:34:14 +0000 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2024-03-29 17:34:14 +0000 |
commit | 8f317a7182e8b61b42c1be83c4760098b1098c6d (patch) | |
tree | 00c599163a2650c4f49f0ed87638d3c1a8e38cfe | |
parent | bd7a7d2ce18babb041492762b3e55fdbad670d5c (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-- | README | 3 | ||||
-rw-r--r-- | message.c | 55 |
2 files changed, 58 insertions, 0 deletions
@@ -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". @@ -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); |