From 5280e648d96fbcb20948f7470afdca8b38f80a44 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Tue, 21 May 2019 22:45:32 +0100 Subject: Support multiple nick prefixes in channels by storing/relaying server 005/RPL_ISUPPORT messages and implementing the start of IRCv3 CAP negotiations (multi-prefix only at the moment). --- TODO | 5 +- blabouncer.c | 158 ++++++++++++++++++++++++++++++++++++++++++++--------------- functions.c | 11 ++++- functions.h | 2 +- 4 files changed, 131 insertions(+), 45 deletions(-) diff --git a/TODO b/TODO index 04e385d..b5b645a 100644 --- a/TODO +++ b/TODO @@ -19,13 +19,10 @@ Can't update greeting if server changed our nick (e.g. nick protection), then we Maybe only do 433 handling if we're not registered yet? (Might be fixed by adding missing free() to fix memory leak in this commit - need to re-test.) -If ChanServ gives us +q upon and then +o upon JOINing a channel, we only see +o if we are connected to blabouncer. If (re)connecting, we see a strange ~@nick status. -Also don't seem to be able to set -q from blabouncer. - Support autojoining passworded channels. Test CTCP. Reconnect server if we get disconnected for some reason. -Do we need to ACK end of CAP requests for CAP multi-prefix? +Only do CAP multi-prefix negotiation with client if server approved it in the first place. diff --git a/blabouncer.c b/blabouncer.c index e839477..401b5fd 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -67,6 +67,9 @@ struct ircdstrings { char greeting002[MAXDATASIZE]; char greeting003[MAXDATASIZE]; char greeting004[MAXDATASIZE]; + char greeting005a[MAXDATASIZE]; + char greeting005b[MAXDATASIZE]; + char greeting005c[MAXDATASIZE]; char ircdname[MAXDATASIZE]; char nickuserhost[MAXDATASIZE]; char ircnick[MAXNICKLENGTH]; @@ -108,6 +111,7 @@ struct client { int pendingwhois; // Whether the client is waiting to hear back from a "WHOIS" command int pendingwhowas; // Whether the client is waiting to hear back from a "WHOWAS" command int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on. + int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER). }; // Return index of requested client FD within the clients array. @@ -126,7 +130,8 @@ int arrindex(struct client *clients, int clientfd) { } // Send whatever string to a specific client by providing the FD -int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings *settings) { +// If "bypass" == 1 then permit sending to client even if unauthenticated (for instance for a CAP LS response) +int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings *settings, int bypass) { // Copy to new string for passing to appendcrlf() to avoid overrun in appendcrlf() char str[MAXDATASIZE]; strcpy(str, strsrc); @@ -138,7 +143,7 @@ int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings * for (i = 0; i < MAXCLIENTS; i++) { if (clients[i].fd == fd) { // Found client in array, check authentication status - if (!clients[i].authed) { + if (!clients[i].authed && !bypass) { printf("sendtoclient(): skipping unauthenticated client with fd %d.\n", clients[i].fd); return 0; } @@ -282,6 +287,7 @@ int disconnectclient(int fd, struct client *clients, struct ircdstrings *ircdstr clients[i].pendingwhois = 0; clients[i].pendingwhowas = 0; clients[i].pendingnames = 0; + clients[i].pendingcap = 0; if (settings->clienttls) { // Finish up with OpenSSL if using client TLS SSL_free(clients[i].ssl); @@ -486,13 +492,13 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set exit(1); } else if (numlines == 0) { snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :0 replay log lines found in the time requested, nothing to send.", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); return 1; } // Announce the start snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Starting log replay....", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // Replay those lines! for (int i = 0; i < numlines; i++) { @@ -548,12 +554,12 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set free(strcopyPtr); printf("Sending replay line: '%s'.\n", outgoingmsg); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); } // Announce the end snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Log replay complete.", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); return 1; } @@ -682,7 +688,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Prefix received? TODO - Care about what the prefix is - what if it's a different server/network/whatever? if (tokens[0][0] == ':') { printf("Prefix found: '%s'! Next token is '%s', length %zd.\n", tokens[0], tokens[1], strlen(tokens[1])); - // Greetings 001 through to 004, store in ircdstrings array for resending when clients connect + // Greetings 001 through to 005, store in ircdstrings array for resending when clients connect // Also store our nick!user@host from greeting 001 // Also store the real IRCd's name from greeting 004 if (strncmp(tokens[1], "001", strlen(tokens[1])) == 0) { @@ -731,6 +737,24 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli joinautochannels(server_ssl, clients, settings); free(strcopyPtr); return 1; + } else if (strncmp(tokens[1], "005", strlen(tokens[1])) == 0) { + printf("Found greeting 005 (%s), storing in ircdstrings struct.\n", str); + // Find an empty greeting005 string in ircdstrings and store in there... + if (!ircdstrings->greeting005a[0]) { + strncpy(ircdstrings->greeting005a, str, strlen(str)); + ircdstrings->greeting005a[strlen(str)] = '\0'; + } else if (!ircdstrings->greeting005b[0]) { + strncpy(ircdstrings->greeting005b, str, strlen(str)); + ircdstrings->greeting005b[strlen(str)] = '\0'; + } else if (!ircdstrings->greeting005c[0]) { + strncpy(ircdstrings->greeting005c, str, strlen(str)); + ircdstrings->greeting005c[strlen(str)] = '\0'; + } else { + // ...or if they are all fill, discard - TODO - Support more than three greeting005 strings! + printf("Already stored three greeting 005 strings, discarding this one.\n"); + } + free(strcopyPtr); + return 1; } // Server JOIN received? Add to our local channel array if it's us, or record the user in the channel if it's not us. @@ -836,7 +860,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingnames > 0) { printf("Sending 353 RPL_NAMREPLY for channel '%s' to client with fd '%d' who was pending %d RPL_NAMREPLYs.\n", tokens[4], clients[i].fd, clients[i].pendingnames); - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); } } } @@ -859,7 +883,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli printf("Server 366 received for an existing channel, sending to all clients who were pending RPL_NAMREPLYs and decrementing their pendingnames count.\n"); for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingnames > 0) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And decrement their pendingnames count printf("Decrementing pendingnames due 366 RPL_ENDOFNAMES to for channel '%s' to client with fd '%d' who was pending %d RPL_NAMREPLYs.\n", tokens[3], clients[i].fd, clients[i].pendingnames); clients[i].pendingnames--; @@ -957,7 +981,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // 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); + updategreetings(ircdstrings->greeting001, ircdstrings->greeting002, ircdstrings->greeting003, ircdstrings->greeting004, ircdstrings->greeting005a, ircdstrings->greeting005b, ircdstrings->greeting005c, ircdstrings->nickuserhost, nickuserhostcpy, tokens[2], ircdstrings->ircnick); // Update our nick strcpy(ircdstrings->ircnick, prefixcopy); printf("Updated ircnick to '%s'.\n", ircdstrings->ircnick); @@ -1019,7 +1043,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingchannelmode == 1) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag clients[i].pendingchannelmode = 0; } @@ -1036,7 +1060,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingban == 1) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag clients[i].pendingban = 0; } @@ -1053,7 +1077,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingwho == 1 && clients[i].fd) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag if it's 315 (RPL_ENDOFWHO) if (strncmp(tokens[1], "315", strlen(tokens[1])) == 0) { clients[i].pendingwho = 0; @@ -1072,7 +1096,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendinglist == 1 && clients[i].fd) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag if it's 323 (RPL_LISTEND) if (strncmp(tokens[1], "323", strlen(tokens[1])) == 0) { clients[i].pendinglist = 0; @@ -1098,7 +1122,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingwhois == 1 && clients[i].fd) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag if it's 318 RPL_ENDOFWHOIS if (strncmp(tokens[1], "318", strlen(tokens[1])) == 0) { clients[i].pendingwhois = 0; @@ -1119,7 +1143,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingwhowas == 1 && clients[i].fd) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // And clear the pending flag if it's 369 RPL_ENDOFWHOWAS if (strncmp(tokens[1], "369", strlen(tokens[1])) == 0) { clients[i].pendingwhowas = 0; @@ -1140,7 +1164,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingwhois == 1 || clients[i].pendingwhowas == 1) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // Note that we were pending this waspending = 1; } @@ -1166,7 +1190,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli // Relay to all pending clients for (int i = 0; i < MAXCLIENTS; i++) { if (clients[i].pendingwhois == 1) { - sendtoclient(clients[i].fd, str, clients, settings); + sendtoclient(clients[i].fd, str, clients, settings, 0); // Note that we were pending this waspending = 1; } @@ -1264,6 +1288,41 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli return 1; } + // CAP received? Clients can send CAP before PASS so we have to deal with this even if they are not authenticated yet. + if (strncasecmp(tokens[0], "CAP", strlen(tokens[0])) == 0) { + // Get the real IRC server name from greeting001 + // They are now pending CAP negotiation + clients[arrindex(clients, sourcefd)].pendingcap = 1; + char outgoingmsg[MAXDATASIZE]; + // If client is requesting CAP list, send it... + if (strncasecmp(tokens[1], "LS", strlen(tokens[1])) == 0) { + if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s CAP * LS :multi-prefix", ircdstrings->ircdname)) { + fprintf(stderr, "Error while preparing CAP LS response!\n"); + exit(1); + } + // ...even if unauthenticated + sendtoclient(sourcefd, outgoingmsg, clients, settings, 1); + free(strcopyPtr); + return 1; + // If client is requesting a CAP... + } else if (strncasecmp(tokens[1], "REQ", strlen(tokens[1])) == 0) { + // ...and it is "multi-prefix", send it + if (strncasecmp(tokens[2], ":multi-prefix", strlen(tokens[2])) == 0) { + if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s CAP %s ACK :multi-prefix ", ircdstrings->ircdname, ircdstrings->ircnick)) { + fprintf(stderr, "Error while preparing CAP ACK response!\n"); + exit(1); + } + // ...even if unauthenticated + sendtoclient(sourcefd, outgoingmsg, clients, settings, 1); + free(strcopyPtr); + return 1; + } + // If client is finishing CAP negotiation then mark them as so + } else if (strncasecmp(tokens[1], "END", strlen(tokens[1])) == 0) { + clients[arrindex(clients, sourcefd)].pendingcap = -1; + } + } + // We're past PASS in the list of possible commands, so ignore // anything else the client says if they are not authenticated yet. if (!clients[arrindex(clients, sourcefd)].authed) { @@ -1272,37 +1331,54 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli return 1; } - // USER received? If so, assume this is a new client connecting and catch them on up on the state - if (strncasecmp(tokens[0], "USER", strlen(tokens[0])) == 0) { + // USER received and not pending CAP negotiation during registration? + // Or client has just finished negotiating CAP (pendingcap = -1)? + // If so, assume this is a new client connecting and catch them on up on the state + if ((strncasecmp(tokens[0], "USER", strlen(tokens[0])) == 0 && clients[arrindex(clients, sourcefd)].pendingcap == 0) || clients[arrindex(clients, sourcefd)].pendingcap == -1) { // Somewhere to store the several strings we will need to build and send char outgoingmsg[MAXDATASIZE]; // String to send to client + // If registering then they must no longer be pending CAP negotiation + clients[arrindex(clients, sourcefd)].pendingcap = 0; + // Tell the client to go away if we aren't registered with the real server yet as defined by the last greeting not being set yet if (!strlen(ircdstrings->greeting004)) { - sendtoclient(sourcefd, "Sorry, we aren't registered with a real IRC server yet.", clients, settings); + sendtoclient(sourcefd, "Sorry, we aren't registered with a real IRC server yet.", clients, settings, 0); disconnectclient(sourcefd, clients, ircdstrings, settings); return 1; } - // Send IRC greeting strings (001/RPL_WELCOME, 002/RPL_YOURHOST, 003/RPL_CREATED, 004/RPL_MYINFO) to client + // Send IRC greeting strings (001/RPL_WELCOME, 002/RPL_YOURHOST, 003/RPL_CREATED, 004/RPL_MYINFO, 005/RPL_ISUPPORT) to client snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting001); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting002); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting003); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting004); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + if (ircdstrings->greeting005a[0]) { + snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting005a); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + } + if (ircdstrings->greeting005b[0]) { + snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting005b); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + } + if (ircdstrings->greeting005c[0]) { + snprintf(outgoingmsg, MAXDATASIZE, "%s", ircdstrings->greeting005c); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); + } // Send our own greeting message snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Welcome to blabouncer!", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); 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); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Valid blabouncer commands are:", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); 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); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // Get the channel count so we can enumerate over all channels. // Storing separately so we can skip over blank channels. @@ -1326,7 +1402,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli fprintf(stderr, "Error while preparing USER just connected, channel JOIN responses!\n"); exit(1); } - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // Send topic (or lack thereof) to client // If there isn't one set (we guess this if topic timestamp is 0), send 331 RPL_NOTOPIC @@ -1337,7 +1413,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli exit(1); } // ..and send it to the client - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // If there is one set, send 332 RPL_TOPIC and 333 RPL_TOPICWHOTIME } else { // Prepare the topic message... @@ -1346,7 +1422,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli exit(1); } // ..and send it to the client - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // Next prepare the topic who/when message... if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s 333 %s %s %s %s", ircdstrings->ircdname, ircdstrings->ircnick, channels[i].name, channels[i].topicwho, channels[i].topicwhen)) { @@ -1354,7 +1430,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli exit(1); } // ..and send it to the client - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); } // Get the latest RPL_NAMREPLY for this channel to relay to the client when it arrives @@ -1368,7 +1444,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli fprintf(stderr, "Error while preparing USER just connected, MODE response!\n"); exit(1); } - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // Set the client as registered clients[arrindex(clients, sourcefd)].registered = 1; @@ -1397,7 +1473,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli fprintf(stderr, "Error while preparing PONG response!\n"); exit(1); } - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); // We processed something so return true free(strcopyPtr); @@ -1554,7 +1630,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli 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.", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); free(strcopyPtr); return 1; } @@ -1566,9 +1642,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli } 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:", ircdstrings->ircnick); - sendtoclient(sourcefd, outgoingmsg, clients, settings); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); 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); + sendtoclient(sourcefd, outgoingmsg, clients, settings, 0); free(strcopyPtr); return 1; } @@ -1736,6 +1812,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { clients[i].pendingwhois = 0; clients[i].pendingwhowas = 0; clients[i].pendingnames = 0; + clients[i].pendingcap = 0; } // Initialise OpenSSL (used for both client and server) @@ -1772,6 +1849,9 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { ircdstrings.greeting002[0] = '\0'; ircdstrings.greeting003[0] = '\0'; ircdstrings.greeting004[0] = '\0'; + ircdstrings.greeting005a[0] = '\0'; + ircdstrings.greeting005b[0] = '\0'; + ircdstrings.greeting005c[0] = '\0'; ircdstrings.ircdname[0] = '\0'; ircdstrings.nickuserhost[0] = '\0'; ircdstrings.ircnick[0] = '\0'; diff --git a/functions.c b/functions.c index bc4680d..94c653e 100644 --- a/functions.c +++ b/functions.c @@ -232,7 +232,7 @@ void updatenickuserhost(char *nickuserhost, char *nick) { } // Update existing greeting strings with a new nickuserhost and new nick -void updategreetings(char *greeting001, char *greeting002, char *greeting003, char *greeting004, char *newnickuserhost, char *oldnickuserhost, char *newnick, char *oldnick) { +void updategreetings(char *greeting001, char *greeting002, char *greeting003, char *greeting004, char *greeting005a, char *greeting005b, char *greeting005c, char *newnickuserhost, char *oldnickuserhost, char *newnick, char *oldnick) { printf("updategreetings(): updating greetings with new nickuserhost '%s' and nick '%s'.\n", newnickuserhost, newnick); // nickuserhost and greeting001's final component first @@ -278,4 +278,13 @@ void updategreetings(char *greeting001, char *greeting002, char *greeting003, ch updategreetingnick(greeting002, "002", newnickcpy, oldnick); updategreetingnick(greeting003, "003", newnickcpy, oldnick); updategreetingnick(greeting004, "004", newnickcpy, oldnick); + if (greeting005a[0]) { + updategreetingnick(greeting005a, "005", newnickcpy, oldnick); + } + if (greeting005b[0]) { + updategreetingnick(greeting005b, "005", newnickcpy, oldnick); + } + if (greeting005c[0]) { + updategreetingnick(greeting005c, "005", newnickcpy, oldnick); + } } diff --git a/functions.h b/functions.h index 2877bc5..fe1bee8 100644 --- a/functions.h +++ b/functions.h @@ -40,6 +40,6 @@ void extractnickfromprefix(char *string); void updatenickuserhost(char *nickuserhost, char *nick); // Update an existing 001 greeting with a new nickuserhost -void updategreetings(char *greeting001, char *greeting002, char *greeting003, char *greeting004, char *newnickuserhost, char *oldnickuserhost, char *newnick, char *oldnick); +void updategreetings(char *greeting001, char *greeting002, char *greeting003, char *greeting004, char *greeting005a, char *greeting005b, char *greeting005c, char *newnickuserhost, char *oldnickuserhost, char *newnick, char *oldnick); #endif -- cgit v1.2.3