ns_suspend.cpp

Go to the documentation of this file.
00001 /* NickServ core functions
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 
00014 #include "module.h"
00015 
00016 class CommandNSSuspend : public Command
00017 {
00018  public:
00019         CommandNSSuspend(Module *creator) : Command(creator, "nickserv/suspend", 2, 3)
00020         {
00021                 this->SetDesc(_("Suspend a given nick"));
00022                 this->SetSyntax(_("\037nickname\037 [+\037expiry\037] \037reason\037"));
00023         }
00024 
00025         void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00026         {
00027 
00028                 const Anope::string &nick = params[0];
00029                 Anope::string expiry = params[1];
00030                 Anope::string reason = params.size() > 2 ? params[2] : "";
00031                 time_t expiry_secs = Config->NSSuspendExpire;
00032 
00033                 if (Anope::ReadOnly)
00034                 {
00035                         source.Reply(READ_ONLY_MODE);
00036                         return;
00037                 }
00038 
00039                 if (expiry[0] != '+')
00040                 {
00041                         reason = expiry + " " + reason;
00042                         reason.trim();
00043                         expiry.clear();
00044                 }
00045                 else
00046                         expiry_secs = Anope::DoTime(expiry);
00047 
00048                 NickAlias *na = NickAlias::Find(nick);
00049                 if (!na)
00050                 {
00051                         source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
00052                         return;
00053                 }
00054 
00055                 if (Config->NSSecureAdmins && na->nc->IsServicesOper())
00056                 {
00057                         source.Reply(_("You may not suspend other Services Operators' nicknames."));
00058                         return;
00059                 }
00060 
00061                 NickCore *nc = na->nc;
00062 
00063                 nc->ExtendMetadata("SUSPENDED");
00064                 nc->ExtendMetadata("SECURE");
00065                 nc->Shrink("KILLPROTECT");
00066                 nc->Shrink("KILL_QUICK");
00067                 nc->Shrink("KILL_IMMED");
00068 
00069                 nc->ExtendMetadata("suspend:by", source.GetNick());
00070                 if (!reason.empty())
00071                         nc->ExtendMetadata("suspend:reason", reason);
00072                 if (expiry_secs > 0)
00073                         nc->ExtendMetadata("suspend:expire", stringify(Anope::CurTime + expiry_secs));
00074 
00075 
00076                 for (unsigned i = 0; i < nc->aliases->size(); ++i)
00077                 {
00078                         NickAlias *na2 = nc->aliases->at(i);
00079 
00080                         if (na2 && *na2->nc == *na->nc)
00081                         {
00082                                 na2->last_quit = reason;
00083 
00084                                 User *u2 = User::Find(na2->nick);
00085                                 if (u2)
00086                                 {
00087                                         u2->Logout();
00088                                         u2->Collide(na2);
00089                                 }
00090                         }
00091                 }
00092 
00093                 Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires in " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never");
00094                 source.Reply(_("Nick %s is now suspended."), nick.c_str());
00095 
00096                 FOREACH_MOD(I_OnNickSuspended, OnNickSuspend(na));
00097 
00098                 return;
00099         }
00100 
00101         bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
00102         {
00103                 this->SendSyntax(source);
00104                 source.Reply(" ");
00105                 source.Reply(_("Suspends a registered nickname, which prevents it from being used\n"
00106                                 "while keeping all the data for that nick. If an expiry is given\n"
00107                                 "the nick will be unsuspended after that period of time, else the\n"
00108                                 "default expiry from the configuration is used."));
00109                 return true;
00110         }
00111 };
00112 
00113 class CommandNSUnSuspend : public Command
00114 {
00115  public:
00116         CommandNSUnSuspend(Module *creator) : Command(creator, "nickserv/unsuspend", 1, 1)
00117         {
00118                 this->SetDesc(_("Unsuspend a given nick"));
00119                 this->SetSyntax(_("\037nickname\037"));
00120         }
00121 
00122         void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00123         {
00124                 const Anope::string &nick = params[0];
00125 
00126                 if (Anope::ReadOnly)
00127                 {
00128                         source.Reply(READ_ONLY_MODE);
00129                         return;
00130                 }
00131 
00132                 NickAlias *na = NickAlias::Find(nick);
00133                 if (!na)
00134                 {
00135                         source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
00136                         return;
00137                 }
00138 
00139                 if (!na->nc->HasExt("SUSPENDED"))
00140                 {
00141                         source.Reply(_("Nick %s is not suspended."), na->nick.c_str());
00142                         return;
00143                 }
00144 
00145                 na->nc->Shrink("SUSPENDED");
00146                 na->nc->Shrink("suspend:expire");
00147                 na->nc->Shrink("suspend:by");
00148                 na->nc->Shrink("suspend:reason");
00149 
00150                 Log(LOG_ADMIN, source, this) << "for " << na->nick;
00151                 source.Reply(_("Nick %s is now released."), nick.c_str());
00152 
00153                 FOREACH_MOD(I_OnNickUnsuspended, OnNickUnsuspended(na));
00154 
00155                 return;
00156         }
00157 
00158         bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
00159         {
00160                 this->SendSyntax(source);
00161                 source.Reply(" ");
00162                 source.Reply(_("Unsuspends a nickname which allows it to be used again."));
00163                 return true;
00164         }
00165 };
00166 
00167 class NSSuspend : public Module
00168 {
00169         CommandNSSuspend commandnssuspend;
00170         CommandNSUnSuspend commandnsunsuspend;
00171 
00172  public:
00173         NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00174                 commandnssuspend(this), commandnsunsuspend(this)
00175         {
00176                 this->SetAuthor("Anope");
00177 
00178                 Implementation i[] = { I_OnPreNickExpire };
00179                 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
00180         }
00181 
00182         void OnPreNickExpire(NickAlias *na, bool &expire) anope_override
00183         {
00184                 if (!na->nc->HasExt("SUSPENDED"))
00185                         return;
00186 
00187                 expire = false;
00188 
00189                 Anope::string *str = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:expire");
00190                 if (str == NULL)
00191                         return;
00192 
00193                 try
00194                 {
00195                         time_t when = convertTo<time_t>(*str);
00196                         if (when < Anope::CurTime)
00197                         {
00198                                 na->last_seen = Anope::CurTime;
00199                                 na->nc->Shrink("SUSPENDED");
00200                                 na->nc->Shrink("suspend:expire");
00201                                 na->nc->Shrink("suspend:by");
00202                                 na->nc->Shrink("suspend:reason");
00203 
00204                                 Log(LOG_NORMAL, "expire", NickServ) << "Expiring suspend for " << na->nick;
00205                         }
00206                 }
00207                 catch (const ConvertException &) { }
00208         }
00209 };
00210 
00211 MODULE_INIT(NSSuspend)