Fix crash when providing bad command line argument
[clinton/bobotpp.git] / source / ChannelUserList.C
CommitLineData
71cf2688 1// ChannelUserList.C -*- C++ -*-
2// Copyright (c) 1997, 1998 Etienne BERNARD
3// Copyright (C) 2002,2005,2008,2009 Clinton Ebadi
4
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// any later version.
9
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18// 02110-1301, USA.
19
20#include "ChannelUserList.H"
21#include "User.H"
22#include "UserList.H"
23#include "UserListItem.H"
24#include "Utils.H"
25
26#include <algorithm>
27#include <functional>
28
29ChannelUserList::ChannelUserList (const std::string & cn) throw ()
30 : users_mutex (true), channel_name (cn)
31{ }
32
33ChannelUserList::~ChannelUserList () throw ()
34{
35 BotLock destructor_lock (users_mutex);
36
37 while (users.begin () != users.end ())
38 {
39 del (users.begin()->nick);
40 }
41}
42
43std::list<User>::iterator
44ChannelUserList::get_user_i_ (const std::string &name)
45{
46 BotLock get_lock (users_mutex);
47
48 return std::find_if (users.begin (), users.end (),
49 std::bind1st (user_equal_p, User(name, 0)));
50}
51
52void
53ChannelUserList::add_ (std::string name, std::string host, int mode,
54 UserListItem* user_list_item, bool names) throw ()
55{
56 BotLock add_lock (users_mutex);
57
58 del (name);
59
60 if (user_list_item)
61 {
62 if (user_list_item->identified)
63 {
64 user_list_item->identified++;
65 }
66 else if (user_list_item->passwd == "")
67 {
68 user_list_item->identified = 1;
69 }
70 }
71
72 Utils::push_sorted (users,
73 names ? User (name, mode)
74 : User (name, host, channel_name, mode, user_list_item),
75 user_less_p);
76}
77
78void
79ChannelUserList::add (std::string name, std::string host, int mode,
80 UserList* user_list, bool names) throw ()
81{
82 BotLock add_lock (users_mutex);
83 name = Utils::to_lower (name);
84
85 UserListItem *uli = names ? 0 : user_list->getUserListItem (name + "!" + host,
86 channel_name);
87
88 add_ (name, host, mode, uli, names);
89}
90
91void
92ChannelUserList::del (const std::string &name) throw ()
93{
94 BotLock del_lock (users_mutex);
95
96 std::list<User>::iterator found = get_user_i_ (name);
97
98 if (found != users.end ())
99 {
100 if (found->userListItem && found->userListItem->identified > 0)
101 found->userListItem->identified--;
102
103 users.erase (found);
104 }
105}
106
107User
d82e6ba2 108ChannelUserList::get (const std::string & name) const
71cf2688 109{
110 BotLock get_lock (users_mutex);
111
112 std::list<User>::const_iterator pos =
113 std::find_if (users.begin (), users.end (),
114 std::bind1st (user_equal_p, User(name, 0)));
115
116 if (pos != users.end ())
117 return *pos;
118 else
119 throw user_not_found (name);
120}
121
122void
123ChannelUserList::change_nickname (const std::string & old_name,
124 std::string new_name)
71cf2688 125{
126 BotLock change_lock (users_mutex);
127
128 User user = get (old_name);
129 del (old_name);
130 add_ (new_name, user.userhost, user.mode, user.userListItem, false);
131}
132
133void
134ChannelUserList::change_user_mode (const std::string &name, int flag, bool remove)
135 throw ()
136{
137 BotLock change_lock (users_mutex);
138
139 std::list<User>::iterator user = get_user_i_ (name);
140
141 if (user != users.end ())
142 {
143 remove ? user->mode &= ~flag : user->mode |= flag;
144 }
145}
146
147bool
148ChannelUserList::in_channel_p (const std::string &name) const throw ()
149{
150 try
151 {
152 get (name);
153 }
154 catch (user_not_found &)
155 {
156 return false;
157 }
158
159 return true;
160}
161
162void
163ChannelUserList::change_user_key (const std::string &name, const std::string &key)
164 throw ()
165{
166 std::list<User>::iterator user = get_user_i_ (name);
167
168 if (user != users.end ())
169 user->userkey = key;
170}
171
172unsigned int
173ChannelUserList::user_count () const throw ()
174{
175 return users.size ();
176}
177
178unsigned int
179ChannelUserList::operator_count () const throw ()
180{
181 unsigned int count = 0;
182
183 for (std::list<User>::const_iterator user = users.begin ();
184 user != users.end ();
185 ++user)
186 {
187 if (user->mode & User::OP_MODE)
188 count++;
189 }
190
191 return count;
192}