From: Egor Date: Thu, 5 May 2022 18:31:09 +0000 (+0300) Subject: move message/response formatting to ircfmt.c X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=bf699d3b863b8f5098e3ba7447663696afbc347b;p=patchyircd.git move message/response formatting to ircfmt.c --- diff --git a/irc.c b/irc.c index cec4431..e40ece9 100644 --- a/irc.c +++ b/irc.c @@ -1,4 +1,5 @@ #include "irc.h" +#include "ircfmt.h" struct dynarr databuf; @@ -7,8 +8,7 @@ struct trie_node *channel_map = NULL; const char *hostname = "irc.patchysicp.xyz"; #define is_registered(cl) ((cl)->nick != 0) -static void err_notregistered(struct client_data *client) { - copy_strf(&databuf, ":%s 451 * :You have not registered\n", hostname); +void sendbuf(struct client_data *client) { send_log(client->FD, databuf.buf, databuf.len, 0); } int processPacket(struct client_data *client) { @@ -86,8 +86,8 @@ int processPacket(struct client_data *client) { if(strcmp(command, "PING") == 0) { if (!args[0]) // FIXME: error message return 0; - copy_strf(&databuf, ":%s PONG %s :%s\n", hostname, hostname, args[0]); - send_log(client->FD, databuf.buf, databuf.len, 0); + msg_pong(args[0]); + sendbuf(client); } else if(strcmp(command, "CAP") == 0) { if (!args[0]) // FIXME: error message return 0; @@ -98,18 +98,18 @@ int processPacket(struct client_data *client) { if (strcmp(args[0], "LS") == 0) { // at least one client hangs if it doesn't see a known extension copy_strf(&databuf, ":%s CAP * LS :multi-prefix\n", hostname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); if (client->regstate != REG_CAPEND || !client->nick || !client->username) client->regstate = REG_CAPLS; } else if (strcmp(args[0], "LIST") == 0) { copy_strf(&databuf, ":%s CAP * LIST :\n", hostname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if (strcmp(args[0], "REQ") == 0) { if (!args[1]) // FIXME: error message return 0; copy_strf(&databuf, ":%s CAP * NAK :%s\n", hostname, args[1]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if (strcmp(args[0], "END") == 0) { if (client->regstate == REG_CAPLS && client->nick && client->username) newUser(client); @@ -122,9 +122,6 @@ int processPacket(struct client_data *client) { if (!args[0]) // FIXME: error message return 0; setNick(client, args[0]); - if (client->nick) - printf("USER SET NICKNAME %s\n", client->nick); - fflush(stdout); if (client->regstate != REG_CAPLS && client->nick && client->username) newUser(client); } else if(strcmp(command, "USER") == 0) { @@ -153,7 +150,7 @@ int processPacket(struct client_data *client) { sendMOTD(client); } else if(strcmp(command, "JOIN") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (!args[0]) // FIXME: error message return 0; if (!strcmp(args[0], "0")) { @@ -172,7 +169,7 @@ int processPacket(struct client_data *client) { channel_join(client, args[0], NULL); } else if(strcmp(command, "PART") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (!args[0]) // FIXME: error message return 0; char *p = strchr(args[0], ','); // TODO: multiple channels @@ -184,7 +181,7 @@ int processPacket(struct client_data *client) { channel_part(client, chan, args[1] ? args[1] : ""); } else if(strcmp(command, "TOPIC") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (!args[0]) // FIXME: error message return 0; struct channel *chan = findChannel(args[0]); @@ -208,47 +205,47 @@ int processPacket(struct client_data *client) { if (!chan->topic_who) abort(); chan->topic_when = time(NULL); } - copy_strf(&databuf, ":%s!%s@%s TOPIC %s :%s\n", client->nick, client->username, client->hostname, chan->name, args[1]); + msg_topic(client, chan); struct trie_find *f = NULL; if (trie_findfirst(&f, &chan->members) == 1) do { struct client_data *cl = f->n->value; - send_log(cl->FD, databuf.buf, databuf.len, 0); + sendbuf(cl); } while (trie_findnext(&f) == 1); } } else if(strcmp(command, "PRIVMSG") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc < 2) // FIXME: error message return 0; - copy_strf(&databuf, ":%s!%s@%s PRIVMSG %s :%s\n", client->nick, client->username, client->hostname, args[0], args[1]); + (command[0] == 'P' ? msg_privmsg : msg_notice)(client, args[0], args[1]); if (args[0][0] == '#' || args[0][0] == '&') { - sendall_log(client->FD, databuf.buf, databuf.len, 0); + sendall_log(client->FD, databuf.buf, databuf.len, 0); // TODO: limit visibility } else { struct client_data *cl = findClient(args[0]); if (!cl) { copy_strf(&databuf, ":%s 401 %s %s :No such nick/channel\n", hostname, client->nick, args[0]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } else { - send_log(cl->FD, databuf.buf, databuf.len, 0); + sendbuf(cl); if (cl->away) { copy_strf(&databuf, ":%s 301 %s %s :%s\n", hostname, client->nick, cl->nick, cl->away); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } } } // Start GitHub Copilot - this shit actually be copy pasting my code lmao } else if(strcmp(command, "QUIT") == 0) { - copy_strf(&databuf, ":%s!%s@%s QUIT :%s\n", client->nick, client->username, client->hostname, args[0] ? args[0] : "Client Quit"); - sendall_log(client->FD, databuf.buf, databuf.len, 0); + msg_quit(client, "Quit: ", args[0] ? args[0] : ""); + sendall_log(client->FD, databuf.buf, databuf.len, 0); // TODO: limit visibility killConnection(client, true); return 1; } else if(strcmp(command, "PONG") == 0) { // Do nothing } else if(strcmp(command, "MODE") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc == 0) // FIXME: error message return 0; char *nick = args[0]; @@ -257,7 +254,7 @@ int processPacket(struct client_data *client) { struct client_data *cl = findClient(nick); if (!cl) { copy_strf(&databuf, ":%s 401 %s %s :No such nick/channel\n", hostname, client->nick, nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } copy_strf(&databuf, ":%s 221 %s +", hostname, client->nick); @@ -267,22 +264,22 @@ int processPacket(struct client_data *client) { if (cl->umode & UMODE_REGISTERED) append_str(&databuf, "r"); if (cl->umode & UMODE_WALLOPS) append_str(&databuf, "w"); append_str(&databuf, "\r\n"); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else { copy_strf(&databuf, ":%s 324 %s %s +nt\n", hostname, client->nick, nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } } else { // set mode if (*nick != '#' && *nick != '&') { struct client_data *cl = findClient(nick); if (!cl) { copy_strf(&databuf, ":%s 401 %s %s :No such nick/channel\n", hostname, client->nick, nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } if (client->FD != cl->FD) { copy_strf(&databuf, ":%s 502 %s :Can't change mode for other users\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } int off; @@ -302,11 +299,11 @@ int processPacket(struct client_data *client) { copy_strf(&databuf, ":%s MODE %s +i\n", hostname, client->nick); cl->umode |= UMODE_INVISIBLE; } - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); break; default: copy_strf(&databuf, ":%s 501 %s :Unknown MODE flag\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } p++; } @@ -314,17 +311,17 @@ int processPacket(struct client_data *client) { if (argc == 2) { // Type A channel modes if (!strcmp(args[1], "+b")) { copy_strf(&databuf, ":%s 368 %s %s :End of channel ban list\n", hostname, client->nick, args[1]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } if (!strcmp(args[1], "+e")) { copy_strf(&databuf, ":%s 349 %s %s :End of channel exception list\n", hostname, client->nick, args[1]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } if (!strcmp(args[1], "+I")) { copy_strf(&databuf, ":%s 347 %s %s :End of Channel Invite Exception List\n", hostname, client->nick, args[1]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return 0; } } @@ -333,23 +330,23 @@ int processPacket(struct client_data *client) { } } else if(strcmp(command, "LIST") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; copy_strf(&databuf, ":%s 321 %s Channel :Users Name\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); struct trie_find *f = NULL; if (trie_findfirst(&f, &channel_map) == 1) do { struct channel *chan = f->n->value; copy_strf(&databuf, ":%s 322 %s %s %u :%s\n", hostname, client->nick, chan->name, chan->member_count, chan->topic ? chan->topic : ""); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } while(trie_findnext(&f) == 1); copy_strf(&databuf, ":%s 323 %s :End of /LIST\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if(strcmp(command, "NAMES") == 0) { // TODO: actual channel support if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc == 0) // FIXME: error message return 0; struct trie_find *f = NULL; @@ -357,13 +354,13 @@ int processPacket(struct client_data *client) { do { struct client_data *cl = f->n->value; copy_strf(&databuf, ":%s 353 %s = %s :%s\n", hostname, client->nick, args[0], cl->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } while(trie_findnext(&f) == 1); copy_strf(&databuf, ":%s 366 %s :End of /NAMES list\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if(strcmp(command, "USERHOST") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc == 0) // FIXME: error message return 0; copy_strf(&databuf, ":%s 302 %s", hostname, client->nick); @@ -383,10 +380,10 @@ int processPacket(struct client_data *client) { } append_str(&databuf, "\r\n"); } - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if(strcmp(command, "WHO") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc == 0) // FIXME: error message return 0; struct client_data *cl = findClient(args[0]); @@ -395,89 +392,83 @@ int processPacket(struct client_data *client) { copy_strf(&databuf, ":%s 352 %s * %s %s %s %s %s%s :1 %s\n", hostname, client->nick, cl->username, cl->hostname, hostname, cl->nick, cl->away ? "G" : "H", cl->umode&UMODE_OPER ? "*" : "", cl->realname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } copy_strf(&databuf, ":%s 315 %s %s :End of WHO list\n", hostname, client->nick, args[0]); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if(strcmp(command, "WHOIS") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (argc == 0) // FIXME: error message return 0; char *nick = args[1] ? args[1] : args[0]; struct client_data *cl = findClient(nick); if (cl) { copy_strf(&databuf, ":%s 311 %s %s %s %s * :%s\n", hostname, client->nick, cl->nick, cl->username, cl->hostname, cl->realname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 312 %s %s %s :Patchy server\n", hostname, client->nick, cl->nick, hostname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); if (cl->umode & UMODE_OPER) { copy_strf(&databuf, ":%s 313 %s %s :is an IRC operator\n", hostname, client->nick, cl->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } if (cl->away) { copy_strf(&databuf, ":%s 301 %s %s :%s\n", hostname, client->nick, cl->nick, cl->away); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } copy_strf(&databuf, ":%s 318 %s %s :End of /WHOIS list\n", hostname, client->nick, cl->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else { copy_strf(&databuf, ":%s 401 %s %s :No such nick/channel\n", hostname, client->nick, nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } } else if(strcmp(command, "AWAY") == 0) { if (!is_registered(client)) - return err_notregistered(client), 0; + return err_notregistered(client), sendbuf(client), 0; if (args[0]) { free(client->away); client->away = mystrdup(args[0]); if (!client->away) abort(); copy_strf(&databuf, ":%s 306 %s :You have been marked as being away\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else { free(client->away); client->away = NULL; copy_strf(&databuf, ":%s 305 %s :You are no longer marked as being away\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } } else { unknown: // Inform user of error copy_strf(&databuf, ":%s 421 %s :Unknown command %s\n", hostname, client->nick, command); - send_log(client->FD, databuf.buf, databuf.len, 0); - fflush(stdout); + sendbuf(client); } return 0; } void newUser(struct client_data *client) { client->regstate = REG_CAPEND; - copy_strf(&databuf, ":%s 001 %s :Welcome to the Patchy Network, %s\n", hostname, client->nick, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); - copy_strf(&databuf, ":%s 002 %s :Your host is PatchyIRCD, running version 0.0.1\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); - copy_strf(&databuf, ":%s 003 %s :This server was created when I had cybersex with your mother.\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); - copy_strf(&databuf, ":%s 004 %s PatchyIRCD 0.0.1 i nt\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); - copy_strf(&databuf, ":%s 005 %s CASEMAPPING=rfc1459 NICKLEN=%u CHANTYPES=#& PREFIX=(ov)@+ :are supported by this server\n", hostname, client->nick, MAX_NICKLEN-1); - send_log(client->FD, databuf.buf, databuf.len, 0); + rpl_welcome(client), sendbuf(client); + rpl_yourhost(client), sendbuf(client); + rpl_created(client), sendbuf(client); + rpl_myinfo(client), sendbuf(client); + rpl_isupport(client), sendbuf(client); copy_strf(&databuf, ":%s 251 %s :This server exists\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 252 %s :Jannies don't exist\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); sendMOTD(client); } void sendMOTD(struct client_data *client) { copy_strf(&databuf, ":%s 375 %s :PatchySICP /MOTD\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 372 %s :Welcome to Montreal!\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 372 %s :You are retarded and I will have cybersex with your mom.\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 376 %s :/MOTD over\n", hostname, client->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } void setNick(struct client_data *client, char* nickname) { @@ -485,14 +476,14 @@ void setNick(struct client_data *client, char* nickname) { if (strlen(nickname) >= MAX_NICKLEN || nickname[0] == '\0') { copy_strf(&databuf, ":%s 432 * %s :Erroneous nickname\n", hostname, nickname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return; } const char *forbidden = " ,*?!@$:#&."; while (*forbidden) if (strchr(nickname, *forbidden++)) { copy_strf(&databuf, ":%s 432 * %s :Erroneous nickname\n", hostname, nickname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return; } @@ -503,15 +494,15 @@ void setNick(struct client_data *client, char* nickname) { if (trie_get(&client_map, key)) { // Nickname is already taken copy_strf(&databuf, ":%s 443 * %s :Nickname is already in use\n", hostname, nickname); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); return; } // Update nickname if(client->nick) { copy_strf(&databuf, ":%s!%s@%s NICK %s\n", client->nick, client->username, client->hostname, nickname); - send_log(client->FD, databuf.buf, databuf.len, 0); - sendall_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); + sendall_log(client->FD, databuf.buf, databuf.len, 0); // TODO: limit visibility trie_set(&client_map, client->key, NULL, NULL); free(client->nick); free(client->key); @@ -532,12 +523,12 @@ void channel_sendtopic(struct client_data *client, struct channel *chan, int joi { if (chan->topic) { copy_strf(&databuf, ":%s 332 %s %s :%s\n", hostname, client->nick, chan->name, chan->topic); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); copy_strf(&databuf, ":%s 333 %s %s %s %u\n", hostname, client->nick, chan->name, chan->topic_who, (unsigned)chan->topic_when); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } else if (!joining) { copy_strf(&databuf, ":%s 331 %s %s :No topic is set\n", hostname, client->nick, chan->name); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } } void channel_join(struct client_data *client, const char *channel, const char *chankey) @@ -580,12 +571,12 @@ void channel_join(struct client_data *client, const char *channel, const char *c abort(); chan->member_count++; // send JOIN to everyone - copy_strf(&databuf, ":%s!%s@%s JOIN :%s\n", client->nick, client->username, client->hostname, chan->name); + msg_join(client, chan); struct trie_find *f = NULL; if (trie_findfirst(&f, &chan->members) == 1) do { struct client_data *cl = f->n->value; - send_log(cl->FD, databuf.buf, databuf.len, 0); + sendbuf(cl); } while(trie_findnext(&f) == 1); // send topic channel_sendtopic(client, chan, 1); @@ -601,23 +592,20 @@ void channel_join(struct client_data *client, const char *channel, const char *c else prefix = ""; copy_strf(&databuf, ":%s 353 %s = %s :%s%s\n", hostname, client->nick, chan->name, prefix, cl->nick); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } while(trie_findnext(&f) == 1); copy_strf(&databuf, ":%s 366 %s %s :End of /NAMES list\n", hostname, client->nick, chan->name); - send_log(client->FD, databuf.buf, databuf.len, 0); + sendbuf(client); } void channel_part(struct client_data *client, struct channel *chan, const char *reason) { if (reason) { - if (*reason) - copy_strf(&databuf, ":%s!%s@%s PART %s :%s\n", client->nick, client->username, client->hostname, chan->name, reason); - else - copy_strf(&databuf, ":%s!%s@%s PART %s\n", client->nick, client->username, client->hostname, chan->name); + msg_part(client, chan, *reason ? reason : NULL); struct trie_find *f = NULL; if (trie_findfirst(&f, &chan->members) == 1) do { struct client_data *cl = f->n->value; - send_log(cl->FD, databuf.buf, databuf.len, 0); + sendbuf(cl); } while (trie_findnext(&f) == 1); } trie_set(&client->channels, chan->key, NULL, NULL); diff --git a/ircfmt.c b/ircfmt.c new file mode 100644 index 0000000..14b5c86 --- /dev/null +++ b/ircfmt.c @@ -0,0 +1,228 @@ +#include "ircfmt.h" +extern struct dynarr databuf; +extern const char *hostname; +void msg_nick(struct client_data *src, const char *newnick) +{ + copy_strf(&databuf, ":%s!%s@%s NICK %s\r\n", + src->nick, src->username, src->hostname, + newnick); +} +#if 0 +void msg_ping(const char *token) +{ + copy_strf(&databuf, ":%s PING :%s\r\n", hostname, token); +} +#endif +void msg_pong(const char *token) +{ + copy_strf(&databuf, ":%s PONG %s :%s\r\n", hostname, hostname, token); +} +void msg_quit(struct client_data *src, const char *prefix, const char *reason) +{ + copy_strf(&databuf, ":%s!%s@%s QUIT :%s%s\r\n", + src->nick, src->username, src->hostname, prefix, reason); +} +void msg_error(const char *reason) +{ + copy_strf(&databuf, ":%s ERROR :%s\r\n", hostname, reason); +} +void msg_join(struct client_data *src, struct channel *chan) +{ + copy_strf(&databuf, ":%s!%s@%s JOIN %s\r\n", + src->nick, src->username, src->hostname, chan->name); +} +void msg_part(struct client_data *src, struct channel *chan, const char *reason) +{ + if (reason) + copy_strf(&databuf, ":%s!%s@%s PART %s :%s\r\n", + src->nick, src->username, src->hostname, chan->name, reason); + else + copy_strf(&databuf, ":%s!%s@%s PART %s\r\n", + src->nick, src->username, src->hostname, chan->name); +} +void msg_topic(struct client_data *src, struct channel *chan) +{ + copy_strf(&databuf, ":%s!%s@%s TOPIC %s :%s\r\n", + src->nick, src->username, src->hostname, + chan->name, chan->topic ? chan->topic : ""); +} +#if 0 +void msg_invite(struct client_data *src, struct client_data *dst, struct channel *chan) +{ + copy_strf(&databuf, ":%s!%s@%s INVITE %s %s\r\n", + src->nick, src->username, src->hostname, dst->nick, chan->name); +} +void msg_kick(struct client_data *src, struct client_data *who, struct channel *chan, const char *reason) +{ + if (reason) + copy_strf(&databuf, ":%s!%s@%s KICK %s %s :%s\r\n", + src->nick, src->username, src->hostname, chan->name, who->nick, reason); + else + copy_strf(&databuf, ":%s!%s@%s KICK %s %s\r\n", + src->nick, src->username, src->hostname, chan->name, who->nick); +} +#endif +void msg_privmsg(struct client_data *src, const char *dst, const char *msg) +{ + copy_strf(&databuf, ":%s!%s@%s PRIVMSG %s :%s\r\n", + src->nick, src->username, src->hostname, dst, msg); +} +void msg_notice(struct client_data *src, const char *dst, const char *msg) +{ + copy_strf(&databuf, ":%s!%s@%s NOTICE %s :%s\r\n", + src->nick, src->username, src->hostname, dst, msg); +} +#if 0 +void msg_kill(struct client_data *src, struct client_data *dst, const char *reason) +{ + copy_strf(&databuf, ":%s!%s@%s KILL %s :%s\r\n", + src->nick, src->username, src->hostname, dst->nick, msg); +} +void msg_wallops(struct client_data *src, const char *msg) +{ + copy_strf(&databuf, ":%s!%s@%s WALLOPS :%s\r\n", + src->nick, src->username, src->hostname, msg); +} +#endif +void rpl_welcome(struct client_data *client) // 001 +{ + copy_strf(&databuf, ":%s 001 %s :Welcome to the Patchy Network, %s\r\n", hostname, client->nick, client->nick); +} +void rpl_yourhost(struct client_data *client) // 002 +{ + copy_strf(&databuf, ":%s 002 %s :Your host is PatchyIRCD, running version 0.0.1\r\n", hostname, client->nick); +} +void rpl_created(struct client_data *client) // 003 +{ + copy_strf(&databuf, ":%s 003 %s :This server was created when I had cybersex with your mother.\n", hostname, client->nick); +} +void rpl_myinfo(struct client_data *client) // 004 +{ + copy_strf(&databuf, ":%s 004 %s PatchyIRCD 0.0.1 i nt\n", hostname, client->nick); +} +void rpl_isupport(struct client_data *client) // 005 +{ + copy_strf(&databuf, ":%s 005 %s CASEMAPPING=rfc1459 NICKLEN=%u CHANTYPES=#& PREFIX=(ov)@+ :are supported by this server\n", hostname, client->nick, MAX_NICKLEN-1); +} +// 010 RPL_BOUNC +// 221 RPL_UMODEIS +// 251 RPL_LUSERCLIENT +// 252 RPL_LUSEROP +// 253 RPL_LUSERUNKNOWN +// 254 RPL_LUSERCHANNELS +// 255 RPL_LUSERME +// 256 RPL_ADMINME +// 257 RPL_ADMINLOC1 +// 258 RPL_ADMINLOC2 +// 259 RPL_ADMINEMAIL +// 263 RPL_TRYAGAIN +// 265 RPL_LOCALUSERS +// 266 RPL_GLOBALUSERS +// 276 RPL_WHOISCERTFP +// 300 RPL_NONE +// 301 RPL_AWAY +// 302 RPL_USERHOST +// 305 RPL_UNAWAY +// 306 RPL_NOWAWAY +// 352 RPL_WHOREPLY +// 315 RPL_ENDOFWHO +// 307 RPL_WHOISREGNICK +// 311 RPL_WHOISUSER +// 312 RPL_WHOISSERVER +// 313 RPL_WHOISOPERATOR +// 314 RPL_WHOWASUSER +// 317 RPL_WHOISIDLE +// 318 RPL_ENDOFWHOIS +// 319 RPL_WHOISCHANNELS +// 320 RPL_WHOISSPECIAL +// 321 RPL_LISTSTART +// 322 RPL_LIST +// 323 RPL_LISTEND +// 324 RPL_CHANNELMODEIS +// 329 RPL_CREATIONTIME +// 330 RPL_WHOISACCOUNT +// 331 RPL_NOTOPIC +// 332 RPL_TOPIC +// 333 RPL_TOPICWHOTIME +// 336 RPL_INVITELIST +// 337 RPL_ENDOFINVITELIST +// 338 RPL_WHOISACTUALLY +// 341 RPL_INVITING +// 346 RPL_INVEXLIST +// 347 RPL_ENDOFINVEXLIST +// 348 RPL_EXCEPTLIST +// 349 RPL_ENDOFEXCEPTLIST +// 351 RPL_VERSION +// 353 RPL_NAMREPLY +// 366 RPL_ENDOFNAMES +// 364 RPL_LINKS +// 365 RPL_ENDOFLINKS +// 367 RPL_BANLIST +// 368 RPL_ENDOFBANLIST +// 369 RPL_ENDOFWHOWAS +// 371 RPL_INFO +// 374 RPL_ENDOFINFO +// 375 RPL_MOTDSTART +// 372 RPL_MOTD +// 376 RPL_ENDOFMOTD +// 378 RPL_WHOISHOST +// 379 RPL_WHOISMODES +// 381 RPL_YOUREOPER +// 382 RPL_REHASHING +// 391 RPL_TIME +// 400 ERR_UNKNOWNERROR +// 401 ERR_NOSUCHNICK +// 402 ERR_NOSUCHSERVER +// 403 ERR_NOSUCHCHANNEL +// 404 ERR_CANNOTSENDTOCHAN +// 405 ERR_TOOMANYCHANNELS +// 406 ERR_WASSNOSUCHNICK +// 409 ERR_NOORIGIN +// 417 ERR_INPUTTOOLONG +// 421 ERR_UNKNOWNCOMMAND +// 422 ERR_NOMOTD +// 432 ERR_ERRONEUSNICKNAME +// 433 ERR_NICKNAMEINUSE +// 441 ERR_USERNOTINCHANNEL +// 442 ERR_NOTONCHANNEL +// 443 ERR_USERONCHANNEL +void err_notregistered(struct client_data *client) // 451 +{ + (void)client; + copy_strf(&databuf, ":%s 451 * :You have not registered\r\n", hostname); +} +// 461 ERR_NEEDMOREPARAMS +// 462 ERR_ALREADYREGISTERED +// 464 ERR_PASWDMISMATCH +// 465 ERR_YOUREBANNEDCREEP +// 471 ERR_CHANNELISFULL +// 472 ERR_UNKNOWNMODE +// 473 ERR_INVITEONLYCHAN +// 474 ERR_BANNEDFROMCHAN +// 475 ERR_BADCHANNELKEY +// 476 ERR_BADCHANMASK +// 481 ERR_NOPRIVILEGES +// 482 ERR_CHANOPRIVSNEEDED +// 483 ERR_CANTKILLSERVER +// 491 ERR_NOOPERHOST +// 501 ERR_UMODEUNKNOWNFLAG +// 502 ERR_USERSDONTMATCH +// 524 ERR_HELPNOTFOUND +// 525 ERR_INVALIDKEY +// 670 RPL_STARTTLS +// 671 RPL_WHOISSECURE +// 691 ERR_STARTTLS +// 696 ERR_INVALIDMODEPARAM +// 704 RPL_HELPSTART +// 705 RPL_HELPTXT +// 706 RPL_ENDOFHELP +// 723 ERR_NOPRIVS +// 900 RPL_LOGGEDIN +// 901 RPL_LOGGEDOUT +// 902 ERR_NICKLOCKED +// 903 RPL_SASLSUCCESS +// 904 ERR_SASLFAIL +// 905 ERR_SASLTOOLONG +// 906 ERR_SASLABORTED +// 907 ERR_SASLALREADY +// 908 RPL_SASLMECHS diff --git a/ircfmt.h b/ircfmt.h new file mode 100644 index 0000000..a9bd157 --- /dev/null +++ b/ircfmt.h @@ -0,0 +1,141 @@ +#ifndef IRCFMT_H_ +#define IRCFMT_H_ +#include "irc.h" +void msg_nick(struct client_data *src, const char *newnick); +void msg_ping(const char *token); +void msg_pong(const char *token); +void msg_quit(struct client_data *src, const char *prefix, const char *reason); +void msg_error(const char *reason); +void msg_join(struct client_data *src, struct channel *chan); +void msg_part(struct client_data *src, struct channel *chan, const char *reason); +void msg_topic(struct client_data *src, struct channel *chan); +void msg_invite(struct client_data *src, struct client_data *dst, struct channel *chan); +void msg_kick(struct client_data *src, struct client_data *who, struct channel *chan, const char *reason); +void msg_privmsg(struct client_data *src, const char *dst, const char *msg); +void msg_notice(struct client_data *src, const char *dst, const char *msg); +void msg_kill(struct client_data *src, struct client_data *dst, const char *reason); +void msg_wallops(struct client_data *src, const char *msg); +void rpl_welcome(struct client_data *client); // 001 +void rpl_yourhost(struct client_data *client); // 002 +void rpl_created(struct client_data *client); // 003 +void rpl_myinfo(struct client_data *client); // 004 +void rpl_isupport(struct client_data *client); // 005 +// 010 RPL_BOUNC +// 221 RPL_UMODEIS +// 251 RPL_LUSERCLIENT +// 252 RPL_LUSEROP +// 253 RPL_LUSERUNKNOWN +// 254 RPL_LUSERCHANNELS +// 255 RPL_LUSERME +// 256 RPL_ADMINME +// 257 RPL_ADMINLOC1 +// 258 RPL_ADMINLOC2 +// 259 RPL_ADMINEMAIL +// 263 RPL_TRYAGAIN +// 265 RPL_LOCALUSERS +// 266 RPL_GLOBALUSERS +// 276 RPL_WHOISCERTFP +// 300 RPL_NONE +// 301 RPL_AWAY +// 302 RPL_USERHOST +// 305 RPL_UNAWAY +// 306 RPL_NOWAWAY +// 352 RPL_WHOREPLY +// 315 RPL_ENDOFWHO +// 307 RPL_WHOISREGNICK +// 311 RPL_WHOISUSER +// 312 RPL_WHOISSERVER +// 313 RPL_WHOISOPERATOR +// 314 RPL_WHOWASUSER +// 317 RPL_WHOISIDLE +// 318 RPL_ENDOFWHOIS +// 319 RPL_WHOISCHANNELS +// 320 RPL_WHOISSPECIAL +// 321 RPL_LISTSTART +// 322 RPL_LIST +// 323 RPL_LISTEND +// 324 RPL_CHANNELMODEIS +// 329 RPL_CREATIONTIME +// 330 RPL_WHOISACCOUNT +// 331 RPL_NOTOPIC +// 332 RPL_TOPIC +// 333 RPL_TOPICWHOTIME +// 336 RPL_INVITELIST +// 337 RPL_ENDOFINVITELIST +// 338 RPL_WHOISACTUALLY +// 341 RPL_INVITING +// 346 RPL_INVEXLIST +// 347 RPL_ENDOFINVEXLIST +// 348 RPL_EXCEPTLIST +// 349 RPL_ENDOFEXCEPTLIST +// 351 RPL_VERSION +// 353 RPL_NAMREPLY +// 366 RPL_ENDOFNAMES +// 364 RPL_LINKS +// 365 RPL_ENDOFLINKS +// 367 RPL_BANLIST +// 368 RPL_ENDOFBANLIST +// 369 RPL_ENDOFWHOWAS +// 371 RPL_INFO +// 374 RPL_ENDOFINFO +// 375 RPL_MOTDSTART +// 372 RPL_MOTD +// 376 RPL_ENDOFMOTD +// 378 RPL_WHOISHOST +// 379 RPL_WHOISMODES +// 381 RPL_YOUREOPER +// 382 RPL_REHASHING +// 391 RPL_TIME +// 400 ERR_UNKNOWNERROR +// 401 ERR_NOSUCHNICK +// 402 ERR_NOSUCHSERVER +// 403 ERR_NOSUCHCHANNEL +// 404 ERR_CANNOTSENDTOCHAN +// 405 ERR_TOOMANYCHANNELS +// 406 ERR_WASSNOSUCHNICK +// 409 ERR_NOORIGIN +// 417 ERR_INPUTTOOLONG +// 421 ERR_UNKNOWNCOMMAND +// 422 ERR_NOMOTD +// 432 ERR_ERRONEUSNICKNAME +// 433 ERR_NICKNAMEINUSE +// 441 ERR_USERNOTINCHANNEL +// 442 ERR_NOTONCHANNEL +// 443 ERR_USERONCHANNEL +void err_notregistered(struct client_data *client); // 451 +// 461 ERR_NEEDMOREPARAMS +// 462 ERR_ALREADYREGISTERED +// 464 ERR_PASWDMISMATCH +// 465 ERR_YOUREBANNEDCREEP +// 471 ERR_CHANNELISFULL +// 472 ERR_UNKNOWNMODE +// 473 ERR_INVITEONLYCHAN +// 474 ERR_BANNEDFROMCHAN +// 475 ERR_BADCHANNELKEY +// 476 ERR_BADCHANMASK +// 481 ERR_NOPRIVILEGES +// 482 ERR_CHANOPRIVSNEEDED +// 483 ERR_CANTKILLSERVER +// 491 ERR_NOOPERHOST +// 501 ERR_UMODEUNKNOWNFLAG +// 502 ERR_USERSDONTMATCH +// 524 ERR_HELPNOTFOUND +// 525 ERR_INVALIDKEY +// 670 RPL_STARTTLS +// 671 RPL_WHOISSECURE +// 691 ERR_STARTTLS +// 696 ERR_INVALIDMODEPARAM +// 704 RPL_HELPSTART +// 705 RPL_HELPTXT +// 706 RPL_ENDOFHELP +// 723 ERR_NOPRIVS +// 900 RPL_LOGGEDIN +// 901 RPL_LOGGEDOUT +// 902 ERR_NICKLOCKED +// 903 RPL_SASLSUCCESS +// 904 ERR_SASLFAIL +// 905 ERR_SASLTOOLONG +// 906 ERR_SASLABORTED +// 907 ERR_SASLALREADY +// 908 RPL_SASLMECHS +#endif diff --git a/net.c b/net.c index 9ecb584..ffe6220 100644 --- a/net.c +++ b/net.c @@ -1,5 +1,6 @@ #include "net.h" #include "irc.h" +#include "ircfmt.h" #include void sendall_log(SOCKET socket, const char *buffer, size_t length, int flags) { @@ -52,13 +53,12 @@ void killConnection(struct client_data *cl, bool byChoice) { #endif // Start GitHub Copilot if(!byChoice && cl->nick && cl->username) { - copy_strf(&databuf, ":%s!%s@%s QUIT :Has left the building (Forced)\n", cl->nick, cl->username, cl->hostname); + msg_quit(cl, "", "Has left the building (Forced)"); sendall_log(cl->FD, databuf.buf, databuf.len, 0); } // Send error to client informing them that they will be disconnected - // ERROR :Closing Link: NICK () - copy_strf(&databuf, "ERROR :Closing Link: %s ()\n", cl->nick); - send_log(cl->FD, databuf.buf, databuf.len, 0); + msg_error("Closing Link"); + sendbuf(cl); // End GitHub Copilot shutdown(cl->FD, SHUT_RDWR); closesocket(cl->FD); diff --git a/net.h b/net.h index 0838e90..5edc6d0 100644 --- a/net.h +++ b/net.h @@ -4,6 +4,7 @@ #include void sendall_log(SOCKET socket, const char *buffer, size_t length, int flags); +void sendbuf(struct client_data *client); struct client_data *allocClient(); void killConnection(struct client_data *client, bool byChoice); void recvProc(struct client_data *cl);