* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- * E-mail:
+ * E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
#include "inspircd_config.h"
#include "inspircd.h"
-#include "inspircd_io.h"
+#include "configreader.h"
#include <unistd.h>
#include <sys/errno.h>
#include <time.h>
{
if (!strcasecmp(i->data,dest))
{
- int MOD_RESULT = 0;
- FOREACH_RESULT(I_OnDelBan,OnDelBan(user,chan,dest));
- if (MOD_RESULT)
- return NULL;
+ int MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnDelBan,OnDelBan(user,chan,dest));
+ if (MOD_RESULT)
+ return NULL;
chan->bans.erase(i);
return dest;
}
}
else
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'o', parameters[param], false, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'o', parameters[param], false, 1));
+ if (!MOD_RESULT)
+ {
r = TakeOps(user,parameters[param++],chan,status);
}
else param++;
r = NULL;
if (mdir == 1)
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'h', parameters[param], true, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'h', parameters[param], true, 1));
+ if (!MOD_RESULT)
+ {
r = GiveHops(user,parameters[param++],chan,status);
}
else param++;
}
else
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'h', parameters[param], false, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'h', parameters[param], false, 1));
+ if (!MOD_RESULT)
+ {
r = TakeHops(user,parameters[param++],chan,status);
}
else param++;
r = NULL;
if (mdir == 1)
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'v', parameters[param], true, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'v', parameters[param], true, 1));
+ if (!MOD_RESULT)
+ {
r = GiveVoice(user,parameters[param++],chan,status);
}
else param++;
}
else
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'v', parameters[param], false, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'v', parameters[param], false, 1));
+ if (!MOD_RESULT)
+ {
r = TakeVoice(user,parameters[param++],chan,status);
}
else param++;
r = NULL;
if (mdir == 1)
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'b', parameters[param], true, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'b', parameters[param], true, 1));
+ if (!MOD_RESULT)
+ {
r = AddBan(user,parameters[param++],chan,status);
}
else param++;
}
else
{
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'b', parameters[param], false, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'b', parameters[param], false, 1));
+ if (!MOD_RESULT)
+ {
r = TakeBan(user,parameters[param++],chan,status);
}
else param++;
if (previously_set_l)
break;
previously_unset_l = true;
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'l', "", false, 0));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'l', "", false, 0));
+ if (!MOD_RESULT)
+ {
if (chan->modes[CM_LIMIT])
{
*outl++ = 'l';
if (invalid)
break;
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'l', parameters[param], true, 1));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'l', parameters[param], true, 1));
+ if (!MOD_RESULT)
+ {
chan->limit = atoi(parameters[param]);
break;
case 'i':
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'i', "", mdir, 0));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'i', "", mdir, 0));
+ if (!MOD_RESULT)
+ {
if (mdir)
{
if (!(chan->modes[CM_INVITEONLY])) *outl++ = 'i';
break;
case 't':
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 't', "", mdir, 0));
- if (!MOD_RESULT)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 't', "", mdir, 0));
+ if (!MOD_RESULT)
+ {
if (mdir)
- {
+ {
if (!(chan->modes[CM_TOPICLOCK])) *outl++ = 't';
- chan->modes[CM_TOPICLOCK] = 1;
- }
- else
- {
+ chan->modes[CM_TOPICLOCK] = 1;
+ }
+ else
+ {
if (chan->modes[CM_TOPICLOCK]) *outl++ = 't';
- chan->modes[CM_TOPICLOCK] = 0;
- }
+ chan->modes[CM_TOPICLOCK] = 0;
+ }
}
break;
case 'n':
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'n', "", mdir, 0));
- if (!MOD_RESULT)
- {
- if (mdir)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'n', "", mdir, 0));
+ if (!MOD_RESULT)
+ {
+ if (mdir)
+ {
if (!(chan->modes[CM_NOEXTERNAL])) *outl++ = 'n';
- chan->modes[CM_NOEXTERNAL] = 1;
- }
- else
- {
+ chan->modes[CM_NOEXTERNAL] = 1;
+ }
+ else
+ {
if (chan->modes[CM_NOEXTERNAL]) *outl++ = 'n';
- chan->modes[CM_NOEXTERNAL] = 0;
- }
+ chan->modes[CM_NOEXTERNAL] = 0;
+ }
}
break;
case 'm':
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'm', "", mdir, 0));
- if (!MOD_RESULT)
- {
- if (mdir)
- {
- if (!(chan->modes[CM_MODERATED])) *outl++ = 'm';
- chan->modes[CM_MODERATED] = 1;
- }
- else
- {
- if (chan->modes[CM_MODERATED]) *outl++ = 'm';
- chan->modes[CM_MODERATED] = 0;
- }
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'm', "", mdir, 0));
+ if (!MOD_RESULT)
+ {
+ if (mdir)
+ {
+ if (!(chan->modes[CM_MODERATED])) *outl++ = 'm';
+ chan->modes[CM_MODERATED] = 1;
+ }
+ else
+ {
+ if (chan->modes[CM_MODERATED]) *outl++ = 'm';
+ chan->modes[CM_MODERATED] = 0;
+ }
}
break;
case 's':
- MOD_RESULT = 0;
- FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 's', "", mdir, 0));
- if (!MOD_RESULT)
- {
- if (mdir)
- {
- if (!(chan->modes[CM_SECRET])) *outl++ = 's';
- chan->modes[CM_SECRET] = 1;
- if (chan->modes[CM_PRIVATE])
- {
- chan->modes[CM_PRIVATE] = 0;
- if (mdir)
- {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 's', "", mdir, 0));
+ if (!MOD_RESULT)
+ {
+ if (mdir)
+ {
+ if (!(chan->modes[CM_SECRET])) *outl++ = 's';
+ chan->modes[CM_SECRET] = 1;
+ if (chan->modes[CM_PRIVATE])
+ {
+ chan->modes[CM_PRIVATE] = 0;
+ if (mdir)
+ {
*outl++ = '-'; *outl++ = 'p'; *outl++ = '+';
- }
- }
- }
- else
- {
- if (chan->modes[CM_SECRET]) *outl++ = 's';
- chan->modes[CM_SECRET] = 0;
- }
+ }
+ }
+ }
+ else
+ {
+ if (chan->modes[CM_SECRET]) *outl++ = 's';
+ chan->modes[CM_SECRET] = 0;
+ }
}
break;
void cmd_mode::Handle (char **parameters, int pcnt, userrec *user)
{
- /*
- * In theory what happens is...
- *
- * Parse mode string here.
- *
- * For each mode character, check against a list of mode 'watchers',
- * a watcher can explicitly deny or allow a mode, it can also modify
- * the mode parameter if there is one.
- *
- * If the mode passes all the 'watchers's checks, call a mode 'handler'
- * for the mode, if one of the watchers said to explicitly allow it then
- * the mode handler will have a flag set, this *should* be honoured and
- * access checks *should* be overridden.
- *
- */
-
- /*
- * Mode handlers should be added with Server::AddHandler(), or some backend call that it uses.
- *
- * Watchers should be added with Server::AddWatcher() or likewise a backend call for it,
- * there should be a way of adding a watcher for all modes, and whatever the method of
- * the watchers that gets called is should have a parameter giving the mode.
- */
-
- /* All module callbacks for modes will be removed. */
-
- /*
- * How I *think* this works is that cmd_mode::Handle() has access checks for modes, but
- * ModeParser::ServerMode() doesn't...
- */
-
chanrec* chan;
- userrec* dest;
+ userrec* dest = Find(parameters[0]);
+ int MOD_RESULT;
+ int can_change;
+ int direction = 1;
+ char outpars[MAXBUF];
+ bool next_ok = true;
+
+ if (!user)
+ return;
- if(!user)
+ if ((dest) && (pcnt == 1))
{
- log(DEBUG, "cmd_mode::Handle() got a null user");
+ WriteServ(user->fd,"221 %s :+%s",dest->nick,dest->modes);
return;
}
-
- if(dest = Find(parameters[0]))
+ else if ((dest) && (pcnt > 1))
{
- if(pcnt == 1)
- {
- /* If there was only one parameter, they were just asking what modes someone has. */
- WriteServ(user->fd, "221 %s :+%s",dest->nick,dest->modes);
- return;
- }
- else if(pcnt > 1)
+ std::string tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false);
+ parameters[1] = (char*)tidied.c_str();
+
+ char dmodes[MAXBUF];
+ strlcpy(dmodes,dest->modes,MAXMODES);
+ log(DEBUG,"pulled up dest user modes: %s",dmodes);
+
+ can_change = 0;
+ if (user != dest)
{
- ServerInstance->ModeGrok->HandleUserModes(parameters, pcnt, user, dest);
- return;
+ if ((*user->oper) || (is_uline(user->server)))
+ {
+ can_change = 1;
+ }
}
- }
- else if(chan = FindChan(parameters[0]))
- {
- if(pcnt == 1)
+ else
{
- /* One parameter, just tell them the channel's modes. */
- 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;
+ can_change = 1;
}
- else if(pcnt > 1)
+ if (!can_change)
{
- ServerInstance->ModeGrok->HandleChannelModes(parameters, pcnt, user, chan);
+ WriteServ(user->fd,"482 %s :Can't change mode for other users",user->nick);
return;
}
- }
- else
- {
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }
-}
-
-void ModeParser::HandleUserModes(char** parameters, int pcnt, userrec* user, userrec* target)
-{
- std::string tidied;
- bool setting_on;
- /* XXX - Neccessary? */
- char dmodes[MAXBUF];
- char out[MAXBUF];
- char* outend;
- char* outpos;
-
- /* XXX - This is nasty, change it somehow so we don't create a std::string and then pretty much discard it */
- /* Maybe as the mode string will always get shorter then we should just pass a char* and modify that? */
- /* This should _not_ leave any '+-+-' in the string, it should be well-formed "+a-b+c" */
- tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false);
- parameters[1] = (char*)tidied.c_str();
-
- strlcpy(dmodes,dest->modes,MAXMODES);
- log(DEBUG,"pulled up dest user modes: %s",dmodes);
+
+ outpars[0] = *parameters[1];
+ outpars[1] = 0;
+ direction = (*parameters[1] == '+');
- if((user != dest) && (!*user->oper) && (!is_uline(user->server)))
- {
- WriteServ(user->fd,"482 %s :Can't change mode for other users",user->nick);
- return;
- }
-
- /*
- * Leaving this so a mode string with no + or - is taken as having a +.
- */
-
- *outpos = (*parameters[1] == '-') ? '-' : '+';
-
- setting_on = true;
- outend = out+MAXBUF;
- outpos = out;
-
- /*
- * outpos always points at where the next char should be added,
- * we have added the first character before we enter the loop
- * so it's safe to check --outpos
- */
+ if ((*parameters[1] != '+') && (*parameters[1] != '-'))
+ return;
- for(char* i = parameters[1]; *i; i++)
- {
- if(outpos == outend)
- {
- /* We somehow hit the end of our buffer... :s */
- break;
- }
-
- switch (*i)
+ for (char* i = parameters[1]; *i; i++)
{
- case ' ':
- /* When does this happen? */
+ if ((i != parameters[1]) && (*i != '+') && (*i != '-'))
+ next_ok = true;
+
+ switch (*i)
+ {
+ case ' ':
continue;
- case '+':
- if(!setting_on && (*--outpos != '-'))
- {
- charlcat(outpars,'+',MAXBUF);
- next_ok = false;
- }
- direction = 1;
+ case '+':
+ if ((direction != 1) && (next_ok))
+ {
+ charlcat(outpars,'+',MAXBUF);
+ next_ok = false;
+ }
+ direction = 1;
break;
case '-':
if ((dest) && (pcnt > 1))
{
- std::string tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false);
- parameters[1] = (char*)tidied.c_str();
+ std::string tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false);
+ parameters[1] = (char*)tidied.c_str();
char dmodes[MAXBUF];
strlcpy(dmodes,dest->modes,MAXBUF);
switch (*i)
{
- case ' ':
- continue;
+ case ' ':
+ continue;
case '+':
if ((direction != 1) && (next_ok))
{
charlcat(dmodes,*i,MAXBUF);
charlcat(outpars,*i,53);
- switch (*i)
- {
- case 'i':
- dest->modebits |= UM_INVISIBLE;
- break;
- case 's':
- dest->modebits |= UM_SERVERNOTICE;
- break;
- case 'w':
- dest->modebits |= UM_WALLOPS;
- break;
- default:
- break;
- }
+ switch (*i)
+ {
+ case 'i':
+ dest->modebits |= UM_INVISIBLE;
+ break;
+ case 's':
+ dest->modebits |= UM_SERVERNOTICE;
+ break;
+ case 'w':
+ dest->modebits |= UM_WALLOPS;
+ break;
+ default:
+ break;
+ }
}
}
}
{
charlcat(outpars,*i,MAXBUF);
charremove(dmodes,*i);
- switch (*i)
- {
- case 'i':
- dest->modebits &= ~UM_INVISIBLE;
- break;
- case 's':
- dest->modebits &= ~UM_SERVERNOTICE;
- break;
- case 'w':
- dest->modebits &= ~UM_WALLOPS;
- break;
- default:
- break;
- }
+ switch (*i)
+ {
+ 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);
-
- }
+ 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;
}