- default:
- can_change = 0;
- if (*user->oper)
- {
- can_change = 1;
- }
- else
- {
- if ((*i == 'i') || (*i == 'w') || (*i == 's') || (ServerInstance->ModeGrok->AllowedUmode(*i,user->modes,direction,false)))
- {
- can_change = 1;
- }
- }
- if (can_change)
- {
- if (direction == 1)
- {
- if ((!strchr(dmodes,*i)) && (ServerInstance->ModeGrok->AllowedUmode(*i,user->modes,true,false)))
- {
- if ((ServerInstance->ModeGrok->ProcessModuleUmode(*i, user, dest, direction)) || (*i == 'i') || (*i == 's') || (*i == 'w') || (*i == 'o'))
- {
- charlcat(dmodes,*i,53);
- charlcat(outpars,*i,MAXMODES);
- switch (*i)
- {
- case 'o':
- FOREACH_MOD(I_OnGlobalOper,OnGlobalOper(dest));
- break;
- case 'i':
- dest->modebits |= UM_INVISIBLE;
- break;
- case 's':
- dest->modebits |= UM_SERVERNOTICE;
- break;
- case 'w':
- dest->modebits |= UM_WALLOPS;
- break;
- default:
- break;
- }
- }
- }
- }
- else
- {
- if ((ServerInstance->ModeGrok->AllowedUmode(*i,user->modes,false,false)) && (strchr(dmodes,*i)))
- {
- if ((ServerInstance->ModeGrok->ProcessModuleUmode(*i, user, dest, direction)) || (*i == 'i') || (*i == 's') || (*i == 'w') || (*i == 'o'))
- {
- charlcat(outpars,*i,MAXMODES);
- charremove(dmodes,*i);
- switch (*i)
- {
- case 'o':
- *dest->oper = 0;
- DeleteOper(dest);
- break;
- case 'i':
- dest->modebits &= ~UM_INVISIBLE;
- break;
- case 's':
- dest->modebits &= ~UM_SERVERNOTICE;
- break;
- case 'w':
- dest->modebits &= ~UM_WALLOPS;
- break;
- default:
- break;
- }
- }
- }
- }
- }
- break;
- }
- }
- if (*outpars)
- {
- char b[MAXBUF];
- char* z = b;
-
- for (char* i = outpars; *i;)
- {
- *z++ = *i++;
- if (((*i == '-') || (*i == '+')) && ((*(i+1) == '-') || (*(i+1) == '+')))
- {
- // someones playing silly buggers and trying
- // to put a +- or -+ into the line...
- i++;
- }
- if (!*(i+1))
- {
- // Someone's trying to make the last character in
- // the line be a + or - symbol.
- if ((*i == '-') || (*i == '+'))
- {
- i++;
- }
- }
- }
- *z = 0;
-
- if ((*b) && (!IS_SINGLE(b,'+')) && (!IS_SINGLE(b,'-')))
- {
- WriteTo(user, dest, "MODE %s :%s", dest->nick, b);
- FOREACH_MOD(I_OnMode,OnMode(user, dest, TYPE_USER, b));
- }
-
- log(DEBUG,"Stripped mode line");
- log(DEBUG,"Line dest is now %s",dmodes);
- strlcpy(dest->modes,dmodes,MAXMODES-1);
-
- }
-
- return;
- }
- else
- {
- chan = FindChan(parameters[0]);
- if(chan)
- {
- if (pcnt == 1)
- {
- /* just /modes #channel */
- WriteServ(user->fd,"324 %s %s +%s",user->nick, chan->name, chanmodes(chan, chan->HasUser(user)));
- WriteServ(user->fd,"329 %s %s %d", user->nick, chan->name, chan->created);
- return;
- }
- else if (pcnt == 2)
- {
- char* mode = parameters[1];
-
- MOD_RESULT = 0;
-
- if (*mode == '+')
- mode++;
-
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, *mode, "", false, 0));
- if(!MOD_RESULT)
- {
- if (*mode == 'b')
- {
- for (BanList::iterator i = chan->bans.begin(); i != chan->bans.end(); i++)
- {
- WriteServ(user->fd,"367 %s %s %s %s %d",user->nick, chan->name, i->data, i->set_by, i->set_time);
- }
- WriteServ(user->fd,"368 %s %s :End of channel ban list",user->nick, chan->name);
- return;
- }
-
- if ((ModeDefined(*mode,MT_CHANNEL)) && (ModeIsListMode(*mode,MT_CHANNEL)))
- {
- // list of items for an extmode
- log(DEBUG,"Calling OnSendList for all modules, list output for mode %c",*mode);
- FOREACH_MOD(I_OnSendList,OnSendList(user,chan,*mode));
- return;
- }
- }
- }
-
- if ((IS_LOCAL(user)) && (!is_uline(user->server)) && (!chan->HasUser(user)))
- {
- WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, chan->name);
- return;
- }
-
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user, NULL, chan, AC_GENERAL_MODE));
-
- if(MOD_RESULT == ACR_DENY)
- return;
-
- if(MOD_RESULT == ACR_DEFAULT)
- {
- if ((IS_LOCAL(user)) && (cstatus(user,chan) < STATUS_HOP))
- {
- WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name);
- return;
- }
- }
-
- ServerInstance->ModeGrok->ProcessModes(parameters,user,chan,cstatus(user,chan),pcnt,false,false,false);
- }
- else
- {
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }