From 0bb22808b466fa049de0b13d2cb3b34facc42446 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Wed, 15 May 2019 21:53:29 +0100 Subject: Add custom command to let a client request a replay of however many seconds at any time. --- blabouncer.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 18 deletions(-) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index 0f70deb..3cf9877 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -431,6 +431,35 @@ int removechannel(struct channel *channels, char *name) { return 0; } +// Send the requested number of lines of replay log to the requested client +// 'sourcefd' is the client to send to, and replayseconds is the number of +// seconds of replay to replay. +// Returns 1 for success or 0 for failure. +int doreplay(int sourcefd, int replayseconds, int arr_clients[], int arr_authed[], SSL **arr_ssl, struct settings *settings) { + char outgoingmsg[MAXDATASIZE]; + + // Figure out how many lines to replay + int numlines = replaylines(replayseconds); + printf("Replay log lines: '%d'.\n", numlines); + + if (numlines < 0) { + printf("Error getting number of replay lines.\n"); + exit(1); + } + + // Replay those lines! + for (int i = 0; i < numlines; i++) { + if (!readreplayline(replayseconds, i, outgoingmsg)) { + printf("Error requesting replay line.\n"); + exit(1); + } + printf("Sending replay line: '%s'.\n", outgoingmsg); + sendtoclient(sourcefd, outgoingmsg, arr_clients, arr_authed, arr_ssl, settings); + } + + return 1; +} + // Figure out what to do with each CRLF-split IRC message (if anything) // by splitting out the different components by space character (ASCII 0x20). // @@ -776,24 +805,8 @@ int processircmessage(SSL *server_ssl, int *clientsockfd, char *str, int source, sendtoclient(sourcefd, outgoingmsg, arr_clients, arr_authed, arr_ssl, settings); } - // Figure out how many lines to replay - int numlines = replaylines(settings->replayseconds); - printf("Replay log lines: '%d'.\n", numlines); - - if (numlines < 0) { - printf("Error getting number of replay lines.\n"); - exit(1); - } - - // Relay those lines! - for (int i = 0; i < numlines; i++) { - if (!readreplayline(settings->replayseconds, i, outgoingmsg)) { - printf("Error requesting replay line.\n"); - exit(1); - } - printf("Sending replay line: '%s'.\n", outgoingmsg); - sendtoclient(sourcefd, outgoingmsg, arr_clients, arr_authed, arr_ssl, settings); - } + // Catch the client up with the default number of seconds of replay + doreplay(sourcefd, settings->replayseconds, arr_clients, arr_authed, arr_ssl, settings); return 1; } @@ -878,6 +891,31 @@ int processircmessage(SSL *server_ssl, int *clientsockfd, char *str, int source, return 1; } + // Custom BLABOUNCER command received + // Case insensitive comparisons here since clients won't be recognising and uppercasing these commands + if (strncasecmp(tokens[0], "BLABOUNCER", strlen(tokens[0])) == 0) { + // REPLAY received, send the requested number of seconds of replay to the client + if (strncasecmp(tokens[1], "REPLAY", strlen(tokens[1])) == 0) { + printf("Client REPLAY (custom blabouncer command) found and it is: %s with length %zd!\n", tokens[1], strlen(tokens[1])); + int replayseconds; + if ((replayseconds = strtol(tokens[2], NULL, 10)) == 0) { + printf("Invalid number of replay seconds provided by REPLAY. Telling client.\n"); + char outgoingmsg[MAXDATASIZE]; + if (!snprintf(outgoingmsg, MAXDATASIZE, "Invalid number of seconds of replay requested by REPLAY command.")) { + fprintf(stderr, "Error while preparing invalid REPLAY command response, exiting!\n"); + exit(1); + } + sendtoclient(sourcefd, outgoingmsg, arr_clients, arr_authed, arr_ssl, settings); + return 1; + } + + doreplay(sourcefd, replayseconds, arr_clients, arr_authed, arr_ssl, settings); + return 1; + } + + // If here then although BLABOUNCER command received, it wasn't recognised, so don't return + } + break; default: fprintf(stderr, "Unexpected raw IRC string source!\n"); -- cgit v1.2.3