+ } else {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ }
+ Req->argv[arg_arg][0] = '\0';
+ arg_arg++;
+ } else {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Origin), Req->command);
+ goto chan_exit;
+ }
+ break;
+ case 'O': /* IRC operators only */
+ if (modeok) {
+ /* Only IRC operators are allowed to
+ * set the 'O' channel mode! */
+ if (set && !(Client_OperByMe(Client)
+ || Client_Type(Client) == CLIENT_SERVER))
+ connected = IRC_WriteStrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ else
+ x[0] = 'O';
+ } else
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ break;
+ case 'P': /* Persistent channel */
+ if (modeok) {
+ /* Only IRC operators are allowed to
+ * set the 'P' channel mode! */
+ if (set && !(Client_OperByMe(Client)
+ || Client_Type(Client) == CLIENT_SERVER))
+ connected = IRC_WriteStrClient(Origin,
+ ERR_NOPRIVILEGES_MSG,
+ Client_ID(Origin));
+ else
+ x[0] = 'P';
+ } else
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ break;
+ /* --- Channel user modes --- */
+ case 'a':
+ case 'h':
+ case 'q':
+ if (Client_Type(Client) != CLIENT_SERVER) {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ goto chan_exit;
+ }
+ case 'o': /* Channel operator */
+ case 'v': /* Voice */
+ if (arg_arg > mode_arg) {
+ if (modeok) {
+ client = Client_Search(Req->argv[arg_arg]);
+ if (client)
+ x[0] = *mode_ptr;
+ else
+ connected = IRC_WriteStrClient(Client,
+ ERR_NOSUCHNICK_MSG,
+ Client_ID(Client),
+ Req->argv[arg_arg]);
+ } else {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ }
+ Req->argv[arg_arg][0] = '\0';
+ arg_arg++;
+ } else {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Origin), Req->command);
+ goto chan_exit;
+ }
+ break;
+ /* --- Channel lists --- */
+ case 'I': /* Invite lists */
+ case 'b': /* Ban lists */
+ case 'e': /* Channel exception lists */
+ if (Mode_Limit_Reached(Client, mode_arg_count++))
+ goto chan_exit;
+ if (arg_arg > mode_arg) {
+ /* modify list */
+ if (modeok) {
+ connected = set
+ ? Add_To_List(*mode_ptr, Origin,
+ Client, Channel,
+ Req->argv[arg_arg])
+ : Del_From_List(*mode_ptr, Origin,
+ Client, Channel,
+ Req->argv[arg_arg]);
+ } else {
+ connected = IRC_WriteStrClient(Origin,
+ ERR_CHANOPRIVSNEEDED_MSG,
+ Client_ID(Origin),
+ Channel_Name(Channel));
+ }
+ Req->argv[arg_arg][0] = '\0';
+ arg_arg++;
+ } else {
+ switch (*mode_ptr) {