summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands.cpp5
-rw-r--r--src/inspircd.cpp1
-rw-r--r--src/modules/m_watch.cpp300
3 files changed, 306 insertions, 0 deletions
diff --git a/src/commands.cpp b/src/commands.cpp
index 26cfa0da6..3a9399f7c 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -2286,6 +2286,11 @@ void handle_n(char token,char* params,serverrec* source,serverrec* reply, char*
if (!user->nick) return;
strlcpy(user->nick, newnick,NICKMAX);
log(DEBUG,"new nick set: %s",user->nick);
+ if (user->registered == 7)
+ {
+ FOREACH_MOD OnUserPostNick(user,oldnick);
+ }
+
}
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 37c98bb1b..c780b8bf1 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -1607,6 +1607,7 @@ void FullConnectUser(userrec* user)
// fix by brain: these should be AFTER the N token, so other servers know what the HELL we're on about... :)
FOREACH_MOD OnUserConnect(user);
+ FOREACH_MOD OnGlobalConnect(user);
WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,user->ip);
}
diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp
new file mode 100644
index 000000000..f613acda3
--- /dev/null
+++ b/src/modules/m_watch.cpp
@@ -0,0 +1,300 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
+ *
+ * Written by Craig Edwards, Craig McLure, and others.
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+using namespace std;
+
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include "users.h"
+#include "channels.h"
+#include "modules.h"
+#include "helperfuncs.h"
+#include "hashcomp.h"
+
+/* $ModDesc: Provides support for the /watch command */
+
+Server *Srv;
+
+class watchentry
+{
+ public:
+ userrec* watcher;
+ std::string target;
+};
+
+typedef std::vector<watchentry> watchlist;
+watchlist watches;
+
+void handle_watch(char **parameters, int pcnt, userrec *user)
+{
+ if (!pcnt)
+ {
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ userrec* targ = Srv->FindNick(q->target);
+ if (targ)
+ {
+ WriteServ(user->fd,"604 %s %s %s %s %lu :is online",user->nick,targ->nick,targ->ident,targ->dhost,targ->age);
+ }
+ }
+ }
+ WriteServ(user->fd,"607 %s :End of WATCH list",user->nick);
+ }
+ else if (pcnt > 0)
+ {
+ for (int x = 0; x < pcnt; x++)
+ {
+ char *nick = parameters[x];
+ if (!strcasecmp(nick,"C"))
+ {
+ // watch clear
+ bool done = false;
+ while (!done)
+ {
+ done = true;
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ done = false;
+ watches.erase(q);
+ break;
+ }
+ }
+ }
+ }
+ if (!strcasecmp(nick,"L"))
+ {
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ userrec* targ = Srv->FindNick(q->target);
+ if (targ)
+ {
+ WriteServ(user->fd,"604 %s %s %s %s %lu :is online",user->nick,targ->nick,targ->ident,targ->dhost,targ->age);
+ }
+ }
+ }
+ WriteServ(user->fd,"607 %s :End of WATCH list",user->nick);
+ }
+ if (!strcasecmp(nick,"S"))
+ {
+ std::string list = "";
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ list = list + " " + q->target;
+ }
+ }
+ char* l = (char*)list.c_str();
+ if (*l == ' ')
+ l++;
+ WriteServ(user->fd,"606 %s :%s",user->nick,l);
+ WriteServ(user->fd,"607 %s :End of WATCH S",user->nick);
+ }
+ if (nick[0] == '-')
+ {
+ // removing an item from the list
+ nick++;
+ irc::string n1 = nick;
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ irc::string n2 = q->target.c_str();
+ userrec* a = Srv->FindNick(q->target);
+ if (a)
+ {
+ WriteServ(user->fd,"602 %s %s %s %s %lu :stopped watching",user->nick,a->nick,a->ident,a->dhost,a->age);
+ }
+ else
+ {
+ WriteServ(user->fd,"602 %s %s * * 0 :stopped watching",user->nick,q->target.c_str());
+ }
+ if (n1 == n2)
+ {
+ watches.erase(q);
+ break;
+ }
+ }
+ }
+ }
+ else if (nick[0] == '+')
+ {
+ nick++;
+ irc::string n1 = nick;
+ bool exists = false;
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ irc::string n2 = q->target.c_str();
+ if (n1 == n2)
+ {
+ // already on watch list
+ exists = true;
+ }
+ }
+ }
+ if (!exists)
+ {
+ watchentry w;
+ w.watcher = user;
+ w.target = nick;
+ watches.push_back(w);
+ log(DEBUG,"*** Added %s to watchlist of %s",nick,user->nick);
+ }
+ userrec* a = Srv->FindNick(nick);
+ if (a)
+ {
+ WriteServ(user->fd,"604 %s %s %s %s %lu :is online",user->nick,a->nick,a->ident,a->dhost,a->age);
+ }
+ else
+ {
+ WriteServ(user->fd,"605 %s %s * * 0 :is offline",user->nick,nick);
+ }
+ }
+ }
+ }
+ return;
+}
+
+
+class Modulewatch : public Module
+{
+
+ public:
+
+ Modulewatch()
+ {
+ Srv = new Server;
+ Srv->AddCommand("WATCH",handle_watch,0,0,"m_watch.so");
+ }
+
+ virtual void OnUserQuit(userrec* user)
+ {
+ log(DEBUG,"*** WATCH: On global quit: user %s",user->nick);
+ irc::string n2 = user->nick;
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ irc::string n1 = q->target.c_str();
+ if (n1 == n2)
+ {
+ log(DEBUG,"*** WATCH: On global quit: user %s is in notify of %s",user->nick,q->watcher->nick);
+ WriteServ(q->watcher->fd,"601 %s %s %s %s %lu :went offline",q->watcher->nick,user->nick,user->ident,user->dhost,time(NULL));
+ }
+ }
+ bool done = false;
+ while (!done)
+ {
+ done = true;
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ if (q->watcher == user)
+ {
+ done = false;
+ watches.erase(q);
+ break;
+ }
+ }
+ }
+ }
+
+ virtual void OnGlobalConnect(userrec* user)
+ {
+ irc::string n2 = user->nick;
+ log(DEBUG,"*** WATCH: On global connect: user %s",user->nick);
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ irc::string n1 = q->target.c_str();
+ if (n1 == n2)
+ {
+ log(DEBUG,"*** WATCH: On global connect: user %s is in notify of %s",user->nick,q->watcher->nick);
+ WriteServ(q->watcher->fd,"600 %s %s %s %s %lu :arrived online",q->watcher->nick,user->nick,user->ident,user->dhost,user->age);
+ }
+ }
+ }
+
+ virtual void OnUserPostNick(userrec* user, std::string oldnick)
+ {
+ irc::string n2 = oldnick.c_str();
+ irc::string n3 = user->nick;
+ log(DEBUG,"*** WATCH: On global nickchange: old nick: %s new nick: %s",oldnick.c_str(),user->nick);
+ for (watchlist::iterator q = watches.begin(); q != watches.end(); q++)
+ {
+ irc::string n1 = q->target.c_str();
+ // changed from a nick on the watchlist to one that isnt
+ if (n1 == n2)
+ {
+ log(DEBUG,"*** WATCH: On global nickchange: old nick %s was on notify list of %s",oldnick.c_str(),q->watcher->nick);
+ WriteServ(q->watcher->fd,"601 %s %s %s %s %lu :went offline",q->watcher->nick,oldnick.c_str(),user->ident,user->dhost,time(NULL));
+ }
+ else if (n1 == n3)
+ {
+ // changed from a nick not on notify to one that is
+ log(DEBUG,"*** WATCH: On global nickchange: new nick %s is on notify list of %s",user->nick,q->watcher->nick);
+ WriteServ(q->watcher->fd,"600 %s %s %s %s %lu :arrived online",q->watcher->nick,user->nick,user->ident,user->dhost,user->age);
+ }
+ }
+ }
+
+ virtual void On005Numeric(std::string &output)
+ {
+ // we don't really have a limit...
+ output = output + " WATCH=999";
+ }
+
+ virtual ~Modulewatch()
+ {
+ delete Srv;
+ }
+
+ virtual Version GetVersion()
+ {
+ return Version(1,0,0,1,VF_VENDOR);
+ }
+};
+
+
+class ModulewatchFactory : public ModuleFactory
+{
+ public:
+ ModulewatchFactory()
+ {
+ }
+
+ ~ModulewatchFactory()
+ {
+ }
+
+ virtual Module * CreateModule()
+ {
+ return new Modulewatch;
+ }
+
+};
+
+
+extern "C" void * init_module( void )
+{
+ return new ModulewatchFactory;
+}
+