X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmode.cpp;h=40ef66f0db76e75bb9a146cf0b5a3e3e0363aeec;hb=59b1a8955142935b02af6446005ab47fc7c3fc8c;hp=5ce7c95adbc17172aa9cef6a51a034f1b257c13d;hpb=496ef08226f93d877d90e56076704795fa349a4b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/mode.cpp b/src/mode.cpp index 5ce7c95ad..40ef66f0d 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. * E-mail: * * @@ -14,16 +14,13 @@ * --------------------------------------------------- */ +using namespace std; + +#include "inspircd_config.h" #include "inspircd.h" #include "inspircd_io.h" -#include "inspircd_util.h" -#include "inspircd_config.h" #include -#include #include -#include -#include -#include #include #include #ifdef GCC3 @@ -34,14 +31,9 @@ #include #include #include -#include #include -#include -#include -#include #include "connection.h" #include "users.h" -#include "servers.h" #include "ctables.h" #include "globals.h" #include "modules.h" @@ -50,138 +42,112 @@ #include "message.h" #include "commands.h" #include "xline.h" - -using namespace std; +#include "inspstring.h" +#include "helperfuncs.h" +#include "mode.h" extern int MODCOUNT; -extern vector modules; -extern vector factory; -extern std::vector module_names; - - -extern int LogLevel; -extern char ServerName[MAXBUF]; -extern char Network[MAXBUF]; -extern char ServerDesc[MAXBUF]; -extern char AdminName[MAXBUF]; -extern char AdminEmail[MAXBUF]; -extern char AdminNick[MAXBUF]; -extern char diepass[MAXBUF]; -extern char restartpass[MAXBUF]; -extern char motd[MAXBUF]; -extern char rules[MAXBUF]; -extern char list[MAXBUF]; -extern char PrefixQuit[MAXBUF]; -extern char DieValue[MAXBUF]; - -extern bool AllowHalfop; -extern bool AllowProtect; -extern bool AllowFounder; - - -char* give_ops(userrec *user,char *dest,chanrec *chan,int status) +extern std::vector modules; +extern std::vector factory; +extern InspIRCd* ServerInstance; +extern ServerConfig* Config; + +extern time_t TIME; + +char* ModeParser::GiveOps(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) - { - log(DEFAULT,"*** BUG *** give_ops was given an invalid parameter"); - return NULL; - } - - if (!isnick(dest)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"the target nickname given to give_ops was invalid"); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + log(DEFAULT,"*** BUG *** GiveOps was given an invalid parameter"); return NULL; } d = Find(dest); if (!d) { - log(DEFAULT,"the target nickname given to give_ops couldnt be found"); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + log(DEFAULT,"the target nickname given to GiveOps couldnt be found"); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_OP)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_OP) && (!is_uline(user->server))) - { - log(DEBUG,"%s cant give ops to %s because they nave status %d and needs %d",user->nick,dest,status,STATUS_OP); - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_OP)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((status < STATUS_OP) && (!is_uline(user->server)) && (IS_LOCAL(user))) + { + log(DEBUG,"%s cant give ops to %s because they nave status %d and needs %d",user->nick,dest,status,STATUS_OP); + WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + return NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) { - if (d->chans[i].uc_modes & UCMODE_OP) + if (d->chans[i].uc_modes & UCMODE_OP) { /* mode already set on user, dont allow multiple */ - log(DEFAULT,"The target user given to give_ops was already opped on the channel"); return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_OP; + d->chans[i].channel->AddOppedUser((char*)d); log(DEBUG,"gave ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } } - log(DEFAULT,"The target channel given to give_ops was not in the users mode list"); + log(DEFAULT,"The target channel given to GiveOps was not in the users mode list"); } return NULL; } -char* give_hops(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::GiveHops(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"*** BUG *** give_hops was given an invalid parameter"); + log(DEFAULT,"*** BUG *** GiveHops was given an invalid parameter"); return NULL; } d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; - } if (!d) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_HALFOP)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_OP) && (!is_uline(user->server))) - { - WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_HALFOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((status < STATUS_OP) && (!is_uline(user->server)) && (IS_LOCAL(user))) + { + WriteServ(user->fd,"482 %s %s :You're not a channel operator",user->nick, chan->name); + return NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) @@ -192,6 +158,7 @@ char* give_hops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_HOP; + d->chans[i].channel->AddHalfoppedUser((char*)d); log(DEBUG,"gave h-ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -200,45 +167,42 @@ char* give_hops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } -char* give_voice(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::GiveVoice(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"*** BUG *** give_voice was given an invalid parameter"); + log(DEFAULT,"*** BUG *** GiveVoice was given an invalid parameter"); return NULL; } d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; - } if (!d) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_VOICE)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_HOP) && (!is_uline(user->server))) - { - WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_VOICE)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((status < STATUS_HOP) && (!is_uline(user->server)) && (IS_LOCAL(user))) + { + 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 NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) @@ -249,6 +213,7 @@ char* give_voice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_VOICE; + d->chans[i].channel->AddVoicedUser((char*)d); log(DEBUG,"gave voice: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -257,47 +222,43 @@ char* give_voice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } -char* take_ops(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::TakeOps(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"*** BUG *** take_ops was given an invalid parameter"); + log(DEFAULT,"*** BUG *** TakeOps was given an invalid parameter"); return NULL; } d = Find(dest); - if (!isnick(dest)) - { - log(DEBUG,"take_ops was given an invalid target nickname of %s",dest); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; - } if (!d) { - log(DEBUG,"take_ops couldnt resolve the target nickname: %s",dest); - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + log(DEBUG,"TakeOps couldnt resolve the target nickname: %s",dest); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEOP)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_OP) && (!is_uline(user->server))) - { - WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_DEOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((status < STATUS_OP) && (!is_uline(user->server)) && (IS_LOCAL(user)) && (IS_LOCAL(user))) + { + WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + return NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) @@ -308,54 +269,53 @@ char* take_ops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_OP; + d->chans[i].channel->DelOppedUser((char*)d); log(DEBUG,"took ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } } - log(DEBUG,"take_ops couldnt locate the target channel in the target users list"); + log(DEBUG,"TakeOps couldnt locate the target channel in the target users list"); } return NULL; } -char* take_hops(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::TakeHops(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"*** BUG *** take_hops was given an invalid parameter"); + log(DEFAULT,"*** BUG *** TakeHops was given an invalid parameter"); return NULL; } d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; - } if (!d) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEHALFOP)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_OP) && (!is_uline(user->server))) - { - WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_DEHALFOP)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + /* Tweak by Brain suggested by w00t, allow a halfop to dehalfop themselves */ + if ((user != d) && ((status < STATUS_OP) && (!is_uline(user->server))) && (IS_LOCAL(user))) + { + WriteServ(user->fd,"482 %s %s :You are not a channel operator",user->nick, chan->name); + return NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) @@ -366,6 +326,7 @@ char* take_hops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_HOP; + d->chans[i].channel->DelHalfoppedUser((char*)d); log(DEBUG,"took h-ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -374,45 +335,42 @@ char* take_hops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } -char* take_voice(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::TakeVoice(userrec *user,char *dest,chanrec *chan,int status) { userrec *d; - int i; - if ((!user) || (!dest) || (!chan)) + if ((!user) || (!dest) || (!chan) || (!*dest)) { - log(DEFAULT,"*** BUG *** take_voice was given an invalid parameter"); + log(DEFAULT,"*** BUG *** TakeVoice was given an invalid parameter"); return NULL; } d = Find(dest); - if (!isnick(dest)) - { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); - return NULL; - } if (!d) { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, dest); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, dest); return NULL; } else { - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,d,chan,AC_DEVOICE)); - - if (MOD_RESULT == ACR_DENY) - return NULL; - if (MOD_RESULT == ACR_DEFAULT) + if (user->server == d->server) { - if ((status < STATUS_HOP) && (!is_uline(user->server))) - { - WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, chan->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_DEVOICE)); + + if (MOD_RESULT == ACR_DENY) return NULL; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((status < STATUS_HOP) && (!is_uline(user->server)) && (IS_LOCAL(user))) + { + 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 NULL; + } } } - for (int i = 0; i != MAXCHANS; i++) + for (unsigned int i = 0; i < d->chans.size(); i++) { if ((d->chans[i].channel != NULL) && (chan != NULL)) if (!strcasecmp(d->chans[i].channel->name,chan->name)) @@ -423,6 +381,7 @@ char* take_voice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_VOICE; + d->chans[i].channel->DelVoicedUser((char*)d); log(DEBUG,"took voice: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -431,39 +390,54 @@ char* take_voice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } -char* add_ban(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::AddBan(userrec *user,char *dest,chanrec *chan,int status) { - if ((!user) || (!dest) || (!chan)) { - log(DEFAULT,"*** BUG *** add_ban was given an invalid parameter"); + BanItem b; + int toomanyexclamation = 0; + int toomanyat = 0; + + if ((!user) || (!dest) || (!chan) || (!*dest)) + { + log(DEFAULT,"*** BUG *** AddBan was given an invalid parameter"); return NULL; } - BanItem b; - if ((!user) || (!dest) || (!chan)) - return NULL; - if (strchr(dest,'!')==0) - return NULL; - if (strchr(dest,'@')==0) - return NULL; - for (int i = 0; i < strlen(dest); i++) - if (dest[i] < 32) - return NULL; - for (int i = 0; i < strlen(dest); i++) - if (dest[i] > 126) + for (char* i = dest; *i; i++) + { + if ((*i < 32) || (*i > 126)) + { return NULL; - int c = 0; - for (int i = 0; i < strlen(dest); i++) - if (dest[i] == '!') - c++; - if (c>1) + } + else if (*i == '!') + { + toomanyexclamation++; + } + else if (*i == '@') + { + toomanyat++; + } + } + + if (toomanyexclamation != 1 || toomanyat != 1) + /* + * this stops sillyness like n!u!u!u@h, though note that most + * ircds don't actually verify banmask validity. --w00t + */ return NULL; - c = 0; - for (int i = 0; i < strlen(dest); i++) - if (dest[i] == '@') - c++; - if (c>1) + + long maxbans = GetMaxBans(chan->name); + if ((unsigned)chan->bans.size() > (unsigned)maxbans) + { + WriteServ(user->fd,"478 %s %s :Channel ban list for %s is full (maximum entries for this channel is %d)",user->nick, chan->name,chan->name,maxbans); + return NULL; + } + + log(DEBUG,"AddBan: %s %s",chan->name,user->nick); + + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAddBan,OnAddBan(user,chan,dest)); + if (MOD_RESULT) return NULL; - log(DEBUG,"add_ban: %s %s",chan->name,user->nick); TidyBan(dest); for (BanList::iterator i = chan->bans.begin(); i != chan->bans.end(); i++) @@ -475,17 +449,24 @@ char* add_ban(userrec *user,char *dest,chanrec *chan,int status) } } - b.set_time = time(NULL); - strncpy(b.data,dest,MAXBUF); - strncpy(b.set_by,user->nick,NICKMAX); + b.set_time = TIME; + strlcpy(b.data,dest,MAXBUF); + if (*user->nick) + { + strlcpy(b.set_by,user->nick,NICKMAX-1); + } + else + { + strlcpy(b.set_by,Config->ServerName,NICKMAX-1); + } chan->bans.push_back(b); return dest; } -char* take_ban(userrec *user,char *dest,chanrec *chan,int status) +char* ModeParser::TakeBan(userrec *user,char *dest,chanrec *chan,int status) { - if ((!user) || (!dest) || (!chan)) { - log(DEFAULT,"*** BUG *** take_ban was given an invalid parameter"); + if ((!user) || (!dest) || (!chan) || (!*dest)) { + log(DEFAULT,"*** BUG *** TakeBan was given an invalid parameter"); return 0; } @@ -494,6 +475,10 @@ char* take_ban(userrec *user,char *dest,chanrec *chan,int status) { if (!strcasecmp(i->data,dest)) { + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnDelBan,OnDelBan(user,chan,dest)); + if (MOD_RESULT) + return NULL; chan->bans.erase(i); return dest; } @@ -501,7 +486,56 @@ char* take_ban(userrec *user,char *dest,chanrec *chan,int status) return NULL; } -void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int pcnt, bool servermode, bool silent, bool local) +// tidies up redundant modes, e.g. +nt-nt+i becomes +-+i, +// a section further down the chain tidies up the +-+- crap. +std::string ModeParser::CompressModes(std::string modes,bool channelmodes) +{ + int counts[127]; + bool active[127]; + memset(counts,0,sizeof(counts)); + memset(active,0,sizeof(active)); + for (unsigned int i = 0; i < modes.length(); i++) + { + if ((modes[i] == '+') || (modes[i] == '-')) + continue; + if (channelmodes) + { + if ((strchr("itnmsp",modes[i])) || ((ModeDefined(modes[i],MT_CHANNEL)) && (ModeDefinedOn(modes[i],MT_CHANNEL)==0) && (ModeDefinedOff(modes[i],MT_CHANNEL)==0))) + { + log(DEBUG,"Tidy mode %c",modes[i]); + counts[(unsigned int)modes[i]]++; + active[(unsigned int)modes[i]] = true; + } + } + else + { + log(DEBUG,"Tidy mode %c",modes[i]); + counts[(unsigned int)modes[i]]++; + active[(unsigned int)modes[i]] = true; + } + } + for (int j = 65; j < 127; j++) + { + if ((counts[j] > 1) && (active[j] == true)) + { + static char v[2]; + v[0] = (unsigned char)j; + v[1] = '\0'; + std::string mode_str = v; + std::string::size_type pos = modes.find(mode_str); + if (pos != std::string::npos) + { + log(DEBUG,"all occurances of mode %c to be deleted...",(unsigned char)j); + while (modes.find(mode_str) != std::string::npos) + modes.erase(modes.find(mode_str),1); + log(DEBUG,"New mode line: %s",modes.c_str()); + } + } + } + return modes; +} + +void ModeParser::ProcessModes(char **parameters,userrec* user,chanrec *chan,int status, int pcnt, bool servermode, bool silent, bool local) { if (!parameters) { log(DEFAULT,"*** BUG *** process_modes was given an invalid parameter"); @@ -517,7 +551,7 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int int ptr = 0; int mdir = 1; char* r = NULL; - bool k_set = false, l_set = false; + bool k_set = false, l_set = false, previously_set_l = false, previously_unset_l = false, previously_set_k = false, previously_unset_k = false; if (pcnt < 2) { @@ -525,36 +559,52 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int } int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,NULL,chan,AC_GENERAL_MODE)); - if (MOD_RESULT == ACR_DENY) - return; + if (IS_LOCAL(user)) + { + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,NULL,chan,AC_GENERAL_MODE)); + if (MOD_RESULT == ACR_DENY) + return; + } log(DEBUG,"process_modes: start: parameters=%d",pcnt); - strcpy(modelist,parameters[1]); /* mode list, e.g. +oo-o */ - /* parameters[2] onwards are parameters for - * modes that require them :) */ - strcpy(outlist,"+"); + strlcpy(modelist,parameters[1],MAXBUF); /* mode list, e.g. +oo-o * + * parameters[2] onwards are parameters for + * modes that require them :) */ + *outlist = '+'; + *(outlist+1) = 0; mdir = 1; log(DEBUG,"process_modes: modelist: %s",modelist); - for (ptr = 0; ptr < strlen(modelist); ptr++) + std::string tidied = this->CompressModes(modelist,true); + strlcpy(modelist,tidied.c_str(),MAXBUF); + + int len = tidied.length(); + while (modelist[len-1] == ' ') + modelist[--len] = '\0'; + + for (char* modechar = modelist; *modechar; ptr++, modechar++) { r = NULL; + /* If we have more than MAXMODES changes in one line, + * drop all after the MAXMODES + */ + if (pc > MAXMODES-1) + break; + { - log(DEBUG,"process_modes: modechar: %c",modelist[ptr]); - char modechar = modelist[ptr]; - switch (modelist[ptr]) + switch (*modechar) { case '-': if (mdir != 0) { - if ((outlist[strlen(outlist)-1] == '+') || (outlist[strlen(outlist)-1] == '-')) + int t = strlen(outlist)-1; + if ((outlist[t] == '+') || (outlist[t] == '-')) { - outlist[strlen(outlist)-1] = '-'; + outlist[t] = '-'; } else { @@ -568,9 +618,10 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int case '+': if (mdir != 1) { - if ((outlist[strlen(outlist)-1] == '+') || (outlist[strlen(outlist)-1] == '-')) + int t = strlen(outlist)-1; + if ((outlist[t] == '+') || (outlist[t] == '-')) { - outlist[strlen(outlist)-1] = '+'; + outlist[t] = '+'; } else { @@ -584,72 +635,124 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int log(DEBUG,"Ops"); if ((param >= pcnt)) break; log(DEBUG,"Enough parameters left"); + r = NULL; if (mdir == 1) { - log(DEBUG,"calling give_ops"); - r = give_ops(user,parameters[param++],chan,status); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'o', parameters[param], true, 1)); + if (!MOD_RESULT) + { + log(DEBUG,"calling GiveOps"); + r = GiveOps(user,parameters[param++],chan,status); + } + else param++; } else { - log(DEBUG,"calling take_ops"); - r = take_ops(user,parameters[param++],chan,status); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'o', parameters[param], false, 1)); + if (!MOD_RESULT) + { + log(DEBUG,"calling TakeOps"); + r = TakeOps(user,parameters[param++],chan,status); + } + else param++; } if (r) { - strcat(outlist,"o"); - strcpy(outpars[pc++],r); + strlcat(outlist,"o",MAXBUF); + strlcpy(outpars[pc++],r,MAXBUF); } break; case 'h': - if (((param >= pcnt)) || (!AllowHalfop)) break; + if (((param >= pcnt)) || (!Config->AllowHalfop)) break; + r = NULL; if (mdir == 1) { - r = give_hops(user,parameters[param++],chan,status); + 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 { - r = take_hops(user,parameters[param++],chan,status); + 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++; } if (r) { - strcat(outlist,"h"); - strcpy(outpars[pc++],r); + strlcat(outlist,"h",MAXBUF); + strlcpy(outpars[pc++],r,MAXBUF); } break; case 'v': if ((param >= pcnt)) break; + r = NULL; if (mdir == 1) { - r = give_voice(user,parameters[param++],chan,status); + 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 { - r = take_voice(user,parameters[param++],chan,status); + 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++; } if (r) { - strcat(outlist,"v"); - strcpy(outpars[pc++],r); + strlcat(outlist,"v",MAXBUF); + strlcpy(outpars[pc++],r,MAXBUF); } break; case 'b': if ((param >= pcnt)) break; + r = NULL; if (mdir == 1) { - r = add_ban(user,parameters[param++],chan,status); + 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 { - r = take_ban(user,parameters[param++],chan,status); + 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 (r) { - strcat(outlist,"b"); - strcpy(outpars[pc++],parameters[param-1]); + strlcat(outlist,"b",MAXBUF); + strlcpy(outpars[pc++],parameters[param-1],MAXBUF); } break; @@ -662,46 +765,68 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int { if (k_set) break; + + if (previously_unset_k) + break; + previously_set_k = true; - if (!strcmp(chan->key,"")) + if (!*chan->key) { - strcat(outlist,"k"); - char key[MAXBUF]; - strcpy(key,parameters[param++]); - if (strlen(key)>32) { - key[31] = '\0'; + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'k', parameters[param], true, 1)); + if (!MOD_RESULT) + { + strcat(outlist,"k"); + char key[MAXBUF]; + strlcpy(key,parameters[param++],32); + strlcpy(outpars[pc++],key,MAXBUF); + strlcpy(chan->key,key,MAXBUF); + k_set = true; } - strcpy(outpars[pc++],key); - strcpy(chan->key,key); - k_set = true; + else param++; } } else { /* checks on -k are case sensitive and only accurate to the first 32 characters */ + if (previously_set_k) + break; + previously_unset_k = true; + char key[MAXBUF]; - strcpy(key,parameters[param++]); - if (strlen(key)>32) { - key[31] = '\0'; - } - /* only allow -k if correct key given */ - if (!strcmp(chan->key,key)) + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'k', parameters[param], false, 1)); + if (!MOD_RESULT) { - strcat(outlist,"k"); - strcpy(chan->key,""); - strcpy(outpars[pc++],key); + strlcpy(key,parameters[param++],32); + /* only allow -k if correct key given */ + if (!strcmp(chan->key,key)) + { + strlcat(outlist,"k",MAXBUF); + strlcpy(chan->key,"",MAXBUF); + strlcpy(outpars[pc++],key,MAXBUF); + } } + else param++; } break; case 'l': if (mdir == 0) { - if (chan->limit) - { - strcat(outlist,"l"); - chan->limit = 0; + 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) + { + if (chan->limit) + { + strcat(outlist,"l"); + chan->limit = 0; + } } } @@ -710,132 +835,193 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int { if (l_set) break; - + if (previously_unset_l) + break; + previously_set_l = true; bool invalid = false; - for (int i = 0; i < strlen(parameters[param]); i++) + for (char* f = parameters[param]; *f; f++) { - if ((parameters[param][i] < '0') || (parameters[param][i] > '9')) + if ((*f < '0') || (*f > '9')) { invalid = true; } } - if (atoi(parameters[param]) < 1) + /* If the limit is < 1, or the new limit is the current limit, dont allow */ + if ((atoi(parameters[param]) < 1) || ((chan->limit > 0) && (atoi(parameters[param]) == chan->limit))) { invalid = true; } if (invalid) break; - - chan->limit = atoi(parameters[param]); - - // reported by mech: large values cause underflow - if (chan->limit < 0) - chan->limit = 0x7FFFFF; + + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'l', parameters[param], true, 1)); + if (!MOD_RESULT) + { + + chan->limit = atoi(parameters[param]); + + // reported by mech: large values cause underflow + if (chan->limit < 0) + chan->limit = 0x7FFF; + } if (chan->limit) { - strcat(outlist,"l"); - strcpy(outpars[pc++],parameters[param++]); + strlcat(outlist,"l",MAXBUF); + strlcpy(outpars[pc++],parameters[param++],MAXBUF); l_set = true; } } break; case 'i': - if (chan->inviteonly != mdir) - { - strcat(outlist,"i"); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'i', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_INVITEONLY)) strlcat(outlist,"i",MAXBUF); + chan->binarymodes |= CM_INVITEONLY; + } + else + { + if (chan->binarymodes & CM_INVITEONLY) strlcat(outlist,"i",MAXBUF); + chan->binarymodes &= ~CM_INVITEONLY; + } } - chan->inviteonly = mdir; break; case 't': - if (chan->topiclock != mdir) - { - strcat(outlist,"t"); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 't', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_TOPICLOCK)) strlcat(outlist,"t",MAXBUF); + chan->binarymodes |= CM_TOPICLOCK; + } + else + { + if (chan->binarymodes & CM_TOPICLOCK) strlcat(outlist,"t",MAXBUF); + chan->binarymodes &= ~CM_TOPICLOCK; + } } - chan->topiclock = mdir; break; case 'n': - if (chan->noexternal != mdir) - { - strcat(outlist,"n"); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'n', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_NOEXTERNAL)) strlcat(outlist,"n",MAXBUF); + chan->binarymodes |= CM_NOEXTERNAL; + } + else + { + if (chan->binarymodes & CM_NOEXTERNAL) strlcat(outlist,"n",MAXBUF); + chan->binarymodes &= ~CM_NOEXTERNAL; + } } - chan->noexternal = mdir; break; case 'm': - if (chan->moderated != mdir) - { - strcat(outlist,"m"); + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'm', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_MODERATED)) strlcat(outlist,"m",MAXBUF); + chan->binarymodes |= CM_MODERATED; + } + else + { + if (chan->binarymodes & CM_MODERATED) strlcat(outlist,"m",MAXBUF); + chan->binarymodes &= ~CM_MODERATED; + } } - chan->moderated = mdir; break; case 's': - if (chan->secret != mdir) - { - strcat(outlist,"s"); - if (chan->c_private) - { - chan->c_private = 0; - if (mdir) - { - strcat(outlist,"-p+"); - } - else - { - strcat(outlist,"+p-"); - } - } + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 's', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_SECRET)) strlcat(outlist,"s",MAXBUF); + chan->binarymodes |= CM_SECRET; + if (chan->binarymodes & CM_PRIVATE) + { + chan->binarymodes &= ~CM_PRIVATE; + if (mdir) + { + strlcat(outlist,"-p+",MAXBUF); + } + } + } + else + { + if (chan->binarymodes & CM_SECRET) strlcat(outlist,"s",MAXBUF); + chan->binarymodes &= ~CM_SECRET; + } } - chan->secret = mdir; break; case 'p': - if (chan->c_private != mdir) - { - strcat(outlist,"p"); - if (chan->secret) - { - chan->secret = 0; - if (mdir) - { - strcat(outlist,"-s+"); - } - else - { - strcat(outlist,"+s-"); - } - } + MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, 'p', "", mdir, 0)); + if (!MOD_RESULT) + { + if (mdir) + { + if (!(chan->binarymodes & CM_PRIVATE)) strlcat(outlist,"p",MAXBUF); + chan->binarymodes |= CM_PRIVATE; + if (chan->binarymodes & CM_SECRET) + { + chan->binarymodes &= ~CM_SECRET; + if (mdir) + { + strlcat(outlist,"-s+",MAXBUF); + } + } + } + else + { + if (chan->binarymodes & CM_PRIVATE) strlcat(outlist,"p",MAXBUF); + chan->binarymodes &= ~CM_PRIVATE; + } } - chan->c_private = mdir; break; default: - log(DEBUG,"Preprocessing custom mode %c: modelist: %s",modechar,chan->custom_modes); + log(DEBUG,"Preprocessing custom mode %c: modelist: %s",*modechar,chan->custom_modes); string_list p; p.clear(); - if (((!strchr(chan->custom_modes,modechar)) && (!mdir)) || ((strchr(chan->custom_modes,modechar)) && (mdir))) + if (((!strchr(chan->custom_modes,*modechar)) && (!mdir)) || ((strchr(chan->custom_modes,*modechar)) && (mdir))) { - if (!ModeIsListMode(modechar,MT_CHANNEL)) + if (!ModeIsListMode(*modechar,MT_CHANNEL)) { - log(DEBUG,"Mode %c isnt set on %s but trying to remove!",modechar,chan->name); + log(DEBUG,"Mode %c isnt set on %s but trying to remove!",*modechar,chan->name); break; } } - if (ModeDefined(modechar,MT_CHANNEL)) + if (ModeDefined(*modechar,MT_CHANNEL)) { log(DEBUG,"A module has claimed this mode"); if (param0) && (mdir)) + if ((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir)) { p.push_back(parameters[param]); } - if ((ModeDefinedOff(modechar,MT_CHANNEL)>0) && (!mdir)) + if ((ModeDefinedOff(*modechar,MT_CHANNEL)>0) && (!mdir)) { p.push_back(parameters[param]); } @@ -844,64 +1030,82 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int if (param>=pcnt) { // we're supposed to have a parameter, but none was given... so dont handle the mode. - if (((ModeDefinedOn(modechar,MT_CHANNEL)>0) && (mdir)) || ((ModeDefinedOff(modechar,MT_CHANNEL)>0) && (!mdir))) + if (((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir)) || ((ModeDefinedOff(*modechar,MT_CHANNEL)>0) && (!mdir))) { - log(DEBUG,"Not enough parameters for module-mode %c",modechar); + log(DEBUG,"Not enough parameters for module-mode %c",*modechar); handled = true; param++; } } - for (int i = 0; i <= MODCOUNT; i++) - { - if (!handled) + + // BIG ASS IDIOTIC CODER WARNING! + // Using OnRawMode on another modules mode's behavour + // will confuse the crap out of admins! just because you CAN + // do it, doesnt mean you SHOULD! + MOD_RESULT = 0; + std::string para = ""; + if (p.size()) + para = p[0]; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, chan, *modechar, para, mdir, pcnt)); + if (!MOD_RESULT) + { + for (int i = 0; i <= MODCOUNT; i++) { - int t = modules[i]->OnExtendedMode(user,chan,modechar,MT_CHANNEL,mdir,p); - if (t != 0) + if (!handled) { - log(DEBUG,"OnExtendedMode returned nonzero for a module"); - char app[] = {modechar, 0}; - if (ModeIsListMode(modechar,MT_CHANNEL)) + int t = modules[i]->OnExtendedMode(user,chan,*modechar,MT_CHANNEL,mdir,p); + if (t != 0) { - if (t == -1) - { - pc++; - } - else + log(DEBUG,"OnExtendedMode returned nonzero for a module"); + char app[] = {*modechar, 0}; + if (ModeIsListMode(*modechar,MT_CHANNEL)) { - if (ptr>0) + if (t == -1) + { + //pc++; + param++; + } + else { - strcat(outlist, app); + if (ptr>0) + { + strlcat(outlist, app,MAXBUF); + } + strlcpy(outpars[pc++],parameters[param++],MAXBUF); } - strcpy(outpars[pc++],parameters[param++]); } - } - else - { - if (ptr>0) + else { - if ((modelist[ptr-1] == '+') || (modelist[ptr-1] == '-')) + if (ptr>0) { - strcat(outlist, app); + if ((modelist[ptr-1] == '+') || (modelist[ptr-1] == '-')) + { + strlcat(outlist, app,MAXBUF); + } + else if (!strchr(outlist,*modechar)) + { + strlcat(outlist, app,MAXBUF); + } } - else if (!strchr(outlist,modechar)) + chan->SetCustomMode(*modechar,mdir); + // include parameters in output if mode has them + if ((ModeDefinedOn(*modechar,MT_CHANNEL)>0) && (mdir)) { - strcat(outlist, app); + chan->SetCustomModeParam(modelist[ptr],parameters[param],mdir); + strlcpy(outpars[pc++],parameters[param++],MAXBUF); } } - chan->SetCustomMode(modechar,mdir); - // include parameters in output if mode has them - if ((ModeDefinedOn(modechar,MT_CHANNEL)>0) && (mdir)) - { - chan->SetCustomModeParam(modelist[ptr],parameters[param],mdir); - strcpy(outpars[pc++],parameters[param++]); - } - } - // break, because only one module can handle the mode. - handled = true; - } - } - } + // break, because only one module can handle the mode. + handled = true; + } + } + } + } } + else + { + WriteServ(user->fd,"472 %s %c :is unknown mode char to me",user->nick,*modechar); + } break; } @@ -909,22 +1113,25 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int } /* this ensures only the *valid* modes are sent out onto the network */ - while ((outlist[strlen(outlist)-1] == '-') || (outlist[strlen(outlist)-1] == '+')) + int xt = strlen(outlist)-1; + while ((outlist[xt] == '-') || (outlist[xt] == '+')) { - outlist[strlen(outlist)-1] = '\0'; + outlist[xt] = '\0'; + xt = strlen(outlist)-1; } - if (strcmp(outlist,"")) + if (outlist[0]) { - strcpy(outstr,outlist); + strlcpy(outstr,outlist,MAXBUF); for (ptr = 0; ptr < pc; ptr++) { - strcat(outstr," "); - strcat(outstr,outpars[ptr]); + strlcat(outstr," ",MAXBUF); + strlcat(outstr,outpars[ptr],MAXBUF); } if (local) { log(DEBUG,"Local mode change"); WriteChannelLocal(chan, user, "MODE %s %s",chan->name,outstr); + FOREACH_MOD(I_OnMode,OnMode(user, chan, TYPE_CHANNEL, outstr)); } else { @@ -932,11 +1139,7 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int { if (!silent) { - WriteChannelWithServ(ServerName,chan,user,"MODE %s %s",chan->name,outstr); - // M token for a usermode must go to all servers - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"M %s %s",chan->name, outstr); - NetSendToAll(buffer); + WriteChannelWithServ(Config->ServerName,chan,"MODE %s %s",chan->name,outstr); } } @@ -945,10 +1148,7 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int if (!silent) { WriteChannel(chan,user,"MODE %s %s",chan->name,outstr); - // M token for a usermode must go to all servers - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"m %s %s %s",user->nick,chan->name, outstr); - NetSendToAll(buffer); + FOREACH_MOD(I_OnMode,OnMode(user, chan, TYPE_CHANNEL, outstr)); } } } @@ -957,9 +1157,14 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int // based on sourcemodes, return true or false to determine if umode is a valid mode a user may set on themselves or others. -bool allowed_umode(char umode, char* sourcemodes,bool adding) +bool ModeParser::AllowedUmode(char umode, char* sourcemodes,bool adding,bool serveroverride) { log(DEBUG,"Allowed_umode: %c %s",umode,sourcemodes); + // Servers can +o and -o arbitrarily + if ((serveroverride == true) && (umode == 'o')) + { + return true; + } // RFC1459 specified modes if ((umode == 'w') || (umode == 's') || (umode == 'i')) { @@ -1003,15 +1208,15 @@ bool allowed_umode(char umode, char* sourcemodes,bool adding) return false; } -bool process_module_umode(char umode, userrec* source, void* dest, bool adding) +bool ModeParser::ProcessModuleUmode(char umode, userrec* source, void* dest, bool adding) { userrec* s2; bool faked = false; if (!source) { s2 = new userrec; - strncpy(s2->nick,ServerName,NICKMAX); - strcpy(s2->modes,"o"); + strlcpy(s2->nick,Config->ServerName,NICKMAX-1); + strlcpy(s2->modes,"o",52); s2->fd = -1; source = s2; faked = true; @@ -1024,7 +1229,7 @@ bool process_module_umode(char umode, userrec* source, void* dest, bool adding) { if (modules[i]->OnExtendedMode(source,(void*)dest,umode,MT_CLIENT,adding,p)) { - log(DEBUG,"Module %s claims umode %c",module_names[i].c_str(),umode); + log(DEBUG,"Module %s claims umode %c",Config->module_names[i].c_str(),umode); return true; } } @@ -1047,11 +1252,11 @@ bool process_module_umode(char umode, userrec* source, void* dest, bool adding) } } -void handle_mode(char **parameters, int pcnt, userrec *user) +void cmd_mode::Handle (char **parameters, int pcnt, userrec *user) { chanrec* Ptr; userrec* dest; - int can_change,i; + int can_change; int direction = 1; char outpars[MAXBUF]; @@ -1070,14 +1275,17 @@ void handle_mode(char **parameters, int pcnt, userrec *user) if ((dest) && (pcnt > 1)) { + std::string tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false); + parameters[1] = (char*)tidied.c_str(); + char dmodes[MAXBUF]; - strncpy(dmodes,dest->modes,MAXBUF); + strlcpy(dmodes,dest->modes,52); log(DEBUG,"pulled up dest user modes: %s",dmodes); - + can_change = 0; if (user != dest) { - if (strchr(user->modes,'o')) + if ((strchr(user->modes,'o')) || (is_uline(user->server))) { can_change = 1; } @@ -1092,21 +1300,25 @@ void handle_mode(char **parameters, int pcnt, userrec *user) return; } - strcpy(outpars,"+"); + outpars[0] = '+'; + outpars[1] = 0; direction = 1; if ((parameters[1][0] != '+') && (parameters[1][0] != '-')) return; - for (int i = 0; i < strlen(parameters[1]); i++) + for (unsigned int i = 0; i < strlen(parameters[1]); i++) { + if (parameters[1][i] == ' ') + continue; if (parameters[1][i] == '+') { if (direction != 1) { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + int t = strlen(outpars)-1; + if ((outpars[t] == '+') || (outpars[t] == '-')) { - outpars[strlen(outpars)-1] = '+'; + outpars[t] = '+'; } else { @@ -1120,9 +1332,10 @@ void handle_mode(char **parameters, int pcnt, userrec *user) { if (direction != 0) { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + int t = strlen(outpars)-1; + if ((outpars[t] == '+') || (outpars[t] == '-')) { - outpars[strlen(outpars)-1] = '-'; + outpars[t] = '-'; } else { @@ -1140,7 +1353,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user) } else { - if ((parameters[1][i] == 'i') || (parameters[1][i] == 'w') || (parameters[1][i] == 's') || (allowed_umode(parameters[1][i],user->modes,direction))) + if ((parameters[1][i] == 'i') || (parameters[1][i] == 'w') || (parameters[1][i] == 's') || (ServerInstance->ModeGrok->AllowedUmode(parameters[1][i],user->modes,direction,false))) { can_change = 1; } @@ -1149,55 +1362,68 @@ void handle_mode(char **parameters, int pcnt, userrec *user) { if (direction == 1) { - if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true))) + if ((!strchr(dmodes,parameters[1][i])) && (ServerInstance->ModeGrok->AllowedUmode(parameters[1][i],user->modes,true,false))) { char umode = parameters[1][i]; - if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) + if ((ServerInstance->ModeGrok->ProcessModuleUmode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) { - dmodes[strlen(dmodes)+1]='\0'; - dmodes[strlen(dmodes)] = parameters[1][i]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; + int q = strlen(dmodes); + int r = strlen(outpars); + dmodes[q+1]='\0'; + dmodes[q] = parameters[1][i]; + outpars[r+1]='\0'; + outpars[r] = parameters[1][i]; + if (parameters[1][i] == 'o') + { + FOREACH_MOD(I_OnGlobalOper,OnGlobalOper(dest)); + } } } } else { - if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i]))) + if ((ServerInstance->ModeGrok->AllowedUmode(parameters[1][i],user->modes,false,false)) && (strchr(dmodes,parameters[1][i]))) { char umode = parameters[1][i]; - if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) + if ((ServerInstance->ModeGrok->ProcessModuleUmode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) { - int q = 0; + unsigned int q = 0; char temp[MAXBUF]; char moo[MAXBUF]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; + unsigned int r = strlen(outpars); + outpars[r+1]='\0'; + outpars[r] = parameters[1][i]; - strcpy(temp,""); + *temp = 0; for (q = 0; q < strlen(dmodes); q++) { if (dmodes[q] != parameters[1][i]) { moo[0] = dmodes[q]; moo[1] = '\0'; - strcat(temp,moo); + strlcat(temp,moo,MAXBUF); } } - strcpy(dmodes,temp); + strlcpy(dmodes,temp,52); + + if (umode == 'o') + { + *dest->oper = 0; + DeleteOper(dest); + } } } } } } } - if (strlen(outpars)) + if (outpars[0]) { char b[MAXBUF]; - strcpy(b,""); - int z = 0; - int i = 0; + strlcpy(b,"",MAXBUF); + unsigned int z = 0; + unsigned int i = 0; while (i < strlen (outpars)) { b[z++] = outpars[i++]; @@ -1222,17 +1448,16 @@ void handle_mode(char **parameters, int pcnt, userrec *user) z = strlen(b)-1; if ((b[z] == '-') || (b[z] == '+')) - b[z] == '\0'; + b[z] = '\0'; - if ((!strcmp(b,"+")) || (!strcmp(b,"-"))) + if ((!b[0]) || (!strcmp(b,"+")) || (!strcmp(b,"-"))) return; - WriteTo(user, dest, "MODE %s :%s", dest->nick, b); - - // M token for a usermode must go to all servers - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"m %s %s %s",user->nick, dest->nick, b); - NetSendToAll(buffer); + if (strcmp(b,"")) + { + WriteTo(user, dest, "MODE %s :%s", dest->nick, b); + FOREACH_MOD(I_OnMode,OnMode(user, dest, TYPE_USER, b)); + } if (strlen(dmodes)>MAXMODES) { @@ -1240,7 +1465,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user) } log(DEBUG,"Stripped mode line"); log(DEBUG,"Line dest is now %s",dmodes); - strncpy(dest->modes,dmodes,MAXMODES); + strlcpy(dest->modes,dmodes,52); } @@ -1253,55 +1478,79 @@ void handle_mode(char **parameters, int pcnt, userrec *user) if (pcnt == 1) { /* just /modes #channel */ - WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name, chanmodes(Ptr)); - WriteServ(user->fd,"329 %s %s %d", user->nick, Ptr->name, Ptr->created); + WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name, chanmodes(Ptr,has_channel(user,Ptr))); + WriteServ(user->fd,"329 %s %s %d", user->nick, Ptr->name, Ptr->created); return; } else if (pcnt == 2) { - if ((!strcmp(parameters[1],"+b")) || (!strcmp(parameters[1],"b"))) - { + char* mode = parameters[1]; + if (*mode == '+') + mode++; + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnRawMode,OnRawMode(user, Ptr, *mode, "", false, 0)); + if (!MOD_RESULT) + { + if (*mode == 'b') + { - for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++) + for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++) + { + WriteServ(user->fd,"367 %s %s %s %s %d",user->nick, Ptr->name, i->data, i->set_by, i->set_time); + } + WriteServ(user->fd,"368 %s %s :End of channel ban list",user->nick, Ptr->name); + return; + } + if ((ModeDefined(*mode,MT_CHANNEL)) && (ModeIsListMode(*mode,MT_CHANNEL))) { - WriteServ(user->fd,"367 %s %s %s %s %d",user->nick, Ptr->name, i->data, i->set_by, i->set_time); + // 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,Ptr,*mode)); + return; } - WriteServ(user->fd,"368 %s %s :End of channel ban list",user->nick, Ptr->name); - return; } } - int MOD_RESULT = 0; - FOREACH_RESULT(OnAccessCheck(user,NULL,Ptr,AC_GENERAL_MODE)); - - if (MOD_RESULT == ACR_DENY) - return; - if (MOD_RESULT == ACR_DEFAULT) + if (((Ptr) && (!has_channel(user,Ptr))) && (!is_uline(user->server)) && (IS_LOCAL(user))) + { + WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name); + return; + } + + if (Ptr) { - if ((cstatus(user,Ptr) < STATUS_HOP) && (Ptr)) - { - WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, Ptr->name); + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,NULL,Ptr,AC_GENERAL_MODE)); + + if (MOD_RESULT == ACR_DENY) return; + if (MOD_RESULT == ACR_DEFAULT) + { + if ((cstatus(user,Ptr) < STATUS_HOP) && (IS_LOCAL(user))) + { + WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, Ptr->name); + return; + } } - } - process_modes(parameters,user,Ptr,cstatus(user,Ptr),pcnt,false,false,false); + ServerInstance->ModeGrok->ProcessModes(parameters,user,Ptr,cstatus(user,Ptr),pcnt,false,false,false); + } } else { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); } } -void server_mode(char **parameters, int pcnt, userrec *user) +void ModeParser::ServerMode(char **parameters, int pcnt, userrec *user) { chanrec* Ptr; userrec* dest; - int can_change,i; + int can_change; int direction = 1; char outpars[MAXBUF]; @@ -1315,26 +1564,31 @@ void server_mode(char **parameters, int pcnt, userrec *user) if ((dest) && (pcnt > 1)) { - log(DEBUG,"params > 1"); + std::string tidied = ServerInstance->ModeGrok->CompressModes(parameters[1],false); + parameters[1] = (char*)tidied.c_str(); char dmodes[MAXBUF]; - strncpy(dmodes,dest->modes,MAXBUF); + strlcpy(dmodes,dest->modes,52); - strcpy(outpars,"+"); + outpars[0] = '+'; + outpars[1] = 0; direction = 1; if ((parameters[1][0] != '+') && (parameters[1][0] != '-')) return; - for (int i = 0; i < strlen(parameters[1]); i++) + for (unsigned int i = 0; i < strlen(parameters[1]); i++) { + if (parameters[1][i] == ' ') + continue; if (parameters[1][i] == '+') { if (direction != 1) { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + int t = strlen(outpars)-1; + if ((outpars[t] == '+') || (outpars[t] == '-')) { - outpars[strlen(outpars)-1] = '+'; + outpars[t] = '+'; } else { @@ -1348,9 +1602,10 @@ void server_mode(char **parameters, int pcnt, userrec *user) { if (direction != 0) { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) + int t = strlen(outpars)-1; + if ((outpars[t] == '+') || (outpars[t] == '-')) { - outpars[strlen(outpars)-1] = '-'; + outpars[t] = '-'; } else { @@ -1368,16 +1623,18 @@ void server_mode(char **parameters, int pcnt, userrec *user) if (direction == 1) { log(DEBUG,"umode %c being added",parameters[1][i]); - if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true))) + if ((!strchr(dmodes,parameters[1][i])) && (ServerInstance->ModeGrok->AllowedUmode(parameters[1][i],user->modes,true,true))) { char umode = parameters[1][i]; log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) + if ((ServerInstance->ModeGrok->ProcessModuleUmode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) { - dmodes[strlen(dmodes)+1]='\0'; - dmodes[strlen(dmodes)] = parameters[1][i]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; + int v1 = strlen(dmodes); + int v2 = strlen(outpars); + dmodes[v1+1]='\0'; + dmodes[v1] = parameters[1][i]; + outpars[v2+1]='\0'; + outpars[v2] = parameters[1][i]; } } } @@ -1385,42 +1642,42 @@ void server_mode(char **parameters, int pcnt, userrec *user) { // can only remove a mode they already have log(DEBUG,"umode %c being removed",parameters[1][i]); - if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i]))) + if ((ServerInstance->ModeGrok->AllowedUmode(parameters[1][i],user->modes,false,true)) && (strchr(dmodes,parameters[1][i]))) { char umode = parameters[1][i]; log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) + if ((ServerInstance->ModeGrok->ProcessModuleUmode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) { - int q = 0; + unsigned int q = 0; char temp[MAXBUF]; char moo[MAXBUF]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; - - strcpy(temp,""); + unsigned int v1 = strlen(outpars); + outpars[v1+1]='\0'; + outpars[v1] = parameters[1][i]; + *temp = 0; for (q = 0; q < strlen(dmodes); q++) { if (dmodes[q] != parameters[1][i]) { moo[0] = dmodes[q]; moo[1] = '\0'; - strcat(temp,moo); + strlcat(temp,moo,MAXBUF); } } - strcpy(dmodes,temp); + strlcpy(dmodes,temp,52); } } } } } } - if (strlen(outpars)) + if (outpars[0]) { char b[MAXBUF]; - strcpy(b,""); - int z = 0; - int i = 0; + strlcpy(b,"",MAXBUF); + unsigned int z = 0; + unsigned int i = 0; while (i < strlen (outpars)) { b[z++] = outpars[i++]; @@ -1445,17 +1702,16 @@ void server_mode(char **parameters, int pcnt, userrec *user) z = strlen(b)-1; if ((b[z] == '-') || (b[z] == '+')) - b[z] == '\0'; + b[z] = '\0'; - if ((!strcmp(b,"+")) || (!strcmp(b,"-"))) + if ((!b[0]) || (!strcmp(b,"+")) || (!strcmp(b,"-"))) return; - WriteTo(user, dest, "MODE %s :%s", dest->nick, b); - - // M token for a usermode must go to all servers - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"m %s %s %s",user->nick, dest->nick, b); - NetSendToAll(buffer); + if (strcmp(b,"")) + { + WriteTo(user, dest, "MODE %s :%s", dest->nick, b); + FOREACH_MOD(I_OnMode,OnMode(user, dest, TYPE_USER, b)); + } if (strlen(dmodes)>MAXMODES) { @@ -1463,7 +1719,7 @@ void server_mode(char **parameters, int pcnt, userrec *user) } log(DEBUG,"Stripped mode line"); log(DEBUG,"Line dest is now %s",dmodes); - strncpy(dest->modes,dmodes,MAXMODES); + strlcpy(dest->modes,dmodes,MAXMODES); } @@ -1473,375 +1729,10 @@ void server_mode(char **parameters, int pcnt, userrec *user) Ptr = FindChan(parameters[0]); if (Ptr) { - process_modes(parameters,user,Ptr,STATUS_OP,pcnt,true,false,false); + ServerInstance->ModeGrok->ProcessModes(parameters,user,Ptr,STATUS_OP,pcnt,true,false,false); } else { - WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); } } - - - -void merge_mode(char **parameters, int pcnt) -{ - chanrec* Ptr; - userrec* dest; - int can_change,i; - int direction = 1; - char outpars[MAXBUF]; - - dest = Find(parameters[0]); - - // fix: ChroNiCk found this - we cant use this as debug if its null! - if (dest) - { - log(DEBUG,"merge_mode on %s",dest->nick); - } - - if ((dest) && (pcnt > 1)) - { - log(DEBUG,"params > 1"); - - char dmodes[MAXBUF]; - strncpy(dmodes,dest->modes,MAXBUF); - - strcpy(outpars,"+"); - direction = 1; - - if ((parameters[1][0] != '+') && (parameters[1][0] != '-')) - return; - - for (int i = 0; i < strlen(parameters[1]); i++) - { - if (parameters[1][i] == '+') - { - if (direction != 1) - { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) - { - outpars[strlen(outpars)-1] = '+'; - } - else - { - strcat(outpars,"+"); - } - } - direction = 1; - } - else - if (parameters[1][i] == '-') - { - if (direction != 0) - { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) - { - outpars[strlen(outpars)-1] = '-'; - } - else - { - strcat(outpars,"-"); - } - } - direction = 0; - } - else - { - log(DEBUG,"begin mode processing entry"); - can_change = 1; - if (can_change) - { - if (direction == 1) - { - log(DEBUG,"umode %c being added",parameters[1][i]); - if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],"o",true))) - { - char umode = parameters[1][i]; - log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, NULL, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) - { - dmodes[strlen(dmodes)+1]='\0'; - dmodes[strlen(dmodes)] = parameters[1][i]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; - } - } - } - else - { - // can only remove a mode they already have - log(DEBUG,"umode %c being removed",parameters[1][i]); - if ((allowed_umode(parameters[1][i],"o",false)) && (strchr(dmodes,parameters[1][i]))) - { - char umode = parameters[1][i]; - log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, NULL, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) - { - int q = 0; - char temp[MAXBUF]; - char moo[MAXBUF]; - - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; - - strcpy(temp,""); - for (q = 0; q < strlen(dmodes); q++) - { - if (dmodes[q] != parameters[1][i]) - { - moo[0] = dmodes[q]; - moo[1] = '\0'; - strcat(temp,moo); - } - } - strcpy(dmodes,temp); - } - } - } - } - } - } - if (strlen(outpars)) - { - char b[MAXBUF]; - strcpy(b,""); - int z = 0; - int i = 0; - while (i < strlen (outpars)) - { - b[z++] = outpars[i++]; - b[z] = '\0'; - if (iMAXMODES) - { - dmodes[MAXMODES-1] = '\0'; - } - log(DEBUG,"Stripped mode line"); - log(DEBUG,"Line dest is now %s",dmodes); - strncpy(dest->modes,dmodes,MAXMODES); - - } - - return; - } - - Ptr = FindChan(parameters[0]); - if (Ptr) - { - userrec s2; - strncpy(s2.nick,ServerName,NICKMAX); - strcpy(s2.modes,"o"); - s2.fd = -1; - process_modes(parameters,&s2,Ptr,STATUS_OP,pcnt,true,true,false); - } -} - - -void merge_mode2(char **parameters, int pcnt, userrec* user) -{ - chanrec* Ptr; - userrec* dest; - int can_change,i; - int direction = 1; - char outpars[MAXBUF]; - - dest = Find(parameters[0]); - - // fix: ChroNiCk found this - we cant use this as debug if its null! - if (dest) - { - log(DEBUG,"merge_mode on %s",dest->nick); - } - - if ((dest) && (pcnt > 1)) - { - log(DEBUG,"params > 1"); - - char dmodes[MAXBUF]; - strncpy(dmodes,dest->modes,MAXBUF); - - strcpy(outpars,"+"); - direction = 1; - - if ((parameters[1][0] != '+') && (parameters[1][0] != '-')) - return; - - for (int i = 0; i < strlen(parameters[1]); i++) - { - if (parameters[1][i] == '+') - { - if (direction != 1) - { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) - { - outpars[strlen(outpars)-1] = '+'; - } - else - { - strcat(outpars,"+"); - } - } - direction = 1; - } - else - if (parameters[1][i] == '-') - { - if (direction != 0) - { - if ((outpars[strlen(outpars)-1] == '+') || (outpars[strlen(outpars)-1] == '-')) - { - outpars[strlen(outpars)-1] = '-'; - } - else - { - strcat(outpars,"-"); - } - } - direction = 0; - } - else - { - log(DEBUG,"begin mode processing entry"); - can_change = 1; - if (can_change) - { - if (direction == 1) - { - log(DEBUG,"umode %c being added",parameters[1][i]); - if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true))) - { - char umode = parameters[1][i]; - log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, NULL, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) - { - dmodes[strlen(dmodes)+1]='\0'; - dmodes[strlen(dmodes)] = parameters[1][i]; - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; - } - } - } - else - { - // can only remove a mode they already have - log(DEBUG,"umode %c being removed",parameters[1][i]); - if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i]))) - { - char umode = parameters[1][i]; - log(DEBUG,"umode %c is an allowed umode",umode); - if ((process_module_umode(umode, NULL, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o')) - { - int q = 0; - char temp[MAXBUF]; - char moo[MAXBUF]; - - outpars[strlen(outpars)+1]='\0'; - outpars[strlen(outpars)] = parameters[1][i]; - - strcpy(temp,""); - for (q = 0; q < strlen(dmodes); q++) - { - if (dmodes[q] != parameters[1][i]) - { - moo[0] = dmodes[q]; - moo[1] = '\0'; - strcat(temp,moo); - } - } - strcpy(dmodes,temp); - } - } - } - } - } - } - if (strlen(outpars)) - { - char b[MAXBUF]; - strcpy(b,""); - int z = 0; - int i = 0; - while (i < strlen (outpars)) - { - b[z++] = outpars[i++]; - b[z] = '\0'; - if (iMAXMODES) - { - dmodes[MAXMODES-1] = '\0'; - } - log(DEBUG,"Stripped mode line"); - log(DEBUG,"Line dest is now %s",dmodes); - strncpy(dest->modes,dmodes,MAXMODES); - - } - - return; - } - - Ptr = FindChan(parameters[0]); - if (Ptr) - { - log(DEBUG,"merge_mode2: found channel %s",Ptr->name); - if (Ptr) - { - if ((cstatus(user,Ptr) < STATUS_HOP) && (!is_uline(user->server))) - { - return; - } - process_modes(parameters,user,Ptr,cstatus(user,Ptr),pcnt,false,false,true); - } - } -} - -