diff options
Diffstat (limited to 'blabouncer.c')
-rw-r--r-- | blabouncer.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/blabouncer.c b/blabouncer.c index 559e2b1..c4396f4 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -114,6 +114,7 @@ struct client { int fd; // Client socket fd - 0 means not connected, greater than 0 means connected and the value is the fd number (so we know which ones to try to read and send to) int authed; // Client authentication status - 0 means not authenticated, 1 means authenticated. SSL *ssl; // OpenSSL structures when using TLS, or faked by casting fd ints to SSL* if not. - TODO - Can we drop one of either "int fd" or "SSL *ssl" now? + int registered; // Whether the client has finished registering with the bouncer }; // Return index of requested client FD within the clients array. @@ -159,8 +160,8 @@ int sendtoclient(int fd, char *str, struct client *clients, struct settings *set } // Disconnect the client fd "fd" by close()ing it and remove -// it from the arr_clients array of clients. -// Also set its authentication status to 0. +// it from the array of clients. +// Also set its authentication and registration statuses to 0. int disconnectclient(int fd, struct client *clients) { printf("disconnectclient(): disconnecting client fd '%d'\n", fd); close(fd); // bye! @@ -170,6 +171,7 @@ int disconnectclient(int fd, struct client *clients) { printf("found and clearing fd %d from clients[%d]\n", fd, i); clients[i].fd = 0; clients[i].authed = 0; + clients[i].registered = 0; return 1; } } @@ -476,7 +478,12 @@ int removechannel(struct channel *channels, char *name) { if (strncmp(channels[i].name, name, strlen(name)) == 0) { // ..and NULL its name (0th character = '\0') channels[i].name[0] = '\0'; - printf("removechannel(): channel removed and topicwhen set to '%s'.\n", channels[i].topicwhen); + printf("removechannel(): channel '%s' removed and topicwhen set to '%s'.\n", name, channels[i].topicwhen); + // Finally clear all its users + for (int j = 0; j < MAXCHANUSERS; j++) { + channels[i].nicks[j][0] = '\0'; + } + printf("removechannel(): channel '%s' users cleared.\n", name); return 1; } } @@ -491,7 +498,7 @@ int removechannel(struct channel *channels, char *name) { // '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, struct client *clients, struct settings *settings) { +int doreplay(int sourcefd, int replayseconds, struct client *clients, struct settings *settings, struct ircdstrings *ircdstrings) { char outgoingmsg[MAXDATASIZE]; // Figure out how many lines to replay @@ -502,7 +509,7 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set printf("Error getting number of replay lines.\n"); exit(1); } else if (numlines == 0) { - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :0 replay log lines found in the time requested, nothing to send.", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :0 replay log lines found in the time requested, nothing to send.", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); return 1; } @@ -768,12 +775,19 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Was it us? if (strncmp(ircdstrings->nickuserhost, tokens[0], strlen(ircdstrings->nickuserhost)) == 0) { + // Make a copy of the old nickuserhost for updategreetings() below + char *nickuserhostcpy = strdup(ircdstrings->nickuserhost); // Update nickuserhost with the new :nick!user@host updatenickuserhost(ircdstrings->nickuserhost, tokens[2]); printf("Updated nickuserhost to '%s'.\n", ircdstrings->nickuserhost); - // Update ircnick + // Prepare to update ircnick and greetings strings + // Temporary copy of new nickuserhost char *prefixcopy = strdup(ircdstrings->nickuserhost); + // Get nick from it extractnickfromprefix(prefixcopy); + // Update greeting strings for relaying to new clients + updategreetings(ircdstrings->greeting001, ircdstrings->greeting002, ircdstrings->greeting003, ircdstrings->greeting004, ircdstrings->nickuserhost, nickuserhostcpy, tokens[2], ircdstrings->ircnick); + // Update our nick strcpy(ircdstrings->ircnick, prefixcopy); printf("Updated ircnick to '%s'.\n", ircdstrings->ircnick); } @@ -830,13 +844,13 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli sendtoclient(sourcefd, outgoingmsg, clients, settings); // Send our own greeting message - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Welcome to blabouncer!", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Welcome to blabouncer!", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Blabouncer commands are all prefixed with BLABOUNCER which you can usually send using \"/QUOTE BLABOUNCER\"", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Blabouncer commands are all prefixed with BLABOUNCER which you can usually send using \"/QUOTE BLABOUNCER\"", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Valid blabouncer commands are:", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Valid blabouncer commands are:", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REPLAY [seconds]\" (Where [seconds] is the number of seconds of replay log to replay.)", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REPLAY [seconds]\" (Where [seconds] is the number of seconds of replay log to replay.)", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); // Get the channel count so we can enumerate over all channels. @@ -917,9 +931,19 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli sendtoclient(sourcefd, outgoingmsg, clients, settings); } + // Set the client as registered + clients[arrindex(clients, sourcefd)].registered = 1; + // Catch the client up with the default number of seconds of replay - doreplay(sourcefd, settings->replayseconds, clients, settings); + doreplay(sourcefd, settings->replayseconds, clients, settings, ircdstrings); + + return 1; + } + // Pretty much ignore anything else the client says if it's not registered yet, + // as the first thing we want to hear is either PASS or USER + if (!clients[arrindex(clients, sourcefd)].registered) { + printf("Ignoring client command '%s' from sourcefd '%d' as not registered yet.\n", tokens[0], sourcefd); return 1; } @@ -1021,19 +1045,19 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli int replayseconds; if ((replayseconds = strtol(tokens[2], NULL, 10)) == 0) { printf("Invalid number of replay seconds provided by REPLAY. Telling client.\n"); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Invalid number of seconds of replay requested by REPLAY command.", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Invalid number of seconds of replay requested by REPLAY command.", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); return 1; } - doreplay(sourcefd, replayseconds, clients, settings); + doreplay(sourcefd, replayseconds, clients, settings, ircdstrings); return 1; // Unrecognised BLABOUNCER command received, send some help instructions } else { printf("Client BLABOUNCER unrecognised command found and it is: %s with length %zd! Sending a help message.\n", tokens[1], strlen(tokens[1])); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Unrecognised BLABOUNCER command received. Valid commands are:", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Unrecognised BLABOUNCER command received. Valid commands are:", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); - snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REPLAY [seconds]\" (Where [seconds] is the number of seconds of replay log to replay.)", settings->ircnick); + snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :\"BLABOUNCER REPLAY [seconds]\" (Where [seconds] is the number of seconds of replay log to replay.)", ircdstrings->ircnick); sendtoclient(sourcefd, outgoingmsg, clients, settings); return 1; } @@ -1186,10 +1210,11 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { // Set up clients structure struct client clients[MAXCLIENTS]; - // Set all the clients to be "not connected" and "not authenticated" + // Set all the clients to be "not connected", "not authenticated", and "not registered" for (int i = 0; i < MAXCLIENTS; i++) { clients[i].fd = 0; clients[i].authed = 0; + clients[i].registered = 0; } // Initialise OpenSSL (used for both client and server) |