From a3c33b1c1329c5278346a55bf3b6c9d2aed329c4 Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 11 May 2022 21:30:14 +0300 Subject: [PATCH] add more numerics --- irc.c | 96 ++++++++++++++++++++++++++++---------------------------- ircfmt.c | 54 ++++++++++++++++++++++++------- ircfmt.h | 18 +++++------ 3 files changed, 99 insertions(+), 69 deletions(-) diff --git a/irc.c b/irc.c index 84eb689..78bcaff 100644 --- a/irc.c +++ b/irc.c @@ -179,13 +179,13 @@ int processPacket(struct client_data *client, char *source, char *command, int a (void)source; databuf.len = 0; if(strcmp(command, "PING") == 0) { - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; msg_pong(args[0]); sendbuf(client); } else if(strcmp(command, "CAP") == 0) { - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; stringupper(args[0]); // don't enable CAP command until we actually have CAPs // because clients can't handle NAKs @@ -217,8 +217,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a #endif } else if(strcmp(command, "NICK") == 0) { // User now registered - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; if (is_registered(client)) { setNick(client, args[0]); } else { @@ -229,11 +229,11 @@ int processPacket(struct client_data *client, char *source, char *command, int a newUser(client); } } else if(strcmp(command, "USER") == 0) { - if (argc < 4) // FIXME: error message - return 0; + if (argc < 4) + return err_needmoreparams(client, command), sendbuf(client), 0; // set username if (is_registered(client)) - return 0; // FIXME: error + return err_alreadyregistered(client), sendbuf(client), 0; free(client->username); client->username = malloc(strlen(args[0])+2); if (!client->username) @@ -253,8 +253,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "OPER") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc < 2) // FIXME: error message - return 0; + if (argc < 2) + return err_needmoreparams(client, command), sendbuf(client), 0; stringlower(args[0]); int res = password_check(args[0], args[1], "ops.txt"); memset(args[1], 0, strlen(args[1])); @@ -277,20 +277,20 @@ int processPacket(struct client_data *client, char *source, char *command, int a return 0; } if (argc < 1) - return 0; + return err_needmoreparams(client, command), sendbuf(client), 0; struct channel *chan = findChannel(args[0]); if (!chan) - return 0; // TODO: error message + return err_nosuchchannel(client, args[0]), sendbuf(client), 0; if (!trie_get(&chan->members, client->key)) - return 0; // TODO: error message + return err_notonchannel(client, chan), sendbuf(client), 0; trie_set(&chan->o, client->key, client, NULL); copy_strf(&databuf, ":cia!cia@cia.gov MODE %s +o %s\r\n", chan->name, client->nick); sendbuf_chan(chan); } else if(strcmp(command, "JOIN") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; if (!strcmp(args[0], "0")) { struct trie_find *f = NULL; if (trie_findfirst(&f, &client->channels) == 1) @@ -315,26 +315,26 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "PART") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; char *p = args[0]; do { char *channel = p; if ((p = strchr(channel, ','))) *p++ = '\0'; struct channel *chan = findChannel(channel); - if (!chan) // TODO: error message - return 0; + if (!chan) + return err_nosuchchannel(client, args[0]), sendbuf(client), 0; channel_part(client, chan, args[1] ? args[1] : ""); } while (p); } else if(strcmp(command, "TOPIC") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (!args[0]) // FIXME: error message - return 0; + if (!args[0]) + return err_needmoreparams(client, command), sendbuf(client), 0; struct channel *chan = findChannel(args[0]); - if (!chan) // TODO: error message - return 0; + if (!chan) + return err_nosuchchannel(client, args[0]), sendbuf(client), 0; if (!args[1]) { // TODO: +s channel_sendtopic(client, chan, 0); @@ -362,8 +362,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "PRIVMSG") == 0 || strcmp(command, "NOTICE") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc < 2) // FIXME: error message - return 0; + if (argc < 2) + return err_needmoreparams(client, command), sendbuf(client), 0; client->lastactivity = get_time(); (command[0] == 'P' ? msg_privmsg : msg_notice)(client, args[0], args[1]); // TODO: extra target forms such as nick@server #hostmask $servermask @@ -454,8 +454,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "MODE") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc == 0) // FIXME: error message - return 0; + if (argc == 0) + return err_needmoreparams(client, command), sendbuf(client), 0; char *nick = args[0]; if (argc == 1) { // get mode if (*nick != '#' && *nick != '&') { @@ -732,7 +732,9 @@ int processPacket(struct client_data *client, char *source, char *command, int a break; } default: - goto unknown; + err_unknownmode(client, *p); + sendbuf(client); + break; } p++; } @@ -759,8 +761,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "NAMES") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc == 0) // FIXME: error message - return 0; + if (argc == 0) + return err_needmoreparams(client, command), sendbuf(client), 0; char *p = args[0]; do { char *channel = p; @@ -777,8 +779,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "USERHOST") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc == 0) // FIXME: error message - return 0; + if (argc == 0) + return err_needmoreparams(client, command), sendbuf(client), 0; copy_strf(&databuf, ":%s 302 %s", hostname, client->nick); int has_output = 0; for (int i = 0; i < 5; i++) { @@ -801,8 +803,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "WHO") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc == 0) // FIXME: error message - return 0; + if (argc == 0) + return err_needmoreparams(client, command), sendbuf(client), 0; // TODO: masks if (strchr("#&", args[0][0])) { struct channel *chan = findChannel(args[0]); @@ -837,8 +839,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a } else if(strcmp(command, "WHOIS") == 0) { if (!is_registered(client)) return err_notregistered(client), sendbuf(client), 0; - if (argc == 0) // FIXME: error message - return 0; + if (argc == 0) + return err_needmoreparams(client, command), sendbuf(client), 0; char *nick = args[1] ? args[1] : args[0]; struct client_data *cl = findClient(nick); if (cl) { @@ -1078,17 +1080,15 @@ void channel_join(struct client_data *client, const char *channel, const char *c } else { if (trie_get(&chan->members, client->key)) return; - if (!(client->umode & UMODE_OPER)) { - if (chan->chankey && (!chankey || strcmp(chan->chankey, chankey) == 0)) - return; // error 475 - if (chan->member_limit != -1 && chan->member_count >= chan->member_limit) - return; // error 471 - if (match_list(client, &chan->listb) && !match_list(client, &chan->liste)) - return; // error 474 - // TODO: actual invites - if (chan->dmode & DMODE_INVITEONLY && !match_list(client, &chan->listI)) - return; // error 474 - } + if (chan->chankey && (!chankey || strcmp(chan->chankey, chankey) == 0)) + return err_badchannelkey(client, chan), sendbuf(client); + if (chan->member_limit != -1 && chan->member_count >= chan->member_limit) + return err_channelisfull(client, chan), sendbuf(client); + if (match_list(client, &chan->listb) && !match_list(client, &chan->liste)) + return err_bannedfromchan(client, chan), sendbuf(client); + // TODO: actual invites + if (chan->dmode & DMODE_INVITEONLY && !match_list(client, &chan->listI)) + return err_inviteonlychan(client, chan), sendbuf(client); } if (trie_set(&chan->members, client->key, client, NULL) == -1) abort(); diff --git a/ircfmt.c b/ircfmt.c index 6d6148f..509aa98 100644 --- a/ircfmt.c +++ b/ircfmt.c @@ -331,7 +331,7 @@ void err_inputtoolong(struct client_data *client) // 417 #endif void err_unknowncommand(struct client_data *client, const char *command) // 421 { - copy_strf(&databuf, ":%s 421 %s %s :Unknown command\r\n", hostname, client->nick, command); + copy_strf(&databuf, ":%s 421 %s %s :Unknown command\r\n", hostname, client->nick ? client->nick : "*", command); } #if 0 void err_nomotd(struct client_data *client) // 422 @@ -351,11 +351,11 @@ void err_usernotinchannel(struct client_data *client, const char *nick, struct c { copy_strf(&databuf, ":%s 441 %s %s %s :They aren't on that channel\r\n", hostname, client->nick, nick, chan->name); } -#if 0 void err_notonchannel(struct client_data *client, struct channel *chan) // 442 { - copy_strf(&databuf, ":%s 442 %s %s :is already on channel\r\n", hostname, client->nick, chan->name); + copy_strf(&databuf, ":%s 442 %s %s :You're not on that channel\r\n", hostname, client->nick, chan->name); } +#if 0 void err_useronchannel(struct client_data *client, const char *nick, struct channel *chan) // 443 { copy_strf(&databuf, ":%s 443 %s %s %s :is already on channel\r\n", hostname, client->nick, nick, chan->name); @@ -366,15 +366,45 @@ 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 +void err_needmoreparams(struct client_data *client, const char *command) // 461 +{ + copy_strf(&databuf, ":%s 461 %s %s :Not enough parameters\r\n", hostname, client->nick ? client->nick : "*", command); +} +void err_alreadyregistered(struct client_data *client) // 462 +{ + copy_strf(&databuf, ":%s 462 %s :You may not reregister\r\n", hostname, client->nick ? client->nick : "*"); +} +#if 0 +void err_passwdmismatch(struct client_data *client) // 464 +{ + copy_strf(&databuf, ":%s 464 %s :Password incorrect\r\n", hostname, client->nick ? client->nick : "*"); +} +void err_yourebannedcreep(struct client_data *client) // 465 +{ + copy_strf(&databuf, ":%s 465 %s :You are banned from this server.\r\n", hostname, client->nick ? client->nick : "*"); +} +#endif +void err_channelisfull(struct client_data *client, struct channel *chan) // 471 +{ + copy_strf(&databuf, ":%s 471 %s %s :Cannot join channel (+l)\r\n", hostname, client->nick, chan->name); +} +void err_unknownmode(struct client_data *client, char mode) // 472 +{ + char modes[2] = {mode, 0}; + copy_strf(&databuf, ":%s 472 %s %s :is unknown mode char to me\r\n", hostname, client->nick, modes); +} +void err_inviteonlychan(struct client_data *client, struct channel *chan) // 473 +{ + copy_strf(&databuf, ":%s 473 %s %s :Cannot join channel (+i)\r\n", hostname, client->nick, chan->name); +} +void err_bannedfromchan(struct client_data *client, struct channel *chan) // 474 +{ + copy_strf(&databuf, ":%s 474 %s %s :Cannot join channel (+b)\r\n", hostname, client->nick, chan->name); +} +void err_badchannelkey(struct client_data *client, struct channel *chan) // 475 +{ + copy_strf(&databuf, ":%s 475 %s %s :Cannot join channel (+k)\r\n", hostname, client->nick, chan->name); +} // 476 ERR_BADCHANMASK // 481 ERR_NOPRIVILEGES // 482 ERR_CHANOPRIVSNEEDED diff --git a/ircfmt.h b/ircfmt.h index af2ee03..10de3df 100644 --- a/ircfmt.h +++ b/ircfmt.h @@ -103,15 +103,15 @@ void err_usernotinchannel(struct client_data *client, const char *nick, struct c void err_notonchannel(struct client_data *client, struct channel *chan); // 442 void err_useronchannel(struct client_data *client, const char *nick, struct channel *chan); // 443 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 +void err_needmoreparams(struct client_data *client, const char *command); // 461 +void err_alreadyregistered(struct client_data *client); // 462 +void err_passwdmismatch(struct client_data *client); // 464 +void err_yourebannedcreep(struct client_data *client); // 465 +void err_channelisfull(struct client_data *client, struct channel *chan); // 471 +void err_unknownmode(struct client_data *client, char mode); // 472 +void err_inviteonlychan(struct client_data *client, struct channel *chan); // 473 +void err_bannedfromchan(struct client_data *client, struct channel *chan); // 474 +void err_badchannelkey(struct client_data *client, struct channel *chan); // 475 // 476 ERR_BADCHANMASK // 481 ERR_NOPRIVILEGES // 482 ERR_CHANOPRIVSNEEDED -- 2.56.0