/** * Handler for the IRC "MODE" command. * * This function detects whether user or channel modes should be modified * and calls the appropriate sub-functions. * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_MODE( CLIENT *Client, REQUEST *Req ) { CLIENT *cl, *origin; CHANNEL *chan; assert(Client != NULL); assert(Req != NULL); _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])) cl = Client_Search(Req->argv[0]); if (Channel_IsValidName(Req->argv[0])) chan = Channel_Search(Req->argv[0]); if (cl) return Client_Mode(Client, Req, origin, cl); if (chan) return Channel_Mode(Client, Req, origin, chan); /* No target found! */ return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[0]); } /* IRC_MODE */
/** * Handler for the IRC "MODE" command. * * See RFC 2812 section 3.1.5 ("user mode message") and section 3.2.3 * ("channel mode message"), and RFC 2811 section 4 ("channel modes"). * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @returns CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_MODE( CLIENT *Client, REQUEST *Req ) { CLIENT *cl, *origin; CHANNEL *chan; assert(Client != NULL); assert(Req != NULL); /* No parameters? */ if (Req->argc < 1) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); /* Origin for answers */ if (Client_Type(Client) == CLIENT_SERVER) { origin = Client_Search(Req->prefix); if (!origin) return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); } else origin = Client; /* Channel or user mode? */ cl = NULL; chan = NULL; if (Client_IsValidNick(Req->argv[0])) cl = Client_Search(Req->argv[0]); if (Channel_IsValidName(Req->argv[0])) chan = Channel_Search(Req->argv[0]); if (cl) return Client_Mode(Client, Req, origin, cl); if (chan) return Channel_Mode(Client, Req, origin, chan); /* No target found! */ return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[0]); } /* IRC_MODE */
/** * Make sure that a given nickname is valid. * * If the nickname is not valid for the given client, this function sends back * the appropriate error messages. * * @param Client Client that wants to change the nickname. * @param Nick New nickname. * @returns true if nickname is valid, false otherwise. */ GLOBAL bool Client_CheckNick(CLIENT *Client, char *Nick) { assert(Client != NULL); assert(Nick != NULL); if (!Client_IsValidNick(Nick)) { if (strlen(Nick ) >= Conf_MaxNickLength) IRC_WriteErrClient(Client, ERR_NICKNAMETOOLONG_MSG, Client_ID(Client), Nick, Conf_MaxNickLength - 1); else IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), Nick); return false; } if (Client_Type(Client) != CLIENT_SERVER && Client_Type(Client) != CLIENT_SERVICE) { /* Make sure that this isn't a restricted/forbidden nickname */ if (Conf_NickIsBlocked(Nick)) { IRC_WriteErrClient(Client, ERR_FORBIDDENNICKNAME_MSG, Client_ID(Client), Nick); return false; } } /* Nickname already registered? */ if (Client_Search(Nick)) { IRC_WriteErrClient(Client, ERR_NICKNAMEINUSE_MSG, Client_ID(Client), Nick); return false; } return true; } /* Client_CheckNick */