+ continue;
+ }
+
+ /* Validate modes */
+ x[0] = '\0';
+ switch (*mode_ptr) {
+ case 'b': /* Block private msgs */
+ case 'C': /* Only messages from clients sharing a channel */
+ case 'i': /* Invisible */
+ case 's': /* Server messages */
+ case 'w': /* Wallops messages */
+ x[0] = *mode_ptr;
+ break;
+ case 'a': /* Away */
+ if (Client_Type(Client) == CLIENT_SERVER) {
+ x[0] = 'a';
+ Client_SetAway(Origin, DEFAULT_AWAY_MSG);
+ } else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
+ case 'B': /* Bot */
+ if (Client_HasMode(Client, 'r'))
+ ok = IRC_WriteErrClient(Origin,
+ ERR_RESTRICTED_MSG,
+ Client_ID(Origin));
+ else
+ x[0] = 'B';
+ break;
+ case 'c': /* Receive connect notices
+ * (only settable by IRC operators!) */
+ if (!set || Client_Type(Client) == CLIENT_SERVER
+ || Client_OperByMe(Origin))
+ x[0] = 'c';
+ else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
+ case 'o': /* IRC operator (only unsettable!) */
+ if (!set || Client_Type(Client) == CLIENT_SERVER) {
+ Client_SetOperByMe(Target, false);
+ x[0] = 'o';
+ } else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
+ case 'q': /* KICK-protected user */
+ if (!set || Client_Type(Client) == CLIENT_SERVER
+ || Client_OperByMe(Origin))
+ x[0] = 'q';
+ else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
+ case 'r': /* Restricted (only settable) */
+ if (set || Client_Type(Client) == CLIENT_SERVER)
+ x[0] = 'r';
+ else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_RESTRICTED_MSG,
+ Client_ID(Origin));
+ break;
+ case 'R': /* Registered (not [un]settable by clients) */
+ if (Client_Type(Client) == CLIENT_SERVER)
+ x[0] = 'R';
+ else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NICKREGISTER_MSG,
+ Client_ID(Origin));
+ break;
+ case 'x': /* Cloak hostname */
+ if (Client_HasMode(Client, 'r'))
+ ok = IRC_WriteErrClient(Origin,
+ ERR_RESTRICTED_MSG,
+ Client_ID(Origin));
+ else if (!set || Conf_CloakHostModeX[0]
+ || Client_Type(Client) == CLIENT_SERVER
+ || Client_OperByMe(Client)) {
+ x[0] = 'x';
+ send_RPL_HOSTHIDDEN_MSG = true;
+ } else
+ ok = IRC_WriteErrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ break;
+ default:
+ if (Client_Type(Client) != CLIENT_SERVER) {
+ Log(LOG_DEBUG,
+ "Unknown mode \"%c%c\" from \"%s\"!?",
+ set ? '+' : '-', *mode_ptr,
+ Client_ID(Origin));
+ ok = IRC_WriteErrClient(Origin,
+ ERR_UMODEUNKNOWNFLAG2_MSG,
+ Client_ID(Origin),
+ set ? '+' : '-',
+ *mode_ptr);
+ x[0] = '\0';
+ } else {
+ Log(LOG_DEBUG,
+ "Handling unknown mode \"%c%c\" from \"%s\" for \"%s\" ...",
+ set ? '+' : '-', *mode_ptr,
+ Client_ID(Origin), Client_ID(Target));
+ x[0] = *mode_ptr;