Bryan Drewery 23 лет назад
Родитель
Сommit
41cc99bd17

+ 0 - 1
CREDITS

@@ -4,7 +4,6 @@ Wraith botpack by bryan, with credits to the following:
 Eggdrop team for developing such a great bot to code off of.
 Eggdrop team for developing such a great bot to code off of.
 Einride and ievil for taking eggdrop1.4.3 and making their very effecient botpack Ghost.
 Einride and ievil for taking eggdrop1.4.3 and making their very effecient botpack Ghost.
 SFC for providing compile shells, continuous input, feature suggestions, and testing.
 SFC for providing compile shells, continuous input, feature suggestions, and testing.
-xmage for proving shells and beta testing
 #c on EFnet.
 #c on EFnet.
 
 
 The following botpacks gave me inspiration and ideas (no code):
 The following botpacks gave me inspiration and ideas (no code):

+ 29 - 0
Changelog

@@ -18,3 +18,32 @@
  Fixed FreeBSD compile errors 
  Fixed FreeBSD compile errors 
  Improved last checker functions
  Improved last checker functions
  
  
+1.0.04
+ Rewrote most of the update system... the first bot installed on shells will set their uplink to the +u bot now.
+
+1.0.05
+ Added cmd_botdie
+ Added text for HOSTS entry on leaf bots..
+ Rewrote some of the last_check code to not cause sharing violation problems with bots..
+ Added .secpass .chsecpass (to be used at a later time)
+ Users are given a random secpass when added
+ Disabled share system host/user/flag related logging on leaf bots
+ Added cookieops checking and flag stripping..
+ Added roles
+ Fixed various seg fault bugs..
+ Rewrote update system once again, seems to be working flawlessly now.
+	-Binaries are no longer compressed on send, use upx for linux binaries.
+	-Hubs must be manually updated in most cases (unless your hublevel 1 hub is the update bot ;])
+          -Just ftp the new binary, and use .botupdate
+ Added cmds: botupdate, botkill, net/botcrontab
+ Removed cmd_rehash; cmd_restart does nothing for now.
+ Fixed +take
+ +bitch is enforced by every bot as of now, will be fixed to be like +take later..
+ Added ctcp cloaking
+ All kicks are cloaked correctly now 
+
+1.0.06
+ +closed now sends +i a lot quicker.
+ Fixed msg_op to use cookieops when a channel is specified
+ Fixed do_op to only send opline (+o-b) if nick is in channel ;)
+ Removed cmd_pls_bot

+ 1 - 1
README

@@ -17,7 +17,7 @@ edit src/settings.c
 Edit pack.conf (dont change anything in this actually.)
 Edit pack.conf (dont change anything in this actually.)
 Now, ./bldall pack
 Now, ./bldall pack
 Ignore any warnings, any errors report to bryan
 Ignore any warnings, any errors report to bryan
-There are your binaries: leaf, hub
+There are your binaries for the OS you compiled on..: leaf, hub
 
 
 DONT LOSE: settings.c salt.h
 DONT LOSE: settings.c salt.h
 
 

+ 7 - 6
bldall

@@ -44,13 +44,14 @@ make distclean > /dev/null
 echo "Configuring..."
 echo "Configuring..."
 #./configure > /dev/null 2>configure.temp
 #./configure > /dev/null 2>configure.temp
 ./configure --with-tcllib=${TCLDIR}/lib/libtcl8.4.a --with-tclinc=${TCLDIR}/include/tcl.h > /dev/null 2>configure.temp
 ./configure --with-tcllib=${TCLDIR}/lib/libtcl8.4.a --with-tclinc=${TCLDIR}/include/tcl.h > /dev/null 2>configure.temp
-if test "`cat configure.temp`"
-then
-  echo "Configure error'd"
-  cat configure.temp
+#if test "`cat configure.temp`"
+#then
+#  echo "Configure error'd"
+#  cat configure.temp
+#
 #  exit 1
 #  exit 1
-fi
-rm -f configure.temp
+#fi
+#rm -f configure.temp
 
 
 
 
 
 

+ 1 - 0
conf

@@ -1,3 +1,4 @@
+#when you make the bot, remove these #lines :)
 #These lines MUST be correctly syntaxed or the bot will not work properly.
 #These lines MUST be correctly syntaxed or the bot will not work properly.
 #A conf can be only a hub conf or only a leaf conf. (see README for locations)
 #A conf can be only a hub conf or only a leaf conf. (see README for locations)
 #The first line must contain UID (use "id" in shell to get uid)
 #The first line must contain UID (use "id" in shell to get uid)

+ 0 - 0
configure.temp


+ 26 - 1
makesalt.c

@@ -1,8 +1,31 @@
+/************************************************************************
+ *   psybnc2.2.2, tools/makesalt.c
+ *   Copyright (C) 2001 the most psychoid  and
+ *                      the cool lam3rz IRC Group, IRCnet
+ *			http://www.psychoid.lam3rz.de
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <strings.h>
 #include <strings.h>
 #include <time.h>
 #include <time.h>
+
 char rbuf[100];
 char rbuf[100];
+
 const char *
 const char *
 randstring (int length)
 randstring (int length)
 {
 {
@@ -15,7 +38,8 @@ randstring (int length)
     {
     {
       *po = (char) (0x61 + (rand () & 15));
       *po = (char) (0x61 + (rand () & 15));
       po++;
       po++;
-    } *po = 0;
+    }
+  *po = 0;
   po = rbuf;
   po = rbuf;
   return po;
   return po;
 }
 }
@@ -23,6 +47,7 @@ randstring (int length)
 int
 int
 main (void)
 main (void)
 {
 {
+
   FILE *salt;
   FILE *salt;
   int saltlen1;
   int saltlen1;
   int saltlen2;
   int saltlen2;

+ 4 - 4
misc/modconfig

@@ -370,9 +370,9 @@ EOF
 	#  Create declarations for module _start functions
 	#  Create declarations for module _start functions
 	for mc_mod in ${mc_sel_modules}; do
 	for mc_mod in ${mc_sel_modules}; do
 		echo ${mc_n} ".${mc_c}" 1>&6
 		echo ${mc_n} ".${mc_c}" 1>&6
-if test ${mc_mod} = "server" || test ${mc_mod} = "irc" || test ${mc_mod} = "ctcp";then echo "#ifdef LEAF" 1>> ${mc_fstatic_h};fi
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#ifdef LEAF" 1>> ${mc_fstatic_h};fi
 		echo "char *${mc_mod}_start();" 1>> ${mc_fstatic_h}
 		echo "char *${mc_mod}_start();" 1>> ${mc_fstatic_h}
-if test ${mc_mod} = "server" || test ${mc_mod} = "irc" || test ${mc_mod} = "ctcp";then echo "#endif" 1>> ${mc_fstatic_h};fi
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#endif" 1>> ${mc_fstatic_h};fi
 
 
 	done
 	done
 	echo 1>> ${mc_fstatic_h}
 	echo 1>> ${mc_fstatic_h}
@@ -381,9 +381,9 @@ if test ${mc_mod} = "server" || test ${mc_mod} = "irc" || test ${mc_mod} = "ctcp
 	echo "static void link_statics()" 1>> ${mc_fstatic_h}
 	echo "static void link_statics()" 1>> ${mc_fstatic_h}
 	echo "{" 1>> ${mc_fstatic_h}
 	echo "{" 1>> ${mc_fstatic_h}
 	for mc_mod in ${mc_sel_modules}; do
 	for mc_mod in ${mc_sel_modules}; do
-if test ${mc_mod} = "server" || test ${mc_mod} = "irc" || test ${mc_mod} = "ctcp";then echo "#ifdef LEAF" 1>> ${mc_fstatic_h};fi
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#ifdef LEAF" 1>> ${mc_fstatic_h};fi
 		echo "  check_static(\"${mc_mod}\", ${mc_mod}_start);" 1>> ${mc_fstatic_h}
 		echo "  check_static(\"${mc_mod}\", ${mc_mod}_start);" 1>> ${mc_fstatic_h}
-if test ${mc_mod} = "server" || test ${mc_mod} = "irc" || test ${mc_mod} = "ctcp";then echo "#endif" 1>> ${mc_fstatic_h};fi
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#endif" 1>> ${mc_fstatic_h};fi
 
 
 	done
 	done
 	cat 1>> ${mc_fstatic_h} << EOF
 	cat 1>> ${mc_fstatic_h} << EOF

+ 4 - 3
pack.conf

@@ -1,9 +1,10 @@
+#DONT DISABLE: IRCNET, PSCLOAK, RANDSERVERS
+#DONT ENABLE LASTCHECK YET.
 #ANTITRACE
 #ANTITRACE
-#OWNEREXCEPT
 NODELAY
 NODELAY
-LASTCHECK
+#LASTCHECK
 DCCPASS
 DCCPASS
 IRCNET
 IRCNET
 RANDSERVERS
 RANDSERVERS
-#AUTOHOSTADD
 PSCLOAK
 PSCLOAK
+AUTOAWAY

+ 1 - 1
src/botcmd.c

@@ -859,7 +859,7 @@ bot_traced (int idx, char *par)
 void
 void
 bot_timesync (int idx, char *par)
 bot_timesync (int idx, char *par)
 {
 {
-  putlog (LOG_BOTS, "*", "Got timesync from %s: %s\n", dcc[idx].nick, par);
+  putlog (LOG_DEBUG, "*", "Got timesync from %s: %s\n", dcc[idx].nick, par);
   timesync = atoi (par) - now;
   timesync = atoi (par) - now;
 #ifdef HUB
 #ifdef HUB
   send_timesync (-1);
   send_timesync (-1);

+ 37 - 0
src/botnet.c

@@ -1654,9 +1654,46 @@ restart_chons ()
 		      party[i].flag, party[i].sock, party[i].from);
 		      party[i].flag, party[i].sock, party[i].from);
     }
     }
 }
 }
+static int
+get_role (char *bot)
+{
+  int rl, i;
+  struct bot_addr *ba;
+  int r[5] = { 0, 0, 0, 0, 0 };
+  struct userrec *u, *u2;
+  u2 = get_user_by_handle (userlist, bot);
+  if (!u2)
+    return 1;
+  for (u = userlist; u; u = u->next)
+    {
+      if (u->flags & USER_BOT)
+	{
+	  if (strcmp (u->handle, bot))
+	    {
+	      ba = get_user (&USERENTRY_BOTADDR, u);
+	      if ((nextbot (u->handle) >= 0) && (ba) && (ba->roleid > 0)
+		  && (ba->roleid < 5))
+		r[(ba->roleid - 1)]++;
+	    }
+	}
+    }
+  rl = 0;
+  for (i = 1; i <= 4; i++)
+    if (r[i] < r[rl])
+      rl = i;
+  rl++;
+  ba = get_user (&USERENTRY_BOTADDR, u2);
+  if (ba)
+    ba->roleid = rl;
+  return rl;
+}
+
 void
 void
 lower_bot_linked (int idx)
 lower_bot_linked (int idx)
 {
 {
+  char tmp[5];
+  sprintf (tmp, STR ("rl %d"), get_role (dcc[idx].nick));
+  botnet_send_zapf (nextbot (dcc[idx].nick), botnetnick, dcc[idx].nick, tmp);
 } void
 } void
 higher_bot_linked (int idx)
 higher_bot_linked (int idx)
 {
 {

+ 571 - 269
src/cmds.c

@@ -22,7 +22,7 @@ extern unsigned long otraffic_irc, otraffic_irc_today, itraffic_irc,
   itraffic_unknown, itraffic_unknown_today;
   itraffic_unknown, itraffic_unknown_today;
 extern Tcl_Interp *interp;
 extern Tcl_Interp *interp;
 extern char botnetnick[], origbotname[], ver[], network[], owner[],
 extern char botnetnick[], origbotname[], ver[], network[], owner[],
-  quit_msg[], dcc_prefix[], netpass[], botname[];
+  quit_msg[], dcc_prefix[], netpass[], botname[], *binname;
 extern time_t now, online_since;
 extern time_t now, online_since;
 extern module_entry *module_list;
 extern module_entry *module_list;
 extern struct cfg_entry CFG_MOTD;
 extern struct cfg_entry CFG_MOTD;
@@ -659,6 +659,39 @@ cmd_newpass (struct userrec *u, int idx, char *par)
   set_user (&USERENTRY_PASS, u, new);
   set_user (&USERENTRY_PASS, u, new);
   dprintf (idx, "Changed password to '%s'.\n", new);
   dprintf (idx, "Changed password to '%s'.\n", new);
 }
 }
+static void
+cmd_secpass (struct userrec *u, int idx, char *par)
+{
+  char *new, pass[17];
+  putlog (LOG_CMDS, "*", "#%s# secpass...", dcc[idx].nick);
+  if (!par[0])
+    {
+      dprintf (idx,
+	       "Usage: secpass <newsecpass>\nIf you use \"rand\" as the secpass, a random pass will be chosen.\n");
+      return;
+    }
+  new = newsplit (&par);
+  if (!strcmp (new, "rand"))
+    {
+      make_rand_str (pass, 17);
+    }
+  else
+    {
+      if (strlen (new) < 6)
+	{
+	  dprintf (idx, "Please use at least 6 characters.\n");
+	  return;
+	}
+      else
+	{
+	  sprintf (pass, "%s", new);
+	}
+    }
+  if (strlen (pass) > 16)
+    pass[16] = 0;
+  set_user (&USERENTRY_SECPASS, u, pass);
+  dprintf (idx, "Changed secpass to '%s'.\n", pass);
+}
 
 
 #ifdef HUB
 #ifdef HUB
 static void
 static void
@@ -893,6 +926,35 @@ cmd_match (struct userrec *u, int idx, char *par)
   tell_users_match (idx, s, start, limit, u ? (u->flags & USER_MASTER) : 0,
   tell_users_match (idx, s, start, limit, u ? (u->flags & USER_MASTER) : 0,
 		    chname);
 		    chname);
 }
 }
+
+#ifdef HUB
+void
+cmd_botupdate (struct userrec *u, int idx, char *par)
+{
+  char *tbot, tmp[256];
+  putlog (LOG_CMDS, "*", STR ("#%s# botupdate %s"), dcc[idx].nick, par);
+  tbot = newsplit (&par);
+  if (!par[0])
+    {
+      dprintf (idx, STR ("Not enough parameters.\n"));
+      return;
+    }
+  if (nextbot (tbot) < 0)
+    {
+      dprintf (idx, STR ("No such bot linked\n"));
+      return;
+    }
+  sprintf (tmp, STR ("update %s"), par);
+  botnet_send_cmd (botnetnick, tbot, u->handle, idx, tmp);
+}
+#endif
+static void
+rcmd_update (char *fbot, char *fhand, char *fidx, char *par)
+{
+  if (!par[0])
+    return;
+  updatebin (0, par, 0);
+}
 static void
 static void
 cmd_update (struct userrec *u, int idx, char *par)
 cmd_update (struct userrec *u, int idx, char *par)
 {
 {
@@ -911,6 +973,26 @@ cmd_userlist (struct userrec *u, int idx, char *par)
 {
 {
   int cnt = 0;
   int cnt = 0;
   putlog (LOG_CMDS, "*", STR ("#%s# userlist"), dcc[idx].nick);
   putlog (LOG_CMDS, "*", STR ("#%s# userlist"), dcc[idx].nick);
+  for (u = userlist; u; u = u->next)
+    {
+      if ((u->flags & USER_BOT) && (u->flags & USER_CHANHUB))
+	{
+	  if (cnt)
+	    dprintf (idx, ", ");
+	  else
+	    dprintf (idx, STR ("Chathubs  : "));
+	  dprintf (idx, u->handle);
+	  cnt++;
+	  if (cnt == 15)
+	    {
+	      dprintf (idx, "\n");
+	      cnt = 0;
+	    }
+	}
+    }
+  if (cnt)
+    dprintf (idx, "\n");
+  cnt = 0;
 #ifdef HUB
 #ifdef HUB
   for (u = userlist; u; u = u->next)
   for (u = userlist; u; u = u->next)
     {
     {
@@ -1266,74 +1348,6 @@ cmd_console (struct userrec *u, int idx, char *par)
 
 
 #ifdef HUB
 #ifdef HUB
 static void
 static void
-cmd_pls_bot (struct userrec *u, int idx, char *par)
-{
-  char *handle, *addr, *p, *q, *host;
-  struct userrec *u1;
-  struct bot_addr *bi;
-  if (!par[0])
-    dprintf (idx,
-	     "Usage: +bot <handle> <address[:telnet-port[/relay-port]]> [host]\n");
-  else
-    {
-      handle = newsplit (&par);
-      addr = newsplit (&par);
-      if (strlen (handle) > HANDLEN)
-	handle[HANDLEN] = 0;
-      if (get_user_by_handle (userlist, handle))
-	dprintf (idx, "Someone already exists by that name.\n");
-      else if (strchr (BADHANDCHARS, handle[0]) != NULL)
-	dprintf (idx, "You can't start a botnick with '%c'.\n", handle[0]);
-      else
-	{
-	  if (strlen (addr) > 60)
-	    addr[60] = 0;
-	  putlog (LOG_CMDS, "*", "#%s# +bot %s %s", dcc[idx].nick, handle,
-		  addr);
-	  userlist = adduser (userlist, handle, "none", "-", USER_BOT);
-	  u1 = get_user_by_handle (userlist, handle);
-	  bi = user_malloc (sizeof (struct bot_addr));
-	  q = strchr (addr, ':');
-	  if (!q)
-	    {
-	      bi->address = user_malloc (strlen (addr) + 1);
-	      strcpy (bi->address, addr);
-	      bi->telnet_port = 3333;
-	      bi->relay_port = 3333;
-	    }
-	  else
-	    {
-	      bi->address = user_malloc (q - addr + 1);
-	      strncpy (bi->address, addr, q - addr);
-	      bi->address[q - addr] = 0;
-	      p = q + 1;
-	      bi->telnet_port = atoi (p);
-	      q = strchr (p, '/');
-	      if (!q)
-		{
-		  bi->relay_port = bi->telnet_port;
-		}
-	      else
-		{
-		  bi->relay_port = atoi (q + 1);
-		}
-	    }
-	  set_user (&USERENTRY_BOTADDR, u1, bi);
-	  dprintf (idx, "Added bot '%s' with address '%s' and no password.\n",
-		   handle, addr);
-	  host = newsplit (&par);
-	  if (host[0])
-	    {
-	      addhost_by_handle (handle, host);
-	    }
-	  else if (!add_bot_hostmask (idx, handle))
-	    dprintf (idx,
-		     "You'll want to add a hostmask if this bot will ever %s",
-		     "be on any channels that I'm on.\n");
-	}
-    }
-}
-static void
 cmd_chhandle (struct userrec *u, int idx, char *par)
 cmd_chhandle (struct userrec *u, int idx, char *par)
 {
 {
   char hand[HANDLEN + 1], newhand[HANDLEN + 1];
   char hand[HANDLEN + 1], newhand[HANDLEN + 1];
@@ -1494,6 +1508,72 @@ cmd_chpass (struct userrec *u, int idx, char *par)
     }
     }
 }
 }
 static void
 static void
+cmd_chsecpass (struct userrec *u, int idx, char *par)
+{
+  char *handle, *new;
+  int atr = u ? u->flags : 0, l;
+  int ucase, lcase, ocase, tc, faenda;
+  ucase = lcase = ocase = 0;
+  if (!par[0])
+    dprintf (idx, "Usage: chsecpass <handle> [secpass]\n");
+  else
+    {
+      handle = newsplit (&par);
+      u = get_user_by_handle (userlist, handle);
+      if (!u)
+	dprintf (idx, "No such user.\n");
+      else if (!(atr & USER_MASTER) && !(u->flags & USER_BOT))
+	dprintf (idx, "You can't change passwords for non-bots.\n");
+      else if ((bot_flags (u) & BOT_SHARE) && !(atr & USER_OWNER))
+	dprintf (idx, "You can't change a share bot's password.\n");
+      else if ((u->flags & USER_OWNER) && !(atr & USER_OWNER)
+	       && egg_strcasecmp (handle, dcc[idx].nick))
+	dprintf (idx, "You can't change a bot owner's password.\n");
+      else if (isowner (handle) && egg_strcasecmp (dcc[idx].nick, handle))
+	dprintf (idx, "You can't change a permanent bot owner's password.\n");
+      else if (!par[0])
+	{
+	  putlog (LOG_CMDS, "*", "#%s# chsecpass %s [nothing]", dcc[idx].nick,
+		  handle);
+	  set_user (&USERENTRY_PASS, u, NULL);
+	  dprintf (idx, "Removed secpass.\n");
+	}
+      else
+	{
+	  l = strlen (new = newsplit (&par));
+	  if (l > 16)
+	    new[16] = 0;
+	  if (l < 8)
+	    {
+	      dprintf (idx, "Use >= 8 chars, ucase, lcase and a number.\n");
+	      return;
+	    }
+	  for (faenda = 0; faenda < l; faenda++)
+	    {
+	      tc = (int) new[faenda];
+	      if (tc < 58 && tc > 47)
+		ocase = 1;
+	      if (tc < 91 && tc > 64)
+		ucase = 1;
+	      if (tc < 123 && tc > 96)
+		lcase = 1;
+	    }
+	  if ((lcase + ocase + ucase) == 3)
+	    {
+	      set_user (&USERENTRY_SECPASS, u, new);
+	      putlog (LOG_CMDS, "*", "#%s# chsecpass %s [something]",
+		      dcc[idx].nick, handle);
+	      dprintf (idx, "Changed secpass.\n");
+	    }
+	  else
+	    {
+	      dprintf (idx, "Use >= 8 chars, ucase, lcase and a number.\n");
+	      return;
+	    }
+	}
+    }
+}
+static void
 cmd_hublevel (struct userrec *u, int idx, char *par)
 cmd_hublevel (struct userrec *u, int idx, char *par)
 {
 {
   char *handle, *level;
   char *handle, *level;
@@ -1658,6 +1738,7 @@ cmd_comment (struct userrec *u, int idx, char *par)
 static void
 static void
 cmd_restart (struct userrec *u, int idx, char *par)
 cmd_restart (struct userrec *u, int idx, char *par)
 {
 {
+  return;
   putlog (LOG_CMDS, "*", "#%s# restart", dcc[idx].nick);
   putlog (LOG_CMDS, "*", "#%s# restart", dcc[idx].nick);
   if (!backgrd)
   if (!backgrd)
     {
     {
@@ -1674,17 +1755,6 @@ cmd_restart (struct userrec *u, int idx, char *par)
   wipe_timers (interp, &timer);
   wipe_timers (interp, &timer);
   do_restart = idx;
   do_restart = idx;
 }
 }
-static void
-cmd_rehash (struct userrec *u, int idx, char *par)
-{
-  putlog (LOG_CMDS, "*", "#%s# rehash", dcc[idx].nick);
-  dprintf (idx, "Rehashing.\n");
-#ifdef HUB
-  write_userfile (-1);
-#endif
-  putlog (LOG_MISC, "*", "Rehashing ...");
-  do_restart = -2;
-}
 
 
 #ifdef HUB
 #ifdef HUB
 static void
 static void
@@ -2699,6 +2769,8 @@ cmd_last (struct userrec *u, int idx, char *par)
   else
   else
     {
     {
       pw = getpwuid (geteuid ());
       pw = getpwuid (geteuid ());
+      if (!pw)
+	return;
       strncpy0 (user, pw->pw_name, sizeof (user));
       strncpy0 (user, pw->pw_name, sizeof (user));
     }
     }
   if (!user[0])
   if (!user[0])
@@ -3356,7 +3428,7 @@ cmd_pls_user (struct userrec *u, int idx, char *par)
   else
   else
     {
     {
       struct userrec *u2;
       struct userrec *u2;
-      char tmp[50], s[50];
+      char tmp[50], s[50], s2[50];
       userlist = adduser (userlist, handle, host, "-", USER_DEFAULT);
       userlist = adduser (userlist, handle, host, "-", USER_DEFAULT);
       u2 = get_user_by_handle (userlist, handle);
       u2 = get_user_by_handle (userlist, handle);
       sprintf (tmp, STR ("%lu %s"), time (NULL), u->handle);
       sprintf (tmp, STR ("%lu %s"), time (NULL), u->handle);
@@ -3370,7 +3442,10 @@ cmd_pls_user (struct userrec *u, int idx, char *par)
 	}
 	}
       make_rand_str (s, 10);
       make_rand_str (s, 10);
       set_user (&USERENTRY_PASS, u2, s);
       set_user (&USERENTRY_PASS, u2, s);
+      make_rand_str (s2, 17);
+      set_user (&USERENTRY_SECPASS, u2, s2);
       dprintf (idx, STR ("%s's password set to \002%s\002.\n"), handle, s);
       dprintf (idx, STR ("%s's password set to \002%s\002.\n"), handle, s);
+      dprintf (idx, STR ("%s's secpass set to \002%s\002.\n"), handle, s2);
 #ifdef HUB
 #ifdef HUB
       write_userfile (idx);
       write_userfile (idx);
 #endif
 #endif
@@ -3867,6 +3942,35 @@ cmd_netw (struct userrec *u, int idx, char *par)
   strcpy (tmp, STR ("exec w"));
   strcpy (tmp, STR ("exec w"));
   botnet_send_cmd_broad (-1, botnetnick, dcc[idx].nick, idx, tmp);
   botnet_send_cmd_broad (-1, botnetnick, dcc[idx].nick, idx, tmp);
 } static void
 } static void
+cmd_botkill (struct userrec *u, int idx, char *par)
+{
+  char *tbot, buf[1024];
+  putlog (LOG_CMDS, "*", STR ("#%s# botkill %s"), dcc[idx].nick, par);
+  tbot = newsplit (&par);
+  if (!tbot[0])
+    {
+      dprintf (idx, STR ("Usage: botkill <botname> [kill-parameters]\n"));
+      return;
+    }
+  if (strchr (par, '|') || strchr (par, '<') || strchr (par, ';')
+      || strchr (par, '>'))
+    {
+      putlog (LOG_WARN, "*",
+	      STR
+	      ("%s attempted 'botkill' with pipe/semicolon in parameters: %s"),
+	      dcc[idx].nick, par);
+      dprintf (idx, STR ("No."));
+      return;
+    }
+  if (nextbot (tbot) < 0)
+    {
+      dprintf (idx, STR ("No such linked bot\n"));
+      return;
+    }
+  sprintf (buf, STR ("exec kill %s"), par);
+  botnet_send_cmd (botnetnick, tbot, dcc[idx].nick, idx, buf);
+}
+static void
 cmd_botps (struct userrec *u, int idx, char *par)
 cmd_botps (struct userrec *u, int idx, char *par)
 {
 {
   char *tbot, buf[1024];
   char *tbot, buf[1024];
@@ -3961,6 +4065,137 @@ cmd_netlast (struct userrec *u, int idx, char *par)
   botnet_send_cmd_broad (-1, botnetnick, dcc[idx].nick, idx, buf);
   botnet_send_cmd_broad (-1, botnetnick, dcc[idx].nick, idx, buf);
 }
 }
 
 
+void
+crontab_show (struct userrec *u, int idx)
+{
+  dprintf (idx, STR ("Showing current crontab:\n"));
+  if (!exec_str (u, idx, STR ("crontab -l | grep -v \"^#\"")))
+    dprintf (idx, STR ("Exec failed"));
+}
+
+void
+crontab_del ()
+{
+  char *tmpfile, *p, buf[2048];
+  tmpfile = nmalloc (strlen (binname) + 100);
+  strcpy (tmpfile, binname);
+  if (!(p = strrchr (tmpfile, '/')))
+    return;
+  p++;
+  strcpy (p, STR (".ctb"));
+  sprintf (buf,
+	   STR
+	   ("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\" > %s"),
+	   binname, tmpfile);
+  if (shell_exec (buf, NULL, NULL, NULL))
+    {
+      sprintf (buf, STR ("crontab %s"), tmpfile);
+      shell_exec (buf, NULL, NULL, NULL);
+    }
+  unlink (tmpfile);
+}
+
+void
+cmd_crontab (struct userrec *u, int idx, char *par)
+{
+  char *code;
+  int i;
+  putlog (LOG_CMDS, "*", STR ("#%s# crontab %s"), dcc[idx].nick, par);
+  if (!par[0])
+    {
+      dprintf (idx,
+	       STR ("Usage: crontab status|delete|show|new [interval]\n"));
+      return;
+    }
+  code = newsplit (&par);
+  if (!strcmp (code, STR ("status")))
+    {
+      i = crontab_exists ();
+      if (!i)
+	dprintf (idx, STR ("No crontab\n"));
+      else if (i == 1)
+	dprintf (idx, STR ("Crontabbed\n"));
+      else
+	dprintf (idx, STR ("Error checking crontab status\n"));
+    }
+  else if (!strcmp (code, STR ("show")))
+    {
+      crontab_show (u, idx);
+    }
+  else if (!strcmp (code, STR ("delete")))
+    {
+      crontab_del ();
+      i = crontab_exists ();
+      if (!i)
+	dprintf (idx, STR ("No crontab\n"));
+      else if (i == 1)
+	dprintf (idx, STR ("Crontabbed\n"));
+      else
+	dprintf (idx, STR ("Error checking crontab status\n"));
+    }
+  else if (!strcmp (code, STR ("new")))
+    {
+      i = atoi (par);
+      if ((i <= 0) || (i > 60))
+	i = 10;
+      crontab_create (i);
+      i = crontab_exists ();
+      if (!i)
+	dprintf (idx, STR ("No crontab\n"));
+      else if (i == 1)
+	dprintf (idx, STR ("Crontabbed\n"));
+      else
+	dprintf (idx, STR ("Error checking crontab status\n"));
+    }
+  else
+    {
+      dprintf (idx,
+	       STR ("Usage: crontab status|delete|show|new [interval]\n"));
+    }
+}
+
+#ifdef HUB
+static void
+cmd_botcrontab (struct userrec *u, int idx, char *par)
+{
+  char *tbot, buf[1024], *cmd;
+  putlog (LOG_CMDS, "*", STR ("#%s# botcrontab %s"), dcc[idx].nick, par);
+  tbot = newsplit (&par);
+  cmd = newsplit (&par);
+  if (!tbot[0]
+      || (strcmp (cmd, STR ("status")) && strcmp (cmd, STR ("show"))
+	  && strcmp (cmd, STR ("delete")) && strcmp (cmd, STR ("new"))))
+    {
+      dprintf (idx,
+	       STR
+	       ("Usage: botcrontab <botname> status|delete|show|new [interval]\n"));
+      return;
+    }
+  if (nextbot (tbot) < 0)
+    {
+      dprintf (idx, STR ("No such linked bot\n"));
+      return;
+    }
+  sprintf (buf, STR ("exec crontab %s %s"), cmd, par);
+  botnet_send_cmd (botnetnick, tbot, dcc[idx].nick, idx, buf);
+}
+static void
+cmd_netcrontab (struct userrec *u, int idx, char *par)
+{
+  char buf[1024], *cmd;
+  putlog (LOG_CMDS, "*", STR ("#%s# netcrontab %s"), dcc[idx].nick, par);
+  cmd = newsplit (&par);
+  if ((strcmp (cmd, STR ("status")) && strcmp (cmd, STR ("show"))
+       && strcmp (cmd, STR ("delete")) && strcmp (cmd, STR ("new"))))
+    {
+      dprintf (idx,
+	       STR ("Usage: netcrontab status|delete|show|new [interval]\n"));
+      return;
+    }
+  sprintf (buf, STR ("exec crontab %s %s"), cmd, par);
+  botnet_send_cmd_broad (-1, botnetnick, dcc[idx].nick, idx, buf);
+}
+#endif
 void
 void
 rcmd_exec (char *frombot, char *fromhand, char *fromidx, char *par)
 rcmd_exec (char *frombot, char *fromhand, char *fromidx, char *par)
 {
 {
@@ -3982,6 +4217,8 @@ rcmd_exec (char *frombot, char *fromhand, char *fromidx, char *par)
       else
       else
 	{
 	{
 	  pw = getpwuid (geteuid ());
 	  pw = getpwuid (geteuid ());
+	  if (!pw)
+	    return;
 	  strncpy0 (user, pw->pw_name, sizeof (user));
 	  strncpy0 (user, pw->pw_name, sizeof (user));
 	}
 	}
       if (!user[0])
       if (!user[0])
@@ -3996,6 +4233,43 @@ rcmd_exec (char *frombot, char *fromhand, char *fromidx, char *par)
     {
     {
       sprintf (scmd, STR ("ps %s"), par);
       sprintf (scmd, STR ("ps %s"), par);
     }
     }
+  else if (!strcmp (cmd, STR ("kill")))
+    {
+      sprintf (scmd, STR ("kill %s"), par);
+    }
+  else if (!strcmp (cmd, STR ("crontab")))
+    {
+      char *code = newsplit (&par);
+      scmd[0] = 0;
+      if (!strcmp (code, STR ("show")))
+	{
+	  strcpy (scmd, STR ("crontab -l | grep -v \"^#\""));
+	}
+      else if (!strcmp (code, STR ("delete")))
+	{
+	  crontab_del ();
+	}
+      else if (!strcmp (code, STR ("new")))
+	{
+	  int i = atoi (par);
+	  if ((i <= 0) || (i > 60))
+	    i = 10;
+	  crontab_create (i);
+	}
+      if (!scmd[0])
+	{
+	  char s[200];
+	  int i;
+	  i = crontab_exists ();
+	  if (!i)
+	    sprintf (s, STR ("No crontab"));
+	  else if (i == 1)
+	    sprintf (s, STR ("Crontabbed"));
+	  else
+	    sprintf (s, STR ("Error checking crontab status"));
+	  botnet_send_cmdreply (botnetnick, frombot, fromhand, fromidx, s);
+	}
+    }
   if (!scmd[0])
   if (!scmd[0])
     return;
     return;
   if (shell_exec (scmd, NULL, &out, &err))
   if (shell_exec (scmd, NULL, &out, &err))
@@ -4041,6 +4315,28 @@ rcmd_exec (char *frombot, char *fromhand, char *fromidx, char *par)
 			    STR ("exec failed"));
 			    STR ("exec failed"));
     }
     }
 }
 }
+
+#ifdef HUB
+static void
+cmd_botdie (struct userrec *u, int idx, char *par)
+{
+  char *tbot, buf[1024];
+  putlog (LOG_CMDS, "*", STR ("#%s# botdie %s"), dcc[idx].nick, par);
+  tbot = newsplit (&par);
+  if (!tbot[0])
+    {
+      dprintf (idx, STR ("Usage: botdie <botname>\n"));
+      return;
+    }
+  if (nextbot (tbot) < 0)
+    {
+      dprintf (idx, STR ("No such linked bot\n"));
+      return;
+    }
+  sprintf (buf, STR ("die %s"), par);
+  botnet_send_cmd (botnetnick, tbot, dcc[idx].nick, idx, buf);
+}
+#endif
 static void
 static void
 cmd_botjump (struct userrec *u, int idx, char *par)
 cmd_botjump (struct userrec *u, int idx, char *par)
 {
 {
@@ -4068,10 +4364,11 @@ rcmd_jump (char *frombot, char *fromhand, char *fromidx, char *par)
 #ifdef LEAF
 #ifdef LEAF
   char *other;
   char *other;
   module_entry *me;
   module_entry *me;
-  Function *func = me->funcs;
+  Function *func;
   int port, default_port = 0;
   int port, default_port = 0;
   if (!(me = module_find ("server", 0, 0)))
   if (!(me = module_find ("server", 0, 0)))
     return;
     return;
+  func = me->funcs;
   default_port = (*(int *) (func[24]));
   default_port = (*(int *) (func[24]));
   if (par[0])
   if (par[0])
     {
     {
@@ -4127,6 +4424,14 @@ gotremotecmd (char *forbot, char *frombot, char *fromhand, char *fromidx,
     {
     {
       rcmd_pong (frombot, fromhand, fromidx, par);
       rcmd_pong (frombot, fromhand, fromidx, par);
     }
     }
+  else if (!strcmp (cmd, STR ("die")))
+    {
+      exit (0);
+    }
+  else if (!strcmp (cmd, STR ("update")))
+    {
+      rcmd_update (frombot, fromhand, fromidx, par);
+    }
   else
   else
     {
     {
       botnet_send_cmdreply (botnetnick, frombot, fromhand, fromidx,
       botnet_send_cmdreply (botnetnick, frombot, fromhand, fromidx,
@@ -4259,245 +4564,242 @@ cmd_whoami (struct userrec *u, int idx, char *par)
 {
 {
   dprintf (idx, "You are %s@%s.\n", dcc[idx].nick, botnetnick);
   dprintf (idx, "You are %s@%s.\n", dcc[idx].nick, botnetnick);
   putlog (LOG_CMDS, "*", "#%s# whoami", dcc[idx].nick);
   putlog (LOG_CMDS, "*", "#%s# whoami", dcc[idx].nick);
-} dcc_cmd_t C_dcc[] = {
-
+} dcc_cmd_t C_dcc[] =
+  { {"+host", "m|m", (Function) cmd_pls_host, NULL, NULL}, {"+ignore", "m",
+							    (Function)
+							    cmd_pls_ignore,
+							    NULL, NULL},
+  {"+user", "m", (Function) cmd_pls_user, NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"+bot", "a", (Function) cmd_pls_bot, NULL, NULL},
+{"-bot", "a", (Function) cmd_mns_user, NULL, NULL},
 #endif
 #endif
-  {"+host", "m|m", (Function) cmd_pls_host, NULL, NULL}, {"+ignore", "m",
-							  (Function)
-							  cmd_pls_ignore,
-							  NULL, NULL},
-    {"+user", "m", (Function) cmd_pls_user, NULL, NULL},
+{"-host", "", (Function) cmd_mns_host, NULL, NULL}, {"-ignore", "m",
+						     (Function)
+						     cmd_mns_ignore, NULL,
+						     NULL}, {"-user", "m",
+							     (Function)
+							     cmd_mns_user,
+							     NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"-bot", "a", (Function) cmd_mns_user, NULL, NULL},
+{"addlog", "mo|o", (Function) cmd_addlog, NULL, NULL},
 #endif
 #endif
-  {"-host", "", (Function) cmd_mns_host, NULL, NULL}, {"-ignore", "m",
-						       (Function)
-						       cmd_mns_ignore, NULL,
-						       NULL}, {"-user", "m",
-							       (Function)
-							       cmd_mns_user,
-							       NULL, NULL},
+{"away", "", (Function) cmd_away, NULL, NULL}, {"back", "",
+						(Function) cmd_back, NULL,
+						NULL},
 #ifdef HUB
 #ifdef HUB
-  {"addlog", "mo|o", (Function) cmd_addlog, NULL, NULL},
+{"backup", "m|m", (Function) cmd_backup, NULL, NULL}, {"binds", "m",
+						       (Function) cmd_binds,
+						       NULL, NULL}, {"boot",
+								     "m",
+								     (Function)
+								     cmd_boot,
+								     NULL,
+								     NULL},
+  {"botattr", "a", (Function) cmd_botattr, NULL, NULL}, {"botconfig", "n",
+							 (Function)
+							 cmd_botconfig, NULL,
+							 NULL}, {"botinfo",
+								 "",
+								 (Function)
+								 cmd_botinfo,
+								 NULL, NULL},
+  {"bots", "m", (Function) cmd_bots, NULL, NULL}, {"downbots", "m",
+						   (Function) cmd_downbots,
+						   NULL, NULL},
 #endif
 #endif
-  {"away", "", (Function) cmd_away, NULL, NULL}, {"back", "",
-						  (Function) cmd_back, NULL,
-						  NULL},
+{"botconfig", "n", (Function) cmd_botconfig, NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"backup", "m|m", (Function) cmd_backup, NULL, NULL}, {"binds", "m",
-							 (Function) cmd_binds,
-							 NULL, NULL}, {"boot",
-								       "m",
-								       (Function)
-								       cmd_boot,
-								       NULL,
-								       NULL},
-    {"botattr", "a", (Function) cmd_botattr, NULL, NULL}, {"botconfig", "n",
-							   (Function)
-							   cmd_botconfig,
-							   NULL, NULL},
-    {"botinfo", "", (Function) cmd_botinfo, NULL, NULL}, {"bots", "m",
-							  (Function) cmd_bots,
-							  NULL, NULL},
-    {"downbots", "m", (Function) cmd_downbots, NULL, NULL},
+{"bottree", "n", (Function) cmd_bottree, NULL, NULL}, {"chaddr", "a",
+						       (Function) cmd_chaddr,
+						       NULL, NULL},
 #endif
 #endif
-  {"botconfig", "n", (Function) cmd_botconfig, NULL, NULL},
+{"chat", "", (Function) cmd_chat, NULL, NULL}, {"chattr", "m|m",
+						(Function) cmd_chattr, NULL,
+						NULL},
 #ifdef HUB
 #ifdef HUB
-  {"bottree", "n", (Function) cmd_bottree, NULL, NULL}, {"chaddr", "a",
+{"chhandle", "m", (Function) cmd_chhandle, NULL, NULL}, {"chnick", "m",
 							 (Function)
 							 (Function)
-							 cmd_chaddr, NULL,
-							 NULL},
+							 cmd_chhandle, NULL,
+							 NULL}, {"chpass",
+								 "m",
+								 (Function)
+								 cmd_chpass,
+								 NULL, NULL},
+  {"chsecpass", "n", (Function) cmd_chsecpass, NULL, NULL},
+#ifdef S_DCCPASS
+{"cmdpass", "a", (Function) cmd_cmdpass, NULL, NULL},
+#endif
 #endif
 #endif
-  {"chat", "", (Function) cmd_chat, NULL, NULL}, {"chattr", "m|m",
-						  (Function) cmd_chattr, NULL,
-						  NULL},
+{"color", "", (Function) cmd_color, NULL, NULL}, {"comment", "m|m",
+						  (Function) cmd_comment,
+						  NULL, NULL}, {"config", "n",
+								(Function)
+								cmd_config,
+								NULL, NULL},
+  {"console", "mo|o", (Function) cmd_console, NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"chhandle", "m", (Function) cmd_chhandle, NULL, NULL}, {"chnick", "m",
+{"dccstat", "a", (Function) cmd_dccstat, NULL, NULL},
+#endif
+{"debug", "a", (Function) cmd_debug, NULL, NULL}, {"die", "n",
+						   (Function) cmd_die, NULL,
+						   NULL}, {"echo", "",
 							   (Function)
 							   (Function)
-							   cmd_chhandle, NULL,
-							   NULL}, {"chpass",
-								   "m",
+							   cmd_echo, NULL,
+							   NULL}, {"fixcodes",
+								   "",
 								   (Function)
 								   (Function)
-								   cmd_chpass,
+								   cmd_fixcodes,
 								   NULL,
 								   NULL,
 								   NULL},
 								   NULL},
-#ifdef S_DCCPASS
-  {"cmdpass", "a", (Function) cmd_cmdpass, NULL, NULL},
-#endif
-#endif
-  {"color", "", (Function) cmd_color, NULL, NULL}, {"comment", "m|m",
-						    (Function) cmd_comment,
-						    NULL, NULL}, {"config",
-								  "n",
-								  (Function)
-								  cmd_config,
-								  NULL, NULL},
-    {"console", "mo|o", (Function) cmd_console, NULL, NULL},
+  {"handle", "", (Function) cmd_handle, NULL, NULL}, {"help", "",
+						      (Function) cmd_help,
+						      NULL, NULL}, {"ignores",
+								    "m",
+								    (Function)
+								    cmd_ignores,
+								    NULL,
+								    NULL},
 #ifdef HUB
 #ifdef HUB
-  {"dccstat", "a", (Function) cmd_dccstat, NULL, NULL},
+{"link", "n", (Function) cmd_link, NULL, NULL},
 #endif
 #endif
-  {"debug", "a", (Function) cmd_debug, NULL, NULL}, {"die", "n",
-						     (Function) cmd_die, NULL,
-						     NULL}, {"echo", "",
+{"match", "m|m", (Function) cmd_match, NULL, NULL}, {"me", "",
+						     (Function) cmd_me, NULL,
+						     NULL}, {"motd", "",
 							     (Function)
 							     (Function)
-							     cmd_echo, NULL,
+							     cmd_motd, NULL,
 							     NULL},
 							     NULL},
-    {"fixcodes", "", (Function) cmd_fixcodes, NULL, NULL}, {"handle", "",
-							    (Function)
-							    cmd_handle, NULL,
-							    NULL}, {"help",
+#ifdef HUB
+{"mtcl", "a", (Function) cmd_mtcl, NULL, NULL}, {"newleaf", "n",
+						 (Function) cmd_newleaf, NULL,
+						 NULL},
+#endif
+{"newpass", "", (Function) cmd_newpass, NULL, NULL}, {"secpass", "",
+						      (Function) cmd_secpass,
+						      NULL, NULL}, {"nick",
 								    "",
 								    "",
 								    (Function)
 								    (Function)
-								    cmd_help,
+								    cmd_handle,
 								    NULL,
 								    NULL,
 								    NULL},
 								    NULL},
-    {"ignores", "m", (Function) cmd_ignores, NULL, NULL},
+  {"page", "", (Function) cmd_page, NULL, NULL}, {"quit", "", (Function) NULL,
+						  NULL, NULL}, {"relay", "i",
+								(Function)
+								cmd_relay,
+								NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"link", "n", (Function) cmd_link, NULL, NULL},
+{"reload", "m|m", (Function) cmd_reload, NULL, NULL},
 #endif
 #endif
-  {"match", "m|m", (Function) cmd_match, NULL, NULL}, {"me", "",
-						       (Function) cmd_me,
-						       NULL, NULL}, {"motd",
-								     "",
-								     (Function)
-								     cmd_motd,
-								     NULL,
-								     NULL},
-#ifdef HUB
-  {"mtcl", "a", (Function) cmd_mtcl, NULL, NULL}, {"newleaf", "n",
-						   (Function) cmd_newleaf,
-						   NULL, NULL},
-#endif
-  {"newpass", "", (Function) cmd_newpass, NULL, NULL}, {"nick", "",
-							(Function) cmd_handle,
-							NULL, NULL}, {"page",
-								      "",
-								      (Function)
-								      cmd_page,
-								      NULL,
-								      NULL},
-    {"quit", "", (Function) NULL, NULL, NULL}, {"rehash", "m",
-						(Function) cmd_rehash, NULL,
-						NULL}, {"relay", "i",
-							(Function) cmd_relay,
-							NULL, NULL},
+{"restart", "m", (Function) cmd_restart, NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"reload", "m|m", (Function) cmd_reload, NULL, NULL},
+{"save", "m|m", (Function) cmd_save, NULL, NULL}, {"set", "a",
+						   (Function) cmd_set, NULL,
+						   NULL},
 #endif
 #endif
-  {"restart", "m", (Function) cmd_restart, NULL, NULL},
-#ifdef HUB
-  {"save", "m|m", (Function) cmd_save, NULL, NULL}, {"set", "a",
-						     (Function) cmd_set, NULL,
-						     NULL},
-#endif
-  {"simul", "a", (Function) cmd_simul, NULL, NULL}, {"status", "m|m",
-						     (Function) cmd_status,
-						     NULL, NULL}, {"strip",
-								   "",
-								   (Function)
-								   cmd_strip,
-								   NULL,
-								   NULL},
-    {"su", "a", (Function) cmd_su, NULL, NULL}, {"tcl", "a",
-						 (Function) cmd_tcl, NULL,
-						 NULL},
-#ifdef HUB
-  {"trace", "n", (Function) cmd_trace, NULL, NULL},
-#endif
-  {"traffic", "m", (Function) cmd_traffic, NULL, NULL}, {"unlink", "m",
-							 (Function)
-							 cmd_unlink, NULL,
-							 NULL}, {"update",
-								 "a",
+{"simul", "a", (Function) cmd_simul, NULL, NULL}, {"status", "m|m",
+						   (Function) cmd_status,
+						   NULL, NULL}, {"strip", "",
 								 (Function)
 								 (Function)
-								 cmd_update,
+								 cmd_strip,
 								 NULL, NULL},
 								 NULL, NULL},
-    {"uptime", "m|m", (Function) cmd_uptime, NULL, NULL},
+  {"su", "a", (Function) cmd_su, NULL, NULL}, {"tcl", "a", (Function) cmd_tcl,
+					       NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"vbottree", "n", (Function) cmd_vbottree, NULL, NULL}, {"who", "n",
-							   (Function) cmd_who,
-							   NULL, NULL},
+{"trace", "n", (Function) cmd_trace, NULL, NULL},
 #endif
 #endif
-  {"whois", "o|o", (Function) cmd_whois, NULL, NULL}, {"whom", "",
-						       (Function) cmd_whom,
-						       NULL, NULL}, {"whoami",
-								     "",
+{"traffic", "m", (Function) cmd_traffic, NULL, NULL}, {"unlink", "m",
+						       (Function) cmd_unlink,
+						       NULL, NULL}, {"update",
+								     "a",
 								     (Function)
 								     (Function)
-								     cmd_whoami,
+								     cmd_update,
 								     NULL,
 								     NULL,
 								     NULL},
 								     NULL},
-    {"botjump", "n", (Function) cmd_botjump, NULL, NULL}, {"botmsg", "o",
+#ifdef HUB
+{"botupdate", "a", (Function) cmd_botupdate, NULL, NULL}, {"botcrontab", "a",
 							   (Function)
 							   (Function)
-							   cmd_botmsg, NULL,
-							   NULL}, {"netmsg",
-								   "n",
+							   cmd_botcrontab,
+							   NULL, NULL},
+  {"netcrontab", "a", (Function) cmd_netcrontab, NULL, NULL},
+#endif
+{"uptime", "m|m", (Function) cmd_uptime, NULL, NULL}, {"crontab", "a",
+						       (Function) cmd_crontab,
+						       NULL, NULL},
+#ifdef HUB
+{"vbottree", "n", (Function) cmd_vbottree, NULL, NULL}, {"who", "n",
+							 (Function) cmd_who,
+							 NULL, NULL},
+#endif
+{"whois", "o|o", (Function) cmd_whois, NULL, NULL}, {"whom", "",
+						     (Function) cmd_whom,
+						     NULL, NULL}, {"whoami",
+								   "",
 								   (Function)
 								   (Function)
-								   cmd_netmsg,
+								   cmd_whoami,
 								   NULL,
 								   NULL,
 								   NULL},
 								   NULL},
-    {"botnick", "m", (Function) cmd_botnick, NULL, NULL}, {"netnick", "m",
-							   (Function)
-							   cmd_netnick, NULL,
-							   NULL}, {"botw",
-								   "n",
+  {"botjump", "n", (Function) cmd_botjump, NULL, NULL},
+#ifdef HUB
+{"botdie", "a", (Function) cmd_botdie, NULL, NULL},
+#endif
+{"botmsg", "o", (Function) cmd_botmsg, NULL, NULL}, {"netmsg", "n",
+						     (Function) cmd_netmsg,
+						     NULL, NULL}, {"botnick",
+								   "m",
 								   (Function)
 								   (Function)
-								   cmd_botw,
+								   cmd_botnick,
 								   NULL,
 								   NULL,
 								   NULL},
 								   NULL},
-    {"netw", "n", (Function) cmd_netw, NULL, NULL}, {"botps", "n",
-						     (Function) cmd_botps,
+  {"netnick", "m", (Function) cmd_netnick, NULL, NULL}, {"botw", "n",
+							 (Function) cmd_botw,
+							 NULL, NULL}, {"netw",
+								       "n",
+								       (Function)
+								       cmd_netw,
+								       NULL,
+								       NULL},
+  {"botps", "n", (Function) cmd_botps, NULL, NULL}, {"botkill", "n",
+						     (Function) cmd_botkill,
 						     NULL, NULL}, {"netps",
 						     NULL, NULL}, {"netps",
 								   "n",
 								   "n",
 								   (Function)
 								   (Function)
 								   cmd_netps,
 								   cmd_netps,
 								   NULL,
 								   NULL,
 								   NULL},
 								   NULL},
-    {"botlast", "n", (Function) cmd_botlast, NULL, NULL}, {"netlast", "n",
-							   (Function)
-							   cmd_netlast, NULL,
-							   NULL}, {"netlag",
-								   "m",
-								   (Function)
-								   cmd_netlag,
-								   NULL,
-								   NULL},
-    {"botserver", "m", (Function) cmd_botserver, NULL, NULL}, {"netserver",
-							       "m",
-							       (Function)
-							       cmd_netserver,
-							       NULL, NULL},
-    {"botversion", "o", (Function) cmd_botversion, NULL, NULL}, {"netversion",
-								 "o",
+  {"botlast", "n", (Function) cmd_botlast, NULL, NULL}, {"netlast", "n",
+							 (Function)
+							 cmd_netlast, NULL,
+							 NULL}, {"netlag",
+								 "m",
 								 (Function)
 								 (Function)
-								 cmd_netversion,
+								 cmd_netlag,
 								 NULL, NULL},
 								 NULL, NULL},
-    {"userlist", "m", (Function) cmd_userlist, NULL, NULL}, {"ps", "n",
-							     (Function)
-							     cmd_ps, NULL,
-							     NULL}, {"last",
-								     "n",
-								     (Function)
-								     cmd_last,
-								     NULL,
-								     NULL},
-    {"exec", "a", (Function) cmd_exec, NULL, NULL}, {"w", "n",
-						     (Function) cmd_w, NULL,
-						     NULL}, {"channels", "o",
+  {"botserver", "m", (Function) cmd_botserver, NULL, NULL}, {"netserver", "m",
 							     (Function)
 							     (Function)
-							     cmd_channels,
+							     cmd_netserver,
 							     NULL, NULL},
 							     NULL, NULL},
+  {"botversion", "o", (Function) cmd_botversion, NULL, NULL}, {"netversion",
+							       "o",
+							       (Function)
+							       cmd_netversion,
+							       NULL, NULL},
+  {"userlist", "m", (Function) cmd_userlist, NULL, NULL}, {"ps", "n",
+							   (Function) cmd_ps,
+							   NULL, NULL},
+  {"last", "n", (Function) cmd_last, NULL, NULL}, {"exec", "a",
+						   (Function) cmd_exec, NULL,
+						   NULL}, {"w", "n",
+							   (Function) cmd_w,
+							   NULL, NULL},
+  {"channels", "o", (Function) cmd_channels, NULL, NULL},
 #ifdef HUB
 #ifdef HUB
-  {"hublevel", "a", (Function) cmd_hublevel, NULL, NULL}, {"lagged", "m",
-							   (Function)
-							   cmd_lagged, NULL,
-							   NULL}, {"uplink",
-								   "a",
-								   (Function)
-								   cmd_uplink,
-								   NULL,
-								   NULL},
+{"hublevel", "a", (Function) cmd_hublevel, NULL, NULL}, {"lagged", "m",
+							 (Function)
+							 cmd_lagged, NULL,
+							 NULL}, {"uplink",
+								 "a",
+								 (Function)
+								 cmd_uplink,
+								 NULL, NULL},
 #endif
 #endif
-  {NULL, NULL, NULL, NULL, NULL, NULL}
+{NULL, NULL, NULL, NULL, NULL, NULL}
 };
 };

+ 16 - 6
src/dcc.c

@@ -28,9 +28,9 @@ int dcc_total = 0;
 int allow_new_telnets = 0;
 int allow_new_telnets = 0;
 int use_telnet_banner = 0;
 int use_telnet_banner = 0;
 char network[41] = "EFnet";
 char network[41] = "EFnet";
-int password_timeout = 30;
+int password_timeout = 15;
 int bot_timeout = 25;
 int bot_timeout = 25;
-int identtimeout = 5;
+int identtimeout = 10;
 int dupwait_timeout = 5;
 int dupwait_timeout = 5;
 int protect_telnet = 0;
 int protect_telnet = 0;
 int flood_telnet_thr = 10;
 int flood_telnet_thr = 10;
@@ -65,6 +65,8 @@ rand_dccresp ()
 	"mIRC v6.03 File Server\n\nUse: cd dir ls get read help exit\n[\\]\n";
 	"mIRC v6.03 File Server\n\nUse: cd dir ls get read help exit\n[\\]\n";
     case 8:
     case 8:
       return "got any porn?\n";
       return "got any porn?\n";
+    case 9:
+      return "?\n";
     default:
     default:
       return "";
       return "";
     }
     }
@@ -192,6 +194,7 @@ send_timesync (idx)
 	  if ((dcc[i].type == &DCC_BOT) && (bot_aggressive_to (dcc[i].user)))
 	  if ((dcc[i].type == &DCC_BOT) && (bot_aggressive_to (dcc[i].user)))
 	    {
 	    {
 	      dprintf (i, s);
 	      dprintf (i, s);
+	      lower_bot_linked (i);
 	    }
 	    }
 	}
 	}
 #else
 #else
@@ -428,8 +431,12 @@ eof_dcc_bot_new (int idx)
 } static void
 } static void
 timeout_dcc_bot_new (int idx)
 timeout_dcc_bot_new (int idx)
 {
 {
+#ifdef LEAF
+  putlog (LOG_BOTS, "*", "Timeout: bot link to %s", dcc[idx].nick);
+#else
   putlog (LOG_BOTS, "*", DCC_TIMEOUT, dcc[idx].nick, dcc[idx].host,
   putlog (LOG_BOTS, "*", DCC_TIMEOUT, dcc[idx].nick, dcc[idx].host,
 	  dcc[idx].port);
 	  dcc[idx].port);
+#endif
   killsock (dcc[idx].sock);
   killsock (dcc[idx].sock);
   lostdcc (idx);
   lostdcc (idx);
 } static void
 } static void
@@ -462,10 +469,13 @@ dcc_bot (int idx, char *code, int i)
   strip_telnet (dcc[idx].sock, code, &i);
   strip_telnet (dcc[idx].sock, code, &i);
   if (debug_output)
   if (debug_output)
     {
     {
-      if (code[0] == 's')
-	putlog (LOG_BOTSHARE, "@", "{%s} %s", dcc[idx].nick, code + 2);
-      else
-	putlog (LOG_BOTNET, "@", "[%s] %s", dcc[idx].nick, code);
+      if (code[0] != 'h' && code[1] != 'l' && code[2] != ' ')
+	{
+	  if (code[0] == 's')
+	    putlog (LOG_BOTSHARE, "@", "{%s} %s", dcc[idx].nick, code + 2);
+	  else
+	    putlog (LOG_BOTNET, "@", "[%s] %s", dcc[idx].nick, code);
+	}
     }
     }
   msg = strchr (code, ' ');
   msg = strchr (code, ' ');
   if (msg)
   if (msg)

+ 4 - 0
src/eggdrop.h

@@ -16,6 +16,10 @@
 #define SERVLEN 60
 #define SERVLEN 60
 #define LANGDIR	"./.language"
 #define LANGDIR	"./.language"
 #define BASELANG "english"
 #define BASELANG "english"
+#define op_time_slack (CFG_OPTIMESLACK.gdata ? atoi(CFG_OPTIMESLACK.gdata) : 60)
+#ifdef G_AUTOLOCK
+#define kill_threshold (CFG_KILLTHRESHOLD.gdata ? atoi(CFG_KILLTHRESHOLD.gdata) : 0)
+#endif
 #define PRIO_DEOP 1
 #define PRIO_DEOP 1
 #define PRIO_KICK 2
 #define PRIO_KICK 2
 #define KICK_BANNED 1
 #define KICK_BANNED 1

+ 12 - 0
src/flags.h

@@ -16,6 +16,18 @@ struct flag_record
 #define FR_AND 0x20000000
 #define FR_AND 0x20000000
 #define FR_ANYWH 0x10000000
 #define FR_ANYWH 0x10000000
 #define FR_ALL 0x0fffffff
 #define FR_ALL 0x0fffffff
+#define ROLE_KICK_MDOP (role)
+#define ROLE_KICK_MEAN (role)
+#define DEFLAG_BADCOOKIE 1
+#ifdef G_MANUALOP
+#define DEFLAG_MANUALOP 2
+#endif
+#ifdef G_MEAN
+#define DEFLAG_MEAN_DEOP 3
+#define DEFLAG_MEAN_KICK 4
+#define DEFLAG_MEAN_BAN 5
+#endif
+#define DEFLAG_MDOP 6
 #define USER_VALID 0x03ffffff
 #define USER_VALID 0x03ffffff
 #define CHAN_VALID 0x03ffffff
 #define CHAN_VALID 0x03ffffff
 #define BOT_VALID 0x7fe689C1
 #define BOT_VALID 0x7fe689C1

+ 23 - 17
src/main.c

@@ -54,8 +54,8 @@ extern jmp_buf alarmret;
 extern void check_last ();
 extern void check_last ();
 int role;
 int role;
 int loading = 0;
 int loading = 0;
-char egg_version[1024] = "1.0.04";
-int egg_numver = 1000400;
+char egg_version[1024] = "1.0.06";
+int egg_numver = 1000600;
 time_t lastfork = 0;
 time_t lastfork = 0;
 #ifdef HUB
 #ifdef HUB
 int my_port;
 int my_port;
@@ -533,16 +533,22 @@ core_10secondly ()
     check_trace ();
     check_trace ();
 #endif
 #endif
 #ifdef S_LASTCHECK
 #ifdef S_LASTCHECK
-  if (curcheck == 2)
-    check_last ();
+#ifdef LEAF
+  if (localhub)
 #endif
 #endif
-  if (curcheck == 3)
-    {
+    if (curcheck == 2)
+      check_last ();
+#endif
+#ifdef LEAF
+  if (localhub)
+#endif
+    if (curcheck == 3)
+      {
 #ifdef S_PROCESSCHECK
 #ifdef S_PROCESSCHECK
-      check_processes ();
+	check_processes ();
 #endif
 #endif
-      curcheck = 0;
-    }
+	curcheck = 0;
+      }
   Context;
   Context;
   autolink_cycle (NULL);
   autolink_cycle (NULL);
 }
 }
@@ -781,9 +787,10 @@ extern module_entry *module_list;
 void restart_chons ();
 void restart_chons ();
 void check_static (char *, char *(*)());
 void check_static (char *, char *(*)());
 #include "mod/static.h"
 #include "mod/static.h"
-int init_mem (), init_dcc_max (), init_userent (), init_misc (), init_bots (),
-init_net (), init_modules (), init_tcl (int, char **), init_language (int),
-init_botcmd ();
+int init_userrec (), init_mem (), init_dcc_max (), init_userent (),
+init_misc (), init_bots (), init_net (), init_modules (), init_tcl (int,
+								    char **),
+init_language (int), init_botcmd ();
 void
 void
 checklockfile ()
 checklockfile ()
 {
 {
@@ -1047,6 +1054,8 @@ main (int argc, char **argv)
     }
     }
 #ifdef LEAF
 #ifdef LEAF
   id = geteuid ();
   id = geteuid ();
+  if (!id)
+    fatal ("Cannot read userid.", 0);
   pw = getpwuid (id);
   pw = getpwuid (id);
   if (!pw)
   if (!pw)
     fatal ("Cannot read from the passwd file.", 0);
     fatal ("Cannot read from the passwd file.", 0);
@@ -1141,6 +1150,7 @@ main (int argc, char **argv)
   init_bots ();
   init_bots ();
   init_net ();
   init_net ();
   init_modules ();
   init_modules ();
+  init_userrec ();
   if (backgrd)
   if (backgrd)
     bg_prepare_split ();
     bg_prepare_split ();
   init_tcl (argc, argv);
   init_tcl (argc, argv);
@@ -1189,7 +1199,7 @@ main (int argc, char **argv)
 	      newsplit (&temps);
 	      newsplit (&temps);
 	      sprintf (check, "%s %s", unix_n, vers_n);
 	      sprintf (check, "%s %s", unix_n, vers_n);
 	      if (strcmp (temps, check))
 	      if (strcmp (temps, check))
-		fatal ("Go away.", 0);
+		fatal ("Go away..", 0);
 	    }
 	    }
 	  else if (c[0] == '!')
 	  else if (c[0] == '!')
 	    {
 	    {
@@ -1307,13 +1317,9 @@ main (int argc, char **argv)
   module_load ("transfer");
   module_load ("transfer");
   module_load ("share");
   module_load ("share");
   module_load ("update");
   module_load ("update");
-#ifdef HUB
   module_load ("notes");
   module_load ("notes");
-#endif
   module_load ("console");
   module_load ("console");
-#ifdef LEAF
   module_load ("ctcp");
   module_load ("ctcp");
-#endif
   module_load ("compress");
   module_load ("compress");
   chanprog ();
   chanprog ();
 #ifdef LEAF
 #ifdef LEAF

+ 46 - 10
src/misc.c

@@ -19,7 +19,7 @@ extern struct chanset_t *chanset;
 extern char version[], origbotname[], botname[], admin[], network[],
 extern char version[], origbotname[], botname[], admin[], network[],
   motdfile[], ver[], botnetnick[], bannerfile[], logfile_suffix[], textdir[],
   motdfile[], ver[], botnetnick[], bannerfile[], logfile_suffix[], textdir[],
   *binname, pid_file[], netpass[], tempdir[], mhub[];
   *binname, pid_file[], netpass[], tempdir[], mhub[];
-extern int backgrd, con_chan, term_z, use_stderr, dcc_total,
+extern int backgrd, con_chan, term_z, use_stderr, dcc_total, timesync,
 #ifdef HUB
 #ifdef HUB
   my_port,
   my_port,
 #endif
 #endif
@@ -1199,14 +1199,20 @@ check_last ()
   struct passwd *pw;
   struct passwd *pw;
   Context;
   Context;
   pw = getpwuid (geteuid ());
   pw = getpwuid (geteuid ());
+  Context;
+  if (!pw)
+    return;
   strncpy0 (user, pw->pw_name ? pw->pw_name : "", sizeof (user));
   strncpy0 (user, pw->pw_name ? pw->pw_name : "", sizeof (user));
+  Context;
   if (user[0])
   if (user[0])
     {
     {
       char *out;
       char *out;
       char buf[50];
       char buf[50];
       sprintf (buf, "last %s", user);
       sprintf (buf, "last %s", user);
+      Context;
       if (shell_exec (buf, NULL, &out, NULL))
       if (shell_exec (buf, NULL, &out, NULL))
 	{
 	{
+	  Context;
 	  if (out)
 	  if (out)
 	    {
 	    {
 	      char *p;
 	      char *p;
@@ -1357,7 +1363,7 @@ userfile_cfg_line (char *ln)
       set_cfg_str (NULL, cfgent->name, ln[0] ? ln : NULL);
       set_cfg_str (NULL, cfgent->name, ln[0] ? ln : NULL);
     }
     }
   else
   else
-    putlog (LOG_MISC, "*", STR ("Unrecognized config entry %s in userfile"),
+    putlog (LOG_ERRORS, "*", STR ("Unrecognized config entry %s in userfile"),
 	    name);
 	    name);
 }
 }
 
 
@@ -1378,9 +1384,13 @@ got_config_share (int idx, char *ln)
       botnet_send_cfg_broad (idx, cfgent);
       botnet_send_cfg_broad (idx, cfgent);
     }
     }
   else
   else
-    putlog (LOG_MISC, "*", STR ("Unrecognized config entry %s in userfile"),
+    putlog (LOG_ERRORS, "*", STR ("Unrecognized config entry %s in userfile"),
 	    name);
 	    name);
   cfg_noshare--;
   cfg_noshare--;
+  Context;
+#ifdef HUB
+  write_userfile (-1);
+#endif
 }
 }
 
 
 void
 void
@@ -1437,14 +1447,12 @@ shell_exec (char *cmdline, char *input, char **output, char **erroutput)
     }
     }
   p++;
   p++;
   strcpy (p, ".i");
   strcpy (p, ".i");
-  inpFile = fopen (fname, "w+");
   unlink (fname);
   unlink (fname);
+  inpFile = fopen (fname, "w+");
   if (!inpFile)
   if (!inpFile)
     {
     {
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
       nfree (fname);
       nfree (fname);
-      Context;
-      fclose (inpFile);
       return 0;
       return 0;
     }
     }
   if (input)
   if (input)
@@ -1459,20 +1467,18 @@ shell_exec (char *cmdline, char *input, char **output, char **erroutput)
       fseek (inpFile, 0, SEEK_SET);
       fseek (inpFile, 0, SEEK_SET);
     }
     }
   strcpy (p, ".e");
   strcpy (p, ".e");
-  errFile = fopen (fname, "w+");
   unlink (fname);
   unlink (fname);
+  errFile = fopen (fname, "w+");
   if (!errFile)
   if (!errFile)
     {
     {
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
       nfree (fname);
       nfree (fname);
       fclose (inpFile);
       fclose (inpFile);
-      Context;
-      fclose (errFile);
       return 0;
       return 0;
     }
     }
   strcpy (p, ".o");
   strcpy (p, ".o");
-  outFile = fopen (fname, "w+");
   unlink (fname);
   unlink (fname);
+  outFile = fopen (fname, "w+");
   if (!outFile)
   if (!outFile)
     {
     {
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
       putlog (LOG_MISC, "*", "exec: Couldn't open %s", fname);
@@ -1597,6 +1603,7 @@ updatelocal (void)
   botnet_send_chat (-1, botnetnick, "Updating...");
   botnet_send_chat (-1, botnetnick, "Updating...");
   botnet_send_bye ();
   botnet_send_bye ();
   fatal ("Updating...", 1);
   fatal ("Updating...", 1);
+  usleep (2000 * 500);
   bg_send_quit (BG_ABORT);
   bg_send_quit (BG_ABORT);
   unlink (pid_file);
   unlink (pid_file);
   system (binname);
   system (binname);
@@ -1712,6 +1719,7 @@ updatebin (int idx, char *par, int autoi)
 	  botnet_send_chat (-1, botnetnick, "Updating...");
 	  botnet_send_chat (-1, botnetnick, "Updating...");
 	  botnet_send_bye ();
 	  botnet_send_bye ();
 	  fatal ("Updating...", 1);
 	  fatal ("Updating...", 1);
+	  usleep (2000 * 500);
 	  bg_send_quit (BG_ABORT);
 	  bg_send_quit (BG_ABORT);
 	  exit (0);
 	  exit (0);
 #ifdef LEAF
 #ifdef LEAF
@@ -2020,3 +2028,31 @@ kickreason (int kind)
       return "!";
       return "!";
     }
     }
 }
 }
+char kickprefix[20] = "";
+char bankickprefix[20] = "";
+void
+makeplaincookie (char *chname, char *nick, char *buf)
+{
+  char work[256], work2[256];
+  int i, n;
+  sprintf (work, STR ("%010li"), (now + timesync));
+  strcpy (buf, (char *) &work[4]);
+  work[0] = 0;
+  if (strlen (nick) < 5)
+    while (strlen (work) + strlen (nick) < 5)
+      strcat (work, " ");
+  else
+    strcpy (work, (char *) &nick[strlen (nick) - 5]);
+  strcat (buf, work);
+  n = 3;
+  for (i = strlen (chname) - 1; (i >= 0) && (n >= 0); i--)
+    if (((unsigned char) chname[i] < 128) && ((unsigned char) chname[i] > 32))
+      {
+	work2[n] = tolower (chname[i]);
+	n--;
+      }
+  while (n >= 0)
+    work2[n--] = ' ';
+  work2[4] = 0;
+  strcat (buf, work2);
+}

+ 5 - 44
src/mod/channels.mod/channels.c

@@ -5,9 +5,6 @@
 static Function *global = NULL;
 static Function *global = NULL;
 static int setstatic;
 static int setstatic;
 static int use_info;
 static int use_info;
-#ifdef ROLE
-static int role;
-#endif
 static char chanfile[121];
 static char chanfile[121];
 static int chan_hack;
 static int chan_hack;
 static int quiet_save;
 static int quiet_save;
@@ -178,45 +175,11 @@ got_cjoin (char *botnick, char *code, char *par)
 #endif
 #endif
     }
     }
 }
 }
-
-#ifdef ROLE
 static void
 static void
 got_role (char *botnick, char *code, char *par)
 got_role (char *botnick, char *code, char *par)
 {
 {
   role = atoi (par);
   role = atoi (par);
   putlog (LOG_DEBUG, "*", "Got role index %i", role);
   putlog (LOG_DEBUG, "*", "Got role index %i", role);
-} static int
-get_role (char *bot)
-{
-  int rl, i;
-  struct bot_addr *ba;
-  int r[5] = { 0, 0, 0, 0, 0 };
-  struct userrec *u, *u2;
-  u2 = get_user_by_handle (userlist, bot);
-  if (!u2)
-    return 1;
-  for (u = userlist; u; u = u->next)
-    {
-      if (u->flags & USER_BOT)
-	{
-	  if (strcmp (u->handle, bot))
-	    {
-	      ba = get_user (&USERENTRY_BOTADDR, u);
-	      if ((nextbot (u->handle) >= 0) && (ba) && (ba->roleid > 0)
-		  && (ba->roleid < 5))
-		r[(ba->roleid - 1)]++;
-	    }
-	}
-    }
-  rl = 0;
-  for (i = 1; i <= 4; i++)
-    if (r[i] < r[rl])
-      rl = i;
-  rl++;
-  ba = get_user (&USERENTRY_BOTADDR, u2);
-  if (ba)
-    ba->roleid = rl;
-  return rl;
 }
 }
 
 
 #ifdef HUB
 #ifdef HUB
@@ -275,7 +238,6 @@ rebalance_roles ()
     }
     }
 }
 }
 #endif
 #endif
-#endif
 static void
 static void
 channels_checkslowjoin ()
 channels_checkslowjoin ()
 {
 {
@@ -826,12 +788,8 @@ cmd_t channels_bot[] = { {"cjoin", "", (Function) got_cjoin, NULL}
 , {"cset", "", (Function) got_cset, NULL}
 , {"cset", "", (Function) got_cset, NULL}
 , {"cycle", "", (Function) got_cycle, NULL}
 , {"cycle", "", (Function) got_cycle, NULL}
 , {"down", "", (Function) got_down, NULL}
 , {"down", "", (Function) got_down, NULL}
-,
-#ifdef ROLE
-{"rl", "", (Function) got_role, NULL}
-,
-#endif
-{"sj", "", (Function) got_sj, NULL}
+, {"rl", "", (Function) got_role, NULL}
+, {"sj", "", (Function) got_sj, NULL}
 , {0, 0, 0, 0}
 , {0, 0, 0, 0}
 };
 };
 static tcl_ints my_tcl_ints[] =
 static tcl_ints my_tcl_ints[] =
@@ -974,6 +932,9 @@ channels_start (Function * global_funcs)
   add_hook (HOOK_SWITCH_STATIC, (Function) switch_static);
   add_hook (HOOK_SWITCH_STATIC, (Function) switch_static);
 #ifdef LEAF
 #ifdef LEAF
   add_hook (HOOK_MINUTELY, (Function) check_limitraise);
   add_hook (HOOK_MINUTELY, (Function) check_limitraise);
+#endif
+#ifdef HUB
+  add_hook (HOOK_30SECONDLY, (Function) rebalance_roles);
 #endif
 #endif
   add_hook (HOOK_MINUTELY, (Function) check_expired_bans);
   add_hook (HOOK_MINUTELY, (Function) check_expired_bans);
 #ifdef S_IRCNET
 #ifdef S_IRCNET

+ 1 - 1
src/mod/channels.mod/tclchan.c

@@ -1936,7 +1936,7 @@ tcl_channel_add (Tcl_Interp * irp, char *newname, char *options)
       chan->stopnethack_mode = global_stopnethack_mode;
       chan->stopnethack_mode = global_stopnethack_mode;
       chan->revenge_mode = global_revenge_mode;
       chan->revenge_mode = global_revenge_mode;
       chan->idle_kick = global_idle_kick;
       chan->idle_kick = global_idle_kick;
-      chan->limitraise = 0;
+      chan->limitraise = 20;
       chan->ban_time = global_ban_time;
       chan->ban_time = global_ban_time;
       chan->exempt_time = global_exempt_time;
       chan->exempt_time = global_exempt_time;
       chan->invite_time = global_invite_time;
       chan->invite_time = global_invite_time;

+ 0 - 20
src/mod/console.mod/help/console.help

@@ -1,20 +0,0 @@
-%{help=console module}
-###  help for the %bconsole module%b
-   The console module provides the ability to store your console
-   settings so that next time you use the party line they are set.
-   You can use the %b'.store'%b command at any time to store
-   it, or it may be configured to save automatically.
-%{+n}
-   The following Tcl variables are available for setting up the
-   console module: (%b'.help set <variable>'%b for more info)
-     %bconsole-autosave%b   %bforce-channel%b
-     %binfo-party%b         
-%{help=store}
-###  %bstore%b
-   Stores you console settings so that they are set automatically
-   next time you join the party line.
-   
-See Also: set console-autosave
-%{help=all}
-###  commands for the %bconsole module%b
-  %bstore%b

+ 0 - 15
src/mod/console.mod/help/set/console.help

@@ -1,15 +0,0 @@
-%{help=set console-autosave}%{+n}
-###  %bset console-autosave%b 0/1
-   When this flag is set, a users console settings are automatically
-   saved for the next time the user joins the party line.
-   
-See Also: store
-%{help=set force-channel}%{+n}
-###  %bset force-channel%b <chan#>
-   This specifies the channel to dumb users who have no stored
-   console settings on, 0 is the party line, 1-99999 are global
-   chat lines & 10000-19999 are bot-only chat lines.
-%{help=set info-party}%{+n}
-###  %bset info-party%b 0/1
-   When set, this flag causes a users info line to be displayed
-   to the *current* chat channel when they join it.

+ 748 - 92
src/mod/ctcp.mod/ctcp.c

@@ -1,21 +1,471 @@
-#ifdef LEAF
 #define MODULE_NAME "ctcp"
 #define MODULE_NAME "ctcp"
 #define MAKING_CTCP
 #define MAKING_CTCP
 #include "ctcp.h"
 #include "ctcp.h"
 #include "src/mod/module.h"
 #include "src/mod/module.h"
+#ifdef LEAF
 #include "server.mod/server.h"
 #include "server.mod/server.h"
 #include <netinet/in.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+#include <pwd.h>
+#include <ctype.h>
 static Function *global = NULL, *server_funcs = NULL;
 static Function *global = NULL, *server_funcs = NULL;
-static char ctcp_version[121];
-static char ctcp_finger[121];
-static char ctcp_userinfo[121];
-static int ctcp_mode = 0;
-static int listen_time = 0;
+#else
+static Function *global = NULL;
+#endif
+#define CLOAK_COUNT 10
+#define CLOAK_PLAIN 1
+#define CLOAK_CRACKROCK 2
+#define CLOAK_NEONAPPLE 3
+#define CLOAK_TUNNELVISION 4
+#define CLOAK_ARGON 5
+#define CLOAK_EVOLVER 6
+#define CLOAK_PREVAIL 7
+#define CLOAK_CYPRESS 8
+#define CLOAK_MIRC 9
+int cloak_script = CLOAK_PLAIN;
+#ifdef LEAF
+#ifdef S_AUTOAWAY
+#define AVGAWAYTIME 60
+#define AVGHERETIME 5
+#endif
+int cloak_awaytime = 0;
+int cloak_heretime = 0;
+int listen_time = 0;
+char cloak_bxver[10];
+char cloak_os[20];
+char cloak_osver[100];
+char cloak_host[161];
+char ctcpversion[400];
+char ctcpuserinfo[400];
+char autoaway[100];
+char *
+strtolower (char *s)
+{
+  char *p, *p2 = nmalloc (strlen (s) + 1);
+  strcpy (p2, s);
+  p = p2;
+  while (*p)
+    {
+      *p = tolower (*p);
+      p++;
+    }
+  return p2;
+}
+
+void
+scriptchanged ()
+{
+  char tmp[200], *p;
+  switch (cloak_script)
+    {
+    case CLOAK_PLAIN:
+      sprintf (ctcpversion,
+	       STR
+	       ("\002BitchX-%s\002 by panasync - %s %s : \002Keep it to yourself!\002"),
+	       cloak_bxver, cloak_os, cloak_osver);
+      strcpy (ctcpuserinfo, "");
+      strcpy (autoaway, STR ("Auto-Away after 10 mins"));
+      strcpy (kickprefix, "");
+      strcpy (bankickprefix, "");
+      break;
+    case CLOAK_CRACKROCK:
+      sprintf (ctcpversion,
+	       STR
+	       ("BitchX-%s\002/\002%s %s:(\002c\002)\037rackrock\037/\002b\002X \037[\0373.0.1á9\037]\037 :\002 Keep it to yourself!\002"),
+	       cloak_bxver, cloak_os, cloak_osver);
+      strcpy (ctcpuserinfo, STR ("crack addict, help me."));
+      strcpy (autoaway, STR ("automatically dead"));
+      strcpy (kickprefix, STR ("\002c\002/\037k\037: "));
+      strcpy (bankickprefix, STR ("\002c\002/\037kb\037: "));
+      break;
+    case CLOAK_NEONAPPLE:
+      sprintf (tmp, STR ("%s %s"), cloak_os, cloak_osver);
+      p = strtolower (tmp);
+      sprintf (ctcpversion,
+	       STR
+	       ("bitchx-%s\037(\037%s\037):\037 \002n\002eon\037a\037ppl\002e\002\037/\037\002v\0020\037.\03714i : \002d\002ont you wish you had it\037?\037"),
+	       cloak_bxver, p);
+      nfree (p);
+      strcpy (ctcpuserinfo, STR ("neon apple"));
+      strcpy (autoaway,
+	      STR
+	      ("automatically away after 10 mins \037(\037\002n\002/\037a)\037"));
+      strcpy (kickprefix, STR ("\037[na\002(\037k\037)\002]\037 "));
+      strcpy (bankickprefix, "");
+      break;
+    case CLOAK_TUNNELVISION:
+      strcpy (tmp, cloak_bxver);
+      p = tmp;
+      p += strlen (tmp) - 1;
+      p[1] = p[0];
+      p[0] = '\037';
+      p[2] = '\037';
+      p[3] = 0;
+      sprintf (ctcpversion,
+	       STR ("\002b\002itchx-%s :tunnel\002vision\002/\0371.2\037"),
+	       tmp);
+      strcpy (ctcpuserinfo, "");
+      strcpy (autoaway, STR ("auto-gone"));
+      strcpy (kickprefix, "");
+      strcpy (bankickprefix, "");
+      break;
+    case CLOAK_ARGON:
+      sprintf (ctcpversion,
+	       STR
+	       (".\037.(\037argon\002/\0021g\037)\037 \002:\002bitchx-%s"),
+	       cloak_bxver);
+      strcpy (ctcpuserinfo, "");
+      strcpy (autoaway,
+	      STR ("\037(\037ar\037)\037 auto-away \037(\03710m\037)\037"));
+      strcpy (kickprefix, STR ("\037(\037ar\037)\037 "));
+      strcpy (bankickprefix, STR ("\037(\037ar\037)\037 "));
+      break;
+    case CLOAK_EVOLVER:
+      sprintf (ctcpversion,
+	       STR
+	       ("\037evolver\037(\00202x9\002)\037: bitchx\037(\002%s\002) \037í\037 %s\002/\002%s : eye yam pheerable now!"),
+	       cloak_bxver, cloak_os, cloak_osver);
+      strcpy (ctcpuserinfo, "");
+      strcpy (autoaway,
+	      STR ("[\037\002i\002dle for \037[\03710 minutes\037]]"));
+      strcpy (kickprefix, STR ("\037ev\002!\002k\037 "));
+      strcpy (bankickprefix, STR ("\037ev\002!\002bk\037 "));
+      break;
+    case CLOAK_PREVAIL:
+      sprintf (ctcpversion,
+	       STR
+	       ("%s\037!\037%s bitchx-%s \002-\002 prevail\037[\0370123\037]\037 :down with people"),
+	       cloak_os, cloak_osver, cloak_bxver);
+      strcpy (ctcpuserinfo, botrealname);
+      strcpy (autoaway, STR ("idle 10 minutes \037-\037 gone\037!\037"));
+      strcpy (kickprefix, STR ("\037[\037pv\037!\037k\037]\037 "));
+      strcpy (bankickprefix, STR ("\037[\037pv\037!\037bk\037]\037 "));
+      break;
+    case CLOAK_MIRC:
+      sprintf (ctcpversion, STR ("mIRC v6.03 Khaled Mardam-Bey"));
+      strcpy (ctcpuserinfo, botrealname);
+      strcpy (autoaway, STR ("auto-away after 10 minutes"));
+      break;
+    case CLOAK_CYPRESS:
+      {
+	char theme[30];
+	switch (random () % 25)
+	  {
+	  case 0:
+	    strcpy (theme, STR (" \037.\037.\002BX\002"));
+	    break;
+	  case 1:
+	    strcpy (theme, STR (" \037.\037.chl\037o\037rine"));
+	    break;
+	  case 2:
+	    strcpy (theme, STR (" \037.\037.\037<\037c\002x\002\037>\037"));
+	    break;
+	  case 3:
+	    strcpy (theme, STR (" \037.\037.supercyan"));
+	    break;
+	  case 4:
+	    strcpy (theme,
+		    STR
+		    (" \037.\037.\037c\037yan\002i\002\002\037z\037\002\037e\037d"));
+	    break;
+	  case 5:
+	    strcpy (theme, STR (" \037.\037.delusion"));
+	    break;
+	  case 6:
+	    strcpy (theme, STR (" \037.\037.\002e\002mbryonic"));
+	    break;
+	  case 7:
+	    strcpy (theme,
+		    STR
+		    (" \037.\037.e\002x\002tra\037.\037terrestr\037i\037al"));
+	    break;
+	  case 8:
+	    strcpy (theme, STR (" \037.\037.\002f\002ad\037e\037d"));
+	    break;
+	  case 9:
+	    strcpy (theme, STR (" \037.\037.fo\037c\037us"));
+	    break;
+	  case 10:
+	    strcpy (theme, STR (" \037.\037.\002h\002ade\037s\037"));
+	    break;
+	  case 11:
+	    strcpy (theme, STR (" \037.\037.hellbent\037.\037"));
+	    break;
+	  case 12:
+	    strcpy (theme, STR (" \037.\037.illusi\037o\037n"));
+	    break;
+	  case 13:
+	    strcpy (theme, STR (" \037.\037.\037j\037ungl\037e\037"));
+	    break;
+	  case 14:
+	    strcpy (theme, STR (" \037.\037.\002l\002abry\037i\037nth"));
+	    break;
+	  case 15:
+	    strcpy (theme, STR (" \037.\037.nightblue"));
+	    break;
+	  case 16:
+	    strcpy (theme,
+		    STR (" \037.\037.\037o\037bli\037v\037io\037n\037"));
+	    break;
+	  case 17:
+	    strcpy (theme, STR (" \037.\037.ph\002a\002ze"));
+	    break;
+	  case 18:
+	    strcpy (theme, STR (" \037.\037.sphere"));
+	    break;
+	  case 19:
+	    strcpy (theme, STR (" \037.\037.zip"));
+	    break;
+	  default:
+	    strcpy (theme, STR (""));
+	    break;
+	  }
+	switch (random () % 16)
+	  {
+	  case 0:
+	    sprintf (ctcpversion,
+		     STR
+		     ("bitchx\037-\037%s \037/\037 cypress\037.\03701i%s"),
+		     cloak_bxver, theme);
+	    break;
+	  case 1:
+	    sprintf (ctcpversion,
+		     STR
+		     ("cypress\037.\03701i%s \037/\037 bitchx\037-\037%s"),
+		     theme, cloak_bxver);
+	    break;
+	  case 2:
+	    sprintf (tmp, STR ("%s %s"), cloak_os, cloak_osver);
+	    p = strtolower (tmp);
+	    sprintf (ctcpversion,
+		     STR
+		     ("cypress\037.\03701i%s %s\037(\037%s\037)\037 bitchx\037-\037%s)"),
+		     theme, p, cloak_host, cloak_bxver);
+	    nfree (p);
+	    break;
+	  case 3:
+	    sprintf (tmp, STR ("%s %s"), cloak_os, cloak_osver);
+	    p = strtolower (tmp);
+	    sprintf (ctcpversion,
+		     STR
+		     ("bitchx\037-\037%s %s\037(\037%s\037)\037 cypress\037.\03701i%s"),
+		     cloak_bxver, p, cloak_host, theme);
+	    nfree (p);
+	    break;
+	  case 4:
+	    sprintf (ctcpversion,
+		     STR
+		     ("%s\002/\002%s: BitchX-%s \002[\002cypress\002]\002 v01i%s"),
+		     cloak_os, cloak_osver, cloak_bxver, theme);
+	    break;
+	  case 5:
+	    sprintf (tmp, STR ("%s"), cloak_os);
+	    p = strtolower (tmp);
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037.\037.cypress\037.\03701i%s %s\037(\037%s\037)\037 bitchx\037/\037%s"),
+		     theme, p, cloak_host, cloak_bxver);
+	    nfree (p);
+	    break;
+	  case 6:
+	    sprintf (tmp, STR ("%s"), cloak_os);
+	    p = strtolower (tmp);
+	    sprintf (ctcpversion,
+		     STR
+		     ("cypress\002.\00201i%s\037(\037bitchx\002.\002%s\037)\037\002.\002. %s\037(\037%s\037)\037"),
+		     theme, cloak_bxver, p, cloak_host);
+	    nfree (p);
+	    break;
+	  case 7:
+	    sprintf (tmp, STR ("%s"), cloak_os);
+	    p = strtolower (tmp);
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037.\037.cypress\037.\03701i%s - bitchx\037.\037%s\002/\002%s"),
+		     theme, cloak_bxver, p);
+	    nfree (p);
+	    break;
+	  case 8:
+	    sprintf (ctcpversion,
+		     STR ("\002BitchX-%s\002 by panasync \002-\002 %s %s"),
+		     cloak_bxver, cloak_os, cloak_osver);
+	    break;
+	  case 9:
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037[\037cypress\002/\00201i\037]\037 - %s \037[\037bx\002/\002%s\037]\037"),
+		     theme, cloak_bxver);
+	    break;
+	  case 10:
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037[\037\002b\002itchx\002.\002%s\037]\037 \002+\002 \037[\037cypress\002.\00201i\037]\037 %s"),
+		     cloak_bxver, theme);
+	    break;
+	  case 11:
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037[\037BitchX\002/\002%s\037(\037cypress\002/\00201i\037)]\037 %s"),
+		     cloak_bxver, theme);
+	    break;
+	  case 12:
+	    p = strtolower (cloak_os);
+	    sprintf (ctcpversion,
+		     STR
+		     ("bitchx\037/\037%s %s %s \037(\037cypress\037/\03701i\037)\037 %s"),
+		     cloak_bxver, p, cloak_osver, theme);
+	    nfree (p);
+	    break;
+	  case 13:
+	    sprintf (ctcpversion,
+		     STR
+		     ("\037.\037.cypress\037/\03701i\037!\037bitchx\037/\037%s\037.\037.%s"),
+		     cloak_bxver, theme);
+	    break;
+	  case 14:
+	    p = strtolower (cloak_bxver);
+	    sprintf (ctcpversion,
+		     STR
+		     ("cypress\002\037.\037\002\037.\03701i\002/\002bitchx\037.\037\002\037.\037\002%s%s"),
+		     p, theme);
+	    nfree (p);
+	    break;
+	  case 15:
+	    p = strtolower (cloak_bxver);
+	    sprintf (ctcpversion,
+		     STR
+		     ("cypress\037.\03701i\037/\037bx%s \037(\037%s\037)\037"),
+		     p, theme);
+	    nfree (p);
+	    break;
+	  }
+	strcpy (ctcpuserinfo, STR (""));
+	strcpy (autoaway, STR ("autoaway after 40 min"));
+	strcpy (kickprefix,
+		STR ("\002.\002.\037(\037\002c\002yp\002/\002k\037)\037 "));
+	strcpy (bankickprefix,
+		STR ("\002.\002.\037(\037\002c\002yp\002/\002bk\037)\037 "));
+	break;
+      }
+    }
+}
+
+#ifdef S_AUTOAWAY
+void
+sendaway ()
+{
+  char awtime[20];
+  int hrs, min, sec, gt;
+  gt = time (NULL) - cloak_awaytime;
+  hrs = gt / 3600;
+  min = (gt % 3600) / 60;
+  sec = gt % 60;
+  switch (cloak_script)
+    {
+    case CLOAK_PLAIN:
+      dprintf (DP_HELP, STR ("AWAY :is away: (%s) [\002BX\002-MsgLog Off]\n"),
+	       autoaway);
+      break;
+    case CLOAK_MIRC:
+      dprintf (DP_HELP, STR ("AWAY :is away: (%s)\n"), autoaway);
+      break;
+    case CLOAK_CRACKROCK:
+      if (hrs)
+	sprintf (awtime, STR ("%dh %dm %ds"), hrs, min, sec);
+      else if (min)
+	sprintf (awtime, STR ("%dm %ds"), min, sec);
+      else
+	sprintf (awtime, STR ("%ds"), sec);
+      dprintf (DP_HELP, STR ("AWAY :%s\002\037[\002%s\002]\037\002\n"),
+	       autoaway, awtime);
+      break;
+    case CLOAK_TUNNELVISION:
+      if (hrs)
+	sprintf (awtime, STR ("%dh%dm%ds"), hrs, min, sec);
+      else if (min)
+	sprintf (awtime, STR ("%dm%ds"), min, sec);
+      else
+	sprintf (awtime, STR ("%ds"), sec);
+      dprintf (DP_HELP, STR ("AWAY :%s \037(\037%s\037)\037\n"), autoaway,
+	       awtime);
+      break;
+    case CLOAK_ARGON:
+      if (hrs)
+	sprintf (awtime, STR ("%dh%dm%ds"), hrs, min, sec);
+      else if (min)
+	sprintf (awtime, STR ("%dm%ds"), min, sec);
+      else
+	sprintf (awtime, STR ("%ds"), sec);
+      dprintf (DP_HELP, STR ("AWAY :%s .\002.\002\037(\037%s\037)\037\n"),
+	       autoaway, awtime);
+      break;
+    case CLOAK_EVOLVER:
+      if (hrs)
+	sprintf (awtime, STR ("%dh %dm %ds"), hrs, min, sec);
+      else if (min)
+	sprintf (awtime, STR ("%dm %ds"), min, sec);
+      else
+	sprintf (awtime, STR ("%ds"), sec);
+      dprintf (DP_HELP,
+	       STR
+	       ("AWAY :away\037: %s (\037l\002:\002off\037,\037 p\002:\002off\037)\037 \037[\037gone\002:\002%s\037]\037\n"),
+	       autoaway, awtime);
+      break;
+    case CLOAK_PREVAIL:
+      if (hrs)
+	sprintf (awtime, STR ("%dh%dm%ds"), hrs, min, sec);
+      else if (min)
+	sprintf (awtime, STR ("%dm%ds"), min, sec);
+      else
+	sprintf (awtime, STR ("%ds"), sec);
+      dprintf (DP_HELP, STR ("AWAY :%s %s\n"), autoaway, awtime);
+      break;
+    case CLOAK_CYPRESS:
+      dprintf (DP_HELP,
+	       STR
+	       ("AWAY :is gone\037.\037. %s \037.\037.\037[\037\002c\002yp\037(\037l\002/\002off\002.\002p\002/\002off)]\n"),
+	       autoaway);
+      break;
+    }
+}
+#endif
 static void
 static void
 ctcp_minutely ()
 ctcp_minutely ()
 {
 {
   int i;
   int i;
+#ifdef S_AUTOAWAY
+  int n;
+  if ((cloak_awaytime == 0) && (cloak_heretime == 0))
+    {
+      cloak_heretime = time (NULL);
+      dprintf (DP_HELP, STR ("AWAY :\n"));
+      return;
+    }
+  n = random ();
+  if (cloak_awaytime == 0)
+    {
+      if (!(n % AVGHERETIME))
+	{
+	  cloak_heretime = 0;
+	  cloak_awaytime = time (NULL) - 600 - random () % 60;
+	  sendaway ();
+	}
+    }
+  else
+    {
+      if (!(n % AVGAWAYTIME))
+	{
+	  cloak_awaytime = 0;
+	  cloak_heretime = time (NULL);
+	  dprintf (DP_HELP, STR ("AWAY :\n"));
+	}
+      else
+	sendaway ();
+    }
+#endif
   if (listen_time <= 0)
   if (listen_time <= 0)
     {
     {
       for (i = 0; i < dcc_total; i++)
       for (i = 0; i < dcc_total; i++)
@@ -38,100 +488,235 @@ static int
 ctcp_FINGER (char *nick, char *uhost, char *handle, char *object,
 ctcp_FINGER (char *nick, char *uhost, char *handle, char *object,
 	     char *keyword, char *text)
 	     char *keyword, char *text)
 {
 {
-  if (ctcp_mode != 1 && ctcp_finger[0])
-    simple_sprintf (ctcp_reply, "%s\001FINGER %s\001", ctcp_reply,
-		    ctcp_finger);
+  char *p;
+  int idletime;
+  struct passwd *pwd;
+  if (cloak_awaytime)
+    idletime = now - cloak_awaytime;
+  else if (cloak_heretime)
+    idletime = now - cloak_heretime;
+  else
+    idletime = 0;
+  if (!(pwd = getpwuid (geteuid ())))
+    return 0;
+#ifndef GECOS_DELIMITER
+#define GECOS_DELIMITER ','
+#endif
+  if ((p = strchr (pwd->pw_gecos, GECOS_DELIMITER)) != NULL)
+    *p = 0;
+  dprintf (DP_HELP,
+	   STR ("NOTICE %s :\001%s %s (%s@%s) Idle %ld second%c\001\n"), nick,
+	   keyword, pwd->pw_gecos, pwd->pw_name,
+	   (char *) (strchr (botuserhost, '@') + 1), idletime,
+	   (idletime == 1) ? "" : "s");
   return 1;
   return 1;
 }
 }
 static int
 static int
-ctcp_ECHOERR (char *nick, char *uhost, char *handle, char *object,
-	      char *keyword, char *text)
+ctcp_ECHO (char *nick, char *uhost, char *handle, char *object, char *keyword,
+	   char *text)
 {
 {
-  if (ctcp_mode != 1 && strlen (text) <= 80)
-    simple_sprintf (ctcp_reply, "%s\001%s %s\001", ctcp_reply, keyword, text);
+  char reply[60];
+  strncpy0 (reply, text, sizeof (reply));
+  dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s\001\n"), nick, keyword, reply);
   return 1;
   return 1;
 }
 }
 static int
 static int
 ctcp_PING (char *nick, char *uhost, char *handle, char *object, char *keyword,
 ctcp_PING (char *nick, char *uhost, char *handle, char *object, char *keyword,
 	   char *text)
 	   char *text)
 {
 {
-  struct userrec *u = get_user_by_handle (userlist, handle);
-  int atr = u ? u->flags : 0;
-  if ((ctcp_mode != 1 || (atr & USER_OP)) && strlen (text) <= 80)
-    simple_sprintf (ctcp_reply, "%s\001%s %s\001", ctcp_reply, keyword, text);
+  if (strlen (text) <= 80)
+    dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s\001\n"), nick, keyword,
+	     text);
   return 1;
   return 1;
 }
 }
 static int
 static int
 ctcp_VERSION (char *nick, char *uhost, char *handle, char *object,
 ctcp_VERSION (char *nick, char *uhost, char *handle, char *object,
 	      char *keyword, char *text)
 	      char *keyword, char *text)
 {
 {
-  if (ctcp_mode != 1 && ctcp_version[0])
-    simple_sprintf (ctcp_reply, "%s\001VERSION %s\001", ctcp_reply,
-		    ctcp_version);
+  char s[50] = "";
+  if (cloak_script == CLOAK_CYPRESS)
+    {
+      switch (random () % 8)
+	{
+	case 0:
+	  strcpy (s, STR (" :should of put the glock down."));
+	  break;
+	case 1:
+	  strcpy (s, STR (" :hot damn, I didn't want to kill a man."));
+	  break;
+	case 2:
+	  strcpy (s, STR (" :check me and I'll check ya back."));
+	  break;
+	case 3:
+	  strcpy (s, STR (" :put the blunt down just for a minute."));
+	  break;
+	case 4:
+	  strcpy (s, STR (" :tried to jack me, my homie got shot."));
+	  break;
+	case 5:
+	  strcpy (s, STR (" :insane in the membrane"));
+	  break;
+	case 6:
+	  strcpy (s, STR (" :slow hits from the bong"));
+	  break;
+	case 7:
+	  strcpy (s, STR (" :k\002-\002leet"));
+	  break;
+	}
+    }
+  dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s%s\001\n"), nick, keyword,
+	   ctcpversion, s);
+  return 1;
+}
+static int
+ctcp_WHOAMI (char *nick, char *uhost, char *handle, char *object,
+	     char *keyword, char *text)
+{
+  dprintf (DP_HELP, STR ("NOTICE %s :\002BitchX\002: Access Denied\n"), nick);
+  return 1;
+}
+static int
+ctcp_OP (char *nick, char *uhost, char *handle, char *object, char *keyword,
+	 char *text)
+{
+  char chan[256], *p;
+  if (text[0])
+    {
+      strncpy0 (chan, text, sizeof (chan));
+      p = strchr (chan, ' ');
+      if (p)
+	*p = 0;
+      dprintf (DP_HELP,
+	       STR
+	       ("NOTICE %s :\002BitchX\002: I'm not on %s or I'm not opped\n"),
+	       nick, chan);
+    }
+  return 1;
+}
+static int
+ctcp_INVITE_UNBAN (char *nick, char *uhost, char *handle, char *object,
+		   char *keyword, char *text)
+{
+  struct chanset_t *chan = chanset;
+  char chname[256], *p;
+  if (text[0] == '#')
+    {
+      strncpy0 (chname, text, sizeof (chname));
+      p = strchr (chname, ' ');
+      if (p)
+	*p = 0;
+      while (chan)
+	{
+	  if (chan->status & CHAN_ACTIVE)
+	    {
+	      if (!strcasecmp (chan->name, chname))
+		{
+		  dprintf (DP_HELP,
+			   STR ("NOTICE %s :\002BitchX\002: Access Denied\n"),
+			   nick);
+		  return 0;
+		}
+	    }
+	  chan = chan->next;
+	}
+      dprintf (DP_HELP,
+	       STR ("NOTICE %s :\002BitchX\002: I'm not on that channel\n"),
+	       nick);
+    }
   return 1;
   return 1;
 }
 }
 static int
 static int
 ctcp_USERINFO (char *nick, char *uhost, char *handle, char *object,
 ctcp_USERINFO (char *nick, char *uhost, char *handle, char *object,
 	       char *keyword, char *text)
 	       char *keyword, char *text)
 {
 {
-  if (ctcp_mode != 1 && ctcp_userinfo[0])
-    simple_sprintf (ctcp_reply, "%s\001USERINFO %s\001", ctcp_reply,
-		    ctcp_userinfo);
+  if (cloak_script == CLOAK_TUNNELVISION)
+    strcpy (ctcpuserinfo, botname);
+  else if (cloak_script == CLOAK_PREVAIL)
+    {
+      strcpy (ctcpuserinfo, botname);
+      strcat (ctcpuserinfo, " ?");
+    }
+  dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s\001\n"), nick, keyword,
+	   ctcpuserinfo);
   return 1;
   return 1;
 }
 }
 static int
 static int
-ctcp_CLIENTINFO (char *nick, char *uhosr, char *handle, char *object,
+ctcp_CLIENTINFO (char *nick, char *uhost, char *handle, char *object,
 		 char *keyword, char *msg)
 		 char *keyword, char *msg)
 {
 {
-  char *p = NULL;
-  if (ctcp_mode == 1)
-    return 1;
-  else if (!msg[0])
-    p = CLIENTINFO;
-  else if (!egg_strcasecmp (msg, "sed"))
-    p = CLIENTINFO_SED;
-  else if (!egg_strcasecmp (msg, "version"))
-    p = CLIENTINFO_VERSION;
-  else if (!egg_strcasecmp (msg, "clientinfo"))
-    p = CLIENTINFO_CLIENTINFO;
-  else if (!egg_strcasecmp (msg, "userinfo"))
-    p = CLIENTINFO_USERINFO;
-  else if (!egg_strcasecmp (msg, "errmsg"))
-    p = CLIENTINFO_ERRMSG;
-  else if (!egg_strcasecmp (msg, "finger"))
-    p = CLIENTINFO_FINGER;
-  else if (!egg_strcasecmp (msg, "time"))
-    p = CLIENTINFO_TIME;
-  else if (!egg_strcasecmp (msg, "action"))
-    p = CLIENTINFO_ACTION;
-  else if (!egg_strcasecmp (msg, "dcc"))
-    p = CLIENTINFO_DCC;
-  else if (!egg_strcasecmp (msg, "utc"))
-    p = CLIENTINFO_UTC;
-  else if (!egg_strcasecmp (msg, "ping"))
-    p = CLIENTINFO_PING;
-  else if (!egg_strcasecmp (msg, "echo"))
-    p = CLIENTINFO_ECHO;
-  if (p == NULL)
-    {
-      simple_sprintf (ctcp_reply,
-		      "%s\001ERRMSG CLIENTINFO: %s is not a valid function\001",
-		      ctcp_reply, msg);
+  char text[256];
+  if (!msg[0])
+    {
+      strcpy (text,
+	      STR
+	      ("SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information"));
     }
     }
+  else if (!strcasecmp (msg, STR ("UNBAN")))
+    strcpy (text, STR ("UNBAN unbans the person from channel"));
+  else if (!strcasecmp (msg, STR ("OPS")))
+    strcpy (text, STR ("OPS ops the person if on userlist"));
+  else if (!strcasecmp (msg, STR ("ECHO")))
+    strcpy (text, STR ("ECHO returns the arguments it receives"));
+  else if (!strcasecmp (msg, STR ("WHOAMI")))
+    strcpy (text, STR ("WHOAMI user list information"));
+  else if (!strcasecmp (msg, STR ("INVITE")))
+    strcpy (text, STR ("INVITE invite to channel specified"));
+  else if (!strcasecmp (msg, STR ("PING")))
+    strcpy (text, STR ("PING returns the arguments it receives"));
+  else if (!strcasecmp (msg, STR ("UTC")))
+    strcpy (text, STR ("UTC substitutes the local timezone"));
+  else if (!strcasecmp (msg, STR ("XDCC")))
+    strcpy (text, STR ("XDCC checks cdcc info for you"));
+  else if (!strcasecmp (msg, STR ("BDCC")))
+    strcpy (text, STR ("BDCC checks cdcc info for you"));
+  else if (!strcasecmp (msg, STR ("CDCC")))
+    strcpy (text, STR ("CDCC checks cdcc info for you"));
+  else if (!strcasecmp (msg, STR ("DCC")))
+    strcpy (text, STR ("DCC requests a direct_client_connection"));
+  else if (!strcasecmp (msg, STR ("ACTION")))
+    strcpy (text, STR ("ACTION contains action descriptions for atmosphere"));
+  else if (!strcasecmp (msg, STR ("FINGER")))
+    strcpy (text,
+	    STR ("FINGER shows real name, login name and idle time of user"));
+  else if (!strcasecmp (msg, STR ("ERRMSG")))
+    strcpy (text, STR ("ERRMSG returns error messages"));
+  else if (!strcasecmp (msg, STR ("USERINFO")))
+    strcpy (text, STR ("USERINFO returns user settable information"));
+  else if (!strcasecmp (msg, STR ("CLIENTINFO")))
+    strcpy (text,
+	    STR
+	    ("CLIENTINFO gives information about available CTCP commands"));
+  else if (!strcasecmp (msg, STR ("SED")))
+    strcpy (text, STR ("SED contains simple_encrypted_data"));
+  else if (!strcasecmp (msg, "OP"))
+    strcpy (text, STR ("OP ops the person if on userlist"));
+  else if (!strcasecmp (msg, STR ("VERSION")))
+    strcpy (text, STR ("VERSION shows client type, version and environment"));
+  else if (!strcasecmp (msg, STR ("XLINK")))
+    strcpy (text, STR ("XLINK x-filez rule"));
+  else if (!strcasecmp (msg, STR ("IDENT")))
+    strcpy (text, STR ("IDENT change userhost of userlist"));
+  else if (!strcasecmp (msg, STR ("TIME")))
+    strcpy (text, STR ("TIME tells you the time on the user's host"));
+  else if (!strcasecmp (msg, STR ("UPTIME")))
+    strcpy (text, STR ("UPTIME my uptime"));
   else
   else
-    simple_sprintf (ctcp_reply, "%s\001CLIENTINFO %s\001", ctcp_reply, p);
+    {
+      dprintf (DP_HELP,
+	       STR ("NOTICE %s :\001ERRMSG %s is not a valid function\001\n"),
+	       nick, msg);
+      return 0;
+    }
+  dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s\001\n"), nick, keyword, text);
   return 1;
   return 1;
 }
 }
 static int
 static int
 ctcp_TIME (char *nick, char *uhost, char *handle, char *object, char *keyword,
 ctcp_TIME (char *nick, char *uhost, char *handle, char *object, char *keyword,
 	   char *text)
 	   char *text)
 {
 {
-  char tms[25];
-  if (ctcp_mode == 1)
-    return 1;
-  strncpy (tms, ctime (&now), 24);
-  tms[24] = 0;
-  simple_sprintf (ctcp_reply, "%s\001TIME %s\001", ctcp_reply, tms);
+  char tms[81];
+  strncpy0 (tms, ctime (&now), sizeof (tms));
+  dprintf (DP_HELP, STR ("NOTICE %s :\001%s %s\001\n"), nick, keyword, tms);
   return 1;
   return 1;
 }
 }
 static int
 static int
@@ -166,23 +751,59 @@ ctcp_CHAT (char *nick, char *uhost, char *handle, char *object, char *keyword,
   return 1;
   return 1;
 }
 }
 static cmd_t myctcp[] =
 static cmd_t myctcp[] =
-  { {"FINGER", "", ctcp_FINGER, NULL}, {"ECHO", "", ctcp_ECHOERR, NULL},
-  {"PING", "", ctcp_PING, NULL}, {"ERRMSG", "", ctcp_ECHOERR, NULL},
-  {"VERSION", "", ctcp_VERSION, NULL}, {"USERINFO", "", ctcp_USERINFO, NULL},
-  {"CLIENTINFO", "", ctcp_CLIENTINFO, NULL}, {"TIME", "", ctcp_TIME, NULL},
-  {"CHAT", "", ctcp_CHAT, NULL}, {NULL, NULL, NULL, NULL} };
-static tcl_strings mystrings[] =
-  { {"ctcp-version", ctcp_version, 120, 0}, {"ctcp-finger", ctcp_finger, 120,
-					     0}, {"ctcp-userinfo",
-						  ctcp_userinfo, 120, 0},
-  {NULL, NULL, 0, 0} };
-static tcl_ints myints[] = { {"ctcp-mode", &ctcp_mode}, {NULL, NULL} };
+  { {"CLIENTINFO", "", ctcp_CLIENTINFO, NULL}, {"FINGER", "", ctcp_FINGER,
+						NULL}, {"WHOAMI", "",
+							ctcp_WHOAMI, NULL},
+  {"OP", "", ctcp_OP, NULL}, {"OPS", "", ctcp_OP, NULL}, {"INVITE", "",
+							  ctcp_INVITE_UNBAN,
+							  NULL}, {"UNBAN", "",
+								  ctcp_INVITE_UNBAN,
+								  NULL},
+  {"ERRMSG", "", ctcp_ECHO, NULL}, {"USERINFO", "", ctcp_USERINFO, NULL},
+  {"ECHO", "", ctcp_ECHO, NULL}, {"VERSION", "", ctcp_VERSION, NULL}, {"PING",
+								       "",
+								       ctcp_PING,
+								       NULL},
+  {"TIME", "", ctcp_TIME, NULL}, {"CHAT", "", ctcp_CHAT, NULL}, {NULL, NULL,
+								 NULL,
+								 NULL} };
+#endif
+void
+cloak_describe (struct cfg_entry *cfgent, int idx)
+{
+  dprintf (idx,
+	   STR
+	   ("cloak-script decides which BitchX script the bot cloaks. If set to 0, a random script will be cloaked.\n"));
+  dprintf (idx,
+	   STR
+	   ("Available: 1=plain bitchx, 2=crackrock, 3=neonapple, 4=tunnelvision, 5=argon, 6=evolver, 7=prevail 8=cypress 9=mIRC\n"));
+} void
+cloak_changed (struct cfg_entry *cfgent, char *oldval, int *valid)
+{
+  char *p;
+  int i;
+  if (!(p = cfgent->ldata ? cfgent->ldata : cfgent->gdata))
+    return;
+  i = atoi (p);
+#ifdef LEAF
+  if (i == 0)
+    i = (random () % CLOAK_COUNT) + 1;
+#endif
+  if ((*valid = ((i >= 0) && (i <= CLOAK_COUNT))))
+    cloak_script = i;
+#ifdef LEAF
+  scriptchanged ();
+#endif
+}
+struct cfg_entry CFG_CLOAK_SCRIPT =
+  { "cloak-script", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL, cloak_changed,
+cloak_changed, cloak_describe };
 static char *
 static char *
 ctcp_close ()
 ctcp_close ()
 {
 {
-  rem_tcl_strings (mystrings);
-  rem_tcl_ints (myints);
+#ifdef LEAF
   rem_builtins (H_ctcp, myctcp);
   rem_builtins (H_ctcp, myctcp);
+#endif
   module_undepend (MODULE_NAME);
   module_undepend (MODULE_NAME);
   return NULL;
   return NULL;
 }
 }
@@ -193,32 +814,67 @@ static Function ctcp_table[] =
 char *
 char *
 ctcp_start (Function * global_funcs)
 ctcp_start (Function * global_funcs)
 {
 {
+#ifdef LEAF
+  char *p;
+#ifdef HAVE_UNAME
+  struct utsname un;
+#endif
+#endif
   global = global_funcs;
   global = global_funcs;
   module_register (MODULE_NAME, ctcp_table, 1, 0);
   module_register (MODULE_NAME, ctcp_table, 1, 0);
+#ifdef LEAF
   if (!(server_funcs = module_depend (MODULE_NAME, "server", 1, 0)))
   if (!(server_funcs = module_depend (MODULE_NAME, "server", 1, 0)))
     {
     {
       module_undepend (MODULE_NAME);
       module_undepend (MODULE_NAME);
       return "This module requires server module 1.0 or later.";
       return "This module requires server module 1.0 or later.";
     }
     }
-  add_tcl_strings (mystrings);
-  add_tcl_ints (myints);
-  add_builtins (H_ctcp, myctcp);
-  add_hook (HOOK_MINUTELY, (Function) ctcp_minutely);
-  if (!ctcp_version[0])
+#ifdef HAVE_UNAME
+  egg_bzero (&un, sizeof (un));
+  if (!uname (&un))
     {
     {
-      strncpy (ctcp_version, ver, 120);
-      ctcp_version[120] = 0;
+      strncpy0 (cloak_os, un.sysname, sizeof (cloak_os));
+      strncpy0 (cloak_osver, un.release, sizeof (cloak_osver));
+      strncpy0 (cloak_host, un.nodename, sizeof (cloak_host));
     }
     }
-  if (!ctcp_finger[0])
+  else
     {
     {
-      strncpy (ctcp_finger, ver, 120);
-      ctcp_finger[120] = 0;
+#endif
+      switch (random () % 2)
+	{
+	case 0:
+	  strcpy (cloak_os, STR ("Linux"));
+	  strcpy (cloak_osver, STR ("2.4.20"));
+	  break;
+	case 1:
+	  strcpy (cloak_os, STR ("FreeBSD"));
+	  strcpy (cloak_osver, STR ("4.5-STABLE"));
+	  break;
+	}
+      strcpy (cloak_host, STR ("login"));
+#ifdef HAVE_UNAME
     }
     }
-  if (!ctcp_userinfo[0])
+#endif
+  if ((p = strchr (cloak_host, '.')))
+    *p = 0;
+  switch (random () % 4)
     {
     {
-      strncpy (ctcp_userinfo, ver, 120);
-      ctcp_userinfo[120] = 0;
+    case 0:
+      strcpy (cloak_bxver, STR ("1.0c17"));
+      break;
+    case 1:
+      strcpy (cloak_bxver, STR ("1.0c18"));
+      break;
+    case 2:
+      strcpy (cloak_bxver, STR ("1.0c19"));
+      break;
+    case 3:
+      strcpy (cloak_bxver, STR ("1.0c20cvs+"));
+      break;
     }
     }
+  scriptchanged ();
+  add_builtins (H_ctcp, myctcp);
+  add_hook (HOOK_MINUTELY, (Function) ctcp_minutely);
+#endif
+  add_cfg (&CFG_CLOAK_SCRIPT);
   return NULL;
   return NULL;
 }
 }
-#endif

+ 0 - 2
src/mod/ctcp.mod/ctcp.h

@@ -1,4 +1,3 @@
-#ifdef LEAF
 #ifndef _EGG_MOD_CTCP_CTCP_H
 #ifndef _EGG_MOD_CTCP_CTCP_H
 #define _EGG_MOD_CTCP_CTCP_H
 #define _EGG_MOD_CTCP_CTCP_H
 #define CLIENTINFO "SED VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME ACTION DCC UTC PING ECHO  :Use CLIENTINFO <COMMAND> to get more specific information"
 #define CLIENTINFO "SED VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME ACTION DCC UTC PING ECHO  :Use CLIENTINFO <COMMAND> to get more specific information"
@@ -15,4 +14,3 @@
 #define CLIENTINFO_PING "PING returns the arguments it receives"
 #define CLIENTINFO_PING "PING returns the arguments it receives"
 #define CLIENTINFO_ECHO "ECHO returns the arguments it receives"
 #define CLIENTINFO_ECHO "ECHO returns the arguments it receives"
 #endif
 #endif
-#endif

+ 72 - 50
src/mod/irc.mod/chan.c

@@ -5,18 +5,34 @@ static time_t last_invtime = (time_t) 0L;
 static char last_invchan[300] = "";
 static char last_invchan[300] = "";
 #define CHANNEL_ID_LEN 5
 #define CHANNEL_ID_LEN 5
 static memberlist *
 static memberlist *
-newmember (struct chanset_t *chan)
+newmember (struct chanset_t *chan, char *nick)
 {
 {
-  memberlist *x;
-  for (x = chan->channel.member; x && x->nick[0]; x = x->next);
-  x->next = (memberlist *) channel_malloc (sizeof (memberlist));
-  x->next->next = NULL;
-  x->next->nick[0] = 0;
-  x->next->split = 0L;
-  x->next->last = 0L;
-  x->next->delay = 0L;
+  memberlist *x, *lx, *n;
+  x = chan->channel.member;
+  lx = NULL;
+  while (x && x->nick[0] && (rfc_casecmp (x->nick, nick) < 0))
+    {
+      lx = x;
+      x = x->next;
+    }
+  n = (memberlist *) channel_malloc (sizeof (memberlist));
+  n->next = NULL;
+  strncpy0 (n->nick, nick, sizeof (n->nick));
+  n->split = 0L;
+  n->last = 0L;
+  n->delay = 0L;
+  if (!lx)
+    {
+      n->next = chan->channel.member;
+      chan->channel.member = n;
+    }
+  else
+    {
+      n->next = lx->next;
+      lx->next = n;
+    }
   chan->channel.members++;
   chan->channel.members++;
-  return x;
+  return n;
 }
 }
 static void
 static void
 update_idle (char *chname, char *nick)
 update_idle (char *chname, char *nick)
@@ -108,7 +124,7 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
       if (!m->user)
       if (!m->user)
 	{
 	{
 	  char s[256];
 	  char s[256];
-	  sprintf (s, "%s!%s", m->nick, m->userhost);
+	  sprintf (s, STR ("%s!%s"), m->nick, m->userhost);
 	  m->user = get_user_by_host (s);
 	  m->user = get_user_by_host (s);
 	}
 	}
       if (m->user
       if (m->user
@@ -116,12 +132,12 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
 	      (USER_BOT | USER_OP)))
 	      (USER_BOT | USER_OP)))
 	{
 	{
 	  ops++;
 	  ops++;
-	  if (!strcmp (m->nick, botname))
+	  if (match_my_nick (m->nick))
 	    bpos = (ops - 1);
 	    bpos = (ops - 1);
 	}
 	}
       else if (!opsonly || chan_hasop (m))
       else if (!opsonly || chan_hasop (m))
 	{
 	{
-	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0 };
+	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0 };
 	  if (m->user)
 	  if (m->user)
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	  if (chan_deop (fr) || glob_deop (fr)
 	  if (chan_deop (fr) || glob_deop (fr)
@@ -146,7 +162,7 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
     {
     {
       if (!opsonly || chan_hasop (m))
       if (!opsonly || chan_hasop (m))
 	{
 	{
-	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0 };
+	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0 };
 	  if (m->user)
 	  if (m->user)
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	  if (chan_deop (fr) || glob_deop (fr)
 	  if (chan_deop (fr) || glob_deop (fr)
@@ -169,8 +185,9 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
 		    {
 		    {
 		      actions++;
 		      actions++;
 		      sent++;
 		      sent++;
-		      dprintf (DP_MODE, "KICK %s %s :%s%s\n", chan->name,
-			       m->nick, kickprefix, kickreason (KICK_CLOSED));
+		      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"),
+			       chan->name, m->nick, kickprefix,
+			       kickreason (KICK_CLOSED));
 		      m->flags |= SENTKICK;
 		      m->flags |= SENTKICK;
 		      if (actions >= ct)
 		      if (actions >= ct)
 			return;
 			return;
@@ -190,7 +207,7 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
     {
     {
       if (!opsonly || chan_hasop (m))
       if (!opsonly || chan_hasop (m))
 	{
 	{
-	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0 };
+	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0 };
 	  if (m->user)
 	  if (m->user)
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	  if (chan_deop (fr) || glob_deop (fr)
 	  if (chan_deop (fr) || glob_deop (fr)
@@ -212,8 +229,9 @@ priority_do (struct chanset_t *chan, int opsonly, int action)
 		  else if ((action == PRIO_KICK) && !chan_sentkick (m))
 		  else if ((action == PRIO_KICK) && !chan_sentkick (m))
 		    {
 		    {
 		      actions++;
 		      actions++;
-		      dprintf (DP_MODE, "KICK %s %s :%s%s\n", chan->name,
-			       m->nick, kickprefix, kickreason (KICK_CLOSED));
+		      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"),
+			       chan->name, m->nick, kickprefix,
+			       kickreason (KICK_CLOSED));
 		      m->flags |= SENTKICK;
 		      m->flags |= SENTKICK;
 		      if ((actions >= ct) || (sent > 5))
 		      if ((actions >= ct) || (sent > 5))
 			return;
 			return;
@@ -229,6 +247,7 @@ target_priority (struct chanset_t *chan, memberlist * target, int opsonly)
 {
 {
   memberlist *m;
   memberlist *m;
   int ops = 0, targets = 0, bpos = 0, ft = 0, ct = 0, tp = (-1), pos = 0;
   int ops = 0, targets = 0, bpos = 0, ft = 0, ct = 0, tp = (-1), pos = 0;
+  return 1;
   for (m = chan->channel.member; m && m->nick[0]; m = m->next)
   for (m = chan->channel.member; m && m->nick[0]; m = m->next)
     {
     {
       if (m->user
       if (m->user
@@ -236,12 +255,12 @@ target_priority (struct chanset_t *chan, memberlist * target, int opsonly)
 	      (USER_BOT | USER_OP)))
 	      (USER_BOT | USER_OP)))
 	{
 	{
 	  ops++;
 	  ops++;
-	  if (!strcmp (m->nick, botname))
+	  if (match_my_nick (m->nick))
 	    bpos = ops;
 	    bpos = ops;
 	}
 	}
       else if (!opsonly || chan_hasop (m))
       else if (!opsonly || chan_hasop (m))
 	{
 	{
-	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0 };
+	  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0 };
 	  if (m->user)
 	  if (m->user)
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	    get_user_flagrec (m->user, &fr, chan->dname);
 	  if (chan_deop (fr) || glob_deop (fr)
 	  if (chan_deop (fr) || glob_deop (fr)
@@ -410,8 +429,8 @@ detect_chan_flood (char *floodnick, char *floodhost, char *from,
 	  if (!chan_sentkick (m) && me_op (chan))
 	  if (!chan_sentkick (m) && me_op (chan))
 	    {
 	    {
 	      putlog (LOG_MODES, chan->dname, IRC_FLOODKICK, floodnick);
 	      putlog (LOG_MODES, chan->dname, IRC_FLOODKICK, floodnick);
-	      dprintf (DP_MODE, "KICK %s %s :%s\n", chan->name, floodnick,
-		       CHAN_FLOOD);
+	      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"), chan->name,
+		       floodnick, kickprefix, kickreason (KICK_FLOOD));
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
 	    }
 	    }
 	  return 1;
 	  return 1;
@@ -450,11 +469,12 @@ detect_chan_flood (char *floodnick, char *floodhost, char *from,
 		    {
 		    {
 		      m->flags |= SENTKICK;
 		      m->flags |= SENTKICK;
 		      if (which == FLOOD_JOIN)
 		      if (which == FLOOD_JOIN)
-			dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name,
-				 m->nick, IRC_JOIN_FLOOD);
+			dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name,
+				 m->nick, kickprefix, IRC_JOIN_FLOOD);
 		      else
 		      else
-			dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name,
-				 m->nick, IRC_NICK_FLOOD);
+			dprintf (DP_SERVER, STR ("KICK %s %s :%s%s\n"),
+				 chan->name, m->nick, kickprefix,
+				 kickreason (KICK_NICKFLOOD));
 		    }
 		    }
 		}
 		}
 	    }
 	    }
@@ -464,8 +484,8 @@ detect_chan_flood (char *floodnick, char *floodhost, char *from,
 	    {
 	    {
 	      putlog (LOG_MODES, chan->dname, "Kicking %s, for mass kick.",
 	      putlog (LOG_MODES, chan->dname, "Kicking %s, for mass kick.",
 		      floodnick);
 		      floodnick);
-	      dprintf (DP_MODE, "KICK %s %s :%s\n", chan->name, floodnick,
-		       IRC_MASSKICK);
+	      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"), chan->name,
+		       floodnick, kickprefix, kickreason (KICK_KICKFLOOD));
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
 	    }
 	    }
 	  return 1;
 	  return 1;
@@ -474,8 +494,8 @@ detect_chan_flood (char *floodnick, char *floodhost, char *from,
 	    {
 	    {
 	      putlog (LOG_MODES, chan->dname, CHAN_MASSDEOP, chan->dname,
 	      putlog (LOG_MODES, chan->dname, CHAN_MASSDEOP, chan->dname,
 		      from);
 		      from);
-	      dprintf (DP_MODE, "KICK %s %s :%s\n", chan->name, floodnick,
-		       CHAN_MASSDEOP_KICK);
+	      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"), chan->name,
+		       floodnick, kickprefix, kickreason (KICK_MASSDEOP));
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
 	    }
 	    }
 	  return 1;
 	  return 1;
@@ -487,6 +507,7 @@ static char *
 quickban (struct chanset_t *chan, char *uhost)
 quickban (struct chanset_t *chan, char *uhost)
 {
 {
   static char s1[512];
   static char s1[512];
+  Context;
   maskhost (uhost, s1);
   maskhost (uhost, s1);
   if ((strlen (s1) != 1) && (strict_host == 0))
   if ((strlen (s1) != 1) && (strict_host == 0))
     s1[2] = '*';
     s1[2] = '*';
@@ -541,15 +562,16 @@ kick_all (struct chanset_t *chan, char *hostmask, char *comment, int bantype)
 	  l = strlen (chan->name) + strlen (kicknick) + strlen (comment) + 5;
 	  l = strlen (chan->name) + strlen (kicknick) + strlen (comment) + 5;
 	  if ((kick_method != 0 && k == kick_method) || (l > 480))
 	  if ((kick_method != 0 && k == kick_method) || (l > 480))
 	    {
 	    {
-	      dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick,
-		       comment);
+	      dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, kicknick,
+		       kickprefix, comment);
 	      k = 0;
 	      k = 0;
 	      kicknick[0] = 0;
 	      kicknick[0] = 0;
 	    }
 	    }
 	}
 	}
     }
     }
   if (k > 0)
   if (k > 0)
-    dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick, comment);
+    dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, kicknick,
+	     kickprefix, comment);
 }
 }
 static void
 static void
 refresh_ban_kick (struct chanset_t *chan, char *user, char *nick)
 refresh_ban_kick (struct chanset_t *chan, char *user, char *nick)
@@ -854,6 +876,7 @@ check_this_member (struct chanset_t *chan, char *nick, struct flag_record *fr)
 {
 {
   memberlist *m;
   memberlist *m;
   char s[UHOSTLEN], *p;
   char s[UHOSTLEN], *p;
+  Context;
   m = ismember (chan, nick);
   m = ismember (chan, nick);
   if (!m || match_my_nick (nick) || !me_op (chan))
   if (!m || match_my_nick (nick) || !me_op (chan))
     return;
     return;
@@ -898,17 +921,10 @@ check_this_member (struct chanset_t *chan, char *nick, struct flag_record *fr)
 	  check_exemptlist (chan, s);
 	  check_exemptlist (chan, s);
 #endif
 #endif
 	  quickban (chan, m->userhost);
 	  quickban (chan, m->userhost);
+	  Context;
 	  p = get_user (&USERENTRY_COMMENT, m->user);
 	  p = get_user (&USERENTRY_COMMENT, m->user);
-	  if (p[0])
-	    {
-	      dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick,
-		       p ? p : IRC_POLITEKICK);
-	    }
-	  else
-	    {
-	      dprintf (DP_SERVER, STR ("KICK %s %s :%s%s\n"), chan->name,
-		       m->nick, bankickprefix, kickreason (KICK_KUSER));
-	    }
+	  dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick,
+		   bankickprefix, p ? p : kickreason (KICK_KUSER));
 	  m->flags |= SENTKICK;
 	  m->flags |= SENTKICK;
 	}
 	}
     }
     }
@@ -948,6 +964,7 @@ recheck_channel (struct chanset_t *chan, int dobans)
   static int stacking = 0;
   static int stacking = 0;
   int botops = 0, botnonops = 0, nonbotops = 0;
   int botops = 0, botnonops = 0, nonbotops = 0;
   int stop_reset = 0;
   int stop_reset = 0;
+  Context;
   if (stacking)
   if (stacking)
     return;
     return;
   if (!userlist)
   if (!userlist)
@@ -1019,18 +1036,23 @@ recheck_channel (struct chanset_t *chan, int dobans)
   for (m = chan->channel.member; m && m->nick[0]; m = m->next)
   for (m = chan->channel.member; m && m->nick[0]; m = m->next)
     {
     {
       sprintf (s, "%s!%s", m->nick, m->userhost);
       sprintf (s, "%s!%s", m->nick, m->userhost);
+      Context;
       if (!m->user && !m->tried_getuser)
       if (!m->user && !m->tried_getuser)
 	{
 	{
 	  m->tried_getuser = 1;
 	  m->tried_getuser = 1;
 	  m->user = get_user_by_host (s);
 	  m->user = get_user_by_host (s);
 	}
 	}
+      Context;
       get_user_flagrec (m->user, &fr, chan->dname);
       get_user_flagrec (m->user, &fr, chan->dname);
+      Context;
       if (glob_bot (fr) && chan_hasop (m) && !match_my_nick (m->nick))
       if (glob_bot (fr) && chan_hasop (m) && !match_my_nick (m->nick))
 	stop_reset = 1;
 	stop_reset = 1;
       check_this_member (chan, m->nick, &fr);
       check_this_member (chan, m->nick, &fr);
     }
     }
+  Context;
   if (channel_closed (chan))
   if (channel_closed (chan))
     channel_check_locked (chan);
     channel_check_locked (chan);
+  Context;
   if (dobans)
   if (dobans)
     {
     {
       if (channel_nouserbans (chan) && !stop_reset)
       if (channel_nouserbans (chan) && !stop_reset)
@@ -1172,7 +1194,7 @@ got352or4 (struct chanset_t *chan, char *user, char *host, char *serv,
   m = ismember (chan, nick);
   m = ismember (chan, nick);
   if (!m)
   if (!m)
     {
     {
-      m = newmember (chan);
+      m = newmember (chan, nick);
       m->joined = m->split = m->delay = 0L;
       m->joined = m->split = m->delay = 0L;
       m->flags = 0;
       m->flags = 0;
       m->last = now;
       m->last = now;
@@ -1814,7 +1836,7 @@ gotjoin (char *from, char *chname)
 	    {
 	    {
 	      if (m)
 	      if (m)
 		killmember (chan, nick);
 		killmember (chan, nick);
-	      m = newmember (chan);
+	      m = newmember (chan, nick);
 	      m->joined = now;
 	      m->joined = now;
 	      m->split = 0L;
 	      m->split = 0L;
 	      m->flags = 0;
 	      m->flags = 0;
@@ -2242,8 +2264,8 @@ gotmsg (char *from, char *msg)
 	    }
 	    }
 	  if (kick_fun)
 	  if (kick_fun)
 	    {
 	    {
-	      dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, nick,
-		       IRC_FUNKICK);
+	      dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, nick,
+		       kickprefix, IRC_FUNKICK);
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
 	    }
 	    }
 	}
 	}
@@ -2407,8 +2429,8 @@ gotnotice (char *from, char *msg)
 	    }
 	    }
 	  if (kick_fun)
 	  if (kick_fun)
 	    {
 	    {
-	      dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, nick,
-		       IRC_FUNKICK);
+	      dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, nick,
+		       kickprefix, IRC_FUNKICK);
 	      m->flags |= SENTKICK;
 	      m->flags |= SENTKICK;
 	    }
 	    }
 	}
 	}

+ 12 - 3
src/mod/irc.mod/cmdsirc.c

@@ -233,7 +233,8 @@ cmd_kickban (struct userrec *u, int idx, char *par)
     do_mask (chan, chan->channel.ban, s1, 'b');
     do_mask (chan, chan->channel.ban, s1, 'b');
   if (!par[0])
   if (!par[0])
     par = "requested";
     par = "requested";
-  dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, par);
+  dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick,
+	   bankickprefix, par);
   m->flags |= SENTKICK;
   m->flags |= SENTKICK;
   u_addban (chan, s1, dcc[idx].nick, par, now + (60 * chan->ban_time), 0);
   u_addban (chan, s1, dcc[idx].nick, par, now + (60 * chan->ban_time), 0);
   dprintf (idx, "Okay, done.\n");
   dprintf (idx, "Okay, done.\n");
@@ -374,6 +375,10 @@ cmd_devoice (struct userrec *u, int idx, char *par)
 void
 void
 do_op (char *nick, struct chanset_t *chan)
 do_op (char *nick, struct chanset_t *chan)
 {
 {
+  memberlist *m;
+  m = ismember (chan, nick);
+  if (!m)
+    return;
   if (channel_fastop (chan))
   if (channel_fastop (chan))
     {
     {
       add_mode (chan, '+', 'o', nick);
       add_mode (chan, '+', 'o', nick);
@@ -920,7 +925,8 @@ cmd_kick (struct userrec *u, int idx, char *par)
       dprintf (idx, "%s is another channel bot!\n", nick);
       dprintf (idx, "%s is another channel bot!\n", nick);
       return;
       return;
     }
     }
-  dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, par);
+  dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, m->nick, kickprefix,
+	   par);
   m->flags |= SENTKICK;
   m->flags |= SENTKICK;
   dprintf (idx, "Okay, done.\n");
   dprintf (idx, "Okay, done.\n");
 }
 }
@@ -1248,7 +1254,7 @@ cmd_adduser (struct userrec *u, int idx, char *par)
   char *nick, *hand;
   char *nick, *hand;
   struct chanset_t *chan;
   struct chanset_t *chan;
   memberlist *m = NULL;
   memberlist *m = NULL;
-  char s[UHOSTLEN], s1[UHOSTLEN];
+  char s[UHOSTLEN], s1[UHOSTLEN], s3[20];
   char tmp[50], s2[30];
   char tmp[50], s2[30];
   int atr = u ? u->flags : 0;
   int atr = u ? u->flags : 0;
   int statichost = 0;
   int statichost = 0;
@@ -1343,8 +1349,11 @@ cmd_adduser (struct userrec *u, int idx, char *par)
       set_user (&USERENTRY_ADDED, u, tmp);
       set_user (&USERENTRY_ADDED, u, tmp);
       make_rand_str (s2, 10);
       make_rand_str (s2, 10);
       set_user (&USERENTRY_PASS, u, s2);
       set_user (&USERENTRY_PASS, u, s2);
+      make_rand_str (s3, 10);
+      set_user (&USERENTRY_PASS, u, s3);
       dprintf (idx, "Added [%s]%s with no flags.\n", hand, p1);
       dprintf (idx, "Added [%s]%s with no flags.\n", hand, p1);
       dprintf (idx, STR ("%s's password set to \002%s\002.\n"), hand, s2);
       dprintf (idx, STR ("%s's password set to \002%s\002.\n"), hand, s2);
+      dprintf (idx, STR ("%s's secpass set to \002%s\002.\n"), hand, s3);
     }
     }
   else
   else
     {
     {

+ 13 - 39
src/mod/irc.mod/irc.c

@@ -27,8 +27,6 @@ static p_tcl_bind_list H_topc, H_splt, H_sign, H_rejn, H_part, H_pub, H_pubm;
 static p_tcl_bind_list H_nick, H_mode, H_kick, H_join, H_need;
 static p_tcl_bind_list H_nick, H_mode, H_kick, H_join, H_need;
 static Function *global = NULL, *channels_funcs = NULL, *server_funcs =
 static Function *global = NULL, *channels_funcs = NULL, *server_funcs =
   NULL, *encryption_funcs = NULL;
   NULL, *encryption_funcs = NULL;
-static char kickprefix[20] = "";
-static char bankickprefix[20] = "";
 static int ctcp_mode;
 static int ctcp_mode;
 static int net_type;
 static int net_type;
 static int strict_host;
 static int strict_host;
@@ -60,33 +58,6 @@ static int include_lk = 1;
 #include "cmdsirc.c"
 #include "cmdsirc.c"
 #include "msgcmds.c"
 #include "msgcmds.c"
 #include "tclirc.c"
 #include "tclirc.c"
-void
-makeplaincookie (char *chname, char *nick, char *buf)
-{
-  char work[256], work2[256];
-  int i, n;
-  sprintf (work, STR ("%010li"), (now + timesync));
-  strcpy (buf, (char *) &work[4]);
-  work[0] = 0;
-  if (strlen (nick) < 5)
-    while (strlen (work) + strlen (nick) < 5)
-      strcat (work, " ");
-  else
-    strcpy (work, (char *) &nick[strlen (nick) - 5]);
-  strcat (buf, work);
-  n = 3;
-  for (i = strlen (chname) - 1; (i >= 0) && (n >= 0); i--)
-    if (((unsigned char) chname[i] < 128) && ((unsigned char) chname[i] > 32))
-      {
-	work2[n] = tolower (chname[i]);
-	n--;
-      }
-  while (n >= 0)
-    work2[n--] = ' ';
-  work2[4] = 0;
-  strcat (buf, work2);
-}
-
 void
 void
 makeopline (struct chanset_t *chan, char *nick, char *buf)
 makeopline (struct chanset_t *chan, char *nick, char *buf)
 {
 {
@@ -97,15 +68,12 @@ makeopline (struct chanset_t *chan, char *nick, char *buf)
     strcpy (nck, m->nick);
     strcpy (nck, m->nick);
   else
   else
     strcpy (nck, nick);
     strcpy (nck, nick);
-  makeplaincookie (chan->name, nck, plaincookie);
+  makeplaincookie (chan->dname, nck, plaincookie);
   strcpy (key, botname);
   strcpy (key, botname);
   strcat (key, netpass);
   strcat (key, netpass);
   p = encrypt_string (key, plaincookie);
   p = encrypt_string (key, plaincookie);
   strcpy (enccookie, p);
   strcpy (enccookie, p);
   nfree (p);
   nfree (p);
-  p = enccookie + strlen (enccookie) - 1;
-  while (*p == '.')
-    *p-- = 0;
   sprintf (buf, STR ("MODE %s +o-b %s *!*@[%s]\n"), chan->name, nck,
   sprintf (buf, STR ("MODE %s +o-b %s *!*@[%s]\n"), chan->name, nck,
 	   enccookie);
 	   enccookie);
 }
 }
@@ -541,6 +509,9 @@ check_hostmask ()
   Context;
   Context;
   tmp = botuserhost;
   tmp = botuserhost;
   Context;
   Context;
+  if (!tmp[0] || !tmp[1])
+    return;
+  Context;
   if (tmp[0] != '~')
   if (tmp[0] != '~')
     sprintf (s, STR ("*!%s"), tmp);
     sprintf (s, STR ("*!%s"), tmp);
   else
   else
@@ -565,6 +536,7 @@ request_op (struct chanset_t *chan)
   memberlist *botops[MAX_BOTS];
   memberlist *botops[MAX_BOTS];
   char s[100], *l, myserv[SERVLEN];
   char s[100], *l, myserv[SERVLEN];
   struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0 };
   struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0 };
+  Context;
   chan->channel.do_opreq = 0;
   chan->channel.do_opreq = 0;
   if (me_op (chan))
   if (me_op (chan))
     return;
     return;
@@ -871,7 +843,8 @@ punish_badguy (struct chanset_t *chan, char *whobad, struct userrec *u,
 	  || !(chan_op (fr) || (glob_op (fr) && !chan_deop (fr))))
 	  || !(chan_op (fr) || (glob_op (fr) && !chan_deop (fr))))
       && !chan_sentkick (m) && me_op (chan) && !mevictim)
       && !chan_sentkick (m) && me_op (chan) && !mevictim)
     {
     {
-      dprintf (DP_MODE, "KICK %s %s :%s\n", chan->name, badnick, kick_msg);
+      dprintf (DP_MODE, STR ("KICK %s %s :%s%s\n"), chan->name, m->nick,
+	       bankickprefix, kickreason (KICK_MEAN));
       m->flags |= SENTKICK;
       m->flags |= SENTKICK;
     }
     }
 }
 }
@@ -1148,7 +1121,7 @@ check_expired_chanstuff ()
   memberlist *m, *n;
   memberlist *m, *n;
   char s[UHOSTLEN];
   char s[UHOSTLEN];
   struct chanset_t *chan;
   struct chanset_t *chan;
-  struct userrec *buser;
+  struct userrec *buser = NULL;
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
   struct flag_record fr3 = { FR_GLOBAL | FR_CHAN, 0, 0 };
   struct flag_record fr3 = { FR_GLOBAL | FR_CHAN, 0, 0 };
   if (!server_online)
   if (!server_online)
@@ -1233,8 +1206,9 @@ check_expired_chanstuff ()
 			   || (glob_op (fr) && !glob_deop (fr))
 			   || (glob_op (fr) && !glob_deop (fr))
 			   || chan_friend (fr) || chan_op (fr)))
 			   || chan_friend (fr) || chan_op (fr)))
 			{
 			{
-			  dprintf (DP_SERVER, "KICK %s %s :idle %d min\n",
-				   chan->name, m->nick, chan->idle_kick);
+			  dprintf (DP_SERVER, "KICK %s %s :%sidle %d min\n",
+				   chan->name, m->nick, kickprefix,
+				   chan->idle_kick);
 			  m->flags |= SENTKICK;
 			  m->flags |= SENTKICK;
 			}
 			}
 		    }
 		    }
@@ -1256,7 +1230,7 @@ check_expired_chanstuff ()
 	      m = n;
 	      m = n;
 	    }
 	    }
 	  buser = get_user_by_handle (userlist, botnetnick);
 	  buser = get_user_by_handle (userlist, botnetnick);
-	  get_user_flagrec (buser, &fr3, chan->name);
+	  get_user_flagrec (buser, &fr3, chan->dname);
 	  if (!loading && channel_active (chan) && me_op (chan) && (buser)
 	  if (!loading && channel_active (chan) && me_op (chan) && (buser)
 	      && (chan_dovoice (fr3) || glob_dovoice (fr3)))
 	      && (chan_dovoice (fr3) || glob_dovoice (fr3)))
 	    {
 	    {
@@ -1265,7 +1239,7 @@ check_expired_chanstuff ()
 		  if (m->user)
 		  if (m->user)
 		    {
 		    {
 		      struct flag_record fr2 = { FR_GLOBAL | FR_CHAN, 0, 0 };
 		      struct flag_record fr2 = { FR_GLOBAL | FR_CHAN, 0, 0 };
-		      get_user_flagrec (m->user, &fr2, chan->name);
+		      get_user_flagrec (m->user, &fr2, chan->dname);
 		      if ((!glob_bot (fr2)
 		      if ((!glob_bot (fr2)
 			   &&
 			   &&
 			   ((chan_voice (fr2)
 			   ((chan_voice (fr2)

+ 29 - 27
src/mod/irc.mod/mode.c

@@ -263,6 +263,7 @@ real_add_mode (struct chanset_t *chan, char plus, char mode, char *op)
   masklist *m;
   masklist *m;
   memberlist *mx;
   memberlist *mx;
   char s[21];
   char s[21];
+  Context;
   if (!me_op (chan))
   if (!me_op (chan))
     return;
     return;
   if (mode == 'o')
   if (mode == 'o')
@@ -455,6 +456,7 @@ got_op (struct chanset_t *chan, char *nick, char *from, char *who,
   struct userrec *u;
   struct userrec *u;
   int check_chan = 0;
   int check_chan = 0;
   int snm = chan->stopnethack_mode;
   int snm = chan->stopnethack_mode;
+  Context;
   m = ismember (chan, who);
   m = ismember (chan, who);
   if (!m)
   if (!m)
     {
     {
@@ -481,33 +483,22 @@ got_op (struct chanset_t *chan, char *nick, char *from, char *who,
     return;
     return;
   if (me_op (chan) && !match_my_nick (who) && nick[0])
   if (me_op (chan) && !match_my_nick (who) && nick[0])
     {
     {
-#ifdef S_OWNEREXCEPT
       if ((channel_bitch (chan) || channel_closed (chan)
       if ((channel_bitch (chan) || channel_closed (chan)
-	   || channel_take (chan)) && !(glob_master (*opper)
-					|| glob_bot (*opper))
-	  && !chan_master (*opper) && !(glob_op (victim) || glob_bot (victim))
-	  && !chan_op (victim))
-#else
-      if (channel_bitch (chan) && !(glob_bot (*opper))
-	  && !(glob_bot (victim) || glob_bot (victim)) && !chan_op (victim))
-#endif
-	add_mode (chan, '-', 'o', who);
-      else if ((chan_deop (victim) ||
-#ifdef S_OWNEREXCEPT
-		(glob_deop (victim) && !chan_op (victim)))
-	       && !glob_master (*opper) && !chan_master (*opper))
-#else
-		(glob_deop (victim) && !chan_op (victim))))
-#endif
-	add_mode (chan, '-', 'o', who);
-      else
-    if (reversing)
-      add_mode (chan, '-', 'o', who);
+	   || channel_take (chan)) && !glob_op (victim) && !chan_op (victim))
+	{
+	  if (target_priority (chan, m, 1))
+	    add_mode (chan, '-', 'o', who);
+	}
+      else if (reversing)
+	{
+	  add_mode (chan, '-', 'o', who);
+	}
     }
     }
   else if (reversing && !match_my_nick (who))
   else if (reversing && !match_my_nick (who))
     add_mode (chan, '-', 'o', who);
     add_mode (chan, '-', 'o', who);
   if (!nick[0] && me_op (chan) && !match_my_nick (who))
   if (!nick[0] && me_op (chan) && !match_my_nick (who))
     {
     {
+      Context;
       if (chan_deop (victim) || (glob_deop (victim) && !chan_op (victim)))
       if (chan_deop (victim) || (glob_deop (victim) && !chan_op (victim)))
 	{
 	{
 	  m->flags |= FAKEOP;
 	  m->flags |= FAKEOP;
@@ -552,6 +543,7 @@ got_op (struct chanset_t *chan, char *nick, char *from, char *who,
   m->flags |= WASOP;
   m->flags |= WASOP;
   if (check_chan)
   if (check_chan)
     {
     {
+      Context;
       recheck_channel (chan, 1);
       recheck_channel (chan, 1);
       check_topic (chan);
       check_topic (chan);
     }
     }
@@ -895,6 +887,7 @@ gotmode (char *from, char *origmsg)
   memberlist *m;
   memberlist *m;
   struct chanset_t *chan;
   struct chanset_t *chan;
   struct flag_record fr3 = { FR_GLOBAL | FR_CHAN, 0, 0 };
   struct flag_record fr3 = { FR_GLOBAL | FR_CHAN, 0, 0 };
+  Context;
   strncpy (buf, origmsg, 510);
   strncpy (buf, origmsg, 510);
   buf[510] = 0;
   buf[510] = 0;
   msg = buf;
   msg = buf;
@@ -906,6 +899,7 @@ gotmode (char *from, char *origmsg)
       chg = newsplit (&msg);
       chg = newsplit (&msg);
       reversing = 0;
       reversing = 0;
       chan = findchan (ch);
       chan = findchan (ch);
+      Context;
       if (!chan)
       if (!chan)
 	{
 	{
 	  putlog (LOG_MISC, "*", CHAN_FORCEJOIN, ch);
 	  putlog (LOG_MISC, "*", CHAN_FORCEJOIN, ch);
@@ -913,8 +907,7 @@ gotmode (char *from, char *origmsg)
 	}
 	}
       else if (channel_active (chan) || channel_pending (chan))
       else if (channel_active (chan) || channel_pending (chan))
 	{
 	{
-	  buser = get_user_by_handle (userlist, botnetnick);
-	  get_user_flagrec (buser, &fr3, chan->name);
+	  Context;
 	  z = strlen (msg);
 	  z = strlen (msg);
 	  if (msg[--z] == ' ')
 	  if (msg[--z] == ' ')
 	    msg[z] = 0;
 	    msg[z] = 0;
@@ -923,6 +916,7 @@ gotmode (char *from, char *origmsg)
 	  u = get_user_by_host (from);
 	  u = get_user_by_host (from);
 	  get_user_flagrec (u, &user, ch);
 	  get_user_flagrec (u, &user, ch);
 	  nick = splitnick (&from);
 	  nick = splitnick (&from);
+	  Context;
 	  m = ismember (chan, nick);
 	  m = ismember (chan, nick);
 	  if (m)
 	  if (m)
 	    m->last = now;
 	    m->last = now;
@@ -935,22 +929,23 @@ gotmode (char *from, char *origmsg)
 	      if (chan_fakeop (m))
 	      if (chan_fakeop (m))
 		{
 		{
 		  putlog (LOG_MODES, ch, CHAN_FAKEMODE, ch);
 		  putlog (LOG_MODES, ch, CHAN_FAKEMODE, ch);
-		  dprintf (DP_MODE, "KICK %s %s :%s\n", ch, nick,
-			   CHAN_FAKEMODE_KICK);
+		  dprintf (DP_MODE, "KICK %s %s :%s%s\n", ch, nick,
+			   kickprefix, CHAN_FAKEMODE_KICK);
 		  m->flags |= SENTKICK;
 		  m->flags |= SENTKICK;
 		  reversing = 1;
 		  reversing = 1;
 		}
 		}
 	      else if (!chan_hasop (m) && !channel_nodesynch (chan))
 	      else if (!chan_hasop (m) && !channel_nodesynch (chan))
 		{
 		{
 		  putlog (LOG_MODES, ch, CHAN_DESYNCMODE, ch);
 		  putlog (LOG_MODES, ch, CHAN_DESYNCMODE, ch);
-		  dprintf (DP_MODE, "KICK %s %s :%s\n", ch, nick,
-			   CHAN_DESYNCMODE_KICK);
+		  dprintf (DP_MODE, "KICK %s %s :%s%s\n", ch, nick,
+			   kickprefix, CHAN_DESYNCMODE_KICK);
 		  m->flags |= SENTKICK;
 		  m->flags |= SENTKICK;
 		  reversing = 1;
 		  reversing = 1;
 		}
 		}
 	    }
 	    }
 	  ms2[0] = '+';
 	  ms2[0] = '+';
 	  ms2[2] = 0;
 	  ms2[2] = 0;
+	  Context;
 	  while ((ms2[1] = *chg))
 	  while ((ms2[1] = *chg))
 	    {
 	    {
 	      int todo = 0;
 	      int todo = 0;
@@ -1028,10 +1023,14 @@ gotmode (char *from, char *origmsg)
 		    reversing = 1;
 		    reversing = 1;
 		  break;
 		  break;
 		case 'l':
 		case 'l':
+		  Context;
+		  buser = get_user_by_handle (userlist, botnetnick);
+		  get_user_flagrec (buser, &fr3, ch);
 		  if ((!nick[0]) && (bounce_modes))
 		  if ((!nick[0]) && (bounce_modes))
 		    reversing = 1;
 		    reversing = 1;
 		  if (ms2[0] == '-')
 		  if (ms2[0] == '-')
 		    {
 		    {
+		      Context;
 		      check_tcl_mode (nick, from, u, chan->dname, ms2, "");
 		      check_tcl_mode (nick, from, u, chan->dname, ms2, "");
 		      if (channel_active (chan))
 		      if (channel_active (chan))
 			{
 			{
@@ -1060,6 +1059,7 @@ gotmode (char *from, char *origmsg)
 		    }
 		    }
 		  else
 		  else
 		    {
 		    {
+		      Context;
 		      op = newsplit (&msg);
 		      op = newsplit (&msg);
 		      fixcolon (op);
 		      fixcolon (op);
 		      if (op == '\0')
 		      if (op == '\0')
@@ -1122,6 +1122,7 @@ gotmode (char *from, char *origmsg)
 		    }
 		    }
 		  break;
 		  break;
 		case 'o':
 		case 'o':
+		  Context;
 		  op = newsplit (&msg);
 		  op = newsplit (&msg);
 		  fixcolon (op);
 		  fixcolon (op);
 		  if (ms2[0] == '+')
 		  if (ms2[0] == '+')
@@ -1263,6 +1264,7 @@ gotmode (char *from, char *origmsg)
 		}
 		}
 	      chg++;
 	      chg++;
 	    }
 	    }
+	  Context;
 	  if (chan->channel.do_opreq)
 	  if (chan->channel.do_opreq)
 	    request_op (chan);
 	    request_op (chan);
 	  if (!me_op (chan) && !nick[0])
 	  if (!me_op (chan) && !nick[0])

+ 6 - 3
src/mod/irc.mod/msgcmds.c

@@ -43,7 +43,7 @@ msg_pass (char *nick, char *host, struct userrec *u, char *par)
   if (strlen (new) < 8)
   if (strlen (new) < 8)
     {
     {
       dprintf (DP_HELP,
       dprintf (DP_HELP,
-	       "NOTICE %s :insecure password, use >= 8 chars ucase, lcase and a number\n",
+	       "NOTICE %s :insecure password, use >= 8 chars uppercase, lowercase and a number\n",
 	       nick);
 	       nick);
       return 0;
       return 0;
     }
     }
@@ -60,7 +60,7 @@ msg_pass (char *nick, char *host, struct userrec *u, char *par)
   if ((ucase + ocase + lcase) != 3)
   if ((ucase + ocase + lcase) != 3)
     {
     {
       dprintf (DP_HELP,
       dprintf (DP_HELP,
-	       "NOTICE %s :insecure password, use >= 8 chars ucase, lcase and a number.\n",
+	       "NOTICE %s :insecure password, use >= 8 chars uppercase, lowercase and a number.\n",
 	       nick);
 	       nick);
       return 0;
       return 0;
     }
     }
@@ -153,7 +153,10 @@ msg_op (char *nick, char *host, struct userrec *u, char *par)
 		{
 		{
 		  get_user_flagrec (u, &fr, par);
 		  get_user_flagrec (u, &fr, par);
 		  if (chan_op (fr) || (glob_op (fr) && !chan_deop (fr)))
 		  if (chan_op (fr) || (glob_op (fr) && !chan_deop (fr)))
-		    add_mode (chan, '+', 'o', nick);
+		    {
+		      stats_add (u, 0, 1);
+		      do_op (nick, chan);
+		    }
 		  putlog (LOG_CMDS, "*", "(%s!%s) !%s! OP %s", nick, host,
 		  putlog (LOG_CMDS, "*", "(%s!%s) !%s! OP %s", nick, host,
 			  u->handle, par);
 			  u->handle, par);
 		  return 1;
 		  return 1;

+ 4 - 3
src/mod/irc.mod/tclirc.c

@@ -775,14 +775,15 @@ static int tcl_putkick STDVAR
       l = strlen (chan->name) + strlen (kicknick) + strlen (comment);
       l = strlen (chan->name) + strlen (kicknick) + strlen (comment);
       if (((kick_method != 0) && (k == kick_method)) || (l > 480))
       if (((kick_method != 0) && (k == kick_method)) || (l > 480))
 	{
 	{
-	  dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick,
-		   comment);
+	  dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, kicknick,
+		   kickprefix, comment);
 	  k = 0;
 	  k = 0;
 	  kicknick[0] = 0;
 	  kicknick[0] = 0;
 	}
 	}
     }
     }
   if (k > 0)
   if (k > 0)
-    dprintf (DP_SERVER, "KICK %s %s :%s\n", chan->name, kicknick, comment);
+    dprintf (DP_SERVER, "KICK %s %s :%s%s\n", chan->name, kicknick,
+	     kickprefix, comment);
   return TCL_OK;
   return TCL_OK;
 }
 }
 static tcl_cmds tclchan_cmds[] =
 static tcl_cmds tclchan_cmds[] =

+ 5 - 0
src/mod/module.h

@@ -504,6 +504,11 @@
 #define isupdatehub ((int (*)(void))global[306])
 #define isupdatehub ((int (*)(void))global[306])
 #define norestruct (*(int*)global[307])
 #define norestruct (*(int*)global[307])
 #define botlink ((int (*)(char *, int, char *))global[308])
 #define botlink ((int (*)(char *, int, char *))global[308])
+/* 309 - 312 */
+#define makeplaincookie ((void (*)(char *, char *, char *))global[309])
+#define kickprefix ((char *)(global[310]))
+#define bankickprefix ((char *)(global[311]))
+#define deflag_user ((void (*)(struct userrec *, int, char *))global[312])
 
 
 /* This is for blowfish module, couldnt be bothered making a whole new .h
 /* This is for blowfish module, couldnt be bothered making a whole new .h
  * file for it ;)
  * file for it ;)

+ 9 - 2
src/mod/server.mod/server.c

@@ -3,7 +3,8 @@
 #define MAKING_SERVER
 #define MAKING_SERVER
 #include "src/mod/module.h"
 #include "src/mod/module.h"
 #include "server.h"
 #include "server.h"
-static Function *global = NULL;
+static Function *global = NULL, *encryption_funcs;
+extern struct cfg_entry CFG_OPTIMESLACK;
 static int ctcp_mode;
 static int ctcp_mode;
 static int serv;
 static int serv;
 static int strict_host;
 static int strict_host;
@@ -1880,7 +1881,8 @@ static Function server_table[] =
 (Function) & server_online, (Function) & min_servs, (Function) & H_raw, (Function) & H_wall,
 (Function) & server_online, (Function) & min_servs, (Function) & H_raw, (Function) & H_wall,
 (Function) & H_msg, (Function) & H_msgm, (Function) & H_notc, (Function) & H_flud, (Function) & H_ctcp,
 (Function) & H_msg, (Function) & H_msgm, (Function) & H_notc, (Function) & H_flud, (Function) & H_ctcp,
 (Function) & H_ctcr, (Function) ctcp_reply, (Function) get_altbotnick, (Function) & nick_len,
 (Function) & H_ctcr, (Function) ctcp_reply, (Function) get_altbotnick, (Function) & nick_len,
-(Function) check_tcl_notc, (Function) & server_lag, (Function) & curserv, (Function) cursrvname, };
+(Function) check_tcl_notc, (Function) & server_lag, (Function) & curserv, (Function) cursrvname,
+(Function) botrealname, };
 char *
 char *
 server_start (Function * global_funcs)
 server_start (Function * global_funcs)
 {
 {
@@ -1944,6 +1946,11 @@ server_start (Function * global_funcs)
   stack_limit = 4;
   stack_limit = 4;
   server_table[4] = (Function) botname;
   server_table[4] = (Function) botname;
   module_register (MODULE_NAME, server_table, 1, 2);
   module_register (MODULE_NAME, server_table, 1, 2);
+  if (!(encryption_funcs = module_depend (MODULE_NAME, "encryption", 0, 0)))
+    {
+      module_undepend (MODULE_NAME);
+      return "This module requires an encryption modules.";
+    }
   s = Tcl_GetVar (interp, "nick", TCL_GLOBAL_ONLY);
   s = Tcl_GetVar (interp, "nick", TCL_GLOBAL_ONLY);
   if (s)
   if (s)
     strncpyz (origbotname, s, NICKLEN);
     strncpyz (origbotname, s, NICKLEN);

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

@@ -41,6 +41,7 @@
 #define server_lag (*(int *)(server_funcs[39]))
 #define server_lag (*(int *)(server_funcs[39]))
 #define curserv (*(int *)(server_funcs[40))
 #define curserv (*(int *)(server_funcs[40))
 #define cursrvname ((char *)(server_funcs[41]))
 #define cursrvname ((char *)(server_funcs[41]))
+#define botrealname ((char *)(server_funcs[42]))
 #else
 #else
 #define free_null(ptr)	do {	nfree(ptr);	ptr = NULL;	} while (0)
 #define free_null(ptr)	do {	nfree(ptr);	ptr = NULL;	} while (0)
 #endif
 #endif

+ 308 - 1
src/mod/server.mod/servmsg.c

@@ -96,6 +96,7 @@ static int
 check_tcl_raw (char *from, char *code, char *msg)
 check_tcl_raw (char *from, char *code, char *msg)
 {
 {
   int x;
   int x;
+  Context;
   Tcl_SetVar (interp, "_raw1", from, 0);
   Tcl_SetVar (interp, "_raw1", from, 0);
   Tcl_SetVar (interp, "_raw2", code, 0);
   Tcl_SetVar (interp, "_raw2", code, 0);
   Tcl_SetVar (interp, "_raw3", msg, 0);
   Tcl_SetVar (interp, "_raw3", msg, 0);
@@ -896,6 +897,7 @@ static int
 gotmode (char *from, char *msg)
 gotmode (char *from, char *msg)
 {
 {
   char *ch;
   char *ch;
+  Context;
   ch = newsplit (&msg);
   ch = newsplit (&msg);
   if (strchr (CHANMETA, ch[0]) == NULL)
   if (strchr (CHANMETA, ch[0]) == NULL)
     {
     {
@@ -958,10 +960,49 @@ timeout_server (int idx)
 static struct dcc_table SERVER_SOCKET =
 static struct dcc_table SERVER_SOCKET =
   { "SERVER", 0, eof_server, server_activity, NULL, timeout_server,
   { "SERVER", 0, eof_server, server_activity, NULL, timeout_server,
 display_server, NULL, kill_server, NULL };
 display_server, NULL, kill_server, NULL };
+int
+isop (char *mode)
+{
+  int state = 0, cnt = 0;
+  char *p;
+  p = mode;
+  while ((*p) && (*p != ' '))
+    {
+      if (*p == '-')
+	state = 1;
+      else if (*p == '+')
+	state = 0;
+      else if ((!state) && (*p == 'o'))
+	cnt++;
+      p++;
+    }
+  return (cnt >= 1);
+}
+
+int
+ismdop (char *mode)
+{
+  int state = 0, cnt = 0;
+  char *p;
+  p = mode;
+  while ((*p) && (*p != ' '))
+    {
+      if (*p == '-')
+	state = 1;
+      else if (*p == '+')
+	state = 0;
+      else if ((state) && (*p == 'o'))
+	cnt++;
+      p++;
+    }
+  return (cnt >= 3);
+}
 static void
 static void
 server_activity (int idx, char *msg, int len)
 server_activity (int idx, char *msg, int len)
 {
 {
-  char *from, *code;
+  char *from, *code, tmp[1024];
+  char sign = '+';
+  Context;
   if (trying_server)
   if (trying_server)
     {
     {
       strcpy (dcc[idx].nick, "(server)");
       strcpy (dcc[idx].nick, "(server)");
@@ -977,6 +1018,272 @@ server_activity (int idx, char *msg, int len)
       from = newsplit (&msg);
       from = newsplit (&msg);
     }
     }
   code = newsplit (&msg);
   code = newsplit (&msg);
+  if (!strcmp (code, STR ("MODE")) && (msg[0] == '#') && strchr (from, '!'))
+    {
+      char *modes[5] = { NULL, NULL, NULL, NULL, NULL };
+      char *nfrom, *hfrom;
+      int i;
+      struct userrec *ufrom = NULL;
+      struct chanset_t *chan = NULL;
+      char work[1024], *wptr, *p;
+      memberlist *m;
+      int modecnt = 0, ops = 0, deops = 0, bans = 0, unbans = 0;
+      strncpy0 (work, msg, sizeof (work));
+      wptr = work;
+      p = newsplit (&wptr);
+      chan = findchan (p);
+      p = newsplit (&wptr);
+      while (*p)
+	{
+	  char *mp;
+	  if (*p == '+')
+	    sign = '+';
+	  else if (*p == '-')
+	    sign = '-';
+	  else if (strchr (STR ("oblkvIe"), p[0]))
+	    {
+	      mp = newsplit (&wptr);
+	      if (strchr ("ob", p[0]))
+		{
+		  modes[modecnt] = nmalloc (strlen (mp) + 4);
+		  sprintf (modes[modecnt], STR ("%c%c %s"), sign, p[0], mp);
+		  modecnt++;
+		  if (p[0] == 'o')
+		    {
+		      if (sign == '+')
+			ops++;
+		      else
+			deops++;
+		    }
+		  if (p[0] == 'b')
+		    {
+		      if (sign == '+')
+			bans++;
+		      else
+			unbans++;
+		    }
+		}
+	    }
+	  else if (strchr (STR ("pstnmi"), p[0]))
+	    {
+	    }
+	  else
+	    {
+	      putlog (LOG_ERRORS, "*", STR ("Forgotten modechar: %c"), p[0]);
+	    }
+	  p++;
+	}
+      ufrom = get_user_by_host (from);
+      strncpy0 (work, from, sizeof (work));
+      p = strchr (work, '!');
+      *p++ = 0;
+      nfrom = work;
+      hfrom = p;
+      if ((chan) && (deops >= 3))
+	{
+	  if ((!ufrom) || (!(ufrom->flags & USER_BOT)))
+	    {
+	      if (ROLE_KICK_MDOP)
+		{
+		  m = ismember (chan, nfrom);
+		  if (!m || !chan_sentkick (m))
+		    {
+		      sprintf (tmp, STR ("KICK %s %s :%s%s\n"), chan->name,
+			       nfrom, kickprefix, kickreason (KICK_MASSDEOP));
+		      tputs (serv, tmp, strlen (tmp));
+		      if (m)
+			m->flags |= SENTKICK;
+		    }
+		}
+	    }
+	}
+      if (chan && ops && (ufrom) && (ufrom->flags & USER_BOT)
+	  && (!channel_fastop (chan)) && (!channel_take (chan)))
+	{
+	  int isbadop = 0;
+	  if ((modecnt != 2) || (strncmp (modes[0], "+o", 2))
+	      || (strncmp (modes[1], "-b", 2)))
+	    isbadop = 1;
+	  else
+	    {
+	      char enccookie[25], plaincookie[25], key[NICKLEN + 20],
+		goodcookie[25];
+	      strncpy0 (enccookie, (char *) &(modes[1][8]),
+			sizeof (enccookie));
+	      p = enccookie + strlen (enccookie) - 1;
+	      strcpy (key, nfrom);
+	      strcat (key, netpass);
+	      p = decrypt_string (key, enccookie);
+	      Context;
+	      strncpy0 (plaincookie, p, sizeof (plaincookie));
+	      nfree (p);
+	      makeplaincookie (chan->dname, (char *) (modes[0] + 3),
+			       goodcookie);
+	      if (strncmp
+		  ((char *) &plaincookie[6], (char *) &goodcookie[6], 5))
+		isbadop = 2;
+	      else
+		if (strncmp
+		    ((char *) &plaincookie[11], (char *) &goodcookie[11], 5))
+		isbadop = 3;
+	      else
+		{
+		  char tmp[20];
+		  long optime;
+		  int off;
+		  sprintf (tmp, STR ("%010li"), (now + timesync));
+		  strncpy0 ((char *) &tmp[4], plaincookie, 7);
+		  optime = atol (tmp);
+		  off = (now + timesync - optime);
+		  if (abs (off) > op_time_slack)
+		    {
+		      isbadop = 4;
+		      putlog (LOG_ERRORS, "*",
+			      "%s opped with bad ts: %li was off by %li",
+			      nfrom, optime, off);
+		    }
+		}
+	    }
+	  if (isbadop)
+	    {
+	      char trg[NICKLEN + 1] = "";
+	      int n, i;
+	      memberlist *m;
+	      Context;
+	      switch (role)
+		{
+		case 0:
+		  break;
+		case 1:
+		  m = ismember (chan, nfrom);
+		  if (!m || !chan_sentkick (m))
+		    {
+		      sprintf (tmp, STR ("KICK %s %s :%s%s\n"), chan->name,
+			       nfrom, kickprefix, kickreason (KICK_BADOP));
+		      tputs (serv, tmp, strlen (tmp));
+		      if (m)
+			m->flags |= SENTKICK;
+		    }
+		  sprintf (tmp, STR ("%s MODE %s"), from, msg);
+		  deflag_user (ufrom, DEFLAG_BADCOOKIE, tmp);
+		  break;
+		default:
+		  n = role - 1;
+		  i = 0;
+		  while ((i < 5) && (n > 0))
+		    {
+		      if (modes[i] && !strncmp (modes[i], "+o", 2))
+			n--;
+		      if (n)
+			i++;
+		    }
+		  if (!n)
+		    {
+		      strcpy (trg, (char *) &modes[i][3]);
+		      m = ismember (chan, trg);
+		      if (m)
+			{
+			  if (!(m->flags & CHANOP))
+			    {
+			      if (!chan_sentkick (m))
+				{
+				  sprintf (tmp, STR ("KICK %s %s :%s%s\n"),
+					   chan->name, trg, kickprefix,
+					   kickreason (KICK_BADOPPED));
+				  tputs (serv, tmp, strlen (tmp));
+				  m->flags |= SENTKICK;
+				}
+			    }
+			}
+		    }
+		}
+	      if (isbadop == 1)
+		putlog (LOG_WARN, "*", STR ("Missing cookie: %s MODE %s"),
+			from, msg);
+	      else if (isbadop == 2)
+		putlog (LOG_WARN, "*",
+			STR ("Invalid cookie (bad nick): %s MODE %s"), from,
+			msg);
+	      else if (isbadop == 3)
+		putlog (LOG_WARN, "*",
+			STR ("Invalid cookie (bad chan): %s MODE %s"), from,
+			msg);
+	      else if (isbadop == 4)
+		putlog (LOG_WARN, "*",
+			STR ("Invalid cookie (bad time): %s MODE %s"), from,
+			msg);
+	    }
+	  else
+	    putlog (LOG_DEBUG, "*", STR ("Good op: %s"), msg);
+	}
+#ifdef G_MANUALOP
+      if ((ops) && chan && !channel_manop (chan) && (ufrom)
+	  && !(ufrom->flags & USER_BOT))
+	{
+	  char trg[NICKLEN + 1] = "";
+	  int n, i;
+	  memberlist *m;
+	  switch (role)
+	    {
+	    case 0:
+	      break;
+	    case 1:
+	      m = ismember (chan, nfrom);
+	      if (!m || !chan_sentkick (m))
+		{
+		  sprintf (tmp, STR ("KICK %s %s :%s%s\n"), chan->name, nfrom,
+			   kickprefix, kickreason (KICK_MANUALOP));
+		  tputs (serv, tmp, strlen (tmp));
+		  if (m)
+		    m->flags |= SENTKICK;
+		}
+	      sprintf (tmp, STR ("%s MODE %s"), from, msg);
+	      deflag_user (ufrom, DEFLAG_MANUALOP, tmp);
+	      break;
+	    default:
+	      n = role - 1;
+	      i = 0;
+	      while ((i < 5) && (n > 0))
+		{
+		  if (modes[i] && !strncmp (modes[i], "+o", 2))
+		    n--;
+		  if (n)
+		    i++;
+		}
+	      if (!n)
+		{
+		  strcpy (trg, (char *) &modes[i][3]);
+		  m = ismember (chan, trg);
+		  if (m)
+		    {
+		      if (!(m->flags & CHANOP)
+			  && (rfc_casecmp (botname, trg)))
+			{
+			  if (!chan_sentkick (m))
+			    {
+			      sprintf (tmp, STR ("KICK %s %s :%s%s\n"),
+				       chan->name, trg, kickprefix,
+				       kickreason (KICK_MANUALOPPED));
+			      tputs (serv, tmp, strlen (tmp));
+			      m->flags |= SENTKICK;
+			    }
+			}
+		    }
+		  else
+		    {
+		      sprintf (tmp, STR ("KICK %s %s :%s%s\n"), chan->name,
+			       trg, kickprefix,
+			       kickreason (KICK_MANUALOPPED));
+		      tputs (serv, tmp, strlen (tmp));
+		    }
+		}
+	    }
+	}
+      for (i = 0; i < 5; i++)
+	if (modes[i])
+	  nfree (modes[i]);
+#endif
+    }
   if (use_console_r)
   if (use_console_r)
     {
     {
       if (!strcmp (code, "PRIVMSG") || !strcmp (code, "NOTICE"))
       if (!strcmp (code, "PRIVMSG") || !strcmp (code, "NOTICE"))

+ 18 - 8
src/mod/share.mod/share.c

@@ -359,9 +359,11 @@ share_chattr (int idx, char *par)
 		  noshare = 0;
 		  noshare = 0;
 		  build_flags (s, &fr, 0);
 		  build_flags (s, &fr, 0);
 		  fr.match = FR_CHAN;
 		  fr.match = FR_CHAN;
+#ifndef LEAF
 		  if (!(dcc[idx].status & STAT_GETTING))
 		  if (!(dcc[idx].status & STAT_GETTING))
 		    putlog (LOG_CMDS, "@", "%s: chattr %s %s", dcc[idx].nick,
 		    putlog (LOG_CMDS, "@", "%s: chattr %s %s", dcc[idx].nick,
 			    hand, s);
 			    hand, s);
+#endif
 		  if ((me = module_find ("irc", 0, 0)))
 		  if ((me = module_find ("irc", 0, 0)))
 		    {
 		    {
 		      Function *func = me->funcs;
 		      Function *func = me->funcs;
@@ -480,8 +482,10 @@ share_newuser (int idx, char *par)
 	      set_user_flagrec (u, &fr, 0);
 	      set_user_flagrec (u, &fr, 0);
 	      fr.match = FR_CHAN;
 	      fr.match = FR_CHAN;
 	      noshare = 0;
 	      noshare = 0;
+#ifndef LEAF
 	      putlog (LOG_CMDS, "@", "%s: newuser %s %s", dcc[idx].nick, nick,
 	      putlog (LOG_CMDS, "@", "%s: newuser %s %s", dcc[idx].nick, nick,
 		      s);
 		      s);
+#endif
 	    }
 	    }
 	}
 	}
     }
     }
@@ -498,7 +502,9 @@ share_killuser (int idx, char *par)
       if (deluser (par))
       if (deluser (par))
 	{
 	{
 	  shareout_but (NULL, idx, "k %s\n", par);
 	  shareout_but (NULL, idx, "k %s\n", par);
+#ifndef LEAF
 	  putlog (LOG_CMDS, "@", "%s: killuser %s", dcc[idx].nick, par);
 	  putlog (LOG_CMDS, "@", "%s: killuser %s", dcc[idx].nick, par);
+#endif
 	}
 	}
       noshare = 0;
       noshare = 0;
     }
     }
@@ -516,7 +522,9 @@ share_pls_host (int idx, char *par)
 	{
 	{
 	  shareout_but (NULL, idx, "+h %s %s\n", hand, par);
 	  shareout_but (NULL, idx, "+h %s %s\n", hand, par);
 	  set_user (&USERENTRY_HOSTS, u, par);
 	  set_user (&USERENTRY_HOSTS, u, par);
+#ifndef LEAF
 	  putlog (LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
 	  putlog (LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand, par);
+#endif
 	}
 	}
     }
     }
 }
 }
@@ -544,9 +552,11 @@ share_pls_bothost (int idx, char *par)
 	      makepass (p);
 	      makepass (p);
 	      userlist = adduser (userlist, hand, par, p, USER_BOT);
 	      userlist = adduser (userlist, hand, par, p, USER_BOT);
 	    }
 	    }
+#ifndef LEAF
 	  if (!(dcc[idx].status & STAT_GETTING))
 	  if (!(dcc[idx].status & STAT_GETTING))
 	    putlog (LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand,
 	    putlog (LOG_CMDS, "@", "%s: +host %s %s", dcc[idx].nick, hand,
 		    par);
 		    par);
+#endif
 	}
 	}
     }
     }
 }
 }
@@ -565,7 +575,9 @@ share_mns_host (int idx, char *par)
 	  noshare = 1;
 	  noshare = 1;
 	  delhost_by_handle (hand, par);
 	  delhost_by_handle (hand, par);
 	  noshare = 0;
 	  noshare = 0;
+#ifndef LEAF
 	  putlog (LOG_CMDS, "@", "%s: -host %s %s", dcc[idx].nick, hand, par);
 	  putlog (LOG_CMDS, "@", "%s: -host %s %s", dcc[idx].nick, hand, par);
+#endif
 	}
 	}
     }
     }
 }
 }
@@ -1219,8 +1231,7 @@ share_version (int idx, char *par)
     ~(STAT_SHARE | STAT_GETTING | STAT_SENDING | STAT_OFFERED |
     ~(STAT_SHARE | STAT_GETTING | STAT_SENDING | STAT_OFFERED |
       STAT_AGGRESSIVE);
       STAT_AGGRESSIVE);
   dcc[idx].u.bot->uff_flags = 0;
   dcc[idx].u.bot->uff_flags = 0;
-  if ((dcc[idx].u.bot->numver == egg_numver)
-      && (bot_aggressive_to (dcc[idx].user)))
+  if (1 && (bot_aggressive_to (dcc[idx].user)))
     {
     {
       if (can_resync (dcc[idx].nick))
       if (can_resync (dcc[idx].nick))
 	dprintf (idx, "s r?\n");
 	dprintf (idx, "s r?\n");
@@ -1239,8 +1250,7 @@ hook_read_userfile ()
     {
     {
       for (i = 0; i < dcc_total; i++)
       for (i = 0; i < dcc_total; i++)
 	if ((dcc[i].type->flags & DCT_BOT) && (dcc[i].status & STAT_SHARE)
 	if ((dcc[i].type->flags & DCT_BOT) && (dcc[i].status & STAT_SHARE)
-	    && !(dcc[i].status & STAT_AGGRESSIVE)
-	    && (dcc[i].u.bot->numver == egg_numver))
+	    && !(dcc[i].status & STAT_AGGRESSIVE) && (1))
 	  {
 	  {
 	    if (dcc[i].status & STAT_SENDING)
 	    if (dcc[i].status & STAT_SENDING)
 	      cancel_user_xfer (-i, 0);
 	      cancel_user_xfer (-i, 0);
@@ -1453,15 +1463,13 @@ check_expired_tbufs ()
 	  {
 	  {
 	    if (now - dcc[i].timeval > 120)
 	    if (now - dcc[i].timeval > 120)
 	      {
 	      {
-		if (dcc[i].user && (bot_aggressive_to (dcc[i].user))
-		    && (dcc[i].u.bot->numver == egg_numver))
+		if (dcc[i].user && (bot_aggressive_to (dcc[i].user)) && (1))
 		  dprintf (i, "s u?\n");
 		  dprintf (i, "s u?\n");
 	      }
 	      }
 	  }
 	  }
 	else if (!(dcc[i].status & STAT_SHARE))
 	else if (!(dcc[i].status & STAT_SHARE))
 	  {
 	  {
-	    if (dcc[i].user && (bot_aggressive_to (dcc[i].user))
-		&& (dcc[i].u.bot->numver == egg_numver))
+	    if (dcc[i].user && (bot_aggressive_to (dcc[i].user)) && (1))
 	      dprintf (i, "s u?\n");
 	      dprintf (i, "s u?\n");
 	    dcc[i].status |= STAT_OFFERED;
 	    dcc[i].status |= STAT_OFFERED;
 	  }
 	  }
@@ -1751,8 +1759,10 @@ finish_share (int idx)
     for (i = 0; i < dcc_total; i++)
     for (i = 0; i < dcc_total; i++)
       dcc[i].user = get_user_by_handle (u, dcc[i].nick);
       dcc[i].user = get_user_by_handle (u, dcc[i].nick);
   loading = 1;
   loading = 1;
+  Context;
   if (!readuserfile (dcc[idx].u.xfer->filename, &u))
   if (!readuserfile (dcc[idx].u.xfer->filename, &u))
     {
     {
+      Context;
       unlink (dcc[idx].u.xfer->filename);
       unlink (dcc[idx].u.xfer->filename);
       putlog (LOG_MISC, "@", "%s", USERF_CANTREAD);
       putlog (LOG_MISC, "@", "%s", USERF_CANTREAD);
       clear_userlist (u);
       clear_userlist (u);

+ 18 - 24
src/mod/transfer.mod/transfer.c

@@ -3,12 +3,13 @@
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include "src/mod/module.h"
 #include "src/mod/module.h"
+#include "src/mod/update.mod/update.h"
 #include "src/tandem.h"
 #include "src/tandem.h"
 #include "src/users.h"
 #include "src/users.h"
 #include "transfer.h"
 #include "transfer.h"
 #include <netinet/in.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
-static Function *global = NULL;
+static Function *global = NULL, *update_funcs = NULL;
 static int copy_to_tmp = 1;
 static int copy_to_tmp = 1;
 static int wait_dcc_xfer = 40;
 static int wait_dcc_xfer = 40;
 static p_tcl_bind_list H_rcvd, H_sent, H_lost, H_tout;
 static p_tcl_bind_list H_rcvd, H_sent, H_lost, H_tout;
@@ -787,17 +788,6 @@ eof_dcc_send (int idx)
 	  putlog (LOG_BOTS, "*", "Lost binary transfer from %s; aborting.",
 	  putlog (LOG_BOTS, "*", "Lost binary transfer from %s; aborting.",
 		  dcc[y].nick);
 		  dcc[y].nick);
 	  unlink (dcc[idx].u.xfer->filename);
 	  unlink (dcc[idx].u.xfer->filename);
-	  dprintf (y, "bye\n");
-	  egg_snprintf (s, sizeof s,
-			"Disconnected %s (aborted binary transfer)",
-			dcc[y].nick);
-	  botnet_send_unlinked (y, dcc[y].nick, s);
-	  chatout ("*** %s\n", dcc[y].nick, s);
-	  if (y != idx)
-	    {
-	      killsock (dcc[y].sock);
-	      lostdcc (y);
-	    }
 	  killsock (dcc[idx].sock);
 	  killsock (dcc[idx].sock);
 	  lostdcc (idx);
 	  lostdcc (idx);
 	}
 	}
@@ -965,10 +955,16 @@ dcc_get (int idx, char *buf, int len)
 		&& (dcc[x].type->flags & DCT_BOT))
 		&& (dcc[x].type->flags & DCT_BOT))
 	      y = x;
 	      y = x;
 	  if (y != 0)
 	  if (y != 0)
-	    dcc[y].status &= ~STAT_SENDINGU;
+	    {
+	      dcc[y].status &= ~STAT_SENDINGU;
+	      dcc[y].status |= STAT_UPDATED;
+	    }
 	  putlog (LOG_BOTS, "*", "Completed binary file send to %s",
 	  putlog (LOG_BOTS, "*", "Completed binary file send to %s",
 		  dcc[y].nick);
 		  dcc[y].nick);
 	  xnick[0] = 0;
 	  xnick[0] = 0;
+#ifdef HUB
+	  bupdating = 0;
+#endif
 	}
 	}
       else
       else
 	{
 	{
@@ -1034,16 +1030,10 @@ eof_dcc_get (int idx)
 	  y = x;
 	  y = x;
       putlog (LOG_BOTS, "*", "Lost binary transfer; aborting.");
       putlog (LOG_BOTS, "*", "Lost binary transfer; aborting.");
       xnick[0] = 0;
       xnick[0] = 0;
-      dprintf (-dcc[y].sock, "bye\n");
-      egg_snprintf (s, sizeof s, "Disconnected %s (aborted binary transfer)",
-		    dcc[y].nick);
-      botnet_send_unlinked (y, dcc[y].nick, s);
-      chatout ("*** %s\n", s);
-      if (y != idx)
-	{
-	  killsock (dcc[y].sock);
-	  lostdcc (y);
-	}
+      dcc[y].status &= ~STAT_SENDINGU;
+#ifdef HUB
+      bupdating = 0;
+#endif
       killsock (dcc[idx].sock);
       killsock (dcc[idx].sock);
       lostdcc (idx);
       lostdcc (idx);
       return;
       return;
@@ -1208,7 +1198,6 @@ tout_dcc_send (int idx)
 	{
 	{
 	  dcc[y].status &= ~STAT_GETTINGU;
 	  dcc[y].status &= ~STAT_GETTINGU;
 	}
 	}
-      unlink (dcc[idx].u.xfer->filename);
       putlog (LOG_BOTS, "*", "Timeout on binary transfer.");
       putlog (LOG_BOTS, "*", "Timeout on binary transfer.");
     }
     }
   else
   else
@@ -1810,6 +1799,11 @@ transfer_start (Function * global_funcs)
   global = global_funcs;
   global = global_funcs;
   fileq = NULL;
   fileq = NULL;
   module_register (MODULE_NAME, transfer_table, 2, 2);
   module_register (MODULE_NAME, transfer_table, 2, 2);
+  if (!(update_funcs = module_depend (MODULE_NAME, "update", 0, 0)))
+    {
+      module_undepend (MODULE_NAME);
+      return "This module requires update module 0.0 or later.";
+    }
   add_tcl_commands (mytcls);
   add_tcl_commands (mytcls);
   add_tcl_ints (myints);
   add_tcl_ints (myints);
   add_builtins (H_load, transfer_load);
   add_builtins (H_load, transfer_load);

+ 49 - 62
src/mod/update.mod/update.c

@@ -25,22 +25,25 @@ int updated = 0;
 static void
 static void
 update_ufno (int idx, char *par)
 update_ufno (int idx, char *par)
 {
 {
-  putlog (LOG_BOTS, "*", "nary file rejected by %s: %s", dcc[idx].nick, par);
+  putlog (LOG_BOTS, "*", "binary file rejected by %s: %s", dcc[idx].nick,
+	  par);
   dcc[idx].status &= ~STAT_OFFEREDU;
   dcc[idx].status &= ~STAT_OFFEREDU;
 } static void
 } static void
 update_ufyes (int idx, char *par)
 update_ufyes (int idx, char *par)
 {
 {
   if (dcc[idx].status & STAT_OFFEREDU)
   if (dcc[idx].status & STAT_OFFEREDU)
     {
     {
-      dcc[idx].status &= ~STAT_OFFEREDU;
-      dcc[idx].status |= STAT_SENDINGU;
       start_sending_binary (idx);
       start_sending_binary (idx);
     }
     }
 }
 }
 static void
 static void
 update_fileq (int idx, char *par)
 update_fileq (int idx, char *par)
 {
 {
+  if (dcc[idx].status & STAT_GETTINGU)
+    return;
 #ifdef LEAF
 #ifdef LEAF
+  if (updated)
+    return;
   if (localhub)
   if (localhub)
     {
     {
 #else
 #else
@@ -48,7 +51,6 @@ update_fileq (int idx, char *par)
     {
     {
 #endif
 #endif
       dprintf (idx, "sb uy\n");
       dprintf (idx, "sb uy\n");
-      dcc[idx].status |= STAT_GETTINGU;
     }
     }
   else if (isupdatehub ())
   else if (isupdatehub ())
     {
     {
@@ -112,11 +114,11 @@ update_ufsend (int idx, char *par)
 }}} static void
 }}} static void
 update_version (int idx, char *par)
 update_version (int idx, char *par)
 {
 {
+  return;
 #ifdef HUB
 #ifdef HUB
   if (bupdating)
   if (bupdating)
     return;
     return;
-  dcc[idx].status &=
-    ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU | STAT_UPDATED);
+  dcc[idx].status &= ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU);
   if ((dcc[idx].u.bot->numver < egg_numver) && (isupdatehub ()))
   if ((dcc[idx].u.bot->numver < egg_numver) && (isupdatehub ()))
     {
     {
       dprintf (idx, "sb u?\n");
       dprintf (idx, "sb u?\n");
@@ -134,14 +136,13 @@ static void
 got_nu (char *botnick, char *code, char *par)
 got_nu (char *botnick, char *code, char *par)
 {
 {
   int newver = 0;
   int newver = 0;
+#ifdef LEAF
   tand_t *bot;
   tand_t *bot;
-#ifdef HUB
-  return;
-#endif
+  struct bot_addr *bi, *obi;
+  struct userrec *u1;
   bot = tandbot;
   bot = tandbot;
   if (!strcmp (bot->bot, botnick))
   if (!strcmp (bot->bot, botnick))
     return;
     return;
-#ifdef LEAF
   if (!localhub)
   if (!localhub)
     return;
     return;
   if (localhub && updated)
   if (localhub && updated)
@@ -152,10 +153,26 @@ got_nu (char *botnick, char *code, char *par)
   newver = atoi (newsplit (&par));
   newver = atoi (newsplit (&par));
   if (newver > egg_numver)
   if (newver > egg_numver)
     {
     {
-      norestruct = 1;
+      Context;
+#ifdef LEAF
+      u1 = get_user_by_handle (userlist, botnetnick);
+      obi = get_user (&USERENTRY_BOTADDR, u1);
+      bi = user_malloc (sizeof (struct bot_addr));
+      bi->uplink = user_malloc (strlen (botnick) + 1);
+      strcpy (bi->uplink, botnick);
+      bi->address = user_malloc (strlen (obi->address) + 1);
+      strcpy (bi->address, obi->address);
+      bi->telnet_port = obi->telnet_port;
+      bi->relay_port = obi->relay_port;
+      bi->hublevel = obi->hublevel;
+      set_user (&USERENTRY_BOTADDR, u1, bi);
+      putlog (LOG_MISC, "*", "Changed uplink to %s for update.", botnick);
       botunlink (-2, bot->bot, "Restructure for update.");
       botunlink (-2, bot->bot, "Restructure for update.");
       usleep (1000 * 500);
       usleep (1000 * 500);
       botlink ("", -3, botnick);
       botlink ("", -3, botnick);
+#else
+      putlog (LOG_MISC, "*", "I need to be updated with %d", newver);
+#endif
     }
     }
 }
 }
 static cmd_t update_bot[] =
 static cmd_t update_bot[] =
@@ -182,7 +199,7 @@ finish_update (int idx)
   uid_t id;
   uid_t id;
   char buf[1024];
   char buf[1024];
   char *buf2;
   char *buf2;
-  int result, i, ic, j = -1;
+  int i, j = -1;
   id = geteuid ();
   id = geteuid ();
   pw = getpwuid (id);
   pw = getpwuid (id);
   for (i = 0; i < dcc_total; i++)
   for (i = 0; i < dcc_total; i++)
@@ -191,35 +208,14 @@ finish_update (int idx)
       j = i;
       j = i;
   if (j == -1)
   if (j == -1)
     return;
     return;
-  ic = 0;
-next:;
-  ic++;
-  if (ic > 5)
-    {
-      putlog (LOG_MISC, "*", "COULD NOT UNCOMPRESS BINARY");
-      return;
-    }
-  result = 0;
-  result = is_compressedfile (dcc[idx].u.xfer->filename);
-  if (result == COMPF_COMPRESSED)
-    {
-      uncompress_file (dcc[idx].u.xfer->filename);
-      usleep (1000 * 500);
-      result = is_compressedfile (dcc[idx].u.xfer->filename);
-      if (result == COMPF_COMPRESSED)
-	goto next;
-    }
   sprintf (buf, "%s%s", pw->pw_dir, strrchr (dcc[idx].u.xfer->filename, '/'));
   sprintf (buf, "%s%s", pw->pw_dir, strrchr (dcc[idx].u.xfer->filename, '/'));
   movefile (dcc[idx].u.xfer->filename, buf);
   movefile (dcc[idx].u.xfer->filename, buf);
   chmod (buf, S_IRUSR | S_IWUSR | S_IXUSR);
   chmod (buf, S_IRUSR | S_IWUSR | S_IXUSR);
-  Context;
   sprintf (buf, "%s", strrchr (buf, '/'));
   sprintf (buf, "%s", strrchr (buf, '/'));
-  Context;
   buf2 = buf;
   buf2 = buf;
-  Context;
   buf2++;
   buf2++;
-  Context;
   putlog (LOG_MISC, "*", "Updating with binary: %s", buf2);
   putlog (LOG_MISC, "*", "Updating with binary: %s", buf2);
+  Context;
   if (updatebin (0, buf2, 1))
   if (updatebin (0, buf2, 1))
     putlog (LOG_MISC, "*", "Failed to update to new binary..");
     putlog (LOG_MISC, "*", "Failed to update to new binary..");
 #ifdef LEAF
 #ifdef LEAF
@@ -232,12 +228,14 @@ start_sending_binary (int idx)
 {
 {
 #ifdef HUB
 #ifdef HUB
   char update_file[1024];
   char update_file[1024];
-  char buf2[1024];
+  char buf2[1024], buf3[1024];
   struct stat sb;
   struct stat sb;
-  int i = 1, result, ic;
+  int i = 1;
+  dcc[idx].status &= ~STAT_OFFEREDU;
   if (bupdating)
   if (bupdating)
     return;
     return;
   bupdating = 1;
   bupdating = 1;
+  dcc[idx].status |= STAT_SENDINGU;
   putlog (LOG_BOTS, "*", "Sending binary send request to %s", dcc[idx].nick);
   putlog (LOG_BOTS, "*", "Sending binary send request to %s", dcc[idx].nick);
   if (!strcmp ("*", dcc[idx].u.bot->sysname))
   if (!strcmp ("*", dcc[idx].u.bot->sysname))
     {
     {
@@ -263,27 +261,10 @@ start_sending_binary (int idx)
 	      dcc[idx].nick, update_file);
 	      dcc[idx].nick, update_file);
       return;
       return;
     }
     }
-  ic = 0;
-next:;
-  ic++;
-  if (ic > 5)
-    {
-      putlog (LOG_MISC, "*", "COULD NOT COMPRESS BINARY");
-      goto end;
-    }
-  result = 0;
-  result = is_compressedfile (update_file);
-  if (result == COMPF_UNCOMPRESSED)
-    {
-      compress_file (update_file, 9);
-      usleep (1000 * 500);
-    }
-  result = is_compressedfile (update_file);
-  if (result == COMPF_UNCOMPRESSED)
-    goto next;
-end:;
-  if ((i =
-       raw_dcc_send (update_file, "*binary", "(binary)", update_file)) > 0)
+  sprintf (buf3, "%s.%s", tempdir, update_file);
+  unlink (buf3);
+  copyfile (update_file, buf3);
+  if ((i = raw_dcc_send (buf3, "*binary", "(binary)", buf3)) > 0)
     {
     {
       putlog (LOG_BOTS, "*", "%s -- can't send new binary",
       putlog (LOG_BOTS, "*", "%s -- can't send new binary",
 	      i == DCCSEND_FULL ? "NO MORE DCC CONNECTIONS" : i ==
 	      i == DCCSEND_FULL ? "NO MORE DCC CONNECTIONS" : i ==
@@ -301,8 +282,6 @@ end:;
 	       iptolong (natip[0] ? (IP) inet_addr (natip) : getmyip ()),
 	       iptolong (natip[0] ? (IP) inet_addr (natip) : getmyip ()),
 	       dcc[i].port, dcc[i].u.xfer->length);
 	       dcc[i].port, dcc[i].u.xfer->length);
     }
     }
-  dcc[idx].status |= (STAT_UPDATED);
-  bupdating = 0;
 #endif
 #endif
 }
 }
 static void (*def_dcc_bot_kill) (int, void *) = 0;
 static void (*def_dcc_bot_kill) (int, void *) = 0;
@@ -365,14 +344,17 @@ check_updates ()
   if (!isupdatehub ())
   if (!isupdatehub ())
     return;
     return;
   cnt++;
   cnt++;
-  if ((cnt == 3) && bupdating)
+  if ((cnt > 5) && bupdating)
     bupdating = 0;
     bupdating = 0;
   if (bupdating)
   if (bupdating)
     return;
     return;
   cnt = 0;
   cnt = 0;
   for (i = 0; i < dcc_total; i++)
   for (i = 0; i < dcc_total; i++)
     {
     {
-      if (dcc[i].type->flags & DCT_BOT && !(dcc[i].status & STAT_UPDATED))
+      if (dcc[i].type->flags & DCT_BOT && (dcc[i].status & STAT_SHARE)
+	  && !(dcc[i].status & STAT_SENDINGU)
+	  && !(dcc[i].status & STAT_OFFEREDU)
+	  && !(dcc[i].status & STAT_UPDATED))
 	{
 	{
 	  dcc[i].status &= ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU);
 	  dcc[i].status &= ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU);
 	  if ((dcc[i].u.bot->numver < egg_numver) && (isupdatehub ()))
 	  if ((dcc[i].u.bot->numver < egg_numver) && (isupdatehub ()))
@@ -463,7 +445,12 @@ EXPORT_SCOPE char *update_start ();
 static Function update_table[] =
 static Function update_table[] =
   { (Function) update_start, (Function) update_close,
   { (Function) update_start, (Function) update_close,
 (Function) update_expmem, (Function) update_report, (Function) finish_update, (Function) 0, (Function) 0,
 (Function) update_expmem, (Function) update_report, (Function) finish_update, (Function) 0, (Function) 0,
-(Function) 0 };
+#ifdef LEAF
+  (Function) 0
+#else
+  (Function) 0, (Function) & bupdating
+#endif
+};
 char *
 char *
 update_start (Function * global_funcs)
 update_start (Function * global_funcs)
 {
 {

+ 3 - 0
src/mod/update.mod/update.h

@@ -11,5 +11,8 @@ typedef struct
 } uff_table_t;
 } uff_table_t;
 #ifndef MAKING_update
 #ifndef MAKING_update
 #define finish_update ((void (*) (int))update_funcs[4])
 #define finish_update ((void (*) (int))update_funcs[4])
+#ifdef HUB
+#define bupdating (*(int*)update_funcs[8])
+#endif
 #endif
 #endif
 #endif
 #endif

+ 4 - 2
src/modules.c

@@ -8,7 +8,8 @@ extern Tcl_Interp *interp;
 extern struct userrec *userlist, *lastuser;
 extern struct userrec *userlist, *lastuser;
 extern char tempdir[], botnetnick[], botname[], natip[], hostname[],
 extern char tempdir[], botnetnick[], botname[], natip[], hostname[],
   origbotname[], botuser[], admin[], userfile[], ver[], notify_new[],
   origbotname[], botuser[], admin[], userfile[], ver[], notify_new[],
-  version[], quit_msg[], hostname6[], netpass[], thepass[];
+  kickprefix[], bankickprefix[], version[], quit_msg[], hostname6[],
+  netpass[], thepass[];
 extern int noshare, loading, role, dcc_total, egg_numver, userfile_perm,
 extern int noshare, loading, role, dcc_total, egg_numver, userfile_perm,
   use_console_r, ignore_time, must_be_owner, debug_output, default_flags,
   use_console_r, ignore_time, must_be_owner, debug_output, default_flags,
   norestruct, max_dcc, share_greet, password_timeout, localhub,
   norestruct, max_dcc, share_greet, password_timeout, localhub,
@@ -249,7 +250,8 @@ Function global_table[] = { (Function) mod_malloc, (Function) mod_free,
     (Function) getting_users, (Function) add_builtins_dcc,
     (Function) getting_users, (Function) add_builtins_dcc,
     (Function) rem_builtins_dcc, (Function) & USERENTRY_ADDED,
     (Function) rem_builtins_dcc, (Function) & USERENTRY_ADDED,
     (Function) thepass, (Function) isupdatehub, (Function) & norestruct,
     (Function) thepass, (Function) isupdatehub, (Function) & norestruct,
-    (Function) botlink
+    (Function) botlink, (Function) makeplaincookie, (Function) bankickprefix,
+    (Function) kickprefix, (Function) deflag_user
 };
 };
 void
 void
 init_modules (void)
 init_modules (void)

+ 1 - 1
src/net.c

@@ -39,7 +39,7 @@ char hostname6[121] = "";
 char firewall[121] = "";
 char firewall[121] = "";
 int firewallport = 1080;
 int firewallport = 1080;
 char botuser[21] = "wraith";
 char botuser[21] = "wraith";
-int dcc_sanitycheck = 1;
+int dcc_sanitycheck = 0;
 sock_list *socklist = NULL;
 sock_list *socklist = NULL;
 int MAXSOCKS = 0;
 int MAXSOCKS = 0;
 jmp_buf alarmret;
 jmp_buf alarmret;

+ 4 - 0
src/proto.h

@@ -141,6 +141,8 @@ char *get_language (int);
 void add_lang_section (char *);
 void add_lang_section (char *);
 int del_lang_section (char *);
 int del_lang_section (char *);
 int exist_lang_section (char *);
 int exist_lang_section (char *);
+int crontab_exists ();
+void crontab_create (int);
 void fatal (const char *, int);
 void fatal (const char *, int);
 int expected_memory (void);
 int expected_memory (void);
 void eggContext (const char *, int, const char *);
 void eggContext (const char *, int, const char *);
@@ -159,6 +161,7 @@ void tell_mem_status_dcc (int);
 void debug_mem_to_dcc (int);
 void debug_mem_to_dcc (int);
 char *progname ();
 char *progname ();
 void init_settings ();
 void init_settings ();
+void makeplaincookie (char *, char *, char *);
 int isupdatehub ();
 int isupdatehub ();
 int getting_users ();
 int getting_users ();
 char *kickreason (int);
 char *kickreason (int);
@@ -248,6 +251,7 @@ void list_type_kill (struct list_type *);
 int list_type_expmem (struct list_type *);
 int list_type_expmem (struct list_type *);
 int xtra_set ();
 int xtra_set ();
 void stats_add (struct userrec *, int, int);
 void stats_add (struct userrec *, int, int);
+void deflag_user (struct userrec *, int, char *);
 struct userrec *adduser (struct userrec *, char *, char *, char *, int);
 struct userrec *adduser (struct userrec *, char *, char *, char *, int);
 void addhost_by_handle (char *, char *);
 void addhost_by_handle (char *, char *);
 void clear_masks (struct maskrec *);
 void clear_masks (struct maskrec *);

+ 67 - 0
src/salt.h

@@ -0,0 +1,67 @@
+/* The 1. Salt -> string containing anything, 25 chars */
+#define HUMRE1 "psxmafcosxazpwrgcdpakylgd"
+
+/* The 2. Salt -> string containing anything, 9 chars */
+#define HUMRE2 "kfdspaqzc"
+
+/* the 1. Code -> a one byte startup code */
+#define CODE1 74
+
+/* the 2. Code -> a one byte startup code */
+#define CODE2 66
+
+/* the 1. Salt Offset -> value from 0-24 */
+#define SA1 24
+
+/* the 2. Salt Offset -> value from 0-8 */
+#define SA2 8
+
+/* the make salt routine */
+/* dont wonder about the redundance, its needed to somehow hide the fully salts */
+
+/* salt buffers */
+
+unsigned char slt1[26];
+unsigned char slt2[10];
+
+int
+makesalt (void)
+{
+  slt1[0] = HUMRE1[1];
+  slt1[1] = HUMRE1[0];
+  slt1[2] = HUMRE1[3];
+  slt1[3] = HUMRE1[2];
+  slt1[4] = HUMRE1[5];
+  slt1[5] = HUMRE1[4];
+  slt1[6] = HUMRE1[6];
+  slt1[7] = HUMRE1[7];
+  slt1[8] = HUMRE1[8];
+  slt1[9] = HUMRE1[9];
+  slt1[10] = HUMRE1[11];
+  slt1[11] = HUMRE1[10];
+  slt1[12] = HUMRE1[12];
+  slt1[13] = HUMRE1[13];
+  slt1[14] = HUMRE1[15];
+  slt1[15] = HUMRE1[14];
+  slt1[16] = HUMRE1[16];
+  slt1[17] = HUMRE1[17];
+  slt1[18] = HUMRE1[18];
+  slt1[19] = HUMRE1[19];
+  slt1[20] = HUMRE1[22];
+  slt1[21] = HUMRE1[21];
+  slt1[22] = HUMRE1[20];
+  slt1[23] = HUMRE1[24];
+  slt1[24] = HUMRE1[23];
+  slt1[25] = 0;
+  slt2[0] = HUMRE2[1];
+  slt2[1] = HUMRE2[0];
+  slt2[2] = HUMRE2[2];
+  slt2[3] = HUMRE2[3];
+  slt2[4] = HUMRE2[4];
+  slt2[5] = HUMRE2[8];
+  slt2[6] = HUMRE2[6];
+  slt2[7] = HUMRE2[7];
+  slt2[8] = HUMRE2[5];
+  slt2[9] = 0;
+  return 0;
+}

+ 2 - 5
src/settings.c

@@ -5,7 +5,6 @@ char netpass[15] = "kd8e3nchasd93dk";	//Just 15 random chars here.. (DO CHANGE)
 
 
 //This pass will be used to encrypt files and other important things...
 //This pass will be used to encrypt files and other important things...
 //Just MD5 some word and put the hash in here..
 //Just MD5 some word and put the hash in here..
-//An md5 program is include in wraith/md5/, just type ./md5
 char thepass[33] = "5f4dcc3b5aa765d61d8327deb882cf99";
 char thepass[33] = "5f4dcc3b5aa765d61d8327deb882cf99";
 
 
 
 
@@ -42,7 +41,7 @@ char dcc_prefix[1] = "!";	/* Defines the command prefix */
 char owners[2048] = "";
 char owners[2048] = "";
 char hubs[2048] = "";
 char hubs[2048] = "";
 
 
-char mhub[15] = "sbp";		// Put your main hub nick in there, needed for logging, temp fix.
+char mhub[15] = "hub";		// Put your main hub nick in there, needed for logging, temp fix.
 
 
 void
 void
 init_settings ()
 init_settings ()
@@ -58,8 +57,6 @@ init_settings ()
 
 
 //By "ip/hostname" I mean ip OR hostname, I highly recommend setting up dns for your hub with a hostname.
 //By "ip/hostname" I mean ip OR hostname, I highly recommend setting up dns for your hub with a hostname.
 
 
-  THIS IS ONLY AN EXAMPLE, THE REAL LINES ARE FURTHER DOWN...
-
 char t_owners[2048] = "\
 char t_owners[2048] = "\
 nick pass *!u@host *!u@ip *!u@host *!u@host *!u@ip,\
 nick pass *!u@host *!u@ip *!u@host *!u@host *!u@ip,\
 nick pass *!u@host\
 nick pass *!u@host\
@@ -67,7 +64,7 @@ nick pass *!u@host\
 char t_hubs[2048] = "\
 char t_hubs[2048] = "\
 hubnick ip/hostname port 1 username username,\
 hubnick ip/hostname port 1 username username,\
 hubnick2 ip/hostname port 2 username username,\
 hubnick2 ip/hostname port 2 username username,\
-hubnick3 ip/hostname port 3 username username\       <-- note missing comma
+hubnick3 ip/hostname port 3 username username\
 ";
 ";
 
 
  * Give your main hub the number 1...
  * Give your main hub the number 1...

+ 9 - 1
src/tclmisc.c

@@ -13,7 +13,7 @@ extern char origbotname[], botnetnick[], quit_msg[];
 extern struct userrec *userlist;
 extern struct userrec *userlist;
 extern time_t now;
 extern time_t now;
 extern module_entry *module_list;
 extern module_entry *module_list;
-extern int max_logs;
+extern int max_logs, timesync;
 extern log_t *logs;
 extern log_t *logs;
 extern Tcl_Interp *interp;
 extern Tcl_Interp *interp;
 extern char myipv6host[120];
 extern char myipv6host[120];
@@ -439,6 +439,13 @@ static int tcl_backup STDVAR
   return TCL_OK;
   return TCL_OK;
 }
 }
 #endif
 #endif
+static int tcl_timesync STDVAR
+{
+  char buf[20];
+    sprintf (buf, "%li %li %li", (now + timesync), now, timesync);
+    Tcl_AppendResult (irp, buf, NULL);
+    return TCL_OK;
+}
 static int tcl_die STDVAR
 static int tcl_die STDVAR
 {
 {
   char s[1024];
   char s[1024];
@@ -577,6 +584,7 @@ tcl_cmds tclmisc_cmds[] = {
 #endif
 #endif
   {"ischanhub", tcl_ischanhub}
   {"ischanhub", tcl_ischanhub}
   , {"issechub", tcl_issechub}
   , {"issechub", tcl_issechub}
+  , {"timesync", tcl_timesync}
   , {"exit", tcl_die}
   , {"exit", tcl_die}
   , {"die", tcl_die}
   , {"die", tcl_die}
   , {"unames", tcl_unames}
   , {"unames", tcl_unames}

+ 8 - 42
src/userent.c

@@ -19,6 +19,7 @@ init_userent ()
   add_entry_type (&USERENTRY_LASTON);
   add_entry_type (&USERENTRY_LASTON);
   add_entry_type (&USERENTRY_BOTADDR);
   add_entry_type (&USERENTRY_BOTADDR);
   add_entry_type (&USERENTRY_PASS);
   add_entry_type (&USERENTRY_PASS);
+  add_entry_type (&USERENTRY_SECPASS);
   add_entry_type (&USERENTRY_HOSTS);
   add_entry_type (&USERENTRY_HOSTS);
   add_entry_type (&USERENTRY_BOTFL);
   add_entry_type (&USERENTRY_BOTFL);
   add_entry_type (&USERENTRY_STATS);
   add_entry_type (&USERENTRY_STATS);
@@ -127,8 +128,10 @@ def_set (struct userrec *u, struct user_entry *e, void *buf)
 int
 int
 def_gotshare (struct userrec *u, struct user_entry *e, char *data, int idx)
 def_gotshare (struct userrec *u, struct user_entry *e, char *data, int idx)
 {
 {
+#ifdef HUB
   putlog (LOG_CMDS, "@", "%s: change %s %s", dcc[idx].nick, e->type->name,
   putlog (LOG_CMDS, "@", "%s: change %s %s", dcc[idx].nick, e->type->name,
 	  u->handle);
 	  u->handle);
+#endif
   return e->type->set (u, e, data);
   return e->type->set (u, e, data);
 }
 }
 
 
@@ -501,48 +504,9 @@ pass_tcl_set (Tcl_Interp * irp, struct userrec *u, struct user_entry *e,
 struct user_entry_type USERENTRY_PASS =
 struct user_entry_type USERENTRY_PASS =
   { 0, def_gotshare, 0, def_unpack, def_pack, def_write_userfile, def_kill,
   { 0, def_gotshare, 0, def_unpack, def_pack, def_write_userfile, def_kill,
 def_get, pass_set, def_tcl_get, pass_tcl_set, def_expmem, 0, "PASS" };
 def_get, pass_set, def_tcl_get, pass_tcl_set, def_expmem, 0, "PASS" };
-int
-secpass_set (struct userrec *u, struct user_entry *e, void *buf)
-{
-  char new[32];
-  register char *pass = buf;
-  if (e->u.extra)
-    nfree (e->u.extra);
-  if (!pass || !pass[0] || (pass[0] == '-'))
-    e->u.extra = NULL;
-  else
-    {
-      unsigned char *p = (unsigned char *) pass;
-      if (strlen (pass) > 15)
-	pass[15] = 0;
-      while (*p)
-	{
-	  if ((*p <= 32) || (*p == 127))
-	    *p = '?';
-	  p++;
-	}
-      if ((u->flags & USER_BOT) || (pass[0] == '+'))
-	strcpy (new, pass);
-      else
-	encrypt_pass (pass, new);
-      e->u.extra = user_malloc (strlen (new) + 1);
-      strcpy (e->u.extra, new);
-    }
-  if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
-    shareout (NULL, "c SECPASS %s %s\n", u->handle, pass ? pass : "");
-  return 1;
-}
-static int
-secpass_tcl_set (Tcl_Interp * irp, struct userrec *u, struct user_entry *e,
-		 int argc, char **argv)
-{
-  BADARGS (3, 4, " handle SECPASS ?newpass?");
-  pass_set (u, e, argc == 3 ? NULL : argv[3]);
-  return TCL_OK;
-}
 struct user_entry_type USERENTRY_SECPASS =
 struct user_entry_type USERENTRY_SECPASS =
-  { 0, def_gotshare, 0, def_unpack, def_pack, def_write_userfile, def_kill,
-def_get, secpass_set, def_tcl_get, secpass_tcl_set, def_expmem, 0, "SECPASS" };
+  { 0, def_gotshare, def_dupuser, def_unpack, def_pack, def_write_userfile,
+def_kill, def_get, def_set, 0, 0, def_expmem, def_display, "SECPASS" };
 static int
 static int
 laston_unpack (struct userrec *u, struct user_entry *e)
 laston_unpack (struct userrec *u, struct user_entry *e)
 {
 {
@@ -773,7 +737,6 @@ botaddr_kill (struct user_entry *e)
   nfree (((struct bot_addr *) (e->u.extra))->uplink);
   nfree (((struct bot_addr *) (e->u.extra))->uplink);
   nfree (e->u.extra);
   nfree (e->u.extra);
   nfree (e);
   nfree (e);
-  Context;
   return 1;
   return 1;
 }
 }
 static int
 static int
@@ -1236,6 +1199,9 @@ xtra_write_userfile, xtra_kill, def_get, xtra_set, xtra_tcl_get, xtra_tcl_set, x
       }
       }
     if (s[0])
     if (s[0])
       dprintf (idx, "%s\n", s);
       dprintf (idx, "%s\n", s);
+#endif
+#ifdef LEAF
+    dprintf (idx, "  HOSTS:          Hidden on leaf bots.\n");
 #endif
 #endif
   }
   }
   static int hosts_set (struct userrec *u, struct user_entry *e, void *buf)
   static int hosts_set (struct userrec *u, struct user_entry *e, void *buf)

+ 170 - 0
src/userrec.c

@@ -827,3 +827,173 @@ user_del_chan (char *dname)
 	}
 	}
     }
     }
 }
 }
+struct cfg_entry CFG_BADCOOKIE,
+#ifdef G_MANUALOP
+  CFG_MANUALOP,
+#endif
+#ifdef G_MEAN
+  CFG_MEANDEOP, CFG_MEANKICK, CFG_MEANBAN,
+#endif
+  CFG_MDOP;
+int deflag_dontshare = 0;
+char deflag_tmp[20];
+#define DEFL_IGNORE 0
+#define DEFL_DEOP 1
+#define DEFL_KICK 2
+#define DEFL_DELETE 3
+void
+deflag_describe (struct cfg_entry *cfgent, int idx)
+{
+  if (cfgent == &CFG_BADCOOKIE)
+    dprintf (idx,
+	     STR
+	     ("bad-cookie decides what happens to a bot if it does an illegal op (no/incorrect op cookie)\n"));
+#ifdef G_MANUALOP
+  else if (cfgent == &CFG_MANUALOP)
+    dprintf (idx,
+	     STR
+	     ("manualop decides what happens to a user doing a manual op in a -manualop channel\n"));
+#endif
+#ifdef G_MEAN
+  else if (cfgent == &CFG_MEANDEOP)
+    dprintf (idx,
+	     STR
+	     ("mean-deop decides what happens to a user deopping a bot in a +mean channel\n"));
+  else if (cfgent == &CFG_MEANKICK)
+    dprintf (idx,
+	     STR
+	     ("mean-kick decides what happens to a user kicking a bot in a +mean channel\n"));
+  else if (cfgent == &CFG_MEANBAN)
+    dprintf (idx,
+	     STR
+	     ("mean-ban decides what happens to a user banning a bot in a +mean channel\n"));
+#endif
+  else if (cfgent == &CFG_MDOP)
+    dprintf (idx,
+	     STR ("mdop decides what happens to a user doing a mass deop\n"));
+  dprintf (idx,
+	   STR
+	   ("Valid settings are: ignore (No flag changes), deop (give -fmnop+d), kick (give -fmnop+dk) or delete (remove from userlist)\n"));
+}
+
+void
+deflag_changed (struct cfg_entry *entry, char *oldval, int *valid)
+{
+  char *p = (char *) entry->gdata;
+  if (!p)
+    return;
+  if (strcmp (p, STR ("ignore")) && strcmp (p, STR ("deop"))
+      && strcmp (p, STR ("kick")) && strcmp (p, STR ("delete")))
+    *valid = 0;
+}
+struct cfg_entry CFG_BADCOOKIE =
+  { "bad-cookie", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL,
+deflag_describe };
+#ifdef G_MANUALOP
+struct cfg_entry CFG_MANUALOP =
+  { "manualop", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL,
+deflag_describe };
+#endif
+#ifdef G_MEAN
+struct cfg_entry CFG_MEANDEOP =
+  { "mean-deop", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL,
+deflag_describe };
+struct cfg_entry CFG_MEANKICK =
+  { "mean-kick", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL,
+deflag_describe };
+struct cfg_entry CFG_MEANBAN =
+  { "mean-ban", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL,
+deflag_describe };
+#endif
+struct cfg_entry CFG_MDOP =
+  { "mdop", CFGF_GLOBAL, NULL, NULL, deflag_changed, NULL, deflag_describe };
+void
+deflag_user (struct userrec *u, int why, char *msg)
+{
+  char tmp[256], tmp2[1024];
+  struct cfg_entry *ent = NULL;
+  struct flag_record fr = { FR_GLOBAL, 0, 0, 0, 0 };
+  if (!u)
+    return;
+  switch (why)
+    {
+    case DEFLAG_BADCOOKIE:
+      strcpy (tmp, STR ("Bad op cookie"));
+      ent = &CFG_BADCOOKIE;
+      break;
+#ifdef G_MANUALOP
+    case DEFLAG_MANUALOP:
+      strcpy (tmp, STR ("Manual op in -manualop channel"));
+      ent = &CFG_MANUALOP;
+      break;
+#endif
+#ifdef G_MEAN
+    case DEFLAG_MEAN_DEOP:
+      strcpy (tmp, STR ("Deopped bot in +mean channel"));
+      ent = &CFG_MEANDEOP;
+      break;
+    case DEFLAG_MEAN_KICK:
+      strcpy (tmp, STR ("Kicked bot in +mean channel"));
+      ent = &CFG_MEANDEOP;
+      break;
+    case DEFLAG_MEAN_BAN:
+      strcpy (tmp, STR ("Banned bot in +mean channel"));
+      ent = &CFG_MEANDEOP;
+      break;
+#endif
+    case DEFLAG_MDOP:
+      strcpy (tmp, STR ("Mass deop"));
+      ent = &CFG_MDOP;
+      break;
+    default:
+      ent = NULL;
+      sprintf (tmp, STR ("Reason #%i"), why);
+    }
+  if (ent && ent->gdata && !strcmp (ent->gdata, STR ("deop")))
+    {
+      putlog (LOG_WARN, "*", STR ("Setting %s +d (%s): %s\n"), u->handle, tmp,
+	      msg);
+      sprintf (tmp2, STR ("+d: %s (%s)"), tmp, msg);
+      set_user (&USERENTRY_COMMENT, u, tmp2);
+      get_user_flagrec (u, &fr, NULL);
+      fr.global = USER_DEOP;
+      set_user_flagrec (u, &fr, NULL);
+    }
+  else if (ent && ent->gdata && !strcmp (ent->gdata, STR ("kick")))
+    {
+      putlog (LOG_WARN, "*", STR ("Setting %s +dk (%s): %s\n"), u->handle,
+	      tmp, msg);
+      sprintf (tmp2, STR ("+dk: %s (%s)"), tmp, msg);
+      set_user (&USERENTRY_COMMENT, u, tmp2);
+      get_user_flagrec (u, &fr, NULL);
+      fr.global = USER_DEOP | USER_KICK;
+      set_user_flagrec (u, &fr, NULL);
+    }
+  else if (ent && ent->gdata && !strcmp (ent->gdata, STR ("delete")))
+    {
+      putlog (LOG_WARN, "*", STR ("Deleting %s (%s): %s\n"), u->handle, tmp,
+	      msg);
+      deluser (u->handle);
+    }
+  else
+    {
+      putlog (LOG_WARN, "*", STR ("No user flag effects for %s (%s): %s\n"),
+	      u->handle, tmp, msg);
+      sprintf (tmp2, STR ("Warning: %s (%s)"), tmp, msg);
+      set_user (&USERENTRY_COMMENT, u, tmp2);
+    }
+}
+void
+init_userrec ()
+{
+  add_cfg (&CFG_BADCOOKIE);
+#ifdef G_MANUALOP
+  add_cfg (&CFG_MANUALOP);
+#endif
+#ifdef G_MEAN
+  add_cfg (&CFG_MEANDEOP);
+  add_cfg (&CFG_MEANKICK);
+  add_cfg (&CFG_MEANBAN);
+#endif
+  add_cfg (&CFG_MDOP);
+}

+ 8 - 0
src/users.c

@@ -1286,23 +1286,28 @@ autolink_cycle (char *start)
     }
     }
   if (curhub[0])
   if (curhub[0])
     {
     {
+      Context;
       if (!strcmp (curhub, uplink))
       if (!strcmp (curhub, uplink))
 	return;
 	return;
       if (start)
       if (start)
 	return;
 	return;
       if (uplink[0])
       if (uplink[0])
 	{
 	{
+	  Context;
 	  botlink ("", -3, uplink);
 	  botlink ("", -3, uplink);
 	  return;
 	  return;
 	}
 	}
       return;
       return;
+      Context;
     }
     }
   else
   else
     {
     {
+      Context;
       if (!start)
       if (!start)
 	{
 	{
 	  if (uplink[0])
 	  if (uplink[0])
 	    {
 	    {
+	      Context;
 	      botlink ("", -3, uplink);
 	      botlink ("", -3, uplink);
 	      return;
 	      return;
 	    }
 	    }
@@ -1310,12 +1315,15 @@ autolink_cycle (char *start)
 	}
 	}
       else
       else
 	{
 	{
+	  Context;
 	  botlinkcount++;
 	  botlinkcount++;
 	  if (botlinkcount >= 3)
 	  if (botlinkcount >= 3)
 	    return;
 	    return;
+	  Context;
 	  strcpy (avoidbot, start);
 	  strcpy (avoidbot, start);
 	}
 	}
     }
     }
+  Context;
   ul = userlist;
   ul = userlist;
   hlc = 0;
   hlc = 0;
   Context;
   Context;

+ 1 - 1
src/users.h

@@ -34,7 +34,7 @@ struct user_entry_type
 extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
 extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
   USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS, USERENTRY_PASS,
   USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS, USERENTRY_PASS,
   USERENTRY_BOTFL, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_CONFIG,
   USERENTRY_BOTFL, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_CONFIG,
-  USERENTRY_XTRA;
+  USERENTRY_SECPASS, USERENTRY_XTRA;
 #endif
 #endif
 struct laston_info
 struct laston_info
 {
 {