$PATCH: +time
$NOTE: shared{} blocks must be set up properly to allow Sentinel to KLINE
$NOTE: users.
$NOTE: You must also apply the kversion patch.
Index: include/config.h
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/include/config.h,v
retrieving revision 1.96
diff -u -r1.96 config.h
--- include/config.h	5 Dec 2003 01:15:20 -0000	1.96
+++ include/config.h	22 Jul 2004 23:59:00 -0000
@@ -97,7 +97,7 @@
 ** the initial burst).  This is a massive increase in memory and network
 ** bandwidth, but can POTENTIALLY help a network.
 */
-#undef TRACK_CTCPVERSION
+#define TRACK_CTCPVERSION
 
 /* On Hybrid 7 (and Hybrid 6 if you have an admin mode patch), this option
 ** will show opers as A O o (with o most likely never being used)
@@ -228,7 +228,7 @@
 ** This requires conf lines to be added for each drone type, and is
 ** CPU intensive
 */
-#undef MON_DRONES
+#define MON_DRONES
 
 /* If you have enabled the alert channel, do you wish to send drone
 ** matches to a drone alert channel?
Index: include/proto.h
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/include/proto.h,v
retrieving revision 1.258
diff -u -r1.258 proto.h
--- include/proto.h	19 May 2004 19:26:01 -0000	1.258
+++ include/proto.h	22 Jul 2004 23:06:04 -0000
@@ -113,10 +113,10 @@
 #if defined(SPYMODE) || defined(ALERTMODE) || defined(DRONES_CHANNEL)
 int ad_delayed;
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* Patched version doesn't need this:  #if defined(TRACK_CTCPVERSION) */
 int mn_delayed;
 dlink_list delayed_users;
-#endif
+/* Patch:  #endif */
 
 #ifdef SPLITSERV
 struct SpServer* map_head;
@@ -303,6 +303,7 @@
 #ifdef TRACK_CTCPVERSION
 void CheckVersionDrones(struct User *, char *);
 #endif
+void CheckTimeDrones(struct User *, char *);
 void RemoveDrone(struct User *);
 void RemoveDroneDL(dlink_node *);
 #endif
@@ -406,9 +407,9 @@
 */
 void evh_CheckAdDelayed(void *unused);
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 void evh_CheckMnDelayed(void *unused);
-#endif
+/* #endif */
 void evh_ConnectServer(void *unused);
 
 /* operlist.c */
Index: src/evh.c
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/src/evh.c,v
retrieving revision 1.56
diff -u -r1.56 evh.c
--- src/evh.c	19 May 2004 19:55:27 -0000	1.56
+++ src/evh.c	22 Jul 2004 23:55:09 -0000
@@ -64,10 +64,10 @@
 
   eventAdd("check admin delayed", evh_CheckAdDelayed, NULL, DEFAULT_DELAY);
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 
   eventAdd("check monserv delayed", evh_CheckMnDelayed, NULL, VERSION_DELAY);
-#endif
+/* #endif */
 #ifdef SPLITSERV
 
   eventAdd("expire splits", evh_ExpireSplits, NULL, EXPIREPOLL);
@@ -96,10 +96,10 @@
 
   eventDelete(evh_CheckAdDelayed, NULL);
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 
   eventDelete(evh_CheckMnDelayed, NULL);
-#endif
+/* #endif */
 #ifdef SPLITSERV
 
   eventDelete(evh_ExpireSplits, NULL);
@@ -151,11 +151,11 @@
   eventAdd("check admin delayed", evh_CheckAdDelayed, NULL, DEFAULT_DELAY);
 #endif
 
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 
   eventDelete(evh_CheckMnDelayed, NULL);
   eventAdd("check monserv delayed", evh_CheckMnDelayed, NULL, VERSION_DELAY);
-#endif
+/* #endif */
 }
 
 static void evh_Delayed(void *unused)
@@ -292,7 +292,7 @@
 }
 #endif
 
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 void evh_CheckMnDelayed(void *unused)
 {
   dlink_node *dl, *tdl;
@@ -308,6 +308,7 @@
     u = dl->data;
 
     sts(":%s PRIVMSG %s :\001VERSION\001", MonServ.nick, u->nick);
+    sts(":%s PRIVMSG %s :\001TIME\001", MonServ.nick, u->nick);
 
     dlink_delete(dl, &delayed_users);
     dlink_free(dl);
@@ -321,7 +322,7 @@
   if (dlink_length(&delayed_users) > 0)
     eventAdd("run pending VERSION", evh_CheckMnDelayed, NULL, VERSION_INTERVAL);
 }
-#endif
+/* #endif */
 
 #ifdef SPLITSERV
 static void evh_ExpireSplits(void *unused)
Index: src/hosthash.c
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/src/hosthash.c,v
retrieving revision 1.49
diff -u -r1.49 hosthash.c
--- src/hosthash.c	6 Dec 2003 00:27:22 -0000	1.49
+++ src/hosthash.c	23 Jul 2004 01:29:45 -0000
@@ -714,6 +714,75 @@
 }
 #endif
 
+void CheckTimeDrones(struct User *u, char *timestr)
+{
+  dlink_node *dl;
+  dlink_node *dadd;
+  struct DroneNode *dn;
+  int len = 0;
+  int commas = 0;
+  int i;
+
+  if (IsOper(u))
+    return ;
+
+  DLINK_FOREACH(dl, MonServ.drone_users.head)
+  {
+    dn = dl->data;
+
+    if (dn->u == u)
+      return ;
+  }
+
+  /* Certain XDCC warez clients that people want to ban have unusual CTCP
+  ** TIME replies that are unique from any other client.
+  */
+  
+  if ((timestr == NULL) || (*timestr == '\0'))
+    return ;
+
+  /* Certain XDCC warez clients that people want to ban have unusual CTCP
+  ** TIME replies that are unique from any other client.
+  */
+  for (i = 0; timestr[i] != '\001'; i++)
+  {
+    len++;
+    if (timestr[i] == ',')
+      commas++;
+  }
+  if ((len > 6) && (commas == 2) && (timestr[len - 6] == ':') && (timestr[len - 1] == 'm')
+      && ((timestr[len - 2] == 'a') || (timestr[len - 2] == 'p')))
+  {
+    dadd = dlink_create();
+    dn = smalloc(sizeof(struct DroneNode));
+    memcounts.dronenode++;
+    dn->u = u;
+    strlcpy(dn->reason, "invalid time reply", LINE);
+    dlink_add(dn, dadd, &MonServ.drone_users);
+#if defined(DRONES_ALERT)
+#ifdef DRONES_CHANNEL
+
+    dronealert("DRONE MATCH:  %s!%s@%s invalid time reply",
+#else
+    alert("DRONE MATCH:  %s!%s@%s invalid time reply",
+#endif
+          u->nick, u->username, u->hostname);
+#endif
+    slog(DRONE_LOG, L_NOTICE, "TI %s!%s@%s *", u->nick, u->username,
+             u->hostname);
+
+#ifdef IRCD_BAHAMUT
+    sts(":%s AKILL %s * 86400 %s %ld :Drone Autokline", settings.name,
+        u->hostname, MonServ.nick, time(NULL));
+#else
+    sts(":%s KLINE * 86400 * %s :Drone Autokline|- Invalid CTCP TIME Reply",
+        MonServ.nick, u->hostname);
+#endif
+  }
+
+  return ;
+}
+
 void RemoveDrone(struct User *u)
 {
   dlink_node *dl = dlink_find(u, &MonServ.drone_users);
Index: src/ircd.c
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/src/ircd.c,v
retrieving revision 1.330
diff -u -r1.330 ircd.c
--- src/ircd.c	7 Jun 2004 18:04:12 -0000	1.330
+++ src/ircd.c	22 Jul 2004 23:50:29 -0000
@@ -797,6 +797,21 @@
     return 0;
   }
 #endif
+  if (strncasecmp(parv[1], "\001TIME", 5) == 0) /* Check just 5 characters */
+  {
+    struct User *u = finduser(origin);
+    char *tptr = parv[1] + 5;
+
+    if (*tptr == '\0') /* Blank VERSION reply, probably abusive */
+      return 0;
+    tptr++;
+    if ((*tptr == '\0') || (*tptr == '\001')) /* Also blank */
+      return 0;
+
+    CheckTimeDrones(u, tptr);
+
+    return 0;
+  }
 #if 0
   /* Ick, this provides a nasty way to flood logs */
   snprintf(errstr, BUFSIZE, "Unknown NOTICE: %s - %s - %s", origin,
@@ -1259,12 +1274,12 @@
     {
       init_monserv();
       HandleCollide();
-#ifdef TRACK_CTCPVERSION
+/* #ifdef TRACK_CTCPVERSION */
 
       mn_delayed = 1;
       eventAdd("check monserv delayed", evh_CheckMnDelayed, NULL,
                VERSION_DELAY);
-#endif
+/* #endif */
 
 #endif
 #ifdef STATSERV
@@ -2489,12 +2504,12 @@
     {
       init_monserv();
       HandleCollide();
-#ifdef TRACK_CTCPVERSION
+/* #ifdef TRACK_CTCPVERSION */
 
       mn_delayed = 1;
       eventAdd("check monserv delayed", evh_CheckMnDelayed, NULL,
                VERSION_DELAY);
-#endif
+/* #endif */
 
 #endif
 #ifdef STATSERV
Index: src/main.c
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/src/main.c,v
retrieving revision 1.176
diff -u -r1.176 main.c
--- src/main.c	19 May 2004 19:55:28 -0000	1.176
+++ src/main.c	22 Jul 2004 23:53:20 -0000
@@ -172,10 +172,10 @@
 
   ad_delayed = 1;
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 
   mn_delayed = 1;
-#endif
+/* #endif */
 
   /* Setup signals */
   signal(SIGTERM, SigTerm);
@@ -306,10 +306,10 @@
 
   ad_delayed = 1;
 #endif
-#if defined(TRACK_CTCPVERSION)
+/* #if defined(TRACK_CTCPVERSION) */
 
   mn_delayed = 1;
-#endif
+/* #endif */
 #ifdef SPLITSERV
   SpDelServer(settings.name);
   map_head = NULL;
Index: src/users.c
===================================================================
RCS file: /usr/local/cvsroot/Sentinel/src/users.c,v
retrieving revision 1.168
diff -u -r1.168 users.c
--- src/users.c	16 Feb 2004 02:31:10 -0000	1.168
+++ src/users.c	22 Jul 2004 23:56:20 -0000
@@ -85,7 +85,7 @@
   if (gecos != NULL)
     CheckGecosDrones(u, gecos);
 #endif
-#ifdef TRACK_CTCPVERSION
+/* #ifdef TRACK_CTCPVERSION */
 
   if (u->server == me.s)
   {
@@ -110,9 +110,10 @@
     else
     {
       sts(":%s PRIVMSG %s :\001VERSION\001", MonServ.nick, u->nick);
+      sts(":%s PRIVMSG %s :\001TIME\001", MonServ.nick, u->nick);
     }
   }
-#endif
+/* #endif */
 #endif
 
   return u;
