X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-info.c;h=841e6e62739274a0b862ba4bab1284091605ff07;hb=391aa8d1f714d5dc2fc1b47ec466082169ef2177;hp=c2f4910e47645807251c82e9815e61ccdbc08279;hpb=566a451299cab41810bafc5ed11a5021e30d9b3d;p=ngircd-alex.git diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index c2f4910e..841e6e62 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-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 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 @@ -37,6 +37,7 @@ #include "match.h" #include "tool.h" #include "parse.h" +#include "irc.h" #include "irc-write.h" #include "exp.h" @@ -647,10 +648,10 @@ IRC_STATS( CLIENT *Client, REQUEST *Req ) * therefore answers with ERR_SUMMONDISABLED. */ GLOBAL bool -IRC_SUMMON(CLIENT * Client, REQUEST * Req) +IRC_SUMMON(CLIENT * Client, UNUSED REQUEST * Req) { return IRC_WriteStrClient(Client, ERR_SUMMONDISABLED_MSG, - Client_ID(Client), Req->command); + Client_ID(Client)); } /* IRC_SUMMON */ @@ -740,10 +741,10 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req) * See RFC 2812 section 4.6. As suggested there the command is disabled. */ GLOBAL bool -IRC_USERS(CLIENT * Client, REQUEST * Req) +IRC_USERS(CLIENT * Client, UNUSED REQUEST * Req) { return IRC_WriteStrClient(Client, ERR_USERSDISABLED_MSG, - Client_ID(Client), Req->command); + Client_ID(Client)); } /* IRC_USERS */ @@ -833,6 +834,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) const char *chan_user_modes; char flags[8]; CLIENT *c; + int count = 0; assert( Client != NULL ); assert( Chan != NULL ); @@ -855,6 +857,9 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) is_visible = strchr(client_modes, 'i') == NULL; if (is_member || is_visible) { + if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO")) + break; + strcpy(flags, who_flags_status(client_modes)); if (is_ircop) strlcat(flags, "*", sizeof(flags)); @@ -866,6 +871,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) if (!write_whoreply(Client, c, Channel_Name(Chan), flags)) return DISCONNECTED; + count++; } } return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), @@ -889,6 +895,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) CHANNEL *chan; bool client_match, is_visible; char flags[4]; + int count = 0; assert (Client != NULL); @@ -939,13 +946,16 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) if (!is_visible) /* target user is not visible */ continue; + if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO")) + break; + strcpy(flags, who_flags_status(Client_Modes(c))); if (strchr(Client_Modes(c), 'o')) strlcat(flags, "*", sizeof(flags)); if (!write_whoreply(Client, c, "*", flags)) return DISCONNECTED; - + count++; } return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), @@ -1015,10 +1025,10 @@ IRC_WHO(CLIENT *Client, REQUEST *Req) /** * Generate WHOIS reply of one actual client. * - * @param Client The client from which this command has been received. - * @param from The client requesting the information ("originator"). - * @param c The client of which information should be returned. - * @returns CONNECTED or DISCONNECTED. + * @param Client The client from which this command has been received. + * @param from The client requesting the information ("originator"). + * @param c The client of which information should be returned. + * @return CONNECTED or DISCONNECTED. */ static bool IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) @@ -1027,6 +1037,10 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) CL2CHAN *cl2chan; CHANNEL *chan; + assert(Client != NULL); + assert(from != NULL); + assert(c != NULL); + /* Nick, user, hostname and client info */ if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from), Client_ID(c), Client_User(c), @@ -1084,30 +1098,41 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) /* IRC-Operator? */ if (Client_HasMode(c, 'o') && - !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG, - Client_ID(from), Client_ID(c))) - return DISCONNECTED; + !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG, + Client_ID(from), Client_ID(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; + !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from), + Client_ID(c))) + return DISCONNECTED; + + /* Registered nick name? */ + if (Client_HasMode(c, 'R') && + !IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG, + Client_ID(from), Client_ID(c))) + return DISCONNECTED; + + if (Client_Conn(c) > NONE && (Client_OperByMe(from) || from == c) && + !IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, Client_ID(from), + Client_ID(c), Client_Hostname(c), + Conn_GetIPAInfo(Client_Conn(c)))) + return DISCONNECTED; /* Idle and signon time (local clients only!) */ if (!Conf_MorePrivacy && Client_Conn(c) > NONE && - !IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG, - Client_ID(from), Client_ID(c), - (unsigned long)Conn_GetIdle(Client_Conn(c)), - (unsigned long)Conn_GetSignon(Client_Conn(c)))) - return DISCONNECTED; + !IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG, + Client_ID(from), Client_ID(c), + (unsigned long)Conn_GetIdle(Client_Conn(c)), + (unsigned long)Conn_GetSignon(Client_Conn(c)))) + return DISCONNECTED; /* Away? */ if (Client_HasMode(c, 'a') && - !IRC_WriteStrClient(from, RPL_AWAY_MSG, - Client_ID(from), Client_ID(c), - Client_Away(c))) - return DISCONNECTED; + !IRC_WriteStrClient(from, RPL_AWAY_MSG, + Client_ID(from), Client_ID(c), Client_Away(c))) + return DISCONNECTED; return CONNECTED; } /* IRC_WHOIS_SendReply */ @@ -1129,7 +1154,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) unsigned int match_count = 0, found = 0; bool has_wildcards, is_remote; bool got_wildcard = false; - const char *query; + char mask[COMMAND_LEN], *query; assert( Client != NULL ); assert( Req != NULL ); @@ -1170,7 +1195,8 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) Req->argv[0], Req->argv[1]); is_remote = Client_Conn(from) < 0; - for (query = strtok(Req->argv[Req->argc - 1], ","); + strlcpy(mask, Req->argv[Req->argc - 1], sizeof(mask)); + for (query = strtok(ngt_LowerStr(mask), ","); query && found < 3; query = strtok(NULL, ","), found++) { @@ -1181,11 +1207,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) * - no wildcards for remote clients * - only one wildcard target per local client * - * also, at most ten matches are returned. + * Also, at most MAX_RPL_WHOIS matches are returned. */ if (!has_wildcards || is_remote) { c = Client_Search(query); - if (c) { + if (c && Client_Type(c) == CLIENT_USER) { if (!IRC_WHOIS_SendReply(Client, from, c)) return DISCONNECTED; } else { @@ -1207,13 +1233,18 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) got_wildcard = true; IRC_SetPenalty(Client, 3); - for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) { + for (c = Client_First(); c; c = Client_Next(c)) { + if (IRC_CheckListTooBig(Client, match_count, + MAX_RPL_WHOIS, "WHOIS")) + break; + if (Client_Type(c) != CLIENT_USER) continue; if (!MatchCaseInsensitive(query, Client_ID(c))) continue; if (!IRC_WHOIS_SendReply(Client, from, c)) return DISCONNECTED; + match_count++; } @@ -1305,11 +1336,11 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) if (last < 0) last = 0; - max = DEFAULT_WHOWAS; + max = DEF_RPL_WHOWAS; if (Req->argc > 1) { max = atoi(Req->argv[1]); if (max < 1) - max = MAX_WHOWAS; + max = MAX_RPL_WHOWAS; } /* @@ -1567,7 +1598,8 @@ IRC_Send_ISUPPORT(CLIENT * Client) return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client), CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1, COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, - COMMAND_LEN - 113); + COMMAND_LEN - 113, MAX_HNDL_MODES_ARG, + MAX_HNDL_CHANNEL_LISTS); } /* IRC_Send_ISUPPORT */