X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-mode.c;h=99255df14a5433f60b3ad56e35f7e8f802175916;hb=2924b3d52ac2ab89e3bc517a1f664ec056a45edd;hp=fe981213b33c8d85a3ad3ccb467e54fd6b54b56d;hpb=5713c49c8480639f08f7fff82fb5a40e8566e1dc;p=ngircd-alex.git diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index fe981213..99255df1 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -68,6 +68,13 @@ IRC_MODE( CLIENT *Client, REQUEST *Req ) _IRC_GET_SENDER_OR_RETURN_(origin, Req, Client) + /* Test for "fake" MODE commands injected by this local instance, + * for example when handling the "DefaultUserModes" settings. + * This doesn't harm real commands, because prefixes of regular + * clients are checked in Validate_Prefix() and can't be faked. */ + if (Req->prefix && Client_Search(Req->prefix) == Client_ThisServer()) + Client = Client_Search(Req->prefix); + /* Channel or user mode? */ cl = NULL; chan = NULL; if (Client_IsValidNick(Req->argv[0])) @@ -199,6 +206,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) case 'b': /* Block private msgs */ case 'C': /* Only messages from clients sharing a channel */ case 'i': /* Invisible */ + case 'I': /* Hide channel list from WHOIS */ case 's': /* Server messages */ case 'w': /* Wallops messages */ x[0] = *mode_ptr; @@ -371,37 +379,44 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel) char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], argadd[CLIENT_PASS_LEN]; const char *mode_ptr; - /* Member or not? -- That's the question! */ - if (!Channel_IsMemberOf(Channel, Origin)) - return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, - Client_ID(Origin), Channel_Name(Channel), Channel_Modes(Channel)); - - /* The sender is a member: generate extended reply */ - strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes)); - mode_ptr = the_modes; - the_args[0] = '\0'; - - while(*mode_ptr) { - switch(*mode_ptr) { - case 'l': - snprintf(argadd, sizeof(argadd), " %lu", Channel_MaxUsers(Channel)); - strlcat(the_args, argadd, sizeof(the_args)); - break; - case 'k': - strlcat(the_args, " ", sizeof(the_args)); - strlcat(the_args, Channel_Key(Channel), sizeof(the_args)); - break; + if (!Channel_IsMemberOf(Channel, Origin)) { + /* Not a member: "simple" mode reply */ + if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, + Client_ID(Origin), Channel_Name(Channel), + Channel_Modes(Channel))) + return DISCONNECTED; + } else { + /* The sender is a member: generate extended reply */ + strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes)); + mode_ptr = the_modes; + the_args[0] = '\0'; + + while(*mode_ptr) { + switch(*mode_ptr) { + case 'l': + snprintf(argadd, sizeof(argadd), " %lu", + Channel_MaxUsers(Channel)); + strlcat(the_args, argadd, sizeof(the_args)); + break; + case 'k': + strlcat(the_args, " ", sizeof(the_args)); + strlcat(the_args, Channel_Key(Channel), + sizeof(the_args)); + break; + } + mode_ptr++; } - mode_ptr++; + if (the_args[0]) + strlcat(the_modes, the_args, sizeof(the_modes)); + + if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, + Client_ID(Origin), Channel_Name(Channel), + the_modes)) + return DISCONNECTED; } - if (the_args[0]) - strlcat(the_modes, the_args, sizeof(the_modes)); - if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, - Client_ID(Origin), Channel_Name(Channel), - the_modes)) - return DISCONNECTED; #ifndef STRICT_RFC + /* Channel creation time */ if (!IRC_WriteStrClient(Origin, RPL_CREATIONTIME_MSG, Client_ID(Origin), Channel_Name(Channel), Channel_CreationTime(Channel))) @@ -565,6 +580,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) case 'M': /* Only identified nicks can write */ case 'm': /* Moderated */ case 'n': /* Only members can write */ + case 'N': /* Can't change nick while on this channel */ case 'Q': /* No kicks */ case 't': /* Topic locked */ if(is_oper || is_machine || is_owner || @@ -1002,15 +1018,15 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, switch (what) { case 'I': - if (!Channel_AddInvite(Channel, mask, false)) + if (!Channel_AddInvite(Channel, mask, false, Client_ID(Client))) return CONNECTED; break; case 'b': - if (!Channel_AddBan(Channel, mask)) + if (!Channel_AddBan(Channel, mask, Client_ID(Client))) return CONNECTED; break; case 'e': - if (!Channel_AddExcept(Channel, mask)) + if (!Channel_AddExcept(Channel, mask, Client_ID(Client))) return CONNECTED; break; }