#include "bancache.h"
#include "commands/cmd_whowas.h"
-static unsigned long already_sent[MAX_DESCRIPTORS] = {0};
+static unsigned long* already_sent = NULL;
+
+
+void InitializeAlreadySent(SocketEngine* SE)
+{
+ already_sent = new unsigned long[SE->GetMaxFds()];
+}
/* XXX: Used for speeding up WriteCommon operations */
unsigned long uniq_id = 0;
Visibility = NULL;
ip = NULL;
MyClass = NULL;
+ io = NULL;
+ AllowedUserModes = NULL;
+ AllowedChanModes = NULL;
AllowedOperCommands = NULL;
chans.clear();
invites.clear();
if (this->MyClass)
{
this->MyClass->RefCount--;
- ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %u", this->MyClass->RefCount);
+ ServerInstance->Logs->Log("USERS", DEBUG, "User destructor -- connect refcount now: %lu", this->MyClass->RefCount);
}
if (this->AllowedOperCommands)
{
AllowedOperCommands = NULL;
}
+ if (this->AllowedUserModes)
+ {
+ delete[] AllowedUserModes;
+ AllowedUserModes = NULL;
+ }
+
+ if (this->AllowedChanModes)
+ {
+ delete[] AllowedChanModes;
+ AllowedChanModes = NULL;
+ }
+
this->InvalidateCache();
this->DecrementModes();
void User::CloseSocket()
{
- ServerInstance->SE->Shutdown(this, 2);
- ServerInstance->SE->Close(this);
+ if (this->fd > -1)
+ {
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
+ }
}
char* User::GetFullHost()
}
}
+bool User::HasModePermission(unsigned char mode, ModeType type)
+{
+ if (!IS_LOCAL(this))
+ return true;
+
+ if (!IS_OPER(this))
+ return false;
+
+ if (!AllowedUserModes || !AllowedChanModes)
+ return false;
+
+ return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')];
+
+}
+
bool User::HasPermission(const std::string &command)
{
/*
if (this->MyClass && (recvq.length() > this->MyClass->GetRecvqMax()))
{
this->SetWriteError("RecvQ exceeded");
- ServerInstance->SNO->WriteToSnoMask('A', "User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->MyClass->GetRecvqMax());
+ ServerInstance->SNO->WriteToSnoMask('A', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick,(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax());
return false;
}
* to repeatedly add the text to the sendq!
*/
this->SetWriteError("SendQ exceeded");
- ServerInstance->SNO->WriteToSnoMask('A', "User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->MyClass->GetSendqMax());
+ ServerInstance->SNO->WriteToSnoMask('A', "User %s SendQ of %lu exceeds connect class maximum of %lu",this->nick,(unsigned long int)sendq.length() + data.length(),this->MyClass->GetSendqMax());
return;
}
else
AllowedOperCommands = new std::map<std::string, bool>;
+ if (!AllowedChanModes)
+ AllowedChanModes = new bool[64];
+
+ if (!AllowedUserModes)
+ AllowedUserModes = new bool[64];
+
+ memset(AllowedUserModes, 0, 64);
+ memset(AllowedChanModes, 0, 64);
+
char* Classes = strdup(iter_opertype->second);
char* myclass = strtok_r(Classes," ",&savept);
while (myclass)
operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass);
if (iter_operclass != ServerInstance->Config->operclass.end())
{
- char* CommandList = strdup(iter_operclass->second);
+ char* CommandList = strdup(iter_operclass->second.commandlist);
mycmd = strtok_r(CommandList," ",&savept2);
while (mycmd)
{
mycmd = strtok_r(NULL," ",&savept2);
}
free(CommandList);
+ this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want.
+ for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c)
+ {
+ if (*c == '*')
+ {
+ memset(this->AllowedUserModes, (int)(true), 64);
+ }
+ else
+ {
+ this->AllowedUserModes[*c - 'A'] = true;
+ }
+ }
+ for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
+ {
+ if (*c == '*')
+ {
+ memset(this->AllowedChanModes, (int)(true), 64);
+ }
+ else
+ {
+ this->AllowedChanModes[*c - 'A'] = true;
+ }
+ }
}
myclass = strtok_r(NULL," ",&savept);
}
delete AllowedOperCommands;
AllowedOperCommands = NULL;
}
+ if (AllowedUserModes)
+ {
+ delete[] AllowedUserModes;
+ AllowedUserModes = NULL;
+ }
+ if (AllowedChanModes)
+ {
+ delete[] AllowedChanModes;
+ AllowedChanModes = NULL;
+ }
+
}
}
this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network);
this->WriteNumeric(001, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick, ServerInstance->Config->Network, this->nick, this->ident, this->host);
- this->WriteNumeric(002, "%s :Your host is %s, running version %s",this->nick,ServerInstance->Config->ServerName,VERSION);
+ this->WriteNumeric(002, "%s :Your host is %s, running version InspIRCd-1.2",this->nick,ServerInstance->Config->ServerName);
this->WriteNumeric(003, "%s :This server was created %s %s", this->nick, __TIME__, __DATE__);
- this->WriteNumeric(004, "%s %s %s %s %s %s", this->nick, ServerInstance->Config->ServerName, VERSION, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
+ this->WriteNumeric(004, "%s %s InspIRCd-1.2 %s %s %s", this->nick, ServerInstance->Config->ServerName, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
ServerInstance->Config->Send005(this);
-
this->WriteNumeric(42, "%s %s :your unique ID", this->nick, this->uuid);
return;
}
- if (ServerInstance->Config->GetIOHook(this->GetPort()))
+ if (this->io)
{
/* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to
* implement their own buffering mechanisms
*/
try
{
- ServerInstance->Config->GetIOHook(this->GetPort())->OnRawSocketWrite(this->fd, text.data(), text.length());
+ this->io->OnRawSocketWrite(this->fd, text.data(), text.length());
}
catch (CoreException& modexcept)
{
uniq_id++;
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
/* We dont want to be doing this n times, just once */
snprintf(tb,MAXBUF,":%s %s",this->GetFullHost(),text.c_str());
std::string out = tb;
return;
uniq_id++;
+
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost(),normal_text.c_str());
snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost(),oper_text.c_str());
std::string out1 = tb1;
return;
uniq_id++;
+
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
snprintf(tb1,MAXBUF,":%s %s",this->GetFullHost(),text.c_str());
out1 = tb1;
void User::WriteWallOps(const std::string &text)
{
- if (!IS_OPER(this) && IS_LOCAL(this))
+ if (!IS_LOCAL(this))
return;
std::string wallop("WALLOPS :");
void User::WriteWallOps(const char* text, ...)
{
+ if (!IS_LOCAL(this))
+ return;
+
char textbuffer[MAXBUF];
va_list argsPtr;
/* deny change if change will take class over the limit */
if (found->limit && (found->RefCount + 1 >= found->limit))
{
- ServerInstance->Logs->Log("USERS", DEBUG, "OOPS: Connect class limit (%u) hit, denying", found->limit);
+ ServerInstance->Logs->Log("USERS", DEBUG, "OOPS: Connect class limit (%lu) hit, denying", found->limit);
return this->MyClass;
}
if (found == this->MyClass) // no point changing this shit :P
return this->MyClass;
this->MyClass->RefCount--;
- ServerInstance->Logs->Log("USERS", DEBUG, "Untying user from connect class -- refcount: %u", this->MyClass->RefCount);
+ ServerInstance->Logs->Log("USERS", DEBUG, "Untying user from connect class -- refcount: %lu", this->MyClass->RefCount);
}
this->MyClass = found;
this->MyClass->RefCount++;
- ServerInstance->Logs->Log("USERS", DEBUG, "User tied to new class -- connect refcount now: %u", this->MyClass->RefCount);
+ ServerInstance->Logs->Log("USERS", DEBUG, "User tied to new class -- connect refcount now: %lu", this->MyClass->RefCount);
}
return this->MyClass;