]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/cull_list.cpp
Ensure that simplemodes are sent first (jilles requested this)
[user/henk/code/inspircd.git] / src / cull_list.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "users.h"
16 #include "cull_list.h"
17
18 CullItem::CullItem(userrec* u, std::string &r)
19 {
20         this->user = u;
21         this->reason = r;
22 }
23
24 CullItem::CullItem(userrec* u, const char* r)
25 {
26         this->user = u;
27         this->reason = r;
28 }
29
30 CullItem::~CullItem()
31 {
32 }
33
34 userrec* CullItem::GetUser()
35 {
36         return this->user;
37 }
38
39 std::string& CullItem::GetReason()
40 {
41         return this->reason;
42 }
43
44 CullList::CullList(InspIRCd* Instance) : ServerInstance(Instance)
45 {
46         list.clear();
47         exempt.clear();
48 }
49
50 void CullList::AddItem(userrec* user, std::string &reason)
51 {
52         AddItem(user, reason.c_str());
53 }
54
55
56 void CullList::AddItem(userrec* user, const char* reason)
57 {
58         if (exempt.find(user) == exempt.end())
59         {
60                 CullItem item(user,reason);
61                 list.push_back(item);
62                 exempt[user] = user;
63         }
64 }
65
66 int CullList::Apply()
67 {
68         int n = list.size();
69         while (list.size())
70         {
71                 std::vector<CullItem>::iterator a = list.begin();
72
73                 user_hash::iterator iter = ServerInstance->clientlist->find(a->GetUser()->nick);
74                 std::map<userrec*, userrec*>::iterator exemptiter = exempt.find(a->GetUser());
75                 std::string reason = a->GetReason();
76
77                 if (reason.length() > MAXQUIT - 1)
78                         reason.resize(MAXQUIT - 1);
79
80                 if (a->GetUser()->registered != REG_ALL)
81                         if (ServerInstance->unregistered_count)
82                                 ServerInstance->unregistered_count--;
83
84                 if (IS_LOCAL(a->GetUser()))
85                 {
86                         a->GetUser()->Write("ERROR :Closing link (%s@%s) [%s]",a->GetUser()->ident,a->GetUser()->host,reason.c_str());
87                         if ((!a->GetUser()->sendq.empty()) && (!(*a->GetUser()->GetWriteError())))
88                                 a->GetUser()->FlushWriteBuf();
89                 }
90
91                 if (a->GetUser()->registered == REG_ALL)
92                 {
93                         a->GetUser()->PurgeEmptyChannels();
94                         a->GetUser()->WriteCommonExcept("QUIT :%s",reason.c_str());
95                         FOREACH_MOD_I(ServerInstance,I_OnUserQuit,OnUserQuit(a->GetUser(),reason));
96                 }
97
98                 FOREACH_MOD_I(ServerInstance,I_OnUserDisconnect,OnUserDisconnect(a->GetUser()));
99
100                 if (IS_LOCAL(a->GetUser()))
101                 {
102                         if (ServerInstance->Config->GetIOHook(a->GetUser()->GetPort()))
103                         {
104                                 try
105                                 {
106                                         ServerInstance->Config->GetIOHook(a->GetUser()->GetPort())->OnRawSocketClose(a->GetUser()->GetFd());
107                                 }
108                                 catch (CoreException& modexcept)
109                                 {
110                                         ServerInstance->Log(DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
111                                 }
112                         }
113
114                         ServerInstance->SE->DelFd(a->GetUser());
115                         a->GetUser()->CloseSocket();
116                 }
117
118                 /*
119                  * this must come before the ServerInstance->SNO->WriteToSnoMaskso that it doesnt try to fill their buffer with anything
120                  * if they were an oper with +sn +qQ.
121                  */
122                 if (a->GetUser()->registered == REG_ALL)
123                 {
124                         if (IS_LOCAL(a->GetUser()))
125                                 ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s!%s@%s [%s]",a->GetUser()->nick,a->GetUser()->ident,a->GetUser()->host,reason.c_str());
126                         else
127                                 ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s!%s@%s [%s]",a->GetUser()->server,a->GetUser()->nick,a->GetUser()->ident,a->GetUser()->host,reason.c_str());
128                         a->GetUser()->AddToWhoWas();
129                 }
130
131                 if (iter != ServerInstance->clientlist->end())
132                 {
133                         if (IS_LOCAL(a->GetUser()))
134                         {
135                                 std::vector<userrec*>::iterator x = find(ServerInstance->local_users.begin(),ServerInstance->local_users.end(),a->GetUser());
136                                 if (x != ServerInstance->local_users.end())
137                                         ServerInstance->local_users.erase(x);
138                         }
139                         ServerInstance->clientlist->erase(iter);
140                         DELETE(a->GetUser());
141                 }
142
143                 list.erase(list.begin());
144                 exempt.erase(exemptiter);
145         }
146         return n;
147 }