summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mode.h11
-rw-r--r--include/users.h32
-rw-r--r--src/cmd_die.cpp2
-rw-r--r--src/cmd_oper.cpp5
-rw-r--r--src/command_parse.cpp17
-rw-r--r--src/helperfuncs.cpp10
-rw-r--r--src/message.cpp6
-rw-r--r--src/modules/extra/m_sqloper.cpp4
-rw-r--r--src/modules/m_botmode.cpp2
-rw-r--r--src/modules/m_cban.cpp2
-rw-r--r--src/modules/m_censor.cpp4
-rw-r--r--src/modules/m_check.cpp2
-rw-r--r--src/modules/m_helpop.cpp2
-rw-r--r--src/modules/m_park.cpp4
-rw-r--r--src/modules/m_services.cpp10
-rw-r--r--src/modules/m_services_account.cpp2
-rw-r--r--src/modules/m_showwhois.cpp2
-rw-r--r--src/modules/m_spanningtree.cpp27
-rw-r--r--src/modules/m_stripcolor.cpp2
-rw-r--r--src/users.cpp5
20 files changed, 66 insertions, 85 deletions
diff --git a/include/mode.h b/include/mode.h
index 170da92d5..59dc9dc3b 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -30,17 +30,6 @@
#include "ctables.h"
/**
- * This enum contains a set of bitmasks which
- * are used to compress the 'standard' usermodes
- * +isw into a bitfield for fast checking.
- */
-enum UserModeBits {
- UM_INVISIBLE = 1,
- UM_SERVERNOTICE = 2,
- UM_WALLOPS = 4
-};
-
-/**
* Holds the values for different type of modes
* that can exist, USER or CHANNEL type.
*/
diff --git a/include/users.h b/include/users.h
index 0d812c0a4..30e524e85 100644
--- a/include/users.h
+++ b/include/users.h
@@ -43,6 +43,15 @@ enum ClassTypes {
CC_DENY = 1
};
+/** RFC1459 channel modes
+ * */
+enum ChannelModes {
+ UM_SERVERNOTICE = 's'-65,
+ UM_WALLOPS = 'w'-65,
+ UM_INVISIBLE = 'i'-65,
+ UM_OPERATOR = 'o'-65,
+};
+
/** Holds a channel name to which a user has been invited.
*/
class Invited : public classbase
@@ -150,22 +159,17 @@ class userrec : public connection
*/
char fullname[MAXGECOS+1];
- /** The user's mode string.
- * This may contain any of the following RFC characters: o, w, s, i
- * Your module may define other mode characters as it sees fit.
- * it is limited to length 54, as there can only be a maximum of 52
- * user modes (26 upper, 26 lower case) a null terminating char, and
- * an optional + character.
+ /** The user's mode list.
+ * This is NOT a null terminated string! In the 1.1 version of InspIRCd
+ * this is an array of values in a similar way to channel modes.
+ * A value of 1 in field (modeletter-65) indicates that the mode is
+ * set, for example, to work out if mode +s is set, we check the field
+ * userrec::modes['s'-65] != 0.
+ * The following RFC characters o, w, s, i have constants defined via an
+ * enum, such as UM_SERVERNOTICE and UM_OPETATOR.
*/
- char modes[54];
+ char modes[64];
- /** This contains a bitmask of the RFC modes +swi,
- * which can be used for fast lookup when iterating all the users.
- * It is maintained by the mode parser and matches the character
- * modes stored in 'modes'.
- */
- char modebits;
-
UserChanList chans;
/** The server the user is connected to.
diff --git a/src/cmd_die.cpp b/src/cmd_die.cpp
index c5514c067..494eba0c5 100644
--- a/src/cmd_die.cpp
+++ b/src/cmd_die.cpp
@@ -40,7 +40,7 @@ void cmd_die::Handle (char **parameters, int pcnt, userrec *user)
{
userrec* a = *i;
- if (IS_LOCAL(a) && (a->modebits & UM_SERVERNOTICE))
+ if (IS_LOCAL(a) && (a->modes[UM_SERVERNOTICE]))
{
WriteServ(a->fd, "NOTICE %s :*** DIE command from %s!%s@%s, terminating...", a->nick, a->nick, a->ident, a->host);
a->FlushWriteBuf();
diff --git a/src/cmd_oper.cpp b/src/cmd_oper.cpp
index a209c7e64..e19281cbf 100644
--- a/src/cmd_oper.cpp
+++ b/src/cmd_oper.cpp
@@ -115,9 +115,10 @@ void cmd_oper::Handle (char **parameters, int pcnt, userrec *user)
/* correct oper credentials */
WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,OperType);
WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,OperType);
- if (!strchr(user->modes,'o'))
+ if (!user->modes[UM_OPERATOR])
{
- strcat(user->modes,"o");
+ user->modes[UM_OPERATOR] = 1;
+ ModeParser::BuildModeString(user);
WriteServ(user->fd,"MODE %s :+o",user->nick);
FOREACH_MOD(I_OnOper,OnOper(user,OperType));
log(DEFAULT,"OPER: %s!%s@%s opered as type: %s",user->nick,user->ident,user->host,OperType);
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 7a26f209b..befcde7ca 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -306,7 +306,7 @@ bool CommandParser::IsValidCommand(const std::string &commandname, int pcnt, use
{
if ((pcnt>=n->second->min_params) && (n->second->source != "<core>"))
{
- if ((strchr(user->modes,n->second->flags_needed)) || (!n->second->flags_needed))
+ if ((!n->second->flags_needed) || (user->modes[n->second->flags_needed-65]))
{
if (n->second->flags_needed)
{
@@ -329,7 +329,7 @@ bool CommandParser::CallHandler(const std::string &commandname,char **parameters
{
if (pcnt >= n->second->min_params)
{
- if ((strchr(user->modes,n->second->flags_needed)) || (!n->second->flags_needed))
+ if ((!n->second->flags_needed) || (user->modes[n->second->flags_needed-65]))
{
if (n->second->flags_needed)
{
@@ -603,12 +603,15 @@ void CommandParser::ProcessCommand(userrec *user, char* cmd)
WriteServ(user->fd,"461 %s %s :Not enough parameters",user->nick,command);
return;
}
- if ((!strchr(user->modes,cm->second->flags_needed)) && (cm->second->flags_needed))
+ if (cm->second->flags_needed)
{
- log(DEBUG,"permission denied: %s %s",user->nick,command);
- WriteServ(user->fd,"481 %s :Permission Denied- You do not have the required operator privilages",user->nick);
- cmd_found = 1;
- return;
+ if (!user->modes[cm->second->flags_needed-65])
+ {
+ log(DEBUG,"permission denied: %s %s",user->nick,command);
+ WriteServ(user->fd,"481 %s :Permission Denied- You do not have the required operator privilages",user->nick);
+ cmd_found = 1;
+ return;
+ }
}
if ((cm->second->flags_needed) && (!user->HasPermission(xcommand)))
{
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index 6250b6285..c190aff4e 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -966,7 +966,7 @@ void WriteOpers_NoFormat(const char* text)
if (IS_LOCAL(a))
{
- if (a->modebits & UM_SERVERNOTICE)
+ if (a->modes[UM_SERVERNOTICE])
{
// send server notices to all with +s
WriteServ(a->fd,"NOTICE %s :%s",a->nick,text);
@@ -1121,7 +1121,7 @@ void WriteWallOps(userrec *source, bool local_only, char* text, ...)
{
userrec* t = (userrec*)(*i);
- if ((IS_LOCAL(t)) && (t->modebits & UM_WALLOPS))
+ if ((IS_LOCAL(t)) && (t->modes[UM_WALLOPS]))
{
WriteTo_NoFormat(source,t,formatbuffer);
}
@@ -1334,7 +1334,7 @@ void userlist(userrec *user,chanrec *c)
for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
{
- if ((!has_user) && (i->second->modebits & UM_INVISIBLE))
+ if ((!has_user) && (i->second->modes[UM_INVISIBLE]))
{
/*
* user is +i, and source not on the channel, does not show
@@ -1385,7 +1385,7 @@ int usercount_i(chanrec *c)
CUList *ulist= c->GetUsers();
for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
{
- if (!(i->second->modebits & UM_INVISIBLE))
+ if (!(i->second->modes[UM_INVISIBLE]))
count++;
}
@@ -1499,7 +1499,7 @@ int usercount_invisible(void)
for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
{
- if ((i->second->registered == 7) && (i->second->modebits & UM_INVISIBLE))
+ if ((i->second->registered == 7) && (i->second->modes[UM_INVISIBLE]))
c++;
}
diff --git a/src/message.cpp b/src/message.cpp
index 28a11fda9..5106bffba 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -198,11 +198,11 @@ int c_count(userrec* u)
}
-bool hasumode(userrec* user, char mode)
+bool hasumode(userrec* user, unsigned char mode)
{
if (user)
{
- return (strchr(user->modes,mode)>0);
+ return user->modes[mode-65];
}
else return false;
}
@@ -422,7 +422,7 @@ std::string chlist(userrec *user,userrec* source)
* If the channel is NOT private/secret AND the user is not invisible.
* If the user is an oper, and the <options:operspywhois> option is set.
*/
- if ((source == user) || (*source->oper && Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET]) && !(user->modebits & UM_INVISIBLE)) || (rec->channel->HasUser(source))))
+ if ((source == user) || (*source->oper && Config->OperSpyWhois) || (((!rec->channel->modes[CM_PRIVATE]) && (!rec->channel->modes[CM_SECRET]) && !(user->modes[UM_INVISIBLE])) || (rec->channel->HasUser(source))))
{
list << cmode(user, rec->channel) << rec->channel->name << " ";
}
diff --git a/src/modules/extra/m_sqloper.cpp b/src/modules/extra/m_sqloper.cpp
index 08ac72bcf..f39be098c 100644
--- a/src/modules/extra/m_sqloper.cpp
+++ b/src/modules/extra/m_sqloper.cpp
@@ -145,9 +145,9 @@ class ModuleSQLOper : public Module
strlcpy(user->oper,rowresult->GetField("type").c_str(),NICKMAX-1);
WriteOpers("*** %s (%s@%s) is now an IRC operator of type %s",user->nick,user->ident,user->host,rowresult->GetField("type").c_str());
WriteServ(user->fd,"381 %s :You are now an IRC operator of type %s",user->nick,rowresult->GetField("type").c_str());
- if(!strchr(user->modes,'o'))
+ if(user->modes[UM_OPERATOR])
{
- strcat(user->modes,"o");
+ user->modes[UM_OPERATOR] = 1;
WriteServ(user->fd,"MODE %s :+o",user->nick);
FOREACH_MOD(I_OnOper,OnOper(user,rowresult->GetField("type")));
AddOper(user);
diff --git a/src/modules/m_botmode.cpp b/src/modules/m_botmode.cpp
index 04204b42e..612eb3b9c 100644
--- a/src/modules/m_botmode.cpp
+++ b/src/modules/m_botmode.cpp
@@ -68,7 +68,7 @@ class ModuleBotMode : public Module
virtual void OnWhois(userrec* src, userrec* dst)
{
- if (strchr(dst->modes,'B'))
+ if (dst->modes['B'-65])
{
Srv->SendTo(NULL,src,"335 "+std::string(src->nick)+" "+std::string(dst->nick)+" :is a \2bot\2 on "+Srv->GetNetworkName());
}
diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp
index 06284a964..fd6a92c22 100644
--- a/src/modules/m_cban.cpp
+++ b/src/modules/m_cban.cpp
@@ -164,7 +164,7 @@ class ModuleCBan : public Module
/* check cbans in here, and apply as necessary. */
for(cbanlist::iterator iter = cbans.begin(); iter != cbans.end(); iter++)
{
- if(iter->chname == cname && !strchr(user->modes, 'o'))
+ if(iter->chname == cname && !user->modes[UM_OPERATOR])
{
// Channel is banned.
WriteServ(user->fd, "384 %s %s :Cannot join channel, CBANed (%s)", user->nick, cname, iter->reason.c_str());
diff --git a/src/modules/m_censor.cpp b/src/modules/m_censor.cpp
index 6a5acb54c..8c8bfc001 100644
--- a/src/modules/m_censor.cpp
+++ b/src/modules/m_censor.cpp
@@ -119,12 +119,12 @@ class ModuleCensor : public Module
if (target_type == TYPE_USER)
{
userrec* t = (userrec*)dest;
- active = (strchr(t->modes,'G') > 0);
+ active = t->modes['G'-65];
}
else if (target_type == TYPE_CHANNEL)
{
chanrec* t = (chanrec*)dest;
- active = (t->IsModeSet('G'));
+ active = t->IsModeSet('G');
}
if (active)
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 3ab31ebbc..5e7b4847c 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -70,7 +70,7 @@ class cmd_check : public command_t
Srv->SendTo(NULL, user, checkstr + " nuh " + targuser->GetFullHost());
Srv->SendTo(NULL, user, checkstr + " realnuh " + targuser->GetFullRealHost());
Srv->SendTo(NULL, user, checkstr + " realname " + targuser->fullname);
- Srv->SendTo(NULL, user, checkstr + " modes +" + targuser->modes);
+ Srv->SendTo(NULL, user, checkstr + " modes +" + targuser->FormatModes());
Srv->SendTo(NULL, user, checkstr + " server " + targuser->server);
if (targuser->awaymsg[0] != 0)
{
diff --git a/src/modules/m_helpop.cpp b/src/modules/m_helpop.cpp
index b6c723ca7..9a7124dda 100644
--- a/src/modules/m_helpop.cpp
+++ b/src/modules/m_helpop.cpp
@@ -234,7 +234,7 @@ class ModuleHelpop : public Module
virtual void OnWhois(userrec* src, userrec* dst)
{
- if (strchr(dst->modes,'h'))
+ if (dst->modes['h'-65])
{
Srv->SendTo(NULL,src,"310 "+std::string(src->nick)+" "+std::string(dst->nick)+" :is available for help.");
}
diff --git a/src/modules/m_park.cpp b/src/modules/m_park.cpp
index 7abe31baf..a5c62da19 100644
--- a/src/modules/m_park.cpp
+++ b/src/modules/m_park.cpp
@@ -161,11 +161,11 @@ class cmd_unpark : public command_t
}
}
// remove all their old modes
- WriteServ(user->fd,"MODE %s -%s",user->nick,user->modes);
+ WriteServ(user->fd,"MODE %s -%s",user->nick,user->FormatModes());
// now, map them to the parked user, while nobody can see :p
Srv->PseudoToUser(user,unpark,"Unparked to "+std::string(parameters[0]));
// set all their new modes
- WriteServ(unpark->fd,"MODE %s +%s",unpark->nick,unpark->modes);
+ WriteServ(unpark->fd,"MODE %s +%s",unpark->nick,unpark->FormatModes());
// spool their away log to them
WriteServ(unpark->fd,"NOTICE %s :*** You are now unparked. You have successfully taken back the nickname and privilages of %s.",unpark->nick,unpark->nick);
for (awaylog::iterator i = awy->begin(); i != awy->end(); i++)
diff --git a/src/modules/m_services.cpp b/src/modules/m_services.cpp
index 4d5183841..c868eefef 100644
--- a/src/modules/m_services.cpp
+++ b/src/modules/m_services.cpp
@@ -54,7 +54,7 @@ class ModuleServices : public Module
/* <- :stitch.chatspike.net 307 w00t w00t :is a registered nick */
virtual void OnWhois(userrec* source, userrec* dest)
{
- if (strchr(dest->modes, 'r'))
+ if (dest->modes['r'-65])
{
/* user is registered */
WriteServ(source->fd, "307 %s %s :is a registered nick", source->nick, dest->nick);
@@ -69,7 +69,7 @@ class ModuleServices : public Module
virtual void OnUserPostNick(userrec* user, const std::string &oldnick)
{
/* On nickchange, if they have +r, remove it */
- if (strchr(user->modes,'r'))
+ if (user->modes['r'-65])
{
char* modechange[2];
modechange[0] = user->nick;
@@ -133,7 +133,7 @@ class ModuleServices : public Module
if (target_type == TYPE_CHANNEL)
{
chanrec* c = (chanrec*)dest;
- if ((c->IsModeSet('M')) && (!strchr(user->modes,'r')))
+ if ((c->IsModeSet('M')) && (!user->modes['r'-65]))
{
if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"")))
{
@@ -148,7 +148,7 @@ class ModuleServices : public Module
if (target_type == TYPE_USER)
{
userrec* u = (userrec*)dest;
- if ((strchr(u->modes,'R')) && (!strchr(user->modes,'r')))
+ if ((u->modes['R'-65]) && (user->modes['r'-65]))
{
if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
{
@@ -174,7 +174,7 @@ class ModuleServices : public Module
{
if (chan->IsModeSet('R'))
{
- if (!strchr(user->modes,'r'))
+ if (user->modes['r'-65])
{
if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
{
diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp
index 62e9baf17..c27e103b7 100644
--- a/src/modules/m_services_account.cpp
+++ b/src/modules/m_services_account.cpp
@@ -105,7 +105,7 @@ class ModuleServicesAccount : public Module
{
userrec* u = (userrec*)dest;
- if ((strchr(u->modes,'R')) && (!account))
+ if ((u->modes['R'-65]) && (!account))
{
if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
{
diff --git a/src/modules/m_showwhois.cpp b/src/modules/m_showwhois.cpp
index dddd29406..519b13352 100644
--- a/src/modules/m_showwhois.cpp
+++ b/src/modules/m_showwhois.cpp
@@ -48,7 +48,7 @@ class ModuleShowwhois : public Module
virtual void OnWhois(userrec* source, userrec* dest)
{
- if((strchr(dest->modes,'W')) && (source != dest))
+ if ((dest->modes['W'-65]) && (source != dest))
{
WriteServ(dest->fd,"NOTICE %s :*** %s (%s@%s) did a /whois on you.",dest->nick,source->nick,source->ident,source->host);
}
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index 841206b8f..076241dea 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -1176,24 +1176,10 @@ class TreeSocket : public InspSocket
strlcpy(clientlist[tempnick]->fullname, params[7].c_str(),MAXGECOS);
clientlist[tempnick]->registered = 7;
clientlist[tempnick]->signon = age;
- strlcpy(clientlist[tempnick]->modes, params[5].c_str(),53);
- for (char *v = clientlist[tempnick]->modes; *v; v++)
+ for (std::string::iterator v = params[5].begin(); v != params[5].end(); v++)
{
- switch (*v)
- {
- case 'i':
- clientlist[tempnick]->modebits |= UM_INVISIBLE;
- break;
- case 'w':
- clientlist[tempnick]->modebits |= UM_WALLOPS;
- break;
- case 's':
- clientlist[tempnick]->modebits |= UM_SERVERNOTICE;
- break;
- default:
- break;
- }
+ clientlist[tempnick]->modes[(*v)-65] = 1;
}
inet_aton(params[6].c_str(),&clientlist[tempnick]->ip4);
@@ -1391,7 +1377,7 @@ class TreeSocket : public InspSocket
{
if (u->second->registered == 7)
{
- snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,inet_ntoa(u->second->ip4),u->second->fullname);
+ snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->FormatModes(),inet_ntoa(u->second->ip4),u->second->fullname);
this->WriteLine(data);
if (*u->second->oper)
{
@@ -1555,11 +1541,8 @@ class TreeSocket : public InspSocket
userrec* u = Srv->FindNick(prefix);
if (u)
{
+ u->modes[UM_OPERATOR] = 1;
strlcpy(u->oper,opertype.c_str(),NICKMAX-1);
- if (!strchr(u->modes,'o'))
- {
- strcat(u->modes,"o");
- }
DoOneToAllButSender(u->nick,"OPERTYPE",params,u->server);
}
return true;
@@ -3667,7 +3650,7 @@ class ModuleSpanningTree : public Module
params.push_back(user->host);
params.push_back(user->dhost);
params.push_back(user->ident);
- params.push_back("+"+std::string(user->modes));
+ params.push_back("+"+std::string(user->FormatModes()));
params.push_back((char*)inet_ntoa(user->ip4));
params.push_back(":"+std::string(user->fullname));
DoOneToMany(Srv->GetServerName(),"NICK",params);
diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp
index 0875399b8..1b8f8c72d 100644
--- a/src/modules/m_stripcolor.cpp
+++ b/src/modules/m_stripcolor.cpp
@@ -128,7 +128,7 @@ class ModuleStripColor : public Module
if (target_type == TYPE_USER)
{
userrec* t = (userrec*)dest;
- active = (strchr(t->modes,'S') > 0);
+ active = t->modes['S'-65];
}
else if (target_type == TYPE_CHANNEL)
{
diff --git a/src/users.cpp b/src/users.cpp
index 87dfca4ab..78409dc6f 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -113,17 +113,18 @@ bool DoneClassesAndTypes(const char* tag)
userrec::userrec()
{
// the PROPER way to do it, AVOID bzero at *ALL* costs
- *password = *nick = *ident = *host = *dhost = *fullname = *modes = *awaymsg = *oper = 0;
+ *password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
server = (char*)FindServerNamePtr(Config->ServerName);
reset_due = TIME;
lines_in = fd = lastping = signon = idle_lastmsg = nping = registered = 0;
- modebits = timeout = flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
+ timeout = flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
haspassed = dns_done = false;
recvq = "";
sendq = "";
chans.clear();
invites.clear();
chans.resize(MAXCHANS);
+ memset(modes,0,sizeof(modes));
for (unsigned int n = 0; n < MAXCHANS; n++)
{