nickalias.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  */
00012 
00013 #include "services.h"
00014 #include "account.h"
00015 #include "modules.h"
00016 #include "opertype.h"
00017 #include "protocol.h"
00018 #include "users.h"
00019 #include "servers.h"
00020 #include "config.h"
00021 
00022 Serialize::Checker<nickalias_map> NickAliasList("NickAlias");
00023 
00024 NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serializable("NickAlias")
00025 {
00026         if (nickname.empty())
00027                 throw CoreException("Empty nick passed to NickAlias constructor");
00028         else if (!nickcore)
00029                 throw CoreException("Empty nickcore passed to NickAlias constructor");
00030 
00031         this->time_registered = this->last_seen = Anope::CurTime;
00032         this->nick = nickname;
00033         this->nc = nickcore;
00034         nickcore->aliases->push_back(this);
00035 
00036         size_t old = NickAliasList->size();
00037         (*NickAliasList)[this->nick] = this;
00038         if (old == NickAliasList->size())
00039                 Log(LOG_DEBUG) << "Duplicate nick " << nickname << " in nickalias table";
00040 
00041         if (this->nc->o == NULL)
00042         {
00043                 Oper *o = Oper::Find(this->nick);
00044                 if (o == NULL)
00045                         o = Oper::Find(this->nc->display);
00046                 nickcore->o = o;
00047                 if (this->nc->o != NULL)
00048                         Log() << "Tied oper " << this->nc->display << " to type " << this->nc->o->ot->GetName();
00049         }
00050 }
00051 
00052 NickAlias::~NickAlias()
00053 {
00054         FOREACH_MOD(I_OnDelNick, OnDelNick(this));
00055 
00056         /* Accept nicks that have no core, because of database load functions */
00057         if (this->nc)
00058         {
00059                 /* Next: see if our core is still useful. */
00060                 std::vector<NickAlias *>::iterator it = std::find(this->nc->aliases->begin(), this->nc->aliases->end(), this);
00061                 if (it != this->nc->aliases->end())
00062                         this->nc->aliases->erase(it);
00063                 if (this->nc->aliases->empty())
00064                 {
00065                         delete this->nc;
00066                         this->nc = NULL;
00067                 }
00068                 else
00069                 {
00070                         /* Display updating stuff */
00071                         if (this->nick.equals_ci(this->nc->display))
00072                                 this->nc->SetDisplay(this->nc->aliases->front());
00073                 }
00074         }
00075 
00076         /* Remove us from the aliases list */
00077         NickAliasList->erase(this->nick);
00078 }
00079 
00080 void NickAlias::Release()
00081 {
00082         if (this->HasExt("HELD"))
00083         {
00084                 if (IRCD->CanSVSHold)
00085                         IRCD->SendSVSHoldDel(this->nick);
00086                 else
00087                 {
00088                         User *u = User::Find(this->nick);
00089                         if (u && u->server == Me)
00090                         {
00091                                 u->Quit();
00092                         }
00093                 }
00094 
00095                 this->Shrink("HELD");
00096         }
00097 }
00098 
00101 class NickServHeld : public Timer
00102 {
00103         static std::map<Anope::string, NickServHeld *> NickServHelds;
00104 
00105         Reference<NickAlias> na;
00106         Anope::string nick;
00107  public:
00108         NickServHeld(NickAlias *n, long l) : Timer(l), na(n), nick(na->nick)
00109         {
00110                 std::map<Anope::string, NickServHeld *>::iterator nit = NickServHelds.find(na->nick);
00111                 if (nit != NickServHelds.end())
00112                         delete nit->second;
00113 
00114                 NickServHelds[na->nick] = this;
00115         }
00116 
00117         ~NickServHeld()
00118         {
00119                 NickServHelds.erase(this->nick);
00120         }
00121 
00122         void Tick(time_t)
00123         {
00124                 if (na)
00125                         na->Shrink("HELD");
00126         }
00127 };
00128 std::map<Anope::string, NickServHeld *> NickServHeld::NickServHelds;
00129 
00132 class CoreExport NickServRelease : public User, public Timer
00133 {
00134         static std::map<Anope::string, NickServRelease *> NickServReleases;
00135         Anope::string nick;
00136 
00137  public:
00142         NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->NSEnforcerUser, Config->NSEnforcerHost, "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
00143         {
00144                 /* Erase the current release timer and use the new one */
00145                 std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
00146                 if (nit != NickServReleases.end())
00147                 {
00148                         IRCD->SendQuit(nit->second, "");
00149                         delete nit->second;
00150                 }
00151 
00152                 NickServReleases.insert(std::make_pair(this->nick, this));
00153 
00154                 IRCD->SendClientIntroduction(this);
00155         }
00156 
00157         virtual ~NickServRelease()
00158         {
00159                 NickServReleases.erase(this->nick);
00160         }
00161 
00165         void Tick(time_t t)
00166         {
00167                 IRCD->SendQuit(this, "");
00168         }
00169 };
00170 std::map<Anope::string, NickServRelease *> NickServRelease::NickServReleases;
00171 
00172 void NickAlias::OnCancel(User *)
00173 {
00174         if (this->HasExt("COLLIDED"))
00175         {
00176                 this->Extend("HELD");
00177                 this->Shrink("COLLIDED");
00178 
00179                 new NickServHeld(this, Config->NSReleaseTimeout);
00180 
00181                 if (IRCD->CanSVSHold)
00182                         IRCD->SendSVSHold(this->nick);
00183                 else
00184                         new NickServRelease(this, Config->NSReleaseTimeout);
00185         }
00186 }
00187 
00188 void NickAlias::SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created)
00189 {
00190         this->vhost_ident = ident;
00191         this->vhost_host = host;
00192         this->vhost_creator = creator;
00193         this->vhost_created = created;
00194 }
00195 
00196 void NickAlias::RemoveVhost()
00197 {
00198         this->vhost_ident.clear();
00199         this->vhost_host.clear();
00200         this->vhost_creator.clear();
00201         this->vhost_created = 0;
00202 }
00203 
00204 bool NickAlias::HasVhost() const
00205 {
00206         return !this->vhost_host.empty();
00207 }
00208 
00209 const Anope::string &NickAlias::GetVhostIdent() const
00210 {
00211         return this->vhost_ident;
00212 }
00213 
00214 const Anope::string &NickAlias::GetVhostHost() const
00215 {
00216         return this->vhost_host;
00217 }
00218 
00219 const Anope::string &NickAlias::GetVhostCreator() const
00220 {
00221         return this->vhost_creator;
00222 }
00223 
00224 time_t NickAlias::GetVhostCreated() const
00225 {
00226         return this->vhost_created;
00227 }
00228 
00229 NickAlias *NickAlias::Find(const Anope::string &nick)
00230 {
00231         nickalias_map::const_iterator it = NickAliasList->find(nick);
00232         if (it != NickAliasList->end())
00233         {
00234                 it->second->QueueUpdate();
00235                 return it->second;
00236         }
00237 
00238         return NULL;
00239 }
00240 
00241 void NickAlias::Serialize(Serialize::Data &data) const
00242 {
00243         data["nick"] << this->nick;
00244         data["last_quit"] << this->last_quit;
00245         data["last_realname"] << this->last_realname;
00246         data["last_usermask"] << this->last_usermask;
00247         data["last_realhost"] << this->last_realhost;
00248         data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
00249         data.SetType("time_registered", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
00250         data["nc"] << this->nc->display;
00251         this->ExtensibleSerialize(data);
00252 
00253         if (this->HasVhost())
00254         {
00255                 data["vhost_ident"] << this->GetVhostIdent();
00256                 data["vhost_host"] << this->GetVhostHost();
00257                 data["vhost_creator"] << this->GetVhostCreator();
00258                 data["vhost_time"] << this->GetVhostCreated();
00259         }
00260 }
00261 
00262 Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
00263 {
00264         Anope::string snc, snick;
00265 
00266         data["nc"] >> snc;
00267         data["nick"] >> snick;
00268 
00269         NickCore *core = NickCore::Find(snc);
00270         if (core == NULL)
00271                 return NULL;
00272 
00273         NickAlias *na;
00274         if (obj)
00275                 na = anope_dynamic_static_cast<NickAlias *>(obj);
00276         else
00277                 na = new NickAlias(snick, core);
00278 
00279         if (na->nc != core)
00280         {
00281                 std::vector<NickAlias *>::iterator it = std::find(na->nc->aliases->begin(), na->nc->aliases->end(), na);
00282                 if (it != na->nc->aliases->end())
00283                         na->nc->aliases->erase(it);
00284 
00285                 if (na->nc->aliases->empty())
00286                         delete na->nc;
00287                 else if (na->nick.equals_ci(na->nc->display))
00288                         na->nc->SetDisplay(na->nc->aliases->front());
00289 
00290                 na->nc = core;
00291                 core->aliases->push_back(na);
00292         }
00293 
00294         data["last_quit"] >> na->last_quit;
00295         data["last_realname"] >> na->last_realname;
00296         data["last_usermask"] >> na->last_usermask;
00297         data["last_realhost"] >> na->last_realhost;
00298         data["time_registered"] >> na->time_registered;
00299         data["last_seen"] >> na->last_seen;
00300         na->ExtensibleUnserialize(data);
00301 
00302         Anope::string vhost_ident, vhost_host, vhost_creator;
00303         time_t vhost_time;
00304 
00305         data["vhost_ident"] >> vhost_ident;
00306         data["vhost_host"] >> vhost_host;
00307         data["vhost_creator"] >> vhost_creator;
00308         data["vhost_time"] >> vhost_time;
00309 
00310         na->SetVhost(vhost_ident, vhost_host, vhost_creator, vhost_time);
00311 
00312         /* Compat */
00313         Anope::string sflags;
00314         data["flags"] >> sflags;
00315         spacesepstream sep(sflags);
00316         Anope::string tok;
00317         while (sep.GetToken(tok))
00318                 na->ExtendMetadata(tok);
00319         /* End compat */
00320 
00321         return na;
00322 }
00323