summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-02-19 08:15:54 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-02-19 08:15:54 +0000
commitbe4c8f3f21f6b5c1a56a60d5843a62d5a3321039 (patch)
tree5c3b0380937253278ff15ec3262e28d97771bc70
parent65735fefd6022aefa1a2d9d4fbcc72dda25ac5b5 (diff)
Fix for crashbugs when quitting users as experienced by satmd, SiliconAI and others.
QA: Please test combinations of /quit, /kill, and friends. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6595 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--src/cmd_nick.cpp8
-rw-r--r--src/cmd_quit.cpp83
-rw-r--r--src/modules.cpp50
3 files changed, 12 insertions, 129 deletions
diff --git a/src/cmd_nick.cpp b/src/cmd_nick.cpp
index 0bba6af0d..ae02a2e6d 100644
--- a/src/cmd_nick.cpp
+++ b/src/cmd_nick.cpp
@@ -69,11 +69,17 @@ CmdResult cmd_nick::Handle (const char** parameters, int pcnt, userrec *user)
if ((ServerInstance->FindNick(parameters[0])) && (ServerInstance->FindNick(parameters[0]) != user) && (ServerInstance->IsNick(parameters[0])))
{
userrec* InUse = ServerInstance->FindNick(parameters[0]);
+ /* XXX FIXME: This no longer works with the global culllist stuff,
+ * because the user is pushed onto the cullList then we accept a new user
+ * with the SAME nickname, so this mucks up the nickname hash completely.
+ * We need to find a way to force a nickchange upon the user whos being
+ * overruled, rather than quitting them. -- Brain
+ *
if (InUse->registered != REG_ALL)
{
userrec::QuitUser(ServerInstance, InUse, "Nickname overruled");
}
- else
+ else*/
{
user->WriteServ("433 %s %s :Nickname is already in use.", user->registered >= REG_NICK ? user->nick : "*", parameters[0]);
return CMD_FAILURE;
diff --git a/src/cmd_quit.cpp b/src/cmd_quit.cpp
index 0c5db928d..2498d4209 100644
--- a/src/cmd_quit.cpp
+++ b/src/cmd_quit.cpp
@@ -26,88 +26,7 @@ extern "C" command_t* init_command(InspIRCd* Instance)
CmdResult cmd_quit::Handle (const char** parameters, int pcnt, userrec *user)
{
- user_hash::iterator iter = ServerInstance->clientlist->find(user->nick);
- char reason[MAXBUF];
- std::string quitmsg = "Client exited";
-
- if (user->registered == REG_ALL)
- {
- /* theres more to do here, but for now just close the socket */
- if (pcnt == 1)
- {
- if (*parameters[0] == ':')
- parameters[0]++;
-
- strlcpy(reason, parameters[0],MAXQUIT-1);
-
- /* We should only prefix the quit for a local user. Remote users have
- * already been prefixed, where neccessary, by the upstream server.
- */
- if (IS_LOCAL(user))
- {
- quitmsg = ServerInstance->Config->PrefixQuit;
- quitmsg.append(parameters[0]);
- user->Write("ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,quitmsg.c_str());
- ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,quitmsg.c_str());
- user->WriteCommonExcept("QUIT :%s", quitmsg.c_str());
- }
- else
- {
- ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s!%s@%s [%s]",user->server,user->nick,user->ident,user->host,parameters[0]);
- user->WriteCommonExcept("QUIT :%s",parameters[0]);
- }
- FOREACH_MOD(I_OnUserQuit,OnUserQuit(user,std::string(ServerInstance->Config->PrefixQuit)+std::string(parameters[0])));
-
- }
- else
- {
- if (IS_LOCAL(user))
- {
- user->Write("ERROR :Closing link (%s@%s) []",user->ident,user->host);
- ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s!%s@%s [Client exited]",user->nick,user->ident,user->host);
- }
- else
- {
- ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s!%s@%s [Client exited]",user->server,user->nick,user->ident,user->host);
- }
- user->WriteCommonExcept("QUIT :Client exited");
- FOREACH_MOD(I_OnUserQuit,OnUserQuit(user,"Client exited"));
-
- }
- user->AddToWhoWas();
- }
-
- FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(user));
-
- if (IS_LOCAL(user))
- {
- ServerInstance->SE->DelFd(user);
- std::vector<userrec*>::iterator x = find(ServerInstance->local_users.begin(),ServerInstance->local_users.end(),user);
- if (x != ServerInstance->local_users.end())
- ServerInstance->local_users.erase(x);
- user->CloseSocket();
- }
-
- if (iter != ServerInstance->clientlist->end())
- {
- ServerInstance->clientlist->erase(iter);
- }
-
- if (user->registered == REG_ALL) {
- user->PurgeEmptyChannels();
- }
-
- if (IS_LOCAL(user))
- {
- std::string original_command = "QUIT :" + quitmsg;
- FOREACH_MOD(I_OnPostCommand,OnPostCommand("QUIT", parameters, pcnt, user, CMD_SUCCESS, original_command));
- }
-
- if (user->registered != REG_ALL)
- if (ServerInstance->unregistered_count)
- ServerInstance->unregistered_count--;
-
- DELETE(user);
+ userrec::QuitUser(ServerInstance, user, pcnt ? parameters[0] : "Client exited");
return CMD_USER_DELETED;
}
diff --git a/src/modules.cpp b/src/modules.cpp
index 83b88b2fa..7505dd21e 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -449,56 +449,14 @@ bool InspIRCd::AddResolver(Resolver* r, bool cached)
bool InspIRCd::UserToPseudo(userrec* user, const std::string &message)
{
- unsigned int old_fd = user->GetFd();
- user->Write("ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,message.c_str());
- user->FlushWriteBuf();
- user->ClearBuffer();
- user->SetFd(FD_MAGIC_NUMBER);
-
- if (find(local_users.begin(),local_users.end(),user) != local_users.end())
- {
- local_users.erase(find(local_users.begin(),local_users.end(),user));
- }
-
- this->SE->DelFd(user);
- shutdown(old_fd,2);
- close(old_fd);
- return true;
+ throw CoreException("The InspIRCd::UsertoPseudo function should not be used in InspIRCd later than 1.0.x");
+ return false;
}
bool InspIRCd::PseudoToUser(userrec* alive, userrec* zombie, const std::string &message)
{
- zombie->SetFd(alive->GetFd());
- FOREACH_MOD_I(this,I_OnUserQuit,OnUserQuit(alive,message));
- alive->SetFd(FD_MAGIC_NUMBER);
- alive->FlushWriteBuf();
- alive->ClearBuffer();
- // save these for later
- std::string oldnick = alive->nick;
- std::string oldhost = alive->host;
- std::string oldident = alive->ident;
- userrec::QuitUser(this,alive,message.c_str());
- if (find(local_users.begin(),local_users.end(),alive) != local_users.end())
- {
- local_users.erase(find(local_users.begin(),local_users.end(),alive));
- }
- // Fix by brain - cant write the user until their fd table entry is updated
- zombie->Write(":%s!%s@%s NICK %s",oldnick.c_str(),oldident.c_str(),oldhost.c_str(),zombie->nick);
- for (UCListIter i = zombie->chans.begin(); i != zombie->chans.end(); i++)
- {
- chanrec* Ptr = i->first;
- zombie->WriteFrom(zombie,"JOIN %s",Ptr->name);
- if (Ptr->topicset)
- {
- zombie->WriteServ("332 %s %s :%s", zombie->nick, Ptr->name, Ptr->topic);
- zombie->WriteServ("333 %s %s %s %d", zombie->nick, Ptr->name, Ptr->setby, Ptr->topicset);
- }
- Ptr->UserList(zombie);
- zombie->WriteServ("366 %s %s :End of /NAMES list.", zombie->nick, Ptr->name);
- }
- if ((find(local_users.begin(),local_users.end(),zombie) == local_users.end()) && (zombie->GetFd() != FD_MAGIC_NUMBER))
- local_users.push_back(zombie);
- return true;
+ throw CoreException("The InspIRCd::PseudotoUser function should not be used in InspIRCd later than 1.0.x");
+ return false;
}
void InspIRCd::AddGLine(long duration, const std::string &source, const std::string &reason, const std::string &hostmask)