+// 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;
+}