The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download | Blog | Stats
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

cmd_whowas Class Reference

Handle /WHOWAS. More...

#include <cmd_whowas.h>

Inheritance diagram for cmd_whowas:

Inheritance graph
[legend]
Collaboration diagram for cmd_whowas:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 cmd_whowas (InspIRCd *Instance)
CmdResult Handle (const char **parameters, int pcnt, userrec *user)
 Handle command.
CmdResult HandleInternal (const unsigned int id, const std::deque< classbase * > &parameters)
 Handle command.
void AddToWhoWas (userrec *user)
void GetStats (Extensible *ext)
void PruneWhoWas (time_t t)
void MaintainWhoWas (time_t t)
virtual ~cmd_whowas ()

Private Attributes

whowas_users whowas
 Whowas container, contains a map of vectors of users tracked by WHOWAS.
whowas_users_fifo whowas_fifo
 Whowas container, contains a map of time_t to users tracked by WHOWAS.
std::string stats

Detailed Description

Handle /WHOWAS.

These command handlers can be reloaded by the core, and handle basic RFC1459 commands. Commands within modules work the same way, however, they can be fully unloaded, where these may not.

Definition at line 59 of file cmd_whowas.h.


Constructor & Destructor Documentation

cmd_whowas::cmd_whowas InspIRCd Instance  ) 
 

Definition at line 26 of file cmd_whowas.cpp.

References TimerManager::AddTimer(), command_t::syntax, and InspIRCd::Timers.

00027 : command_t(Instance, "WHOWAS", 0, 1)
00028 {
00029         syntax = "<nick>{,<nick>}";
00030         timer = new WhoWasMaintainTimer(Instance, 3600);
00031         Instance->Timers->AddTimer(timer);
00032 }

cmd_whowas::~cmd_whowas  )  [virtual]
 

Definition at line 276 of file cmd_whowas.cpp.

References DEFAULT, DELETE(), TimerManager::DelTimer(), InspIRCd::Log(), command_t::ServerInstance, InspIRCd::Timers, whowas, and whowas_fifo.

00277 {
00278         if (timer)
00279         {
00280                 ServerInstance->Timers->DelTimer(timer);
00281         }
00282 
00283         whowas_users::iterator iter;
00284         int fifosize;
00285         while ((fifosize = (int)whowas_fifo.size()) > 0)
00286         {
00287                 iter = whowas.find(whowas_fifo[0].second);
00288                 /* hopefully redundant integrity check, but added while debugging r6216 */
00289                 if (iter == whowas.end())
00290                 {
00291                         /* this should never happen, if it does maps are corrupt */
00292                         ServerInstance->Log(DEFAULT, "BUG: Whowas maps got corrupted! (3)");
00293                         return;
00294                 }
00295                 whowas_set* n = (whowas_set*)iter->second;
00296                 if (n->size())
00297                 {
00298                         while (n->begin() != n->end())
00299                         {
00300                                 WhoWasGroup *a = *(n->begin());
00301                                 DELETE(a);
00302                                 n->pop_front();
00303                         }
00304                 }
00305                 DELETE(n);
00306                 whowas.erase(iter);
00307                 whowas_fifo.pop_front();
00308         }
00309 }


Member Function Documentation

void cmd_whowas::AddToWhoWas userrec user  ) 
 

Definition at line 136 of file cmd_whowas.cpp.

References InspIRCd::Config, DELETE(), userrec::nick, command_t::ServerInstance, InspIRCd::Time(), whowas, whowas_fifo, ServerConfig::WhoWasGroupSize, and ServerConfig::WhoWasMaxGroups.

Referenced by HandleInternal().

00137 {
00138         /* if whowas disabled */
00139         if (ServerInstance->Config->WhoWasGroupSize == 0 || ServerInstance->Config->WhoWasMaxGroups == 0)
00140         {
00141                 return;
00142         }
00143 
00144         whowas_users::iterator iter = whowas.find(user->nick);
00145 
00146         if (iter == whowas.end())
00147         {
00148                 whowas_set* n = new whowas_set;
00149                 WhoWasGroup *a = new WhoWasGroup(user);
00150                 n->push_back(a);
00151                 whowas[user->nick] = n;
00152                 whowas_fifo.push_back(std::make_pair(ServerInstance->Time(),user->nick));
00153 
00154                 if ((int)(whowas.size()) > ServerInstance->Config->WhoWasMaxGroups)
00155                 {
00156                         whowas_users::iterator iter = whowas.find(whowas_fifo[0].second);
00157                         if (iter != whowas.end())
00158                         {
00159                                 whowas_set* n = (whowas_set*)iter->second;
00160                                 if (n->size())
00161                                 {
00162                                         while (n->begin() != n->end())
00163                                         {
00164                                                 WhoWasGroup *a = *(n->begin());
00165                                                 DELETE(a);
00166                                                 n->pop_front();
00167                                         }
00168                                 }
00169                                 DELETE(n);
00170                                 whowas.erase(iter);
00171                         }
00172                         whowas_fifo.pop_front();
00173                 }
00174         }
00175         else
00176         {
00177                 whowas_set* group = (whowas_set*)iter->second;
00178                 WhoWasGroup *a = new WhoWasGroup(user);
00179                 group->push_back(a);
00180 
00181                 if ((int)(group->size()) > ServerInstance->Config->WhoWasGroupSize)
00182                 {
00183                         WhoWasGroup *a = (WhoWasGroup*)*(group->begin());
00184                         DELETE(a);
00185                         group->pop_front();
00186                 }
00187         }
00188 }

void cmd_whowas::GetStats Extensible ext  ) 
 

Definition at line 118 of file cmd_whowas.cpp.

References ConvToStr(), Extensible::Extend(), stats, whowas, and whowas_fifo.

Referenced by HandleInternal().

00119 {
00120         int whowas_size = 0;
00121         int whowas_bytes = 0;
00122         whowas_users_fifo::iterator iter;
00123         for (iter = whowas_fifo.begin(); iter != whowas_fifo.end(); iter++)
00124         {
00125                 whowas_set* n = (whowas_set*)whowas.find(iter->second)->second;
00126                 if (n->size())
00127                 {
00128                         whowas_size += n->size();
00129                         whowas_bytes += (sizeof(whowas_set) + ( sizeof(WhoWasGroup) * n->size() ) );
00130                 }
00131         }
00132         stats.assign("Whowas(MAPSETS) " +ConvToStr(whowas_size)+" ("+ConvToStr(whowas_bytes)+" bytes)");
00133         ext->Extend("stats", stats.c_str());
00134 }

CmdResult cmd_whowas::Handle const char **  parameters,
int  pcnt,
userrec user
[virtual]
 

Handle command.

Parameters:
parameters The parameters to the comamnd
pcnt The number of parameters passed to teh command
user The user issuing the command
Returns:
A value from CmdResult to indicate command success or failure.

Implements command_t.

Definition at line 34 of file cmd_whowas.cpp.

References CMD_FAILURE, CMD_SUCCESS, command_t::command, InspIRCd::Config, WhoWasGroup::dhost, WhoWasGroup::gecos, ServerConfig::HideWhoisServer, WhoWasGroup::host, WhoWasGroup::ident, IS_OPER, MAXBUF, userrec::nick, WhoWasGroup::server, command_t::ServerInstance, WhoWasGroup::signon, strlcpy(), whowas, ServerConfig::WhoWasGroupSize, ServerConfig::WhoWasMaxGroups, and userrec::WriteServ().

00035 {
00036         /* if whowas disabled in config */
00037         if (ServerInstance->Config->WhoWasGroupSize == 0 || ServerInstance->Config->WhoWasMaxGroups == 0)
00038         {
00039                 user->WriteServ("421 %s %s :This command has been disabled.",user->nick,command.c_str());
00040                 return CMD_FAILURE;
00041         }
00042 
00043         whowas_users::iterator i = whowas.find(parameters[0]);
00044 
00045         if (i == whowas.end())
00046         {
00047                 user->WriteServ("406 %s %s :There was no such nickname",user->nick,parameters[0]);
00048                 user->WriteServ("369 %s %s :End of WHOWAS",user->nick,parameters[0]);
00049                 return CMD_FAILURE;
00050         }
00051         else
00052         {
00053                 whowas_set* grp = i->second;
00054                 if (grp->size())
00055                 {
00056                         for (whowas_set::iterator ux = grp->begin(); ux != grp->end(); ux++)
00057                         {
00058                                 WhoWasGroup* u = *ux;
00059                                 time_t rawtime = u->signon;
00060                                 tm *timeinfo;
00061                                 char b[MAXBUF];
00062         
00063                                 timeinfo = localtime(&rawtime);
00064                                 
00065                                 /* XXX - 'b' could be only 25 chars long and then strlcpy() would terminate it for us too? */
00066                                 strlcpy(b,asctime(timeinfo),MAXBUF);
00067                                 b[24] = 0;
00068 
00069                                 user->WriteServ("314 %s %s %s %s * :%s",user->nick,parameters[0],u->ident,u->dhost,u->gecos);
00070                                 
00071                                 if (IS_OPER(user))
00072                                         user->WriteServ("379 %s %s :was connecting from *@%s", user->nick, parameters[0], u->host);
00073                                 
00074                                 if (*ServerInstance->Config->HideWhoisServer && !IS_OPER(user))
00075                                         user->WriteServ("312 %s %s %s :%s",user->nick,parameters[0], ServerInstance->Config->HideWhoisServer, b);
00076                                 else
00077                                         user->WriteServ("312 %s %s %s :%s",user->nick,parameters[0], u->server, b);
00078                         }
00079                 }
00080                 else
00081                 {
00082                         user->WriteServ("406 %s %s :There was no such nickname",user->nick,parameters[0]);
00083                         user->WriteServ("369 %s %s :End of WHOWAS",user->nick,parameters[0]);
00084                         return CMD_FAILURE;
00085                 }
00086         }
00087 
00088         user->WriteServ("369 %s %s :End of WHOWAS",user->nick,parameters[0]);
00089         return CMD_SUCCESS;
00090 }

CmdResult cmd_whowas::HandleInternal const unsigned int  id,
const std::deque< classbase * > &  parameters
[virtual]
 

Handle command.

Parameters:
parameters The parameters to the comamnd
pcnt The number of parameters passed to teh command
user The user issuing the command
Returns:
A value from CmdResult to indicate command success or failure.

Reimplemented from command_t.

Definition at line 92 of file cmd_whowas.cpp.

References AddToWhoWas(), CMD_SUCCESS, GetStats(), MaintainWhoWas(), PruneWhoWas(), command_t::ServerInstance, InspIRCd::Time(), WHOWAS_ADD, WHOWAS_MAINTAIN, WHOWAS_PRUNE, and WHOWAS_STATS.

00093 {
00094         switch (id)
00095         {
00096                 case WHOWAS_ADD:
00097                         AddToWhoWas((userrec*)parameters[0]);
00098                 break;
00099 
00100                 case WHOWAS_STATS:
00101                         GetStats((Extensible*)parameters[0]);
00102                 break;
00103 
00104                 case WHOWAS_PRUNE:
00105                         PruneWhoWas(ServerInstance->Time());
00106                 break;
00107 
00108                 case WHOWAS_MAINTAIN:
00109                         MaintainWhoWas(ServerInstance->Time());
00110                 break;
00111 
00112                 default:
00113                 break;
00114         }
00115         return CMD_SUCCESS;
00116 }

void cmd_whowas::MaintainWhoWas time_t  t  ) 
 

Definition at line 259 of file cmd_whowas.cpp.

References InspIRCd::Config, DELETE(), command_t::ServerInstance, whowas, and ServerConfig::WhoWasMaxKeep.

Referenced by HandleInternal().

00260 {
00261         for (whowas_users::iterator iter = whowas.begin(); iter != whowas.end(); iter++)
00262         {
00263                 whowas_set* n = (whowas_set*)iter->second;
00264                 if (n->size())
00265                 {
00266                         while ((n->begin() != n->end()) && ((*n->begin())->signon < t - ServerInstance->Config->WhoWasMaxKeep))
00267                         {
00268                                 WhoWasGroup *a = *(n->begin());
00269                                 DELETE(a);
00270                                 n->erase(n->begin());
00271                         }
00272                 }
00273         }
00274 }

void cmd_whowas::PruneWhoWas time_t  t  ) 
 

Definition at line 191 of file cmd_whowas.cpp.

References InspIRCd::Config, DEFAULT, DELETE(), InspIRCd::Log(), command_t::ServerInstance, whowas, whowas_fifo, ServerConfig::WhoWasGroupSize, ServerConfig::WhoWasMaxGroups, and ServerConfig::WhoWasMaxKeep.

Referenced by HandleInternal().

00192 {
00193         /* config values */
00194         int groupsize = ServerInstance->Config->WhoWasGroupSize;
00195         int maxgroups = ServerInstance->Config->WhoWasMaxGroups;
00196         int maxkeep =   ServerInstance->Config->WhoWasMaxKeep;
00197 
00198         /* first cut the list to new size (maxgroups) and also prune entries that are timed out. */
00199         whowas_users::iterator iter;
00200         int fifosize;
00201         while ((fifosize = (int)whowas_fifo.size()) > 0)
00202         {
00203                 if (fifosize > maxgroups || whowas_fifo[0].first < t - maxkeep)
00204                 {
00205                         iter = whowas.find(whowas_fifo[0].second);
00206                         /* hopefully redundant integrity check, but added while debugging r6216 */
00207                         if (iter == whowas.end())
00208                         {
00209                                 /* this should never happen, if it does maps are corrupt */
00210                                 ServerInstance->Log(DEFAULT, "BUG: Whowas maps got corrupted! (1)");
00211                                 return;
00212                         }
00213                         whowas_set* n = (whowas_set*)iter->second;
00214                         if (n->size())
00215                         {
00216                                 while (n->begin() != n->end())
00217                                 {
00218                                         WhoWasGroup *a = *(n->begin());
00219                                         DELETE(a);
00220                                         n->pop_front();
00221                                 }
00222                         }
00223                         DELETE(n);
00224                         whowas.erase(iter);
00225                         whowas_fifo.pop_front();
00226                 }
00227                 else
00228                         break;
00229         }
00230 
00231         /* Then cut the whowas sets to new size (groupsize) */
00232         fifosize = (int)whowas_fifo.size();
00233         for (int i = 0; i < fifosize; i++)
00234         {
00235                 iter = whowas.find(whowas_fifo[0].second);
00236                 /* hopefully redundant integrity check, but added while debugging r6216 */
00237                 if (iter == whowas.end())
00238                 {
00239                         /* this should never happen, if it does maps are corrupt */
00240                         ServerInstance->Log(DEFAULT, "BUG: Whowas maps got corrupted! (2)");
00241                         return;
00242                 }
00243                 whowas_set* n = (whowas_set*)iter->second;
00244                 if (n->size())
00245                 {
00246                         int nickcount = n->size();
00247                         while (n->begin() != n->end() && nickcount > groupsize)
00248                         {
00249                                 WhoWasGroup *a = *(n->begin());
00250                                 DELETE(a);
00251                                 n->pop_front();
00252                                 nickcount--;
00253                         }
00254                 }
00255         }
00256 }


Member Data Documentation

std::string cmd_whowas::stats [private]
 

Definition at line 72 of file cmd_whowas.h.

Referenced by GetStats().

whowas_users cmd_whowas::whowas [private]
 

Whowas container, contains a map of vectors of users tracked by WHOWAS.

Definition at line 64 of file cmd_whowas.h.

Referenced by AddToWhoWas(), GetStats(), Handle(), MaintainWhoWas(), PruneWhoWas(), and ~cmd_whowas().

whowas_users_fifo cmd_whowas::whowas_fifo [private]
 

Whowas container, contains a map of time_t to users tracked by WHOWAS.

Definition at line 68 of file cmd_whowas.h.

Referenced by AddToWhoWas(), GetStats(), PruneWhoWas(), and ~cmd_whowas().


The documentation for this class was generated from the following files: