--- /dev/null
+// BanList.C -*- C++ -*-
+// Copyright (C) 2008 Clinton Ebadi
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+
+#include "BanList.H"
+
+#include <algorithm>
+
+#include "BanEntry.H"
+#include "Mask.H"
+
+BanList::BanList ()
+{ }
+
+BanList::~BanList ()
+{
+ BotLock ban_lock (ban_mutex);
+
+ while (!storage.empty ())
+ {
+ delete storage.front ();
+ storage.pop_front ();
+ }
+}
+
+bool BanList::add (const Mask & mask, std::time_t expiration)
+{
+ BotLock ban_lock (ban_mutex);
+ iterator it = find (mask);
+
+ if (it != storage.end ())
+ {
+ if (expiration > (*it)->getExpirationDate())
+ (*it)->setExpirationDate (expiration);
+
+ return false;
+ }
+ else
+ {
+ storage.push_back (new BanEntry (mask, expiration));
+
+ return true;
+ }
+}
+
+bool BanList::del (const Mask & mask)
+{
+ BotLock ban_lock (ban_mutex);
+ iterator it = find (mask);
+
+ if (it != storage.end ())
+ {
+ BanEntry *b = *it;
+ storage.erase (it);
+ delete b;
+
+ return true;
+ }
+ return false;
+}
+
+namespace
+{
+ struct BanEntryFind
+ {
+ Mask mask;
+
+ BanEntryFind (const Mask &m)
+ : mask (m)
+ { }
+
+ bool operator() (const BanEntry * ban_entry) const
+ { return mask.getMask() == ban_entry->getMask().getMask (); }
+ };
+}
+
+BanList::iterator BanList::find (const Mask & mask)
+{
+ BanEntryFind find_ban_entry (mask);
+
+ return std::find_if (storage.begin (), storage.end (), find_ban_entry);
+}
+
+BanList::MatchList BanList::find_matches (const Mask & mask) const
+{
+ BotLock ban_lock (ban_mutex);
+ MatchList matches;
+
+ for (List::const_iterator it = storage.begin ();
+ it != storage.end ();
+ ++it)
+ {
+ Mask dupmask = (*it)->getMask ();
+ if (mask.matches (dupmask))
+ {
+ matches.push_front (dupmask);
+ }
+ }
+
+ return matches;
+}
+
+BanList::MatchList BanList::delete_expired_x ()
+{
+ BotLock ban_lock (ban_mutex);
+ std::time_t now = std::time (0);
+ MatchList expired;
+
+ List::iterator it = storage.begin ();
+ while (it != storage.end ())
+ {
+ if ((*it)->getExpirationDate () > -1 && (*it)->getExpirationDate () < now)
+ {
+ expired.push_front ((*it)->getMask ());
+ delete *it;
+ storage.erase (it++);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+
+ return expired;
+}
--- /dev/null
+// BanList.H -*- C++ -*-
+// Copyright (C) 2008 Clinton Ebadi
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#ifndef BANLIST_H
+#define BANLIST_H
+
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <string>
+
+#include <ctime>
+
+#include "BotThreading.H"
+#include "Mask.H"
+
+class BanEntry;
+
+class BanList
+{
+public:
+ typedef std::list<BanEntry *> List;
+ typedef std::list<Mask> MatchList;
+ typedef List::iterator iterator;
+
+private:
+ List storage;
+ BotMutex ban_mutex;
+
+ iterator find (const Mask&);
+
+public:
+ BanList ();
+ ~BanList ();
+
+ bool add (const Mask&, std::time_t = -1);
+ bool del (const Mask&);
+
+ MatchList find_matches (const Mask&) const;
+ MatchList delete_expired_x ();
+
+ template<typename T>
+ void foreach (const T & fun)
+ {
+ BotLock ban_lock (ban_mutex);
+ std::for_each (storage.begin (), storage.end (), fun);
+ }
+};
+
+#endif
#include "ServerList.H"
#include "ShitList.H"
#include "StringTokenizer.H"
-#include "TodoList.H"
#include "User.H"
#include "UserCommands.H"
#include "UserList.H"
readConfig();
userList = new UserList(userListFileName);
shitList = new ShitList(shitListFileName);
- todoList = new TodoList();
dccConnections = new DCCManager ();
// Let's read the alias file
shitList->save();
delete channelList;
delete userList;
- delete todoList;
delete serverList;
delete shitList;
delete serverConnection;
if ((*it).second > 0)
(*it).second--;
- String line;
- while ((line = todoList->getNext()) != "") {
- serverConnection->queue->sendChannelMode(line);
- }
+ for (std::map<String, Channel *, std::less<String> >::iterator it = channelList->begin ();
+ it != channelList->end ();
+ ++it)
+ {
+ it->second->purge_expired_bans ();
+ }
#ifdef USESCRIPTS
botInterp->RunTimers(currentTime);
class ServerConnection;
class ServerList;
class ShitList;
-class TodoList;
class UserList;
class UserCommands;
UserList * userList;
ShitList * shitList;
ServerList * serverList;
- TodoList * todoList;
#ifdef USESCRIPTS
BotInterp * botInterp;
#endif
#include "BanEntry.H"
#include "Bot.H"
#include "Macros.H"
+#include "Mask.H"
#include "Person.H"
#include "ServerConnection.H"
#include "ShitEntry.H"
{
#ifdef HAVE_STL_CLEAR
channelMemory.clear();
- channelBanlist.clear();
#endif
if (c->bot->wantedChannels[channelName])
{
channelMemory.erase(it);
delete u;
}
-
- BanEntry *b;
- std::vector<BanEntry *>::iterator it2;
-
- while (channelBanlist.size() != 0) {
- it2 = channelBanlist.begin();
- b = *it2;
- channelBanlist.erase(it2);
- delete b;
- }
}
void
}
void
-Channel::addBan(String mask, std::time_t expiration)
+Channel::addBan(const Mask & mask, std::time_t expiration)
{
- for (std::vector<BanEntry *>::iterator it = channelBanlist.begin();
- it != channelBanlist.end(); ++it)
- if ((*it)->getMask().getMask() == mask) {
- if (expiration > (*it)->getExpirationDate())
- (*it)->setExpirationDate(expiration);
- return;
- }
- channelBanlist.push_back(new BanEntry(mask, expiration));
+ if (channelBanlist.add (mask, expiration))
+ cnx->queue->sendChannelMode (channelName, "+b", mask.getMask ());
}
void
-Channel::delBan(String mask)
+Channel::delBan(const Mask & mask)
{
- for (std::vector<BanEntry *>::iterator it = channelBanlist.begin();
- it != channelBanlist.end(); ++it)
- if (mask == (*it)->getMask().getMask()) {
- BanEntry *b = *it;
- channelBanlist.erase(it);
- delete b;
- break;
+ BanList::MatchList matches = channelBanlist.find_matches (mask);
+
+ for (BanList::MatchList::const_iterator it = matches.begin ();
+ it != matches.end ();
+ ++it)
+ {
+ if (channelBanlist.del (*it))
+ cnx->queue->sendChannelMode (channelName, "-b", mask.getMask ());
}
}
+void Channel::purge_expired_bans ()
+{
+ BanList::MatchList expired = channelBanlist.delete_expired_x ();
+
+ for (BanList::MatchList::const_iterator it = expired.begin ();
+ it != expired.end ();
+ ++it)
+ cnx->queue->sendChannelMode (channelName, "-b", (*it).getMask ());
+}
+
void
Channel::resynchModes()
{
break;
case 'b':
String m = st.next_token();
- sign == '+' ? addBan(m) : delBan(m);
- if (sign == '-') {
- ShitEntry * se =
- cnx->bot->shitList->getShit(m, channelName);
- if (se && se->isStillValid() &&
- se->getShitLevel() >= ShitEntry::SHIT_NODEBAN)
+ if (sign == '+')
+ channelBanlist.add (m);
+ if (sign == '-')
+ {
+ ShitEntry * se = cnx->bot->shitList->getShit(m, channelName);
+
+ if (se && se->isStillValid() &&
+ se->getShitLevel() >= ShitEntry::SHIT_NODEBAN)
cnx->queue->sendChannelMode(channelName, "+b", m);
- }
+ else
+ channelBanlist.del (m);
+
+ }
}
}
// Channel.H -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
+// Copyright (C) 2002,2008 Clinton Ebadi
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
#ifndef CHANNEL_H
#define CHANNEL_H
-#include <ctime>
+#include <algorithm>
+#include <functional>
#include <map>
#include <vector>
+#include <ctime>
+
+#include "BanList.H"
#include "String.H"
class BanEntry;
class Bot;
class Commands;
+class Mask;
class Parser;
class Person;
class ServerConnection;
bool doMode;
bool gotWho;
std::map<String, User *, std::less<String> > channelMemory;
- std::vector<BanEntry *> channelBanlist;
+ BanList channelBanlist;
ServerConnection * cnx;
public:
bool hasNick(String);
User * getUser(String);
- void addBan(String, std::time_t = -1);
- void delBan(String);
+ void addBan(const Mask&, std::time_t = -1);
+ void delBan(const Mask&);
+ void purge_expired_bans ();
+ template<typename T> void for_each_ban_entry (const T & fun)
+ { channelBanlist.foreach (fun); }
void parseMode(Person *, String);
void resynchModes();
#include "ShitEntry.H"
#include "ShitList.H"
#include "StringTokenizer.H"
-#include "TodoList.H"
#include "User.H"
#include "UserList.H"
#include "Utils.H"
(*it)->channelMask.matches(channel) &&
(*it)->prot >= User::NO_BAN)
return UserProtected(who, channel);
-
- for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
- it != c->channelBanlist.end(); ++it)
- if (m.matches((*it)->getMask ()) && (*it)->getMask().getMask() != m.getMask())
- QUEUE->sendChannelMode(channel, "-b", (*it)->getMask().getMask());
- QUEUE->sendChannelMode(channel, "+b", dest);
-
+ c->delBan (m);
+ c->addBan (m, -1);
+
return Ok;
}
dest = Utils::make_wildcard(dest);
Mask m(dest);
+
+ BanList::MatchList matches = c->channelBanlist.find_matches (m);
- for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
- it != c->channelBanlist.end(); ++it)
- if (m.matches((*it)->getMask())) {
- // Let's see if the ban is in the shitlist
- ShitEntry *se = bot->shitList->getShit((*it)->getMask().getMask(), channel);
- if (!se || !se->isStillValid() ||
- se->getShitLevel() < ShitEntry::SHIT_NODEBAN)
- QUEUE->sendChannelMode(channel, "-b", (*it)->getMask().getMask());
- }
+ for (BanList::MatchList::iterator it = matches.begin ();
+ it != matches.end();
+ ++it)
+ if (m.matches(*it))
+ {
+ // Let's see if the ban is in the shitlist
+ ShitEntry *se = bot->shitList->getShit(it->getMask(), channel);
+ if (!se || !se->isStillValid() ||
+ se->getShitLevel() < ShitEntry::SHIT_NODEBAN)
+ c->delBan (m);
+ }
return Ok;
}
// Make sure all of the inputs are valid
if (!c)
- {
- return NotOnChannel(channel);
- }
-
+ return NotOnChannel(channel);
if (!bot->iAmOp(channel))
- {
- return NotChannelOp(channel);
- }
-
+ return NotChannelOp(channel);
if (seconds <= 0)
- {
- return InvalidTime(seconds);
- }
-
+ return InvalidTime(seconds);
+
// Look for user
if (!Utils::wildcard_p(who))
- {
- dest = bot->getUserhost(channel, who);
- }
+ dest = bot->getUserhost(channel, who);
else
- {
- dest = who;
- }
-
+ dest = who;
+
if (dest.length() == 0)
- {
- return UserNotFound(who, channel);
- }
-
+ return UserNotFound(who, channel);
dest = Utils::make_wildcard(dest);
Mask m(dest);
}
}
- // Clear existing bans on the user
- for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
- it != c->channelBanlist.end(); ++it)
- {
- if (m.matches((*it)->getMask ()))
- {
- QUEUE->sendChannelMode(channel, "-b", (*it)->getMask().getMask());
- }
- }
- // Ban them
- CHANNEL(channel)->addBan(dest, seconds);
- QUEUE->sendChannelMode(channel, "+b", dest);
- bot->todoList->addDeban(channel, dest, seconds);
+ // c->delBan (dest);
+ c->addBan(dest, seconds);
return Ok;
}
bin_PROGRAMS = bobotpp
bobotpp_SOURCES = BanEntry.C \
+ BanList.C \
Bot.C \
BotConfig.C \
BotInterp.C \
Socket.C \
String.C \
StringTokenizer.C \
- TodoList.C \
User.C \
UserCommands.C \
UserList.C \
Utils.C \
BanEntry.H \
+ BanList.H \
Bot.H \
BotConfig.H \
BotInterp.H \
Socket.H \
String.H \
StringTokenizer.H \
- TodoList.H \
User.H \
UserCommands.H \
UserList.H \
if (st.rest ().length ())
{
st.next_token ('=');
- String parameters = st.rest ();
- parameters = parameters.substr (1);
- cnx->bot->userhostMap[num] = parameters;
+ cnx->bot->userhostMap[num] = Utils::trim_str (st.rest().substr(1));
}
else
cnx->bot->userhostMap[num] = "";
st.next_token ();
String ch = st.next_token ();
if (Channel * c = cnx->bot->channelList->getChannel (ch))
- c->addBan (st.next_token (), -1);
+ c->addBan (Mask(st.next_token ()), -1);
}
void
+++ /dev/null
-// TodoList.C -*- C++ -*-
-// Copyright (c) 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
-
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#include "TodoList.H"
-
-TodoList::TodoList()
-{
-#ifdef HAVE_STL_CLEAR
- todoQueue.clear();
-#endif
-}
-
-TodoList::~TodoList()
-{ }
-
-void
-TodoList::addDeban(String channel, String mask, time_t when)
-{
- TodoListItem tdli(String("MODE ") + channel +
- " -b " + mask, when);
- todoQueue.insert(tdli);
-}
-
-String
-TodoList::getNext()
-{
- std::multiset<TodoListItem, std::less<TodoListItem> >::iterator it;
- std::time_t current_time = time(0);
-
- it = todoQueue.begin();
-
- if (it == todoQueue.end() || (*it).when > current_time)
- return "";
-
- String result = (*it).line;
- todoQueue.erase(it);
-
- return result;
-}
+++ /dev/null
-// TodoList.H -*- C++ -*-
-// Copyright (c) 1998 Etienne BERNARD
-// Copyright (c) 2002 Clinton Ebadi
-
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#ifndef TODOLIST_H
-#define TODOLIST_H
-
-#include <functional>
-#include <set>
-
-#include <ctime>
-
-#include "String.H"
-
-class TodoList;
-
-class TodoListItem {
- String line;
- std::time_t when;
-public:
- TodoListItem(String l, std::time_t w)
- : line(l), when(w) { }
-
- bool operator<(const TodoListItem &t) const
- { return when < t.when; }
-
- friend class TodoList;
-};
-
-class TodoList {
-
- std::multiset<TodoListItem, std::less<TodoListItem> > todoQueue;
-
-public:
- TodoList();
- ~TodoList();
-
- void addDeban(String, String, std::time_t);
-
- String getNext();
-};
-
-#endif
#include "UserCommands.H"
#include <fstream>
+#include <functional>
#include <map>
#include <string>
#include "ServerList.H"
#include "ShitEntry.H"
#include "StringTokenizer.H"
-#include "TodoList.H"
#include "User.H"
#include "UserList.H"
#include "Utils.H"
from->sendNotice(m.getMessage());
}
+namespace
+{
+ void print_ban_list (Person * from, const BanEntry * b)
+ {
+ if (b->getExpirationDate() == -1)
+ from->sendNotice(b->getMask().getMask().pad(30) + " -1");
+ else
+ from->sendNotice(b->getMask().getMask().pad(30) + " " +
+ String((long)(b->getExpirationDate() - std::time (0))));
+ }
+}
+
void
UserCommands::BanList(ServerConnection *cnx, Person *from,
String channel, String rest)
{
- time_t current = time(0);
Channel *c = cnx->bot->channelList->getChannel(channel);
+
from->sendNotice(String("\002Banlist for channel\002 ") +
channel + "\002:\002");
from->sendNotice("\002Mask Expires (seconds)\002");
- for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
- it != c->channelBanlist.end(); ++it)
- if ((*it)->getExpirationDate() == -1)
- from->sendNotice((*it)->getMask().getMask().pad(30) + " -1");
- else
- from->sendNotice((*it)->getMask().getMask().pad(30) + " " +
- String((long)((*it)->getExpirationDate()-current)));
+
+ c->for_each_ban_entry (std::bind1st (std::ptr_fun (print_ban_list),
+ from));
+
from->sendNotice("\002End of banlist.\002");
}
channel);
}
-// FIXME: Convert
void
UserCommands::TBan(ServerConnection *cnx, Person *from,
String channel, String rest)
{
Channel * c = cnx->bot->channelList->getChannel(channel);
-
StringTokenizer st(rest);
String who = st.next_token();
String t = st.next_token();
- String dest;
if (who == "" || t == "") {
if (from)
}
}
- if (!cnx->bot->iAmOp(channel)) {
- if (from)
- from->sendNotice(String("\002I am not channel op on\002 ") +
- channel);
- return;
- }
-
- if (!Utils::wildcard_p(who))
- dest = cnx->bot->getUserhost(channel, who);
- else
- dest = who;
-
- if (dest == "") {
- if (from)
- from->sendNotice(String("\002I can not find\002 ") + who);
- return;
- }
-
- time_t w;
-
- if ((w = Utils::str2time(t)) == 0) {
- if (from)
- from->sendNotice(t + " \002is an invalid time.\002");
- return;
- }
-
- dest = Utils::make_wildcard(dest);
- Mask m(dest);
-
- for (std::list<UserListItem *>::iterator it = cnx->bot->userList->l.begin();
- it != cnx->bot->userList->l.end();
- it++)
- if (m.matches((*it)->mask) &&
- (*it)->channelMask.matches(channel) &&
- (*it)->prot >= User::NO_BAN) {
- if (from)
- from->sendNotice(String("\002I can not ban\002 ") +
- who + " \002on channel\002 " +
- channel + " \002(protection).\002");
- return;
- }
-
- for (std::vector<BanEntry *>::iterator it = c->channelBanlist.begin();
- it != c->channelBanlist.end(); ++it)
- if (m.matches((*it)->getMask()))
- cnx->queue->sendChannelMode(channel, "-b", (*it)->getMask().getMask());
-
- cnx->bot->channelList->getChannel(channel)->addBan(dest, w);
- cnx->queue->sendChannelMode(channel, "+b", dest);
- cnx->bot->todoList->addDeban(channel, dest, (time_t)w);
+ Message ret = Commands::TBan (cnx->bot, channel, who, Utils::str2time (t));
+ if (ret.getCode () && from)
+ from->sendNotice ("\002" + ret.getMessage () + "\002");
}
// FIXME: Convert