Explorar o código

* Added cmd_swhois.

svn: 1058
Bryan Drewery %!s(int64=22) %!d(string=hai) anos
pai
achega
b963e31558
Modificáronse 6 ficheiros con 225 adicións e 14 borrados
  1. 1 0
      doc/UPDATES
  2. 8 0
      misc/help.txt
  3. 2 0
      src/dcc.h
  4. 23 0
      src/mod/irc.mod/cmdsirc.c
  5. 1 0
      src/mod/server.mod/server.c
  6. 190 14
      src/mod/server.mod/servmsg.c

+ 1 - 0
doc/UPDATES

@@ -30,6 +30,7 @@ This is a summary of ChangeLog basically.
 26.FreeBSD packages now have release # again, ie: FreeBSD4.
 27.Fixed hub not searching for update bins in it's own dir.
 28.Shell config option 'watcher', will make 1 extra PID per bot to block process hijackers.
+29.Added cmd: swhois, see help.
 
 1.1.7
 

+ 8 - 0
misc/help.txt

@@ -1522,6 +1522,14 @@ See also: fixcodes, color, echo, page
    Lets you assume the identity of another user. If you are a global owner,
    this does not require a password. Otherwise, you will be asked for the
    user's password. %b%dquit%b returns you to your original handle.
+:leaf:swhois
+###  %bswhois%b [server/nick] <nick>
+   Displays a server /whois for the specified nick. Specifying
+   the nick twice will display idle time. Specifying a server will 
+   display the whois as viewed by that server.
+   If the nick is currently not online, a /WHOWAS is done automatically.
+ 
+See also: find
 :leaf:topic
 ###  %btopic%b <text>
    changes the channel's topic, assuming the bot is a chanop or the

+ 2 - 0
src/dcc.h

@@ -52,6 +52,7 @@ struct dcc_t {
   int ssl;                      /* use ssl on this dcc? */
   int simul;                    /* this will hold the idx on the remote bot to return result. */
   int msgc;			/* forward the output back to irc? */
+  int whowas;
   port_t port;
 #ifdef USE_IPV6
   char addr6[121];              /* easier.. ipv6 address in regular notation (3ffe:80c0:225::) */
@@ -59,6 +60,7 @@ struct dcc_t {
   char simulbot[NICKLEN];       /* used for hub->leaf cmd simulation, holds bot that results should be sent to */
   char hash[MD5_HASH_LENGTH + 1];                /* used for dcc authing */
   char nick[NICKLEN];
+  char whois[UHOSTLEN];
   char host[UHOSTLEN];
 };
 

+ 23 - 0
src/mod/irc.mod/cmdsirc.c

@@ -145,6 +145,28 @@ static void cmd_say(struct userrec *u, int idx, char *par)
   dprintf(idx, "Said to %s: %s\n", chan->dname, par);
 }
 
+static void cmd_swhois(struct userrec *u, int idx, char *par)
+{
+  char *server = NULL, *nick = NULL;
+
+  if (!par[0]) {
+    dprintf(idx, "Usage: swhois [server/nick] nick\n");
+    return;
+  }
+
+  putlog(LOG_CMDS, "*", "#%s# swhois %s", dcc[idx].nick, par);
+  if (!server_online) {
+    dprintf(idx, "I am currently not connected!\n");
+    return;
+  }
+  server = newsplit(&par);
+  if (par[0])
+    nick = newsplit(&par);
+
+  strncpyz(dcc[idx].whois, nick ? nick : server, UHOSTLEN);
+  dprintf(DP_SERVER, "WHOIS %s %s\n", server, nick ? nick : "");
+}
+
 static void cmd_kickban(struct userrec *u, int idx, char *par)
 {
   struct chanset_t *chan = NULL;
@@ -1675,6 +1697,7 @@ static cmd_t irc_dcc[] =
   {"resetexempts",	"o|o",	 (Function) cmd_resetexempts,	NULL},
   {"resetinvites",	"o|o",	 (Function) cmd_resetinvites,	NULL},
   {"say",		"o|o",	 (Function) cmd_say,		NULL},
+  {"swhois",		"n",	 (Function) cmd_swhois,		NULL},
   {"topic",		"o|o",	 (Function) cmd_topic,		NULL},
   {"voice",		"o|o",	 (Function) cmd_voice,		NULL},
   {NULL,		NULL,	 NULL,				NULL}

+ 1 - 0
src/mod/server.mod/server.c

@@ -23,6 +23,7 @@
 #include "src/mod/channels.mod/channels.h"
 #include "src/mod/irc.mod/irc.h"
 #include "server.h"
+#include <stdarg.h>
 
 int checked_hostmask;	/* Used in request_op()/check_hostmask() cleared on connect */
 int ctcp_mode;

+ 190 - 14
src/mod/server.mod/servmsg.c

@@ -174,10 +174,10 @@ static int got001(char *from, char *msg)
   int i;
   struct chanset_t *chan = NULL;
 
-  /* Ok...param #1 of 001 = what server thinks my nick is */
   server_online = now;
   checked_hostmask = 0;
   fixcolon(msg);
+  /* Ok...param #1 of 001 = what server thinks my nick is */
   strncpyz(botname, msg, NICKLEN);
   altnick_char = 0;
   strncpyz(cursrvname, from, sizeof(cursrvname));
@@ -187,7 +187,7 @@ static int got001(char *from, char *msg)
   x = serverlist;
   if (x == NULL)
     return 0;			/* Uh, no server list */
-  /* Only join if the IRC module is loaded. */
+
   for (chan = chanset; chan; chan = chan->next) {
     chan->status &= ~(CHAN_ACTIVE | CHAN_PEND);
     if (shouldjoin(chan))
@@ -1122,6 +1122,7 @@ static int gotkick(char *from, char *msg)
 
 /* Another sec penalty if bot did a whois on another server.
  */
+static int got318_369(char *, char *, int);
 static int whoispenalty(char *from, char *msg)
 {
   struct server_list *x = serverlist;
@@ -1147,27 +1148,192 @@ static int whoispenalty(char *from, char *msg)
         putlog(LOG_SRVOUT, "*", "adding 1sec penalty (remote whois)");
     }
   }
+
+  got318_369(from, msg, 0);
   return 0;
 }
 
+static void irc_whois(char *, char *, ...) __attribute__((format(printf, 2, 3)));
+
+static void
+irc_whois(char *nick, char *format, ...)
+{
+  char va_out[2001] = "";
+  va_list va;
+  int idx;
+
+  va_start(va, format);
+  egg_vsnprintf(va_out, sizeof(va_out) - 1, format, va);
+  va_end(va);
+
+  for (idx = 0; idx < dcc_total; idx++)
+    if (dcc[idx].whois[0] && !rfc_casecmp(nick, dcc[idx].whois))
+      dprintf(idx, "%s\n", va_out);
+}
+
+/* 311 $me nick username address * :realname */
 static int got311(char *from, char *msg)
 {
-  char *n1 = NULL, *n2 = NULL, *u = NULL, *h = NULL;
+  char *nick = NULL, *username = NULL, *address = NULL;
   
-  n1 = newsplit(&msg);
-  n2 = newsplit(&msg);
-  u = newsplit(&msg);
-  h = newsplit(&msg);
-  
-  if (!n1 || !n2 || !u || !h)
-    return 0;
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  username = newsplit(&msg);
+  address = newsplit(&msg);
+  newsplit(&msg);
+  fixcolon(msg);
     
-  if (match_my_nick(n2))
-    egg_snprintf(botuserhost, sizeof botuserhost, "%s@%s", u, h);
+  if (match_my_nick(nick))
+    egg_snprintf(botuserhost, sizeof botuserhost, "%s@%s", username, address);
+
+  irc_whois(nick, "$b%s$b [%s@%s]", nick, username, address);
+  irc_whois(nick, " ircname  : %s", msg);
+  
+  return 0;
+}
+
+/* 319 $me nick :channels */
+static int got319(char *from, char *msg)
+{
+  char *nick = NULL;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+
+  irc_whois(nick, " channels : %s", msg);
+
+  return 0;
+}
+
+/* 312 $me nick server :text */
+static int got312(char *from, char *msg)
+{
+  char *nick = NULL, *server = NULL;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  server = newsplit(&msg);
+  fixcolon(msg);
+
+  irc_whois(nick, " server   : %s [%s]", server, msg);
+  return 0;
+}
+
+/* 301 $me nick :away msg */
+static int got301(char *from, char *msg)
+{
+  char *nick = NULL;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+
+  irc_whois(nick, " away     : %s", msg);
+
+  return 0;
+}
+
+/* 313 $me nick :server text */
+static int got313(char *from, char *msg)
+{
+  char *nick = NULL;
   
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+ 
+  irc_whois(nick, "          : $b%s$b", msg);
+
   return 0;
 }
 
+/* 317 $me nick idle signon :idle-eng signon-eng */
+static int got317(char *from, char *msg)
+{
+  char *nick = NULL, date[50] = "";
+  time_t idle, signon;
+  int mydays, myhours, mymins, mysecs;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  idle = atol(newsplit(&msg));
+  signon = atol(newsplit(&msg));
+  fixcolon(msg);
+
+  egg_strftime(date, sizeof date, "%c %Z", gmtime(&signon));
+
+  mydays = idle / 86400;
+  idle = idle % 86400;
+  myhours = idle / 3600;
+  idle = idle % 3600;
+  mymins = idle / 60;
+  idle = idle % 60;
+  mysecs = idle;
+  irc_whois(nick, " idle     : %d days %d hours %d mins %d secs [signon: %s]", mydays, myhours, mymins, mysecs, date);
+
+  return 0;
+}
+
+static int got369(char *from, char *msg)
+{
+  return got318_369(from, msg, 1);
+}
+
+/* 318/319 $me nick :End of /? */
+static int got318_369(char *from, char *msg, int whowas)
+{
+  char *nick = NULL;
+  int idx;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+
+  irc_whois(nick, "%s", msg);
+  for (idx = 0; idx < dcc_total; idx++) {
+    if (dcc[idx].whois[0] && !rfc_casecmp(dcc[idx].whois, nick) &&
+       ((!whowas && !dcc[idx].whowas) || (whowas && dcc[idx].whowas))) {
+      dcc[idx].whois[0] = 0;
+      dcc[idx].whowas = 0;
+    }
+  }
+
+  return 0;
+}
+
+/* 401 $me nick :text */
+static int got401(char *from, char *msg)
+{
+  char *nick = NULL;
+  int idx;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+  irc_whois(nick, "%s", msg);
+  for (idx = 0; idx < dcc_total; idx++)
+    if (dcc[idx].whois[0] && !rfc_casecmp(dcc[idx].whois, nick))
+      dcc[idx].whowas = 1;
+
+  dprintf(DP_SERVER, "WHOWAS %s %s\n", nick, from);
+ 
+  return 0;
+}
+
+/* 406 $me nick :text */
+static int got406(char *from, char *msg)
+{
+  char *nick = NULL;
+
+  newsplit(&msg);
+  nick = newsplit(&msg);
+  fixcolon(msg);
+  irc_whois(nick, "%s", msg);
+ 
+  return 0;
+}
+ 
 static cmd_t my_raw_binds[] =
 {
   {"PRIVMSG",	"",	(Function) gotmsg,		NULL},
@@ -1190,8 +1356,18 @@ static cmd_t my_raw_binds[] =
 /* ircu2.10.10 has a bug when a client is throttled ERROR is sent wrong */
   {"ERROR:",	"",	(Function) goterror,		NULL},
   {"KICK",	"",	(Function) gotkick,		NULL},
-  {"318",	"",	(Function) whoispenalty,	NULL},
-  {"311", 	"", 	(Function) got311, 		NULL},
+  /* WHOIS RAWS */
+  {"311", 	"", 	(Function) got311, 		NULL},	/* ident host * :realname */
+  {"314",	"",	(Function) got311,		NULL},	/* "" -WHOWAS */
+  {"319",	"",	(Function) got319,		NULL},	/* :#channels */
+  {"312",	"",	(Function) got312,		NULL},	/* server :gecos */
+  {"301",	"",	(Function) got301,		NULL},	/* :away msg */
+  {"313",	"",	(Function) got313,		NULL},	/* :ircop */
+  {"317",	"",	(Function) got317,		NULL},	/* idle, signon :idle-eng, signon-eng */
+  {"401",	"",	(Function) got401,		NULL},
+  {"406",	"",	(Function) got406,		NULL},
+  {"318",	"",	(Function) whoispenalty,	NULL},	/* :End of /WHOIS */
+  {"369",	"",	(Function) got369,		NULL},	/* :End of /WHOWAS */
   {NULL,	NULL,	NULL,				NULL}
 };