X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-info.c;h=1bbaf57b3b53a35e905be647c5f075690ade38ac;hp=24d65651611411d1d83447dad0782e87617b3d2d;hb=f8f7f83f5a2228bb9deeb8324be015cd76b84ced;hpb=2c96966431d99ce611736ed841e813c1fac6df8c diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index 24d65651..1bbaf57b 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,13 +16,12 @@ * IRC info commands */ -#include "imp.h" #include -#include #include #include #include #include +#include #include "ngircd.h" #include "conn-func.h" @@ -30,19 +29,16 @@ #include "channel.h" #include "class.h" #include "conf.h" -#include "defines.h" #include "lists.h" -#include "log.h" #include "messages.h" #include "match.h" -#include "tool.h" #include "parse.h" #include "irc.h" #include "irc-macros.h" #include "irc-write.h" #include "client-cap.h" +#include "op.h" -#include "exp.h" #include "irc-info.h" /* Local functions */ @@ -87,14 +83,6 @@ write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *f flags, Client_Hops(c), Client_Info(c)); } -static const char * -who_flags_status(const char *client_modes) -{ - if (strchr(client_modes, 'a')) - return "G"; /* away */ - return "H"; -} - /** * Return channel user mode prefix(es). * @@ -152,7 +140,6 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) { bool is_visible, is_member, is_ircop; CL2CHAN *cl2chan; - const char *client_modes; char flags[10]; CLIENT *c; int count = 0; @@ -160,12 +147,10 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) assert( Client != NULL ); assert( Chan != NULL ); - IRC_SetPenalty(Client, 1); - is_member = Channel_IsMemberOf(Chan, Client); /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan)); @@ -173,17 +158,21 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) for (; cl2chan ; cl2chan = Channel_NextMember(Chan, cl2chan)) { c = Channel_GetClient(cl2chan); - client_modes = Client_Modes(c); - is_ircop = strchr(client_modes, 'o') != NULL; + is_ircop = Client_HasMode(c, 'o'); if (OnlyOps && !is_ircop) continue; - is_visible = strchr(client_modes, 'i') == NULL; + is_visible = !Client_HasMode(c, 'i'); if (is_member || is_visible) { - strlcpy(flags, who_flags_status(client_modes), - sizeof(flags)); + memset(flags, 0, sizeof(flags)); + + if (Client_HasMode(c, 'a')) + flags[0] = 'G'; /* away */ + else + flags[0] = 'H'; + if (is_ircop) - strlcat(flags, "*", sizeof(flags)); + flags[1] = '*'; who_flags_qualifier(Client, Channel_UserModes(Chan, c), flags, sizeof(flags)); @@ -195,7 +184,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) } } - /* If there are a lot of clients, augment penalty a bit */ + /* If there are a lot of clients, increase the penalty a bit */ if (count > MAX_RPL_WHO) IRC_SetPenalty(Client, 1); @@ -218,7 +207,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) CL2CHAN *cl2chan; CHANNEL *chan; bool client_match, is_visible; - char flags[4]; + char flags[3]; int count = 0; assert (Client != NULL); @@ -274,9 +263,15 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO")) break; - strlcpy(flags, who_flags_status(Client_Modes(c)), sizeof(flags)); - if (strchr(Client_Modes(c), 'o')) - strlcat(flags, "*", sizeof(flags)); + memset(flags, 0, sizeof(flags)); + + if (Client_HasMode(c, 'a')) + flags[0] = 'G'; /* away */ + else + flags[0] = 'H'; + + if (Client_HasMode(c, 'o')) + flags[1] = '*'; if (!write_whoreply(Client, c, "*", flags)) return DISCONNECTED; @@ -298,7 +293,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) static bool IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) { - char str[LINE_LEN + 1]; + char str[COMMAND_LEN]; CL2CHAN *cl2chan; CHANNEL *chan; @@ -318,51 +313,60 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) Client_Info(Client_Introducer(c)))) return DISCONNECTED; - /* Channels */ - snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, - Client_ID(from), Client_ID(c)); - cl2chan = Channel_FirstChannelOf(c); - while (cl2chan) { - chan = Channel_GetChannel(cl2chan); - assert(chan != NULL); - - /* next */ - cl2chan = Channel_NextChannelOf(c, cl2chan); - - /* Secret channel? */ - if (strchr(Channel_Modes(chan), 's') - && !Channel_IsMemberOf(chan, Client)) - continue; + /* Channels, show only if client has no +I or if from is oper */ + if(!(Client_HasMode(c, 'I')) || Client_HasMode(from, 'o')) { + snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, + Client_ID(from), Client_ID(c)); + cl2chan = Channel_FirstChannelOf(c); + while (cl2chan) { + chan = Channel_GetChannel(cl2chan); + assert(chan != NULL); + + /* next */ + cl2chan = Channel_NextChannelOf(c, cl2chan); + + /* Secret channel? */ + if (Channel_HasMode(chan, 's') + && !Channel_IsMemberOf(chan, Client)) + continue; - /* Local channel and request is not from a user? */ - if (Client_Type(Client) == CLIENT_SERVER - && Channel_IsLocal(chan)) - continue; + /* Local channel and request is not from a user? */ + if (Client_Type(Client) == CLIENT_SERVER + && Channel_IsLocal(chan)) + continue; - /* Concatenate channel names */ - if (str[strlen(str) - 1] != ':') - strlcat(str, " ", sizeof(str)); + /* Concatenate channel names */ + if (str[strlen(str) - 1] != ':') + strlcat(str, " ", sizeof(str)); - who_flags_qualifier(Client, Channel_UserModes(chan, c), - str, sizeof(str)); - strlcat(str, Channel_Name(chan), sizeof(str)); + who_flags_qualifier(Client, Channel_UserModes(chan, c), + str, sizeof(str)); + strlcat(str, Channel_Name(chan), sizeof(str)); - if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) { - /* Line becomes too long: send it! */ + if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) { + /* Line becomes too long: send it! */ + if (!IRC_WriteStrClient(Client, "%s", str)) + return DISCONNECTED; + snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, + Client_ID(from), Client_ID(c)); + } + } + if(str[strlen(str) - 1] != ':') { + /* There is data left to send: */ if (!IRC_WriteStrClient(Client, "%s", str)) return DISCONNECTED; - snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, - Client_ID(from), Client_ID(c)); } } - if(str[strlen(str) - 1] != ':') { - /* There is data left to send: */ - if (!IRC_WriteStrClient(Client, "%s", str)) - return DISCONNECTED; - } + + /* IRC-Services? */ + if (Client_Type(c) == CLIENT_SERVICE && + !IRC_WriteStrClient(from, RPL_WHOISSERVICE_MSG, + Client_ID(from), Client_ID(c))) + return DISCONNECTED; /* IRC-Operator? */ - if (Client_HasMode(c, 'o') && + if (Client_Type(c) != CLIENT_SERVICE && + Client_HasMode(c, 'o') && !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG, Client_ID(from), Client_ID(c))) return DISCONNECTED; @@ -374,10 +378,19 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) return DISCONNECTED; /* Connected using SSL? */ - if (Conn_UsesSSL(Client_Conn(c)) && - !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from), - Client_ID(c))) - return DISCONNECTED; + if (Conn_UsesSSL(Client_Conn(c))) { + if (!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from), + Client_ID(c))) + return DISCONNECTED; + + /* Certificate fingerprint? */ + if (Conn_GetCertFp(Client_Conn(c)) && + from == c && + !IRC_WriteStrClient(from, RPL_WHOISCERTFP_MSG, + Client_ID(from), Client_ID(c), + Conn_GetCertFp(Client_Conn(c)))) + return DISCONNECTED; + } /* Registered nickname? */ if (Client_HasMode(c, 'R') && @@ -385,13 +398,20 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) Client_ID(from), Client_ID(c))) return DISCONNECTED; + /* Account name metadata? */ + if (Client_AccountName(c) && + !IRC_WriteStrClient(from, RPL_WHOISLOGGEDIN_MSG, + Client_ID(from), Client_ID(c), + Client_AccountName(c))) + return DISCONNECTED; + /* Local client and requester is the user itself or an IRC Op? */ if (Client_Conn(c) > NONE && - (from == c || (!Conf_MorePrivacy && Client_HasMode(from, 'o')))) { + (from == c || Client_HasMode(from, 'o'))) { /* Client hostname */ if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, - Client_ID(from), Client_ID(c), Client_Hostname(c), - Conn_GetIPAInfo(Client_Conn(c)))) + Client_ID(from), Client_ID(c), + Client_Hostname(c), Client_IPAText(c))) return DISCONNECTED; /* Client modes */ if (!IRC_WriteStrClient(from, RPL_WHOISMODES_MSG, @@ -432,51 +452,37 @@ WHOWAS_EntryWrite(CLIENT *prefix, WHOWAS *entry) entry->id, entry->server, t_str); } -static bool -Show_MOTD_Start(CLIENT *Client) -{ - return IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG, - Client_ID( Client ), Client_ID( Client_ThisServer( ))); -} - -static bool -Show_MOTD_Sendline(CLIENT *Client, const char *msg) -{ - return IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID( Client ), msg); -} - -static bool -Show_MOTD_End(CLIENT *Client) -{ - if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client))) - return DISCONNECTED; - - if (*Conf_CloakHost) - return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG, - Client_ID(Client), - Client_Hostname(Client)); - - return CONNECTED; -} - #ifdef SSL_SUPPORT -static bool Show_MOTD_SSLInfo(CLIENT *Client) +static bool +Show_MOTD_SSLInfo(CLIENT *Client) { - bool ret = true; - char buf[COMMAND_LEN] = "Connected using Cipher "; - - if (!Conn_GetCipherInfo(Client_Conn(Client), buf + 23, sizeof buf - 23)) - return true; + char buf[COMMAND_LEN]; + char c_str[128]; + + if (Conn_GetCipherInfo(Client_Conn(Client), c_str, sizeof(c_str))) { + snprintf(buf, sizeof(buf), "Connected using Cipher %s", c_str); + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, + Client_ID(Client), buf)) + return false; + } - if (!Show_MOTD_Sendline(Client, buf)) - ret = false; + if (Conn_GetCertFp(Client_Conn(Client))) { + snprintf(buf, sizeof(buf), + "Your client certificate fingerprint is: %s", + Conn_GetCertFp(Client_Conn(Client))); + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, + Client_ID(Client), buf)) + return false; + } - return ret; + return true; } #else -static inline bool +static bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) -{ return true; } +{ + return true; +} #endif /* Global functions */ @@ -496,9 +502,6 @@ IRC_ADMIN(CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) @@ -541,9 +544,6 @@ IRC_INFO(CLIENT * Client, REQUEST * Req) assert(Client != NULL); assert(Req != NULL); - IRC_SetPenalty(Client, 2); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) @@ -593,8 +593,6 @@ IRC_ISON( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) - strlcpy(rpl, RPL_ISON_MSG, sizeof rpl); for (i = 0; i < Req->argc; i++) { /* "All" ircd even parse ": ..." arguments and split @@ -631,9 +629,6 @@ IRC_LINKS(CLIENT *Client, REQUEST *Req) assert(Client != NULL); assert(Req != NULL); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) /* Get pointer to server mask or "*", if none given */ @@ -686,9 +681,6 @@ IRC_LUSERS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) @@ -715,13 +707,9 @@ IRC_SERVLIST(CLIENT *Client, REQUEST *Req) { CLIENT *c; - IRC_SetPenalty(Client, 1); - assert(Client != NULL); assert(Req != NULL); - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) - if (Req->argc < 2 || strcmp(Req->argv[1], "0") == 0) { for (c = Client_First(); c!= NULL; c = Client_Next(c)) { if (Client_Type(c) != CLIENT_SERVICE) @@ -757,9 +745,6 @@ IRC_MOTD( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 3); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from) @@ -790,9 +775,6 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) @@ -831,14 +813,14 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req ) while (c) { if (Client_Type(c) == CLIENT_USER && Channel_FirstChannelOf(c) == NULL - && !strchr(Client_Modes(c), 'i')) + && !Client_HasMode(c, 'i')) { /* its a user, concatenate ... */ if (rpl[strlen(rpl) - 1] != ':') strlcat(rpl, " ", sizeof(rpl)); strlcat(rpl, Client_ID(c), sizeof(rpl)); - if (strlen(rpl) > LINE_LEN - CLIENT_NICK_LEN - 4) { + if (strlen(rpl) > COMMAND_LEN - CLIENT_NICK_LEN - 4) { /* Line is gwoing too long, send now */ if (!IRC_WriteStrClient(from, "%s", rpl)) return DISCONNECTED; @@ -872,13 +854,11 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) unsigned int days, hrs, mins; struct list_head *list; struct list_elem *list_item; + bool more_links = false; assert(Client != NULL); assert(Req != NULL); - IRC_SetPenalty(Client, 2); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 1, from) @@ -900,7 +880,7 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) case 'k': /* Server-local bans ("K-Lines") */ case 'K': if (!Client_HasMode(from, 'o')) - return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG, + return IRC_WriteErrClient(from, ERR_NOPRIVILEGES_MSG, Client_ID(from)); if (query == 'g' || query == 'G') list = Class_GetList(CLASS_GLINE); @@ -917,16 +897,20 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) list_item = Lists_GetNext(list_item); } break; + case 'L': /* Link status (servers and user links) */ + if (!Op_Check(from, Req)) + return Op_NoPrivileges(from, Req); + more_links = true; + case 'l': /* Link status (servers and own link) */ - case 'L': time_now = time(NULL); for (con = Conn_First(); con != NONE; con = Conn_Next(con)) { cl = Conn_GetClient(con); if (!cl) continue; - if ((Client_Type(cl) == CLIENT_SERVER) - || (cl == Client)) { - /* Server link or our own connection */ + if (Client_Type(cl) == CLIENT_SERVER || + cl == Client || + (more_links && Client_Type(cl) == CLIENT_USER)) { #ifdef ZLIB if (Conn_Options(con) & CONN_ZIP) { if (!IRC_WriteStrClient @@ -994,9 +978,7 @@ IRC_SUMMON(CLIENT * Client, UNUSED REQUEST * Req) { assert(Client != NULL); - IRC_SetPenalty(Client, 1); - - return IRC_WriteStrClient(Client, ERR_SUMMONDISABLED_MSG, + return IRC_WriteErrClient(Client, ERR_SUMMONDISABLED_MSG, Client_ID(Client)); } /* IRC_SUMMON */ @@ -1017,9 +999,6 @@ IRC_TIME( CLIENT *Client, REQUEST *Req ) assert(Client != NULL); assert(Req != NULL); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from) @@ -1053,10 +1032,6 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req) assert(Client != NULL); assert(Req != NULL); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_GE_OR_RETURN_(Client, Req, 1) - if (Req->argc > 5) max = 5; else @@ -1098,9 +1073,7 @@ IRC_USERS(CLIENT * Client, UNUSED REQUEST * Req) { assert(Client != NULL); - IRC_SetPenalty(Client, 1); - - return IRC_WriteStrClient(Client, ERR_USERSDISABLED_MSG, + return IRC_WriteErrClient(Client, ERR_USERSDISABLED_MSG, Client_ID(Client)); } /* IRC_USERS */ @@ -1119,9 +1092,6 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, prefix) @@ -1133,10 +1103,19 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req ) } /* send version information */ - return IRC_WriteStrClient(Client, RPL_VERSION_MSG, Client_ID(prefix), - PACKAGE_NAME, PACKAGE_VERSION, - NGIRCd_DebugLevel, Conf_ServerName, - NGIRCd_VersionAddition); + if (!IRC_WriteStrClient(Client, RPL_VERSION_MSG, Client_ID(prefix), + PACKAGE_NAME, PACKAGE_VERSION, + NGIRCd_DebugLevel, Conf_ServerName, + NGIRCd_VersionAddition)) + return DISCONNECTED; + +#ifndef STRICT_RFC + /* send RPL_ISUPPORT(005) numerics */ + if (!IRC_Send_ISUPPORT(prefix)) + return DISCONNECTED; +#endif + + return CONNECTED; } /* IRC_VERSION */ /** @@ -1155,20 +1134,17 @@ IRC_WHO(CLIENT *Client, REQUEST *Req) assert (Client != NULL); assert (Req != NULL); - IRC_SetPenalty(Client, 1); - - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) - only_ops = false; if (Req->argc == 2) { if (strcmp(Req->argv[1], "o") == 0) only_ops = true; #ifdef STRICT_RFC - else - return IRC_WriteStrClient(Client, + else { + return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); + } #endif } @@ -1187,7 +1163,6 @@ IRC_WHO(CLIENT *Client, REQUEST *Req) } /* No channel or (valid) mask given */ - IRC_SetPenalty(Client, 2); return IRC_WHO_Mask(Client, NULL, only_ops); } /* IRC_WHO */ @@ -1210,13 +1185,12 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - IRC_SetPenalty(Client, 1); - - /* Bad number of parameters? */ - if (Req->argc < 1 || Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + /* Wrong number of parameters? */ + if (Req->argc < 1) + return IRC_WriteErrClient(Client, ERR_NONICKNAMEGIVEN_MSG, + Client_ID(Client)); + _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) /* Get target server for this command */ @@ -1256,7 +1230,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) if (!IRC_WHOIS_SendReply(Client, from, c)) return DISCONNECTED; } else { - if (!IRC_WriteStrClient(Client, + if (!IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), query)) @@ -1266,12 +1240,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) } if (got_wildcard) { /* we already handled one wildcard query */ - if (!IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + if (!IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), query)) return DISCONNECTED; continue; } got_wildcard = true; + /* Increase penalty for wildcard queries */ IRC_SetPenalty(Client, 3); for (c = Client_First(); c; c = Client_Next(c)) { @@ -1290,7 +1265,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) } if (match_count == 0) - IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[Req->argc - 1]); } @@ -1317,19 +1292,19 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - /* Do not reveal any info on disconnected users? */ - if (Conf_MorePrivacy) - return CONNECTED; - /* Wrong number of parameters? */ if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NONICKNAMEGIVEN_MSG, + return IRC_WriteErrClient(Client, ERR_NONICKNAMEGIVEN_MSG, Client_ID(Client)); _IRC_ARGC_LE_OR_RETURN_(Client, Req, 3) _IRC_GET_SENDER_OR_RETURN_(prefix, Req, Client) _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 2, prefix) + /* Do not reveal any info on disconnected users? */ + if (Conf_MorePrivacy) + return CONNECTED; + /* Forward? */ if (target != Client_ThisServer()) { IRC_WriteStrClientPrefix(target, prefix, "WHOWAS %s %s %s", @@ -1378,7 +1353,7 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) break; } while (i != last); - if (nc == 0 && !IRC_WriteStrClient(prefix, ERR_WASNOSUCHNICK_MSG, + if (nc == 0 && !IRC_WriteErrClient(prefix, ERR_WASNOSUCHNICK_MSG, Client_ID(prefix), nick)) return DISCONNECTED; } @@ -1402,7 +1377,7 @@ IRC_Send_LUSERS(CLIENT *Client) assert(Client != NULL); - /* Users, services and serevers in the network */ + /* Users, services and servers in the network */ if (!IRC_WriteStrClient(Client, RPL_LUSERCLIENT_MSG, Client_ID(Client), Client_UserCount(), Client_ServiceCount(), Client_ServerCount())) @@ -1468,9 +1443,10 @@ IRC_Show_MOTD( CLIENT *Client ) len_tot = array_bytes(&Conf_Motd); if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client))) - return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client)); + return IRC_WriteErrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client)); - if (!Show_MOTD_Start(Client)) + if (!IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG, Client_ID(Client), + Client_ID(Client_ThisServer()))) return DISCONNECTED; line = array_start(&Conf_Motd); @@ -1480,14 +1456,23 @@ IRC_Show_MOTD( CLIENT *Client ) assert(len_tot >= len_str); len_tot -= len_str; - if (!Show_MOTD_Sendline(Client, line)) + if (!IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID(Client), line)) return DISCONNECTED; line += len_str; } if (!Show_MOTD_SSLInfo(Client)) return DISCONNECTED; - return Show_MOTD_End(Client); + + if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client))) + return DISCONNECTED; + + if (*Conf_CloakHost) + return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG, + Client_ID(Client), + Client_Hostname(Client)); + + return CONNECTED; } /* IRC_Show_MOTD */ /** @@ -1501,7 +1486,7 @@ GLOBAL bool IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) { bool is_visible, is_member; - char str[LINE_LEN + 1]; + char str[COMMAND_LEN]; CL2CHAN *cl2chan; CLIENT *cl; @@ -1518,7 +1503,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) return CONNECTED; /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return CONNECTED; snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, Client_ID(Client), "=", @@ -1527,7 +1512,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) while (cl2chan) { cl = Channel_GetClient(cl2chan); - if (strchr(Client_Modes(cl), 'i')) + if (Client_HasMode(cl, 'i')) is_visible = false; else is_visible = true; @@ -1540,7 +1525,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) str, sizeof(str)); strlcat(str, Client_ID(cl), sizeof(str)); - if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 4)) { + if (strlen(str) > (COMMAND_LEN - CLIENT_NICK_LEN - 4)) { if (!IRC_WriteStrClient(Client, "%s", str)) return DISCONNECTED; snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, @@ -1567,8 +1552,12 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) GLOBAL bool IRC_Send_ISUPPORT(CLIENT * Client) { + if (Conf_Network[0] && !IRC_WriteStrClient(Client, RPL_ISUPPORTNET_MSG, + Client_ID(Client), + Conf_Network)) + return DISCONNECTED; if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client), - Conf_MaxJoins)) + CHANTYPES, CHANTYPES, Conf_MaxJoins)) return DISCONNECTED; return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client), CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,