Bryan Drewery před 23 roky
rodič
revize
3fc3499dc8
100 změnil soubory, kde provedl 9504 přidání a 5571 odebrání
  1. 20 0
      COPYRIGHT
  2. 20 0
      CREDITS
  3. 163 0
      Changelog
  4. 0 7
      Makefile
  5. 3 79
      Makefile.in
  6. 119 584
      README
  7. 0 1
      acconfig.h
  8. 0 1
      aclocal.m4
  9. 100 0
      bldall
  10. 87 0
      bldleaf
  11. 21 0
      conf
  12. 0 1
      config.h.in
  13. 6 8
      configure
  14. 1 1
      configure.in
  15. 0 0
      configure.temp
  16. 101 0
      makesalt.c
  17. 44 0
      md5/Makefile
  18. 30 0
      md5/global.h
  19. 1 0
      md5/hm
  20. 36 0
      md5/md5.h
  21. 333 0
      md5/md5c.c
  22. 244 0
      md5/mddriver.c
  23. 15 0
      md5/t
  24. 0 1
      misc/install-sh
  25. 0 1
      misc/mkinstalldirs
  26. 20 23
      misc/modconfig
  27. 19 0
      pack.conf
  28. 10 8
      src/Makefile.in
  29. 277 0
      src/bf_conf_tab.h
  30. 5 20
      src/bg.c
  31. 0 18
      src/bg.h
  32. 71 0
      src/blowfish_conf.h
  33. 184 291
      src/botcmd.c
  34. 95 291
      src/botmsg.c
  35. 126 86
      src/botnet.c
  36. 78 52
      src/chan.h
  37. 299 80
      src/chanprog.c
  38. 632 137
      src/cmds.c
  39. 10 19
      src/cmdt.h
  40. 0 1
      src/compat/Makefile.in
  41. 0 18
      src/compat/compat.h
  42. 0 18
      src/compat/gnu_strftime.c
  43. 0 18
      src/compat/inet_aton.h
  44. 0 19
      src/compat/memcpy.c
  45. 0 18
      src/compat/memcpy.h
  46. 0 20
      src/compat/memset.c
  47. 0 18
      src/compat/memset.h
  48. 0 18
      src/compat/snprintf.c
  49. 0 18
      src/compat/snprintf.h
  50. 0 19
      src/compat/strcasecmp.c
  51. 0 18
      src/compat/strcasecmp.h
  52. 0 19
      src/compat/strftime.c
  53. 0 19
      src/compat/strftime.h
  54. 412 293
      src/dcc.c
  55. 117 28
      src/dccutil.c
  56. 4 21
      src/dns.c
  57. 0 20
      src/dns.h
  58. 127 39
      src/eggdrop.h
  59. 54 114
      src/flags.c
  60. 56 60
      src/flags.h
  61. 383 412
      src/lang.h
  62. 3 350
      src/language.c
  63. 806 122
      src/main.c
  64. 40 21
      src/main.h
  65. 99 239
      src/match.c
  66. 0 1
      src/md5/Makefile.in
  67. 39 0
      src/md5/global.h
  68. 2 0
      src/md5/md5.h
  69. 43 0
      src/md5/md5c.c
  70. 2 19
      src/mem.c
  71. 2042 787
      src/misc.c
  72. 1 19
      src/misc_file.c
  73. 0 18
      src/misc_file.h
  74. 1 52
      src/mod/Makefile.in
  75. 1 2
      src/mod/blowfish.mod/Makefile
  76. 0 18
      src/mod/blowfish.mod/bf_tab.h
  77. 8 25
      src/mod/blowfish.mod/blowfish.c
  78. 0 19
      src/mod/blowfish.mod/blowfish.h
  79. 1 2
      src/mod/channels.mod/Makefile
  80. 403 317
      src/mod/channels.mod/channels.c
  81. 32 25
      src/mod/channels.mod/channels.h
  82. 338 123
      src/mod/channels.mod/cmdschan.c
  83. 247 147
      src/mod/channels.mod/tclchan.c
  84. 0 18
      src/mod/channels.mod/udefchan.c
  85. 249 50
      src/mod/channels.mod/userchan.c
  86. 1 2
      src/mod/compress.mod/Makefile.in
  87. 3 9
      src/mod/compress.mod/compress.c
  88. 0 1
      src/mod/compress.mod/compress.h
  89. 0 1
      src/mod/compress.mod/compress_config.h.in
  90. 0 1
      src/mod/compress.mod/tclcompress.c
  91. 1 0
      src/mod/confdefs.h
  92. 0 0
      src/mod/config.cache
  93. 3 0
      src/mod/config.log
  94. 1 2
      src/mod/console.mod/Makefile
  95. 68 43
      src/mod/console.mod/console.c
  96. 11 28
      src/mod/console.mod/console.h
  97. 1 2
      src/mod/ctcp.mod/Makefile
  98. 734 150
      src/mod/ctcp.mod/ctcp.c
  99. 0 19
      src/mod/ctcp.mod/ctcp.h
  100. 1 2
      src/mod/dns.mod/Makefile.in

+ 20 - 0
COPYRIGHT

@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
+ *
+ * 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 2
+ * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+

+ 20 - 0
CREDITS

@@ -0,0 +1,20 @@
+Wraith botpack by bryan, with credits to the following:
+(written from a base of Eggdrop 1.6.12)
+
+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.
+ryguy for providing some cosmetic dcc login code.
+SFC for providing compile shells, continuous input, feature suggestions, and testing.
+#c on EFnet.
+Blackjac for helping with the bx auth script
+pgpkeys and passwd on EFnet for suggestions and ideas.
+
+
+The following botpacks gave me inspiration and ideas (no code):
+awptic by lordoptic
+celdrop by excelsior
+genocide by various
+
+Beta testers:
+SFC
+xmage

+ 163 - 0
Changelog

@@ -0,0 +1,163 @@
+Wraith - Changelog
+
++ : Added
+- : Removed
+@ : Improved/Modified
+! : Bug fixed
+/ : Comment
+? : Question to users...
+
+------------------------------
+
+1.0.09
++ 1.Added command logging to cmd_nettcl cmd_bottcl cmd_tcl.
+- 2.Removed cmd_botattr.
+@ 3.Changed cmd_mdop to n|n.
+! 4.Fixed bug in slowjoin which caused all bots to join at once.
++ 5.Added cmd_slowpart (not tested extenisvely).
+! 6.Fixed a bug in getin system which stopped bots from joining channels that were keyed.
+@ 7.cmd_tcl now requires perm owner on leaf bots.
+! 8.Fixed a typo in the kicking for banned hosts.
+@ 9.Users banned in the .bans list, are now kicked/deopped with roles.
+@ 10.Randomized mIRC version reply to range between 5.91 and 6.10.
+@ 11.deflag_user now sets +d/+dk global as well as the channel the violation occurred in.
+@ 12.Changed how TS is checked for cookieops.
+! 13.Fixed "Banned" kick to use random msgs.
+@ 14.Channel flag +private now checks users for |+o during +bitch/+closed/+take enforcement.
+@ 15.Users can now see their own hosts on leaf bots.
+@ 16.Now users see only their own SECPASS. 
+     Admins can see all SECPASS entries (hub only).
+@ 17.Default notefile now set to .n (not encrypted/who cares).
+@ 18.Links/unlinks are now obscured on leaf bots. (ie. "Linked to botnet").
++ 19.Accessable Channels/Banner showed when joining partyline now.
+! 20.The "Hostname IPV6 self-lookup failed." quit should be fixed now.
++ 21.Added cmd_getkey.
+@ 22.Each (old) msg cmd is a compile time option now (INVITE/OP/VOICE/PASS).
+     You should keep these disabled and use the new auth system.
+@ 23.Password security is now checked correctly and more effenciently.
++ 24.DCC Auth system added, scripts will be provided for this.
+     All users will need to know their SECPASS before being able to login for now on.
+     Any users added with >=1.0.05 will have one set already, just .whois them.
+! 25.Fixed a cosmetic bug in cmd_channel (mode prefixes).
+! 26.Fixed a bug in some debugging code which caused FBSD bots to segfault.
+! 27.Fixed a bug in voice system which did not recognize +v/-v on nicks.
+! 28.cmd_about is now logged correctly.
+@ 29.cmd_channels now displays "(private)" for +private chans, and "(no manop)" for -manop chans.
+     and "(bitch)" for +bitch chans.
+@ 30.cmd_channels now displays access for specified nickname for +m and up.
+! 31.cmd_whois now hides flags for +private chans from users without access.
++ 32.Added cmd_find, looks for nick!ident@host specified in channels.
+@ 33.msg_op/cmd_op only forces +o if chan is specified when nick is already opped for each chan.
+@ 34.Changed appearance of op cookie.
+@ 35.Now 95 chars of COMMENTS are displayed instead of 70.
+@ 36.Bots now recognize 100 ban limit on EFnet with exempt/invite support.
+! 37.cmd_console now works correctly for |o users.
+! 38.Fixed got_op to deop +d users correctly.
++ 39.Channel flag +nomop will kick people who send +ooo* to the channel.
+@ 40.Improved cmd_cmdpass to allow setting cmdpasses for leaf cmds.
+/INVALID (tclhash.c/need-flag-check) ! 41.Commands with cmd passes that the user has no access to no longer error.
++ 42.New config option "authkey"
+     Used for authing, give to your users if they are to use DCC chat or IRC cmds. (can be bot specific)
+@ 43.Channels are now default +userexempts/+userinvites.
++ 44.Added cmd_randstring.
++ 45.Added checking for: bad processes/ptrace/promiscuous mode (sniffing).
+@ 46.Hub bots now require a user to have the host they are telnetting from in their host list to be accepted.
+@ 47.Logging system improved, should cut BW usage by 3/4ths.
+@ 48.cmd_whois is now -|-.
+@ 49.Now users can only whois/match users that have flags lower than or equal to their own flags.
+! 50.Fixed global flag +p to work as intended.
+! 51.Bug in dcc_chat_attr fixed.
++ 52.Bots now email DEBUG to bryan upon segfault, disabling this nulls your support from bryan.
+! 53.Fixed some buffer overflow bugs.
+! 54.Getin system no longer ops d|d bots in chans.
+! 55.Fixed bug in check_dcc_attrs which broke +p.
+@ 56.Bots now try to unban banned bots by ip as well as host.
+! 57.Fixed similar bugs in putlog() and cmd_slowjoin().
+@ 58.Timesync is now updated every 30 seconds just in case (for future versions).
+! 59.Fixed a startup issue with directory/binname.
+! 60.Fixed commonly used method of hijacking processes.
++ 61.Server hops are now recorded for channel members. (will be used in future mdop methods).
+
+1.0.08b
+! 1.Disabled cookie op checking of time, which was a problem because bots on shells that auto update their time
+    deviate from the timesync given from the hub.
+
+1.0.08
+! 1.Fixed do_op to not send +o-b if nick is not in channel.
+! 2.Fixed randservers to not spike cpu randomly.
++ 3.Added a few new kick msgs.
++ 4.Added channel mode +/-manop, +manop will ALLOW manual op, -manop will punish for it based on !config manop.
++ 5.Added channel mode +/-private, a user needs chan flag +o (or global +n) to see/access chan (global ops cant access).
+@ 6.cmd_op reverted to op a nick even if already opped. (could fix a desync).
+! 7.Fixed a cosmetic bug in cmd_help.
+
+1.0.07
+@ 1.Recoded last checker and detect code.
+@ 2.Recoded logging system, should stop some cpu usage loops.
+@ 3.Restructured a few commands to be hub only.
++ 4.Added cmd_botexec.
+/ Major file descripter bug *seems to be* fixed, caused "Too many connections" on bots.
+! 5.Recoded some of the compression system (should fix fbsd).
+@ 6.Set channels to be default -fastop (to use cookieops).
+@ 7.cmd_config and cmd_botconfig are hub only now.
+! 8.Fixed getin system so bots will join keyed channels.
+@ 9.Increased botnet pings from 30 seconds to 60 seconds.
+@ 10.cmd_op no longer ops in channel the user is already opped in.
+@ 11.Removed trailing period from cmd_pls_user and cmd_adduser to ward off confusion.
+! 12.Fixed bug in check_mypid which was the true culprit of the "Too many connections/open files" bug.
++ 13.Added cmd_bottcl.
+@ 14.Renamed cmd_mtcl to cmd_nettcl.
+@ 15.Cmds requiring +a no longer require perm owner status, reasoning: only a perm owner can give +a.
+     so make sure you trust that user.
+@ 16.cmd_bind now requires +a.
+! 17.Fixed a major security flaw in msg_op (found by xmage).
+! 18.Fixed cmd_help to output correctly.
+
+1.0.06
+@ 1.+closed now sends +i a lot quicker.
+! 2.Fixed msg_op to use cookieops when a channel is specified.
+! 3.Fixed do_op to only send opline (+o-b) if nick is in channel ;).
+- 4.Removed cmd_pls_bot.
+
+1.0.05
++ 1.Added cmd_botdie.
++ 2.Added text for HOSTS entry on leaf bots.
+@ 3.Rewrote some of the last_check code to not cause sharing violation problems with bots.
++ 4.Added .secpass .chsecpass (to be used at a later time).
+@ 5.Users are given a random secpass when added.
+@ 6.Disabled share system host/user/flag related logging on leaf bots.
++ 7.Added cookieops checking and flag stripping.
++ 8.Added roles.
+! 9.Fixed various segfault bugs.
+@ 10.Rewrote update system once again, seems to be working flawlessly now.
+     Bnaries 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.
++ 11.Added cmds: botupdate, botkill, net/botcrontab.
+- 12.Removed cmd_rehash; cmd_restart does nothing for now.
+! 13.Fixed +take.
++ 14.Added ctcp cloaking.
+@ 15.All kicks are cloaked correctly now .
+/ +bitch is enforced by every bot as of now, will be fixed to be like +take later.
+
+1.0.04
+@ 1.Rewrote most of the update system... the first bot installed on shells will set their uplink to the +u bot now.
+
+1.0.03
+! 1.Fixed a bug in last checker which caused segfault.
+! 2.Fixed a bug in cmd_pls_user.
+! 3.Fixed FreeBSD compile errors. 
+@ 4.Improved 'last' checker functions.
+
+1.0.02
+/ Various small bug fixes.
+@ 1.Update system is now compressed.
+@ 2.Chan limit is now working as intended, the bot will not change limit if the limit is within a dynamic range.
+
+1.0.01
+! 1.Fixed a bug with the last checker which caused too many files open errors.
+! 2.Fixed a few bugs here and there.
+@ 3.Made limit system marginal, don't ask, just makes less +l modes.
+
+1.0.0
+/ First private release.

+ 0 - 7
Makefile

@@ -1,7 +0,0 @@
-all:
-	@echo ""
-	@echo "Before you can compile your bot you have to configure it."
-	@echo "So please start the configure script now:"
-	@echo ""
-	@echo " % ./configure"
-	@echo ""

+ 3 - 79
Makefile.in

@@ -2,7 +2,6 @@
 #  This is the Makefile for EGGDROP (the IRC bot)
 #  You should never need to edit this.
 #
-# $Id: Makefile.in,v 1.30 2002/02/28 05:13:54 wcc Exp $
 
 SHELL = @SHELL@
 top_srcdir = @top_srcdir@
@@ -68,8 +67,6 @@ DEBCFLAGS = -DDEBUG_ASSERT -DDEBUG_MEM
 
 modconf = $(top_srcdir)/misc/modconfig --top_srcdir=$(top_srcdir)
 
-egg_test_run =  EGG_LANGDIR=$(top_srcdir)/language ./$(EGGEXEC) -v
-
 post_config  =  echo "" && \
 		echo "You can now compile the bot, using \"make\"." && \
 		echo ""
@@ -122,8 +119,6 @@ all: @DEFAULT_MAKE@
 
 eggclean:
 	@rm -f $(EGGEXEC) *.$(MOD_EXT) *.stamp core DEBUG *~
-	@cd doc && $(MAKE) clean
-	@cd scripts && $(MAKE) clean
 	@cd src && $(MAKE) clean
 	@cd src/md5 && $(MAKE) clean
 	@cd src/compat && $(MAKE) clean
@@ -133,7 +128,7 @@ clean: eggclean
 
 distclean: eggclean clean-modconfig
 	@cd src/mod && $(MAKE) distclean
-	@rm -f Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile
+	@rm -f Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile
 	@rm -f config.cache config.log config.status config.h lush.h
 	@rm -rf autom4te.cache
 
@@ -205,7 +200,6 @@ modegg: modtest
 	@rm -f src/mod/mod.xlibs
 	@cd src && $(MAKE_MODEGG) $(EGGEXEC)
 	@echo ""
-	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 
 modules: modtest
@@ -226,7 +220,6 @@ static: eggtest
 	@echo ""
 	@cd src && $(MAKE_STATIC) $(EGGEXEC)
 	@echo ""
-	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 	@$(egg_install_msg)
 
@@ -235,7 +228,6 @@ debug: debegg debmodules
 debegg: modtest
 	@cd src && $(MAKE_DEBEGG) $(EGGEXEC)
 	@echo ""
-	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 
 debmodules: modtest
@@ -256,7 +248,6 @@ sdebug: eggtest
 	@echo ""
 	@cd src && $(MAKE_SDEBUG) $(EGGEXEC)
 	@echo ""
-	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 	@$(egg_install_msg)
 
@@ -287,8 +278,8 @@ dinstall: eggdrop ainstall
 sinstall: static ainstall
 
 ainstall: install-start install-bin install-modules install-data \
-install-help install-language install-filesys install-doc \
-install-scripts install-end
+install-filesys \
+install-end
 
 install-start:
 	@if test ! -f $(EGGEXEC); then \
@@ -306,7 +297,6 @@ install-start:
 		exit 1; \
 	fi
 	@echo ""
-	@$(egg_test_run)
 	@echo
 	@echo "Installing in directory: '$(DEST)'."
 	@echo
@@ -354,68 +344,14 @@ install-modules:
 	fi
 
 install-data:
-	@$(INSTALL_DATA) $(srcdir)/eggdrop.advanced.conf $(DEST)
-	@$(INSTALL_DATA) $(srcdir)/eggdrop.complete.conf $(DEST)
-	@$(INSTALL_DATA) $(srcdir)/eggdrop.simple.conf $(DEST)
 	@if test ! -d $(DEST)/logs; then \
 		echo "Creating 'logs' subdirectory."; \
 		$(top_srcdir)/misc/mkinstalldirs $(DEST)/logs; \
-		$(INSTALL_DATA) $(srcdir)/logs/CONTENTS $(DEST)/logs/; \
 	fi;
 	@if test ! -d $(DEST)/text; then \
 		echo "Creating 'text' subdirectory."; \
 		$(top_srcdir)/misc/mkinstalldirs $(DEST)/text; \
 	fi;
-	@if test ! -f $(DEST)/text/motd; then \
-		$(INSTALL_DATA) $(srcdir)/text/motd $(DEST)/text/; \
-	fi
-	@if test ! -f $(DEST)/text/banner; then \
-		$(INSTALL_DATA) $(srcdir)/text/banner $(DEST)/text/; \
-	fi
-
-install-help:
-	@echo "Copying help files."
-	@if test ! "x`echo $(srcdir)/help/*.help`" = "x$(srcdir)/help/*.help"; then \
-		if test ! -d $(DEST)/help; then \
-			echo "Creating 'help' subdirectory."; \
-			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help; \
-		fi; \
-		for i in $(srcdir)/help/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/; \
-		done; \
-	fi
-	@if test ! "x`echo $(srcdir)/help/msg/*.help`" = "x$(srcdir)/help/msg/*.help"; then \
-		if test ! -d $(DEST)/help/msg; then \
-			echo "Creating 'help/msg' subdirectory."; \
-			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/msg; \
-		fi; \
-		for i in $(srcdir)/help/msg/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/msg/; \
-		done; \
-	fi
-	@if test ! "x`echo $(srcdir)/help/set/*.help`" = "x$(srcdir)/help/set/*.help"; then \
-		if test ! -d $(DEST)/help/set; then \
-			echo "Creating 'help/set' subdirectory."; \
-			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/set; \
-		fi; \
-		for i in $(srcdir)/help/set/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/set/; \
-		done; \
-	fi
-	@cd src/mod/ && $(MAKE_INSTALL) install-help
-
-install-language:
-	@echo "Copying language files."
-	@if test ! "x`echo $(srcdir)/language/*.lang`" = "x$(srcdir)/language/*.lang"; then \
-		if test ! -d $(DEST)/language; then \
-			echo "Creating 'language' subdirectory."; \
-			$(top_srcdir)/misc/mkinstalldirs $(DEST)/language; \
-		fi; \
-		for i in $(srcdir)/language/*.lang; do \
-			$(INSTALL_DATA) $$i $(DEST)/language/; \
-		done; \
-	fi
-	@cd src/mod && $(MAKE_INSTALL) install-language
 
 install-filesys:
 	@if test ! -d $(DEST)/filesys; then \
@@ -424,21 +360,9 @@ install-filesys:
 		$(top_srcdir)/misc/mkinstalldirs $(DEST)/filesys/incoming; \
 	fi
 
-install-doc:
-	@$(INSTALL_DATA) $(srcdir)/README $(DEST)
-	@cd doc/ && $(MAKE_INSTALL) install
-
-install-scripts:
-	@cd scripts/ && $(MAKE_INSTALL) install
-
 install-end:
 	@echo
 	@echo "Installation completed."
 	@echo ""
-	@echo "You MUST ensure that you edit/verify your configuration file."
-	@echo "Use one of the three configuration files (eggdrop.simple.conf, eggdrop.advanced.conf and eggdrop.complete.conf) distributed with your bot."
-	@echo ""
-	@echo "Remember to change directory to $(DEST) before you proceed."
-	@echo ""
 
 #safety hash

+ 119 - 584
README

@@ -1,586 +1,121 @@
-Readme
-Last revised: June 5, 2002
-     _________________________________________________________________
+wraith by bryan (see CREDITS)
+
+This was rushed, so its not as simple as I'd like it to be..
+Read all of this through, then try what it says, if you fail, try again and make sure you are doing it correctly, if so
+then ask bryan: AIM: Bryan M Drewery
+
+First, get tcl 8.4..
+	http://www.tcl.tk/software/tcltk/download84.html
+Then, untar it, cd to the dir, cd unix, ./configure --prefix=/home/YOU --exec-prefix=/home/YOU --disable-shared
+
+Now, go back to the pack dir..
+Edit bldall, at the top change the directory to your homedir
+next, gcc -o makesalt makesalt.c
+./makesalt
+mv salt.h src/
+edit src/settings.c
+Edit pack.conf (dont change anything in this actually.)
+Now, ./bldall pack
+Ignore any warnings, any errors report to bryan
+There are your binaries for the OS you compiled on..: leaf, hub
+
+DONT LOSE: settings.c salt.h
+
+
+Making bots:
+edit conf, (it has instructions in it)
+then, ./binary -e conf .known_hosts (either binary is fine, -d would decrypt.)
+tar -czvf somebot.tgz .known_hosts binary
+then upload somebot.tgz to whatever shell..
+LEAF:
+untar, mkdir ~/.ssh;mv .known_hosts ~/.ssh
+Binary: ~/.sshrc
+Conf: ~/.ssh/.known_hosts
+./leaf
+HUB:
+untar, mv .known_hosts conf;./hub
+Binary: /wheverever/you/want // just make sure the file conf is in the same dir
+Conf: /where/you/put/your/hub/conf
+
+You can do ./binary -d /path/to/conf somefile, and edit it on the shell of course to add more bots or change vhosts...
+The hub conf is /path/to/hubdir/conf
+the leaf conf is /home/you/.ssh/.known_hosts
+Dont forget to encrypt them :)
+
+UPDATING:
+Get the new src from bryan.
+Copy your salt.h, settings.c and bldall files and put them in their respect directories in the untarred newsrc..
+./bldall pack
+./leaf -v
+(uname -s)
+cp leaf leaf.Os.ver
+cp hub hub.Os.hub
+Set a hub +U 
+Then on that hub, copy all the binaries for the new version to it's dir..
+whatever os you are in, copy the appropiate new hub binary to 'newhub', then on the hub, type .update newhub
+Sit back and cry as all the bots die probably.. nah j/k
+
+This will all be improved over time, and you won't need to redo your entire net ever...
+
+Channel modes:
+	Read eggdrop docs.
+	Additions:
+	+/-fastop, -fastop does cookieops
+	+voice voices all except +q users and people that > |+m devoice
+	+closed is like +locked (kicks all non-users and keeps +i set)
+        +nomop Kicks users who set +ooo*
+	Anything not listed here or in eggdrop docs is not finished.
+
+Warnings:
+	Do not set a channel +voice, and then op a bot that is not linked to the wraith botnet.
+	  This will cause some serious bot fights.
+
+
+
+Memorize these:
+To see what commands they give access to:
+  See http://www.shatow.net/vb/showthread.php?s=&threadid=33
+(that may be old, but the general idea is there)
+
+Only +a can give certain flags, I forget which ones, but you'll figure that out ;)
+
+   Global  Chan    Does
+   --------------------------------------------------
+   a               administrator
+   b               bot
+   c               leaf chat hub (leaf that accepts /dcc chat or /ctcp chat)
+                   There is no limit to chat hubs, set all leafs +c if you want.
+                   Better idea to just set a few leafs +c and tell your users.
+   d       d       auto deop (never +o)
+   e       e       exempt from stopnethack //useless
+   f       f       friend
+   h               highlighting //useless
+   i               hub access
+   j               leaf chat hub access
+   k       k       autokick (never on chan)
+   l       l       bot sets limit
+   m       m       master
+   n       n       owner
+   o       o       op
+   p               partyline chat access (-p wont be able to talk)
+   q       q       quiet (never +v)
+   s               bot is sec hub (NOT FUNCTIONAL YET, DO NOT SET)
+   u               bot is the updatehub (MAKE SURE IT HAS OOGLES OF BW)
+   v       v       auto-voice
+   w       w       bot gives autovoice
+   x       x       users is exempt for flood kicks
+   y       y       bot gives out voices
+
+
+important console modes:
+	+m msgs
+	+o misc
+	+s server
+	+e errors
+	+u warnings
+	+w wallops
+	+c cmds
+	+b bots
+set with !console +abcde...
 
-                                   Readme
 
-
-  Please at least SKIM this document before asking questions. In fact, READ
-  IT if you've never successfully set up an Eggdrop bot before. PLEASE! READ
-  IT!
-
-  Contents
-
-    0. Important notice
-    1. What is Eggdrop?
-    2. How do I get Eggdrop?
-       2a. How to get the latest version of Eggdrop via CVS
-    3. Quick startup
-    4. Upgrading
-       4a. Upgrading from a pre-1.3 version to 1.6
-       4b. Upgrading from an older 1.3/1.4/1.5/1.6 version to a newer one
-    5. Command line
-    6. Frequently Asked Questions
-       6a. What do I do if I get the error "User file not found"?
-       6b. My Eggdrop won't run; It just says "Can't find your hostname!"
-       6c. What the Heck is Tcl?
-       6d. My bot dies and the last entry in the logfile is "Received terminate
-           signal". What does that mean and can I prevent it?
-       6e. My compile dies at the last minute with "LD fatal signal 11"!
-       6f. Someone else set up a bot I don't like. Are there any backdoors I
-           can use to take their bot down?
-       6g. What are modules?
-       6h. Can I compile Eggdrop without dynamic modules?
-           6h1. Do I still need to "loadmodule" modules?
-       6i. Where can I get a pre-compiled Eggdrop for my computer?
-       6j. I get "Makefile:3 : invalid operator" or some such thing when I
-           try to "make".
-       6k. When I "tclsh scripts/weed <userfile> c" It barfs chunks at me
-           and dies.
-       6l. I get "ld-elf.so.1: Shared object "libtcl80.so.1" not found" or
-           "eggdrop: error in loading shared libraries / libtcl8.1.so: cannot
-           open shared object file: No such file or directory" when I try to
-           start my bot.
-       6m. I get a whole pile of "unresolved symbol 'Tcl_AppendResult'" (or
-           some other symbol) when I try to load a module.
-    7. Setting up a crontab
-       7a. Setting up a crontab using autobotchk
-    8. Boring legal stuff
-    9. Mailing list
-   10. Documentation
-   11. Obtaining help
-
-     _________________________________________________________________
-
-
-  (0) NOTICE
-
-    Please read this file carefully before trying to set up Eggdrop. Also,
-    make SURE that you select your +n (owner) users wisely! They have 100%
-    access to your bot and account! ONLY GIVE THIS POWER TO SOMEONE YOU
-    TRUST COMPLETELY!!
-
-
-  (1) WHAT IS EGGDROP?
-
-    Eggdrop is the world's most popular Internet Relay Chat (IRC) bot; it is
-    freely distributable under the GNU General Public License (GPL). Eggdrop
-    is a feature rich program designed to be easily used and expanded upon by
-    both novice and advanced IRC users on a variety of hardware and software
-    platforms.
-
-    An IRC bot is a program that sits on an IRC channel and preforms automated
-    tasks while looking just like a normal user on the channel. Some of these
-    functions include protecting the channel from abuse, allowing privileged
-    users to gain op or voice status, logging channel events, providing
-    information, hosting games, etc.
-
-    One of the features that makes Eggdrop stand out from other bots is module
-    and Tcl scripting support. With scripts and modules, you can make the bot
-    preform almost any task you want. They can do anything from preventing
-    floods to greeting users and banning advertisers from channels.
-
-    You can also link multiple Eggdrop bots together to form a botnet. This
-    can allow bots to op each other securely, control floods efficiently, and
-    even link channels across multiple IRC networks. It also allows the
-    Eggdrops share user lists, ban lists, exempt/invite lists, and ignore
-    lists with other bots if userfile sharing is enabled. This allows users
-    to have the same access on every bot on your botnet. It also allows the
-    bots to distribute tasks such as opping and banning users. See doc/BOTNET
-    for information on setting up a botnet.
-
-    Eggdrop is always being improved and adjusted because there are bugs to
-    be fixed and features to be added (if the users demand them, and they make
-    actually sense). In fact, it existed for several years as v0.7 - v0.9
-    before finally going 1.0. This version of Eggdrop is part of the 1.6 tree.
-    A valiant effort has been made to chase down and destroy bugs.
-
-    This README file contains information about how to get Eggdrop, command
-    line options for Eggdrop, what you may need to do when upgrading from
-    older versions, a list of frequently asked questions, how to set up a
-    crontab, some boring legal stuff, info about the mailing list (a great
-    place to ask questions, and a good place to report bugs, too), some basics
-    about CVS usage, and some channels where you might get help with Eggdrop.
-
-
-  (2) HOW TO GET EGGDROP
-
-    Before you can compile Eggdrop, you need to have Tcl installed on your
-    system. Most systems should have Tcl on them by now -- you can check by
-    trying the command "tclsh". If it works, you will be given a "%" prompt,
-    and you can type "exit" to exit the program. This means Tcl is installed
-    on your system. If tclsh doesn't load, then Tcl probably isn't on your
-    system, and you will need to install it. The best ftp site for Tcl is
-    ftp://ftp.scriptics.com/pub/tcl.
-
-    Tcl comes with the most distributions of Linux. HOWEVER, the one that comes
-    on Slackware 3.0 is goofed up and you'll have to re-install it for yourself
-    to get it working.
-
-    Currently, the 1.6 tree of Eggdrop is developed at eggheads.org. You can
-    get the latest version of Eggdrop from the following url:
-
-      http://www.geteggdrop.com
-
-    You might try www.eggheads.org for help and information.
-
-
-  (2a) CVS USAGE
-
-    You can obtain the VERY LATEST version of Eggdrop, that is still under
-    development, by using CVS. CVS means 'Concurrent Versions System' and is
-    a tool for developers to always keep source code up to date. Try 'man cvs'
-    on your shell for more information about CVS.
-
-    This is intended only for users that know a good bit about Eggdrop. Be
-    aware that the versions of Eggdrop that you get via CVS are still being
-    developed, and may be buggy. The Eggheads devteam will in NO WAY take
-    any responsibility for whatever might happen to you or your shell if
-    you use a CVS version of Eggdrop.
-
-    To obtain Eggdrop over CVS, do as follows:
-
-      1. Log into your shell.
-
-      2. Type: 'export
-         CVSROOT=:pserver:anonymous@cvs.eggheads.org:/usr/local/cvsroot'.
-
-      3. Type 'cvs login'.
-
-      4. Press <enter> when prompted for a password.
-
-      5. In your home dir, type 'cvs checkout eggdrop1.6'
-
-      6. In ~/eggdrop1.6, you should have a copy of the latest CVS version
-         of Eggdrop.
-
-    Notes:
-
-      o You can 'cvs logout', but you don't need to.
-
-      o You don't need to go through this whole process every time. If you
-        want to get a CVS version of Eggdrop at a later time, you can just
-        'cd ~/eggdrop1.6' and type 'cvs update -dAP'.
-
-      o If you experience errors when using 'export', you might be using tclsh
-        as a shell. If so, try using the command 'setenv' instead of 'export':
-
-          setenv CVSROOT :pserver:anonymous@cvs.eggheads.org:/usr/local/cvsroot
-
-
-  (3) QUICK STARTUP
-
-    Please see the 'INSTALL' file AFTER you finish reading this file.
-
-
-  (4) UPGRADING
-
-
-  (4a) UPGRADING FROM A PRE-1.3 VERSION TO 1.6
-
-    #### BACK UP YOUR USERFILE ####
-
-    We can't stress this enough. If you are upgrading and you have even a
-    slight possibility of downgrading again later, you will HAVE to back up
-    your userfile, or you will lose it. v1.3 of Eggdrop radically changed a
-    lot of things.
-
-    There are many major changes between v0.9, v1.0, v1.1 and v1.6, so PAY
-    ATTENTION to this part if you have a v0.9, 1.0 or 1.1 bot currently. If
-    you're just starting out, you can skip this section.
-
-    If you run share bots, you will need to upgrade them all at the same time
-    because of the new userfile format. Older bots will be able to link in,
-    but will not get or send a userfile. MAKE A NEW CONFIG FILE from the
-    example; there are some radical changes.
-
-    If you are upgrading from 0.9/1.0 to 1.6, just redo the whole thing.
-    Absolutely everything has changed, including the userfile and config file
-    formats.
-
-    If you are upgrading from 1.1/1.2 to 1.6, you will likely want to redo
-    the config file, as much as changed. BACK UP! You will need to run 'tclsh
-    scripts/weed/<userfile> c' to convert your userfile from v3 (1.1/1.2) to
-    v4 (1.3/1.4/1.5/1.6).
-
-
-  (4b) UPGRADING FROM AN OLDER 1.3/1.4/1.5/1.6 VERSION TO A NEWER 1.6 VERSION
-
-    If you followed the 'INSTALL' file and did a 'make install' (or 'make
-    install DEST="path"') after 'make', this will be pretty easy. Just upload
-    the new eggdrop1.6.x.tar.gz file to your home dir on your shell, gunzip
-    and untar it, and type 'cd ~/eggdrop1.6.x'. Next, type './configure',
-    'make config' or 'make iconfig', then 'make'. Then, kill the bot ('.die'
-    on the party line), and 'make install' to the same directory your bot
-    is currently in. After that, you can just restart your bot. You may wish
-    to delete the old Eggdrop executable and modules as well, especially if
-    you have limited disk space.
-
-    You should read through the new eggdrop.complete.conf file for all the new
-    options in Eggdrop 1.6.x if you are upgrading from 1.3.x or 1.4.x. You can
-    copy and paste any of these settings into you current conf file if you do
-    not want to use the default settings.
-
-
-  (5) COMMAND LINE
-
-    Eggdrop has some command-line options -- not many, because most things
-    should be defined through the config file. However, sometimes you may
-    want to start up the bot in a different mode, and the command-line
-    options let you do that. Basically, the command line for Eggdrop is:
-
-      % eggdrop [options] [config-file]
-
-    The options available are:
-
-      -n: Don't background. Normally, Eggdrop will move itself into the
-          background when you start it up, meaning you'll get another shell
-          prompt, and you can do other things while the bot is running. With
-          -n, you won't return to the shell prompt until the bot exits (which
-          won't normally happen until it's killed). By default, -n will send
-          all log entries to the console.
-
-      -nt: Don't background, use terminal. This is just like -n, except that
-           instead of seeing log entries, your console will simulate a DCC
-           chat with the bot.
-
-      -nc: Don't background, show channel info. This is just like -n, except
-           that instead of seeing log entries, every 10 seconds your screen
-           will clear and you will see the current channel status, sort of
-           like "top".
-
-      -m: Create userfile. If you don't have a userfile, this will make Eggdrop
-          create one and give owner status to the first person that introduces
-          himself or herself to it. You'll need to do this when you first set
-          up your bot.
-
-      -v: Show version info, then quit.
-
-    Most people never use any of the options except -m, and you usually only
-    need to use that once.
-
-
-  (6) FREQUENTLY ASKED QUESTIONS (or "Why doesn't this thing work?")
-
-    6a. WHAT DO I DO IF I GET THE ERROR "USER FILE NOT FOUND"?
-
-      1. Run Eggdrop with the "-m" option (i.e., "eggdrop -m eggdrop.conf").
-
-      2. Go to IRC and send "hello" to your bot (i.e., "/msg mybot hello").
-
-      3. You will become an owner on your bot. You can leave the bot running
-         (nobody else will become an owner if they say "hello"), but in the
-         future, don't use the "-m" option when running the bot.
-
-    6b. MY EGGDROP WON'T RUN; IT JUST SAYS "CAN'T FIND YOUR HOSTNAME!"
-
-      Your machine is set up strangely, and Eggdrop can't figure out its
-      network hostname. You can get around this by setting the my-ip setting
-      in the config file correctly.
-
-    6c. WHAT THE HECK IS Tcl?
-
-      Tcl is a scripting language written by John Ousterhout. It's much better
-      than most "built-in" script languages (like the one in ircII) and is
-      meant to be linked with anything needing a  scripting language, so I
-      linked it with Eggdrop. The file "tcl-commands.doc" in the doc directory
-      contains a list of additional Tcl commands provided by Eggdrop. There
-      are also several example scripts in the scripts/ directory, and one in
-      the doc directory called first_script.txt. Hundreds of scripts floating
-      around on the ftp/web sites if you like working by example (which is
-      typically the best way).
-
-    6d. MY BOT DIES, AND THE LAST ENTRY IN THE LOGFILE IS "RECEIVED TERMINATE
-        SIGNAL". WHAT DOES THAT MEAN, AND CAN I PREVENT IT?
-
-      There's nothing you can do to prevent it. It means the system
-      administrator is killing the Eggdrop process. Most of the time, it's an
-      automatic thing that happens when the system is being rebooted, so it's
-      harmless. If you have a crontab running, the bot will get restarted when
-      the system is back online. Occasionally, the system administrator will
-      kill the bot manually. For example, if he/she doesn't want bots running
-      on the system.
-
-    6e. MY COMPILE DIES AT THE LAST MINUTE WITH "LD FATAL SIGNAL 11"!
-      
-      See doc/compiling.FAQ.
-
-    6f. SOMEONE ELSE SET UP A BOT I DON'T LIKE. ARE THERE ANY BACKDOORS I CAN
-        USE TO TAKE THEIR BOT DOWN?
-
-      No, there have never been any backdoors and there never will be, so
-      please stop asking. Every once in a while, someone finds a way to
-      exploit a bug in Eggdrop, but we fix these bugs as soon as we find out
-      about them. If you want to bring down someone else's bot, you will not
-      have my/our help.
-
-    6g. WHAT ARE MODULES?
-
-      Modules are a way of adding extra features to the bot, much like Tcl
-      scripts, without requiring the bot to be recompiled. See doc/MODULES
-      for more information.
-
-    6h. CAN I COMPILE EGGDROP WITHOUT DYNAMIC MODULES?
-
-       Yes, you can. If the configure script detects that your system CAN'T
-       run modules, it will setup 'make' to link the modules in statically
-       for you. You can choose this option yourself by using 'make static'.
-       You can also try to compile dynamic modules on a static-only system
-       by using 'make eggdrop'.
-
-    6h1. DO I STILL NEED TO 'loadmodule' MODULES?
-
-      YES, when you compile statically, all the modules are linked into the
-      main executable. HOWEVER, they are not enabled until you use loadmodule
-      to enable them, hence you get nearly the same functionality with static
-      modules as with dynamic modules.
-
-    6i. WHERE CAN I GET A PRE-COMPILED EGGDROP FOR MY COMPUTER?
-
-      It is HIGHLY recommended AGAINST using pre-compiled Eggdrops from
-      un-trusted sources. Eggdrop has been a regular target for hacking and
-      crashing. Distribution of pre-compiled (binary) versions of Eggdrop are
-      the easiest way for hackers to provide you with the easiest (and most
-      dangerous) way of gaining access to, not only your bot, but to your
-      computer account directly. Don't advertise your pre-compiled Eggdrop
-      binary sites on the Eggdrop list either. =P
-
-    6j. I GET 'Makefile:3 :invalid operator' OR SOME-SUCH-THING WHEN I TRY
-        TO 'make'.
-
-      Try 'gmake'.
-
-    6k. WHEN I 'tclsh scripts/weed <userfile> c' IT BARFS CHUNKS AT ME AND
-        DIES. :(
-
-      Upgrade your Tcl. You are probably using Tcl 7.5 or earlier. Some of the
-      commands in weed require Tcl7.6 to run, so either upgrade it or remove
-      the offending lines from you userfile manually (those starting with '.'
-      generally) and accept the loss of that data.
-
-    6l. I GET "ld-elf.so.1: Shared object "libtcl80.so.1" not found" or
-        "eggdrop: error in loading shared libraries libtcl8.1.so: \
-        cannot open shared object file: No such file or directory" WHEN I TRY
-        TO START MY BOT.
-
-      './configure' is looking in the wrong place for Tcl; it looks like it
-      compiled with one version of Tcl and tries to load another. Maybe your
-      sysadmin upgraded Tcl and didn't tell you. In that case, you should just
-      need to recompile your bot.
-
-      Maybe, when upgrading, he didn't clean the old version of Tcl and
-      './configure' is looking for the files in the wrong places, or trying
-      to use different versions of tcl.h and libtcl*. Smack your admin and
-      have him install Tcl properly. ;)
-
-      You can also try:
-
-        ./configure --with-tcllib=<path-to-tcl-lib>
-                    --with-tclinc=<path-to-tcl-inc>
-
-      This will tell configure where to look for the Tcl files.
-
-      Try looking for libtcl by:
-
-        ls /usr/lib/libtcl*
-        ls /usr/local/lib/libtcl*
-
-      Try looking for tcl.h by:
-
-        ls /usr/include/tcl.h
-        ls /usr/local/include/tcl.h
-
-        If everything else fails, try to install Tcl to your home dir ;)
-        (Suggested by dw@Undernet, dw@lixom.nu)
-
-    6m. I GET A WHOLE PILE OF "Unresolved symbol 'Tcl_AppendResult'" (OR SOME
-        OTHER SYMBOL) WHEN I TRY TO LOAD A MODULES.
-
-      POSSIBILITY A: See section 12.
-
-      POSSIBILITY B:
-
-        Some of the standard libraries have been compiled for static linking
-        only on your machine, you have 3 options:
-
-          1. If it's your own machine, recompile Tcl using dynamic linking by
-             using './configure --enable-shared' when you configure Tcl (not
-             the bot) and then remake, and reinstall.
-
-          2. If it's not your machine, you make have to resort to 'make static'
-             and 'make install DEST="path"' to make and install your bot.
-
-          3. If you are of a more aggressive sense of mind, go beat the
-             stuffing out of your admin for having lame static libraries. :)
-
-
-  (7) SETTING UP A CRONTAB
-
-    Eggdrop has become more stable with time, thanks mostly to people
-    reporting bug details and helping find places where it crashes. However,
-    there are still a -few- places where things aren't perfect. Few, if any,
-    things in life are.
-
-    Also, most systems go down from time to time. These things cause your bot
-    to disappear from IRC, and you have to restart it.
-
-    Eggdrop comes with a shell script called 'botchk' that will help keep the
-    bot online. It will make the machine check every ten minutes to make sure
-    your bot is still running. To use it, you have to add a line to your
-    crontab. First, edit 'botchk' and change the directory and command line
-    parameters so that it will be able to start up your bot. Then, add this
-    line to your crontab:
-
-      0,10,20,30,40,50 * * * * /home/mydir/botchk
-
-    If you don't want to get e-mails from cron, use this:
-
-      0,10,20,30,40,50 * * * * /home/mydir/botchk >/dev/null 2>&1
-
-    Naturally, you need to change the path to the correct path for botchk. If
-    you've never used crontab before, here is a simple way to add that line:
-
-      1. Create a new file called 'mycron' and put the above line into it.
-
-      2. From your shell prompt, type '% crontab mycron'.
-
-    That will create a new crontab entry for you with a line that runs botchk
-    every ten minutes. Botchk will then restart the bot when necessary (and
-    send you email informing you).
-
-
-  (7a) SETTING UP A CRONTAB USING AUTOBOTCHK
-
-    Included with your Eggdrop is an Eggdrop utility called 'autobotchk'.
-    Using autobotchk is probably the fastest way of creating your botchk and
-    crontabbing it with just a few required steps:
-
-      1. Type 'cp scripts/autobotchk ..'.
-
-      2. Type './autobotchk <Eggdrop config file>'.
-
-    This will hopefully crontab your bot using the default setup. If you want
-    a list of autobotchk options, type './autobotchk'. An example with options
-    would be:
-
-      ./autobotchk <Eggdrop config file> -noemail -5
-
-    This would setup crontab to run the botchk every 5 minutes and also to
-    not send you e-mail saying that it restarted your bot.
-
-
-  (8) BORING LEGAL STUFF
-
-    The Eggdrop bot is copyright (C) by Robey Pointer. As of January, 1997,
-    Eggdrop is distributed according to the GNU General Public License. There
-    should be a copy of this license in the file 'COPYING'. If not, write to
-    the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    As of eggdrop1.3.28, all changes made by the Eggheads development team to
-    the Eggdrop source code and any related files are copyright (C) by
-    Eggheads. The source code will still be distributed according to the GNU
-    General Public License as Robey Pointer did in the past.
-
-    Releases previous to 1.0m were made using a different licensing scheme.
-    You may, at your option, use the GNU General Public License on those
-    versions (instead of the license packaged with them) with my blessing.
-    For any versions bearing a copyright date of 1997 or later, you have
-    no choice -- you must use the GNU General Public License.
-
-    The files "match.c", "net.c", and "blowfish.c" are exempt from the above
-    restrictions. "match.c" is original code by Chris Fuller (email:
-    crf@cfox.bchs.uh.edu) and has been placed by him into the public domain.
-    "net.c" is by me, and I [who?] also choose to place it in the public
-    domain. "blowfish.c" is by various sources and is in the public domain
-    as well. All 3 files contain useful functions that could easily be
-    ported to other applications.
-
-    Tcl is by John Ousterhout and is in no way affiliated with Eggdrop. It
-    likely has its own set of copyrights and whatnots.
-
-    There is no warranty, implied or whatever. You use this software at your
-    own risk, no matter what purpose you put it to.
-
-
-  (9) MAILING LIST
-
-    There are currently a couple of mailing lists about Eggdrop.
-    eggheads@eggheads.org is the one relevant for posts about Eggdrop 1.4 and
-    up (suggestions, help, etc).
-
-    To subscribe to the eggheads mailing list, send e-mail to
-    eggheads-request@eggheads.org. In the body of the message, put "subscribe
-    eggheads". You can also go to the following url:
-
-      http://scrambled.eggheads.org/mailman/listinfo/eggheads
-
-    ### DO NOT SEND ROBEY EMAIL ABOUT EGGDROP! ###
-
-    Robey is no longer developing the Eggdrop code, so don't bother e-mailing
-    him. If you have a serious problem, email the eggheads mailing list and
-    it will get to the coders.
-
-    Please, before posting to this list, see what things are like. When you do
-    post, read over your post for readability, spelling, and grammar mistakes.
-    Obviously, we're all human (or are we?) and we all make mistakes (heck,
-    look at this document! ;).
-
-    Open discussion and debate is integral to change and progress. Don't flame
-    others over mere form (grammar and spelling), or even substantive issues
-    for that matter. Please read and follow the mailing list rules.
-
-    The eggheads@eggheads.org mailing list is not dedicated to those all too
-    common questions we have all seen on other lists... For example:
-
-      o "Why does my bot say this: Please edit your config file."
-      o "How do I telnet my bot?"
-      o "Where do I get Eggdrop for windows??????"
-
-    Technical questions, your thoughts or suggestions on new features being
-    added to Eggdrop, things that should be removed or fixed, amazing problems
-    that even stump the guru's, etc. are what we want to see here.
-
-    Bug reports should be sent to bugs@eggheads.org. Please read and fill out
-    the BUG-REPORT file in the doc directory.
-
-    DO NOT SEND HTML E-MAILS TO ANY OF THE EGGHEADS.ORG MAILING LISTS. ANYONE
-    CAUGHT SENDING HTML E-MAILS TO ONE OF THESE LISTS WILL BE REMOVED
-    IMMEDIATELY!
-
-
-  (10) DOCUMENTATION
-
-    We're trying to keep the documentation up to date. If you feel that
-    anything is missing here or that anything should be added, etc, please
-    email eggheads@eggheads.org about it. Thank you.
-
-
-  (11) OBTAINING HELP
-
-    You can obtain help with Eggdrop in the following IRC channels:
-
-      Undernet - #eggdrop, #eggies
-      EFnet - #egghelp, #eggfaq
-      IRCnet - #eggdrop
-      DALnet - #eggdrop, #botcentral
-      OPN - #eggdrop, #egghelp
-      QuakeNet - #eggdrop
-
-    If you plan to ask questions in any of the above channels, you should be
-    familiar with and follow IRC etiquette.
-
-      o Don't type using CAPITAL letters, colors, or bold.
-
-      o Don't use  "!" and "?" excessively.
-
-      o Don't /msg people without their permission.
-
-      o Don't repeat or paste large amounts of text to the channel.
-
-    If there are any other serious Eggdrop related channels that should be
-    added to the above list, please let us know.
-
-  ________________________________________________________________________
-
-Copyright (C) 1997 Robey Pointer
-Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team

+ 0 - 1
acconfig.h

@@ -5,7 +5,6 @@
  * acconfig.h
  *   template file autoheader uses when building config.h.in
  * 
- * $Id: acconfig.h,v 1.10 2001/11/11 20:24:44 guppy Exp $
  */
 
 /* Define if modules will work on your system  */

+ 0 - 1
aclocal.m4

@@ -1,7 +1,6 @@
 dnl aclocal.m4
 dnl   macros autoconf uses when building configure from configure.in
 dnl
-dnl $Id: aclocal.m4,v 1.57 2002/03/12 19:11:32 guppy Exp $
 dnl
 
 

+ 100 - 0
bldall

@@ -0,0 +1,100 @@
+#!/bin/sh
+
+#edit this to your homedir (no trailing slash)
+
+TCLDIR="/home/bryan"
+
+
+#### DO NOT EDIT BELOW THIS LINE #####
+
+# Figure out whether to use default or a specified config file
+if test $1
+then
+  packname=$1
+else
+  packname=default
+fi
+
+# Verify we got the config file
+if ! test -f $packname.conf
+then
+  echo "Can't find pack configuration file $packname.conf"
+  exit 1
+fi
+
+# Figure what bins we're making
+case `uname` in
+  Linux) prefix=linux;;
+  FreeBSD) case `uname -r` in
+    4*) prefix=freebsd4;;
+    3*) prefix=freebsd3;;
+  esac;;
+  OpenBSD) prefix=openbsd;;
+esac
+if test -z $prefix
+then
+  echo "Automated packing disabled, `uname` isn't recognized"
+fi
+
+# make clean, just in case
+echo "Cleaning up old binaries..."
+make distclean > /dev/null
+
+# Run ./configure, then verify it's ok
+echo "Configuring..."
+#./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
+#if test "`cat configure.temp`"
+#then
+#  echo "Configure error'd"
+#  cat configure.temp
+#
+#  exit 1
+#fi
+#rm -f configure.temp
+
+
+
+# Read the config
+echo -n "Pack configuration:"
+for cnf in `cat $packname.conf | grep -v "^#"`
+do
+  defines="$defines -DS_$cnf"
+  echo -n "$cnf "
+done
+echo ""
+
+# Build utils and check we got the bins
+#echo "Building utils..."
+#make utils CFLGS="$defines" > /dev/null
+#if ! test -f readlog -a -f makebot -a -f makepack -a -f stringfix
+#then
+#  echo "Util build failed"
+#  exit 1
+#fi
+
+# Build leaf and check
+echo "Building leaf..."
+make config CFLGS="-DLEAF $defines" > /dev/null
+make static CFLGS="-DLEAF $defines" > /dev/null
+#make static CFLGS="-DLEAF $defines" > /dev/null
+mv -f eggdrop leaf
+if ! test -f leaf
+then
+  echo "leaf build failed"
+  exit 1
+fi
+
+# Build hub and check
+echo "Building hub..."
+make clean > /dev/null
+make config CFLGS="-DHUB $defines" > /dev/null
+#make -j sdebug CFLGS="-DHUB $defines" > /dev/null
+make static CFLGS="-DHUB $defines" > /dev/null
+mv -f eggdrop hub
+if ! test -f hub
+then
+  echo "hub build failed"
+  exit 1
+fi
+make clean > /dev/null

+ 87 - 0
bldleaf

@@ -0,0 +1,87 @@
+#!/bin/sh
+
+#edit this to your homedir (no trailing slash)
+
+TCLDIR="/home/bryan"
+
+
+#### DO NOT EDIT BELOW THIS LINE #####
+
+# Figure out whether to use default or a specified config file
+if test $1
+then
+  packname=$1
+else
+  packname=default
+fi
+
+# Verify we got the config file
+if ! test -f $packname.conf
+then
+  echo "Can't find pack configuration file $packname.conf"
+  exit 1
+fi
+
+# Figure what bins we're making
+case `uname` in
+  Linux) prefix=linux;;
+  FreeBSD) case `uname -r` in
+    4*) prefix=freebsd4;;
+    3*) prefix=freebsd3;;
+  esac;;
+  OpenBSD) prefix=openbsd;;
+esac
+if test -z $prefix
+then
+  echo "Automated packing disabled, `uname` isn't recognized"
+fi
+
+# make clean, just in case
+#echo "Cleaning up old binaries..."
+#make distclean > /dev/null
+
+# Run ./configure, then verify it's ok
+echo "Configuring..."
+#./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
+#if test "`cat configure.temp`"
+#then
+#  echo "Configure error'd"
+#  cat configure.temp
+#
+#  exit 1
+#fi
+#rm -f configure.temp
+
+
+
+# Read the config
+echo -n "Pack configuration:"
+for cnf in `cat $packname.conf | grep -v "^#"`
+do
+  defines="$defines -DS_$cnf"
+  echo -n "$cnf "
+done
+echo ""
+
+# Build utils and check we got the bins
+#echo "Building utils..."
+#make utils CFLGS="$defines" > /dev/null
+#if ! test -f readlog -a -f makebot -a -f makepack -a -f stringfix
+#then
+#  echo "Util build failed"
+#  exit 1
+#fi
+
+# Build leaf and check
+echo "Building leaf..."
+make config CFLGS="-DLEAF $defines" > /dev/null
+make sdebug CFLGS="-DLEAF $defines" > /dev/null
+#make static CFLGS="-DLEAF $defines" > /dev/null
+mv -f eggdrop leaf
+if ! test -f leaf
+then
+  echo "leaf build failed"
+  exit 1
+fi
+

+ 21 - 0
conf

@@ -0,0 +1,21 @@
+#when you make the bot, remove these #lines :)
+#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)
+#The first line must contain UID (use "id" in shell to get uid)
+#- 1113
+#The second must be the output from uname -nv (-nr on FBSD)
+#+ somebox #1 SMP Thu May 29 06:55:05 EDT 2003
+#any lines after should be in this format:
+#botnick [!]ip4 [+]hostname (the + means ipv6) (the ! means internal NAT ip address, IE: 10.10.0.3, Hostname REQUIRED)
+#Full example:
+#- 101 
+#+ somebox 5.1-RELEASE
+#wraith 66.34.23.123 66-34-23-123.roc.mn.charter.com
+#leetbot 66.34.23.123 +ipv6.uber.leet.la
+#modem 66.34.23.124 some.ipv4.vhost.at.wraith.net
+- 501
++ veritas #1 SMP Thu May 29 06:55:05 EDT 2003
+sbptest 66.188.213.191 66-188-213-191.roc.mn.charter.com
+updated 66.188.213.191 66-188-213-191.roc.mn.charter.com
+elinked 66.188.213.191 66-188-213-191.roc.mn.charter.com
+

+ 0 - 1
config.h.in

@@ -5,7 +5,6 @@
  * acconfig.h
  *   template file autoheader uses when building config.h.in
  * 
- * $Id: config.h.in,v 1.24 2001/12/20 00:10:43 guppy Exp $
  */
 
 /* Define if modules will work on your system  */

+ 6 - 8
configure

@@ -5879,13 +5879,13 @@ else
   # Set default make as static for unshared Tcl library
   if test ! "$DEFAULT_MAKE" = "static"
   then
-    cat << 'EOF' >&2
-configure: warning:
+#    cat << 'EOF' >&2
+#configure: warning:
 
-  Your Tcl library is not a shared lib.
-  configure will now set default make type to static...
+#  Your Tcl library is not a shared lib.
+#  configure will now set default make type to static...
 
-EOF
+#EOF
     DEFAULT_MAKE=static
       fi
 
@@ -5991,7 +5991,7 @@ esac
 
   ac_config_commands="$ac_config_commands default-2"
 
-ac_config_files="$ac_config_files Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile"
+ac_config_files="$ac_config_files Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -6312,8 +6312,6 @@ do
   case "$ac_config_target" in
   # Handling of arguments.
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-  "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
-  "scripts/Makefile" ) CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
   "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
   "src/md5/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/md5/Makefile" ;;
   "src/compat/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/compat/Makefile" ;;

+ 1 - 1
configure.in

@@ -127,6 +127,6 @@ EGG_SUBST_DEST
 EGG_SUBST_MOD_UPDIR
 EGG_CATCH_MAKEFILE_REBUILD
 
-AC_OUTPUT(Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile)
+AC_OUTPUT(Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile)
 
 EGG_MSG_CONFIGURE_END

+ 0 - 0
configure.temp


+ 101 - 0
makesalt.c

@@ -0,0 +1,101 @@
+/************************************************************************
+ *   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 <stdlib.h>
+#include <strings.h>
+#include <time.h>
+
+char rbuf[100];
+
+const char *randstring(int length)
+{
+    char *po;
+    int i;
+    po=rbuf;
+    if (length>100) length=100;
+    for(i=0;i<length;i++) {*po=(char)(0x61+(rand()&15)); po++;}
+    *po=0;
+    po=rbuf;
+    return po;
+}
+
+int main(void)
+{
+
+    FILE* salt;
+    int saltlen1;
+    int saltlen2;
+    int foo;
+    srand(time(NULL));
+    saltlen1=(rand()&20)+5;
+    saltlen2=(rand()&20)+5;
+    if ( (salt=fopen("salt.h","r"))!=NULL) {
+	fclose(salt);
+	printf("Using existent Salt-File\n");
+	exit(0x0);
+    }
+    printf("Creating Salt File\n");
+    if ( (salt=fopen("salt.h","w"))==NULL) {
+	printf("Cannot created Salt-File.. aborting\n");
+	exit(0x1);
+    }
+    fprintf(salt,"/* The 1. Salt -> string containing anything, %d chars */\n",saltlen1);
+    fprintf(salt,"#define SALT1 %c%s%c\n",34,randstring(saltlen1),34);
+    fprintf(salt,"\n");
+    fprintf(salt,"/* The 2. Salt -> string containing anything, %d chars */\n",saltlen2);
+    fprintf(salt,"#define SALT2 %c%s%c\n",34,randstring(saltlen2),34);
+    fprintf(salt,"\n");
+    fprintf(salt,"/* the 1. Code -> a one byte startup code */\n");
+    fprintf(salt,"#define CODE1 %d\n",64+(rand()&15));
+    fprintf(salt,"\n");
+    fprintf(salt,"/* the 2. Code -> a one byte startup code */\n");
+    fprintf(salt,"#define CODE2 %d\n",64+(rand()&15));
+    fprintf(salt,"\n");
+    fprintf(salt,"/* the 1. Salt Offset -> value from 0-%d */\n",saltlen1-1);
+    fprintf(salt,"#define SA1 %d\n",rand()&(saltlen1-1));
+    fprintf(salt,"\n");
+    fprintf(salt,"/* the 2. Salt Offset -> value from 0-%d */\n",saltlen2-1);
+    fprintf(salt,"#define SA2 %d\n",rand()&(saltlen2-1));
+    fprintf(salt,"\n");
+    fprintf(salt,"/* the make salt routine */\n");
+    fprintf(salt,"/* dont wonder about the redundance, its needed to somehow hide the fully salts */\n");
+    fprintf(salt,"\n");
+    fprintf(salt,"/* salt buffers */\n");
+    fprintf(salt,"\n");
+    fprintf(salt,"unsigned char slt1[%d];\n",saltlen1+1);
+    fprintf(salt,"unsigned char slt2[%d];\n",saltlen2+1);
+    fprintf(salt,"\n");
+    fprintf(salt,"int makesalt(void)\n");
+    fprintf(salt,"{\n");
+    for (foo=0;foo<saltlen1;foo++) 
+        fprintf(salt,"    slt1[%d]=SALT1[%d];\n",foo,foo);
+    fprintf(salt,"    slt1[%d]=0;\n",saltlen1);
+    for (foo=0;foo<saltlen2;foo++) 
+        fprintf(salt,"    slt2[%d]=SALT2[%d];\n",foo,foo);
+    fprintf(salt,"    slt2[%d]=0;\n",saltlen2);
+    fprintf(salt,"return 0;\n");
+    fprintf(salt,"}");
+    fprintf(salt,"\n");
+    fclose(salt);
+    printf("Salt File created.\n");
+    exit (0x0);
+}

+ 44 - 0
md5/Makefile

@@ -0,0 +1,44 @@
+# This makefile compiles the source code for the "RSA Data Security, Inc.
+# MD5 Message-Digest Algorithm" as found in RFC 1321.  That code is copyrighted:
+#
+#	Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
+#	All rights reserved.
+#
+# See the source code for copyright restrictions.
+#
+# No "makefile" is provided in the RFC.
+# This one was written by Jim Ellis (jte@cert.org) for convenience.
+
+CC = gcc
+
+# Note: a bug in mddriver causes "MD" to default to an incorrect value,
+# so we set it to "5" here.
+CFLAGS = -O -DMD=5
+
+md5: md5c.o mddriver.o
+	$(CC) -o md5 md5c.o mddriver.o
+
+mddriver.o: global.h md5.h
+	$(CC) -c $(CFLAGS) mddriver.c
+
+md5c.o: global.h md5.h
+	$(CC) -c $(CFLAGS) md5c.c
+
+test: md5 test.rfc
+	-./md5 -x | diff - test.rfc > diffs 2>&1
+	@-if test -s diffs ; then echo '*** MD5 TEST FAILED'; cat diffs; else echo '*** MD5 Test Passed'; fi
+	rm -f diffs
+
+# test.rfc is taken from Appendix 5 of RFC 1321.
+test.rfc:
+	echo 'MD5 test suite:' > test.rfc
+	echo 'MD5 ("") = d41d8cd98f00b204e9800998ecf8427e' >> test.rfc
+	echo 'MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661' >> test.rfc
+	echo 'MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72' >> test.rfc
+	echo 'MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0' >> test.rfc
+	echo 'MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b' >> test.rfc
+	echo 'MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f' >> test.rfc
+	echo 'MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a' >> test.rfc
+
+clean:
+	rm -f *.o md5 diffs test.rfc

+ 30 - 0
md5/global.h

@@ -0,0 +1,30 @@
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+  function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+  been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+  returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif

+ 1 - 0
md5/hm

@@ -0,0 +1 @@
+l

+ 36 - 0
md5/md5.h

@@ -0,0 +1,36 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));

+ 333 - 0
md5/md5c.c

@@ -0,0 +1,333 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include "global.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context;                                        /* context */
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants.
+*/
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context;                                        /* context */
+unsigned char *input;                                /* input block */
+unsigned int inputLen;                     /* length of input block */
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+   < ((UINT4)inputLen << 3))
+ context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible.
+*/
+  if (inputLen >= partLen) {
+ MD5_memcpy
+   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+   MD5Transform (context->state, &input[i]);
+
+ index = 0;
+  }
+  else
+ i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+  inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16];                         /* message digest */
+MD5_CTX *context;                                       /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+*/
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}

+ 244 - 0
md5/mddriver.c

@@ -0,0 +1,244 @@
+/* MDDRIVER.C - test driver for MD2, MD4 and MD5
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+rights reserved.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* The following makes MD default to MD5 if it has not already been
+  defined with C compiler flags.
+ */
+#ifndef MD
+#define MD MD5
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <sys/types.h>
+#include "global.h"
+#if MD == 2
+#include "md2.h"
+#endif
+#if MD == 4
+#include "md4.h"
+#endif
+#if MD == 5
+#include "md5.h"
+#endif
+
+/* Length of test block, number of test blocks.
+ */
+#define TEST_BLOCK_LEN 1000
+#define TEST_BLOCK_COUNT 1000
+
+static void MDString PROTO_LIST ((char *));
+static void MDTimeTrial PROTO_LIST ((void));
+static void MDTestSuite PROTO_LIST ((void));
+static void MDFile PROTO_LIST ((char *));
+static void MDFilter PROTO_LIST ((void));
+static void MDPrint PROTO_LIST ((unsigned char [16]));
+
+#if MD == 2
+#define MD_CTX MD2_CTX
+#define MDInit MD2Init
+#define MDUpdate MD2Update
+#define MDFinal MD2Final
+#endif
+#if MD == 4
+#define MD_CTX MD4_CTX
+#define MDInit MD4Init
+#define MDUpdate MD4Update
+#define MDFinal MD4Final
+#endif
+#if MD == 5
+#define MD_CTX MD5_CTX
+#define MDInit MD5Init
+#define MDUpdate MD5Update
+#define MDFinal MD5Final
+#endif
+
+/* Main driver.
+
+Arguments (may be any combination):
+  -sstring - digests string
+  -t       - runs time trial
+  -x       - runs test script
+  -b       - print MD5 sum in binary on stdout
+  filename - digests file
+  (none)   - digests standard input
+ */
+
+short bflag = 0;	/* 1 == print sums in binary */
+
+int main (argc, argv)
+int argc;
+char *argv[];
+{
+  int i;
+
+  if (argc > 1)
+ for (i = 1; i < argc; i++)
+   if (argv[i][0] == '-' && argv[i][1] == 's')
+     MDString (argv[i] + 2);
+   else if (strcmp (argv[i], "-t") == 0)
+     MDTimeTrial ();
+   else if (strcmp (argv[i], "-x") == 0)
+     MDTestSuite ();
+   else if (strcmp (argv[i], "-b") == 0)
+     bflag = 1;
+   else
+     MDFile (argv[i]);
+  else
+ MDFilter ();
+
+  return (0);
+}
+
+/* Digests a string and prints the result.
+ */
+static void MDString (string)
+char *string;
+{
+  MD_CTX context;
+  unsigned char digest[16];
+  unsigned int len = strlen (string);
+
+  MDInit (&context);
+  MDUpdate (&context, string, len);
+  MDFinal (digest, &context);
+
+//  if (!bflag) printf ("%s",string);
+  MDPrint (digest);
+  if (!bflag) printf ("\n");
+}
+
+/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
+  blocks.
+ */
+static void MDTimeTrial ()
+{
+  MD_CTX context;
+  time_t endTime, startTime;
+  unsigned char block[TEST_BLOCK_LEN], digest[16];
+  unsigned int i;
+
+  printf
+ ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
+  TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
+
+  /* Initialize block */
+  for (i = 0; i < TEST_BLOCK_LEN; i++)
+ block[i] = (unsigned char)(i & 0xff);
+
+  /* Start timer */
+  time (&startTime);
+
+  /* Digest blocks */
+  MDInit (&context);
+  for (i = 0; i < TEST_BLOCK_COUNT; i++)
+ MDUpdate (&context, block, TEST_BLOCK_LEN);
+  MDFinal (digest, &context);
+
+  /* Stop timer */
+  time (&endTime);
+
+  printf (" done\n");
+  printf ("Digest = ");
+  MDPrint (digest);
+  printf ("\nTime = %d seconds\n", (time_t)(endTime-startTime));
+  /*
+   * Be careful that endTime-startTime is not zero.
+   * (Bug fix from Ric Anderson, ric@Artisoft.COM.)
+   */
+  printf
+ ("Speed = %d bytes/second\n",
+  (time_t)TEST_BLOCK_LEN * (time_t)TEST_BLOCK_COUNT/((endTime-startTime) != 0 ? (endTime-startTime):1));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+static void MDTestSuite ()
+{
+  printf ("MD%d test suite:\n", MD);
+
+  MDString ("");
+  MDString ("a");
+  MDString ("abc");
+  MDString ("message digest");
+  MDString ("abcdefghijklmnopqrstuvwxyz");
+  MDString
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+  MDString
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+}
+
+/* Digests a file and prints the result.
+ */
+static void MDFile (filename)
+char *filename;
+{
+  FILE *file;
+  MD_CTX context;
+  int len;
+  unsigned char buffer[1024], digest[16];
+
+  if ((file = fopen (filename, "rb")) == NULL)
+ printf ("%s can't be opened\n", filename);
+
+  else {
+ MDInit (&context);
+ while (len = fread (buffer, 1, 1024, file))
+   MDUpdate (&context, buffer, len);
+ MDFinal (digest, &context);
+
+ fclose (file);
+
+ if (!bflag) printf ("MD%d (%s) = ", MD, filename);
+ MDPrint (digest);
+ if (!bflag) printf ("\n");
+  }
+}
+
+/* Digests the standard input and prints the result.
+ */
+static void MDFilter ()
+{
+  MD_CTX context;
+  int len;
+  unsigned char buffer[16], digest[16];
+
+  MDInit (&context);
+  while (len = fread (buffer, 1, 16, stdin))
+ MDUpdate (&context, buffer, len);
+  MDFinal (digest, &context);
+
+  MDPrint (digest);
+  if (!bflag) printf ("\n");
+}
+
+/* Prints a message digest in hexadecimal or binary.
+ */
+static void MDPrint (digest)
+unsigned char digest[16];
+{
+  unsigned int i;
+
+  if (bflag) {
+	/* print in binary */
+	write(1, &digest[0], 16);
+  } else {
+	/* print in hex */
+	for (i = 0; i < 16; i++)
+		printf ("%02x", digest[i]);
+  }
+}

+ 15 - 0
md5/t

@@ -0,0 +1,15 @@
+#!/bin/sh
+make clean
+make
+echo -n "Partyline pass:	"
+read party
+echo -n "Admin pass:		"
+read admin
+echo -n "\"War\" pass:		"
+read war
+eparty=$(./md5 -s$party)
+eadmin=$(./md5 -s$admin)
+ewar=$(./md5 -s$war)
+echo "set partylinepass \"$eparty\""
+echo "set adminpass \"$eadmin\""
+echo "set warpass \"$ewar\""

+ 0 - 1
misc/install-sh

@@ -3,7 +3,6 @@
 # install - install a program, script, or datafile
 # This comes from X11R5 (mit/util/scripts/install.sh).
 #
-# $Id: install-sh,v 1.1 2000/03/05 23:22:48 fabian Exp $
 #
 # Copyright 1991 by the Massachusetts Institute of Technology
 #

+ 0 - 1
misc/mkinstalldirs

@@ -4,7 +4,6 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs,v 1.1 2000/03/05 23:22:48 fabian Exp $
 
 errstatus=0
 

+ 20 - 23
misc/modconfig

@@ -19,7 +19,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-# $Id: modconfig,v 1.9 2002/02/24 07:37:01 guppy Exp $
 
 
 mc_pn=`echo $0 | sed -e 's/^.*\///'`
@@ -107,9 +106,6 @@ mc_fmodules=${mc_bindir}/.modules
 #  List of all modules we have detected so far.
 mc_fknownmods=${mc_bindir}/.known_modules
 
-#  List of modules disabled by default
-mc_fdisabledmods=${mc_top_srcdir}/disabled_modules
-
 mc_mod_dir=${mc_srcdir}/mod
 
 mc_mod_bin_dir=${mc_bindir}/src/mod
@@ -258,24 +254,19 @@ xdetect-modules)
 		#  Do we have an existing configuration?
 		if (test "${mc_mods_configured}" = yes); then
 			#  Is the module active?
-			if (grep "^${mc_mod}.mod\$" ${mc_fmodules} 1>&7 2>&1)
+                        if (grep "^${mc_mod}\.mod\$" ${mc_fmodules} 1>&7 2>&1)
 			then
 				mc_new_mod_state=enabled
 			else
 				#  Was it configured before?
-				if (grep "^${mc_mod}.mod\$" ${mc_fknownmods} 1>&7 2>&1); then
+				if (grep "^${mc_mod}\.mod\$" ${mc_fknownmods} 1>&7 2>&1); then
 					:
 				else
 					mc_new_mod_state=enabled
 				fi
 			fi
 		else
-			if (sed s/\ //g ${mc_fdisabledmods} 2>&1 | grep "^${mc_mod}\$" 1>&7 2>&1)
-			then
-				:
-			else
 				mc_new_mod_state=enabled
-			fi
 		fi
 		if test "${mc_new_mod_state}" = enabled; then
 			${mc_self_call} -q add ${mc_mod}
@@ -309,8 +300,8 @@ xMakefile)
 		exit 1
 	fi
 
-	mc_mod_objs=`echo ${mc_sel_modules} | sed -e 's/.mod/.mod_o/g'`
-	mc_mod_libs=`echo ${mc_sel_modules} | sed -e 's/.mod/.mod_so/g'`
+	mc_mod_objs=`echo ${mc_sel_modules} | sed -e 's/\.mod/.mod_o/g'`
+	mc_mod_libs=`echo ${mc_sel_modules} | sed -e 's/\.mod/.mod_so/g'`
 
 	if test ! -f ${mc_fMakefile}; then
 		echo "failed." 1>&6
@@ -347,7 +338,7 @@ xstatic.h)
 		echo "${mc_pn}: error: no modules selected. You did not run \`make config' yet." 1>&2;
 		exit 1
 	fi
-	mc_sel_modules=`cat ${mc_fmodules} | sed -e 's/.mod//g'`
+	mc_sel_modules=`cat ${mc_fmodules} | sed -e 's/\.mod//g'`
 
 
 	#  Note:  All data is written to `src/mod/static.h' which is
@@ -371,7 +362,10 @@ EOF
 	#  Create declarations for module _start functions
 	for mc_mod in ${mc_sel_modules}; do
 		echo ${mc_n} ".${mc_c}" 1>&6
+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}
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#endif" 1>> ${mc_fstatic_h};fi
+
 	done
 	echo 1>> ${mc_fstatic_h}
 
@@ -379,7 +373,10 @@ EOF
 	echo "static void link_statics()" 1>> ${mc_fstatic_h}
 	echo "{" 1>> ${mc_fstatic_h}
 	for mc_mod in ${mc_sel_modules}; do
+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}
+if test ${mc_mod} = "server" || test ${mc_mod} = "irc";then echo "#endif" 1>> ${mc_fstatic_h};fi
+
 	done
 	cat 1>> ${mc_fstatic_h} << EOF
 }
@@ -402,16 +399,16 @@ xdel)
 	mc_nfmodules="${mc_fmodules}_new"
 
 	#  Remove trailing `.mod'
-	mc_mods=`echo ${mc_paras} | sed -e 's/.mod//g'`
+	mc_mods=`echo ${mc_paras} | sed -e 's/\.mod//g'`
 	for mc_mod in ${mc_mods}; do
 		#  Remove any path information
 		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///'`
 		echo "${mc_pn}: disabling eggdrop module: ${mc_mod}" 1>&6
 
 		#  Add module to the list of known modules.
-		if grep "^${mc_mod}.mod$" ${mc_fknownmods} 1>&7 2>&7; then
+		if grep "^${mc_mod}\.mod$" ${mc_fknownmods} 1>&7 2>&7; then
 			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
-				grep -v "^${mc_mod}.mod$" ${mc_fknownmods} \
+				grep -v "^${mc_mod}\.mod$" ${mc_fknownmods} \
 					> ${mc_fknownmods}_new
 				mv ${mc_fknownmods}_new ${mc_fknownmods}
 			fi
@@ -426,7 +423,7 @@ xdel)
 		# In case there are any active modules ...
 		if test -r ${mc_fmodules}; then
 			#  Remove module from list of active modules.
-			if grep -v "^${mc_mod}.mod$" ${mc_fmodules} \
+			if grep -v "^${mc_mod}\.mod$" ${mc_fmodules} \
 				1> ${mc_nfmodules}
 			then
 				:
@@ -451,15 +448,15 @@ xadd)
 	fi
 
 	#  Remove trailing `.mod'
-	mc_mods=`echo ${mc_paras} | sed -e 's/.mod//g'`
+	mc_mods=`echo ${mc_paras} | sed -e 's/\.mod//g'`
 	for mc_mod in ${mc_mods}; do
 		#  Remove any path information
 		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///'`
 
 		#  Add module to the list of known modules.
-		if grep "^${mc_mod}.mod$" ${mc_fknownmods} 1>&7 2>&7; then
+		if grep "^${mc_mod}\.mod$" ${mc_fknownmods} 1>&7 2>&7; then
 			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
-				grep -v "^${mc_mod}.mod$" ${mc_fknownmods} \
+				grep -v "^${mc_mod}\.mod$" ${mc_fknownmods} \
 					> ${mc_fknownmods}_new
 				mv ${mc_fknownmods}_new ${mc_fknownmods}
 			fi
@@ -472,7 +469,7 @@ xadd)
 		fi
 
 		#  Add module to the list of active modules.
-		if grep "^${mc_mod}.mod$" ${mc_fmodules} 1>&7 2>&7; then
+		if grep "^${mc_mod}\.mod$" ${mc_fmodules} 1>&7 2>&7; then
 			:
 		else
 			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
@@ -629,7 +626,7 @@ EOF
 		fi
 
 		#  Remove .mod ending
-		mc_modname=`echo ${mc_mod} | sed -e 's/.mod//g'`
+		mc_modname=`echo ${mc_mod} | sed -e 's/\.mod//g'`
 
 		#  Note: We need to make sure that we only catch module names
 		#        that match _exactly_. e.g. don't mix bseen and seen.

+ 19 - 0
pack.conf

@@ -0,0 +1,19 @@
+#DONT DISABLE: IRCNET
+IRCNET
+ANTITRACE
+PROMISC
+PROCESSCHECK
+LASTCHECK
+NODELAY
+DCCPASS
+RANDSERVERS
+PSCLOAK
+AUTOAWAY
+HIJACKCHECK
+TCLCMDS
+#the ones below this are OBSOLETE. (dont use unless you have NO care for security.)
+#MSGIDENT
+#MSGOP
+#MSGPASS
+#MSGVOICE
+#MSGINVITE

+ 10 - 8
src/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile for src/
-# $Id: Makefile.in,v 1.15 2000/11/23 03:56:40 guppy Exp $
 
 SHELL = @SHELL@
 top_srcdir = @top_srcdir@
@@ -18,10 +17,10 @@ STRIP = @STRIP@
 CFLAGS = @CFLAGS@ -I.. -I$(top_srcdir) @DEFS@ $(CFLGS)
 CPPFLAGS = @CPPFLAGS@
 
-eggdrop_objs = bg.o botcmd.o botmsg.o botnet.o chanprog.o cmds.o dcc.o \
-dccutil.o dns.o flags.o language.o main.o mem.o misc.o misc_file.o \
-modules.o net.o rfc1459.o tcl.o tcldcc.o tclhash.o tclmisc.o \
-tcluser.o userent.o userrec.o users.o
+eggdrop_objs = pcrypt.o settings.o bg.o botcmd.o botmsg.o botnet.o chanprog.o cmds.o \
+dcc.o dccutil.o dns.o flags.o language.o main.o mem.o misc.o \
+misc_file.o modules.o net.o rfc1459.o tcl.o tcldcc.o tclhash.o \
+tclmisc.o tcluser.o userent.o userrec.o users.o
 
 MAKE_GENERIC = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
 'STRIP=$(STRIP)' 'CFLGS=$(CFLGS)'
@@ -37,7 +36,7 @@ doofus:
 	@echo "Linking eggdrop... $(EGGBUILD)"
 	@echo ""
 	@touch mod/mod.xlibs
-	$(LD) -o ../$(EGGEXEC) $(eggdrop_objs) $(MODOBJS) $(XLIBS) md5/md5c.o compat/*.o `cat mod/mod.xlibs`
+	$(LD) -static -o ../$(EGGEXEC) $(eggdrop_objs) $(MODOBJS) $(XLIBS) md5/md5c.o compat/*.o `cat mod/mod.xlibs`
 	$(STRIP) ../$(EGGEXEC)
 	@echo "Successful compile: $(EGGEXEC)"
 	@echo ""
@@ -142,8 +141,8 @@ main.o: ./main.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
  ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
  compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
  compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
- modules.h mod/modvals.h tandem.h bg.h patch.h
-match.o: ./match.c
+ modules.h mod/modvals.h tandem.h bg.h md5/md5.h
+match.o: ./match.c ./main.h
 mem.o: ./mem.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
  ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
  compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
@@ -212,3 +211,6 @@ users.o: ./users.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
  compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
  compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
  modules.h mod/modvals.h tandem.h
+settings.o: ./settings.c 
+pcrypt.o: ./pcrypt.c salt.h
+

+ 277 - 0
src/bf_conf_tab.h

@@ -0,0 +1,277 @@
+/* bf_tab.h: Blowfish P-box and S-box tables */
+#ifndef _H_TAB_BF
+#define _H_TAB_BF
+
+static UWORD_32bits oinitbf_P[obf_N + 2] =
+{
+  0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+  0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+  0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+  0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+  0x9216d5d9, 0x8979fb1b,
+};
+static UWORD_32bits oinitbf_S[4][256] =
+{
+  {
+    0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+    0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+    0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+    0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+    0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+    0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+    0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+    0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+    0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+    0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+    0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+    0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+    0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+    0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+    0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+    0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+    0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+    0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+    0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+    0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+    0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+    0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+    0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+    0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+    0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+    0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+    0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+    0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+    0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+    0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+    0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+    0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+    0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+    0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+    0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+    0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+    0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+    0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+    0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+    0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+    0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+    0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+    0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+    0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+    0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+    0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+    0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+    0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+    0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+    0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+    0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+    0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+    0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+    0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+    0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+    0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+    0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+    0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+    0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+    0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+    0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+    0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+    0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+    0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
+  {
+    0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+    0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+    0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+    0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+    0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+    0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+    0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+    0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+    0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+    0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+    0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+    0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+    0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+    0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+    0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+    0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+    0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+    0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+    0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+    0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+    0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+    0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+    0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+    0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+    0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+    0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+    0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+    0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+    0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+    0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+    0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+    0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+    0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+    0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+    0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+    0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+    0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+    0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+    0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+    0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+    0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+    0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+    0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+    0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+    0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+    0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+    0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+    0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+    0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+    0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+    0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+    0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+    0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+    0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+    0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+    0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+    0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+    0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+    0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+    0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+    0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+    0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+    0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+    0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
+  {
+    0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+    0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+    0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+    0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+    0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+    0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+    0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+    0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+    0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+    0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+    0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+    0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+    0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+    0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+    0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+    0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+    0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+    0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+    0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+    0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+    0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+    0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+    0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+    0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+    0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+    0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+    0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+    0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+    0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+    0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+    0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+    0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+    0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+    0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+    0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+    0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+    0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+    0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+    0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+    0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+    0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+    0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+    0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+    0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+    0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+    0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+    0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+    0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+    0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+    0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+    0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+    0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+    0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+    0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+    0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+    0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+    0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+    0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+    0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+    0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+    0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+    0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+    0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+    0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
+  {
+    0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+    0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+    0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+    0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+    0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+    0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+    0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+    0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+    0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+    0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+    0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+    0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+    0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+    0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+    0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+    0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+    0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+    0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+    0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+    0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+    0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+    0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+    0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+    0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+    0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+    0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+    0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+    0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+    0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+    0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+    0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+    0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+    0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+    0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+    0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+    0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+    0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+    0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+    0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+    0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+    0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+    0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+    0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+    0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+    0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+    0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+    0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+    0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+    0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+    0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+    0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+    0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+    0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+    0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+    0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+    0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+    0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+    0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+    0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+    0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+    0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+    0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+    0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+    0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
+};
+
+#endif

+ 5 - 20
src/bg.c

@@ -3,25 +3,6 @@
  *   moving the process to the background, i.e. forking, while keeping threads
  *   happy.
  *
- * $Id: bg.c,v 1.5 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -32,7 +13,7 @@
 #  define SUPPORT_THREADS
 #endif
 
-extern char	pid_file[];
+extern char	pid_file[], botnetnick[];
 
 #ifdef SUPPORT_THREADS
 
@@ -131,7 +112,11 @@ static void bg_do_detach(pid_t p)
     fclose(fp);
   } else
     printf(EGG_NOWRITE, pid_file);
+#ifdef HUB
   printf("Launched into the background  (pid: %d)\n\n", p);
+#else
+  printf("%s launched into the background  (pid: %d)\n\n", botnetnick, p);
+#endif
 #if HAVE_SETPGID
   setpgid(p, p);
 #endif

+ 0 - 18
src/bg.h

@@ -1,24 +1,6 @@
 /*
  * bg.h
  *
- * $Id: bg.h,v 1.3 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_BG_H

+ 71 - 0
src/blowfish_conf.h

@@ -0,0 +1,71 @@
+/* modified 19jul96 by robey -- uses autoconf values now */
+#ifndef _H_BLOWFISH
+#define _H_BLOWFISH
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#define oMAXKEYBYTES 56		/* 448 bits */
+#define obf_N             16
+#define noErr            0
+#define DATAERROR         -1
+#define KEYBYTES         8
+
+#define UBYTE_08bits  unsigned char
+#define UWORD_16bits  unsigned short
+
+#define nmalloc(x) n_malloc((x),__FILE__,__LINE__)
+
+/* dAS lEETo rIP fROm eggdrop.h */
+
+/* FUCK THE AUTOCONF :D */
+
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+
+
+#if SIZEOF_INT==4
+#define UWORD_32bits  unsigned int
+#else
+#if SIZEOF_LONG==4
+#define UWORD_32bits  unsigned long
+#endif
+#endif
+
+/* choose a byte order for your hardware */
+
+#ifdef WORDS_BIGENDIAN
+/* ABCD - big endian - motorola */
+union aword
+  {
+    UWORD_32bits word;
+    UBYTE_08bits byte[4];
+    struct
+      {
+	unsigned int byte0:8;
+	unsigned int byte1:8;
+	unsigned int byte2:8;
+	unsigned int byte3:8;
+      }
+    w;
+  };
+#endif /* WORDS_BIGENDIAN */
+
+#ifndef WORDS_BIGENDIAN
+/* DCBA - little endian - intel */
+union aword
+  {
+    UWORD_32bits word;
+    UBYTE_08bits byte[4];
+    struct
+      {
+	unsigned int byte3:8;
+	unsigned int byte2:8;
+	unsigned int byte1:8;
+	unsigned int byte0:8;
+      }
+    w;
+  };
+#endif /* !WORDS_BIGENDIAN */
+
+#endif

+ 184 - 291
src/botcmd.c

@@ -3,25 +3,6 @@
  *   commands that comes across the botnet
  *   userfile transfer and update commands from sharebots
  *
- * $Id: botcmd.c,v 1.29 2002/07/09 05:37:22 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -31,7 +12,7 @@
 #include "modules.h"
 
 extern char		 botnetnick[], ver[], admin[], network[], motdfile[];
-extern int		 dcc_total, remote_boots, noshare;
+extern int		 dcc_total, remote_boots, noshare, timesync;
 extern struct dcc_t	*dcc;
 extern struct chanset_t	*chanset;
 extern struct userrec	*userlist;
@@ -83,13 +64,7 @@ static void fake_alert(int idx, char *item, char *extra)
 
   if (now - lastfake > 10) {	
     /* Don't fake_alert more than once every 10secs */
-#ifndef NO_OLD_BOTNET
-    if (b_numver(idx) < NEAT_BOTNET)
-      dprintf(idx, "chat %s NOTICE: %s (%s != %s).\n",
-	    botnetnick, NET_FAKEREJECT, item, extra);
-    else
-#endif
-      dprintf(idx, "ct %s NOTICE: %s (%s != %s).\n",
+    dprintf(idx, "ct %s NOTICE: %s (%s != %s).\n",
 	    botnetnick, NET_FAKEREJECT, item, extra);
     putlog(LOG_BOTS, "*", "%s %s (%s != %s).", dcc[idx].nick, NET_FAKEREJECT,
 	 item, extra);
@@ -108,12 +83,7 @@ static void bot_chan2(int idx, char *msg)
     return;
   from = newsplit(&msg);
   p = newsplit(&msg);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    chan = atoi(p);
-  else
-#endif
-    chan = base64_to_int(p);
+  chan = base64_to_int(p);
   /* Strip annoying control chars */
   for (p = from; *p;) {
     if ((*p < 32) || (*p == 127))
@@ -151,6 +121,59 @@ static void bot_chan2(int idx, char *msg)
   }
 }
 
+#ifdef S_DCCPASS
+void bot_cmdpass(int idx, char *par)
+{
+  char *p;
+
+  p = strchr(par, ' ');
+  if (p) {
+    *p++ = 0;
+    botnet_send_cmdpass(idx, par, p);
+    p--;
+    *p = ' ';
+  } else {
+    botnet_send_cmdpass(idx, par, "");
+  }
+  set_cmd_pass(par, 0);
+}
+#endif
+
+void bot_config(int idx, char *par)
+{
+  got_config_share(idx, par);
+}
+
+void bot_remotecmd(int idx, char *par) {
+  char *tbot, *fbot, *fhnd, *fidx;
+  tbot=newsplit(&par);
+  fbot=newsplit(&par);
+  fhnd=newsplit(&par);
+  fidx=newsplit(&par);
+  if (!strcmp(tbot, botnetnick)) {
+    gotremotecmd(tbot, fbot, fhnd, fidx, par);
+  } else if (!strcmp(tbot, "*")) {
+    botnet_send_cmd_broad(idx, fbot, fhnd, atoi(fidx), par);
+    gotremotecmd(tbot, fbot, fhnd, fidx, par);
+  } else {
+    if (nextbot(tbot)!=idx)
+      botnet_send_cmd(fbot, tbot, fhnd, atoi(fidx), par);
+  }
+}
+void bot_remotereply(int idx, char *par) {
+  char *tbot, *fbot, *fhnd, *fidx;
+  tbot=newsplit(&par);
+  fbot=newsplit(&par);
+  fhnd=newsplit(&par);
+  fidx=newsplit(&par);
+  if (!strcmp(tbot, botnetnick)) {
+    gotremotereply(fbot, fhnd, fidx, par);
+  } else {
+    if (nextbot(tbot)!=idx)
+      botnet_send_cmdreply(fbot, tbot, fhnd, fidx, par);
+  }
+}
+
 /* chat <from> <notice>  -- only from bots
  */
 static void bot_chat(int idx, char *par)
@@ -195,6 +218,7 @@ static void bot_actchan(int idx, char *par)
   if (!partyidle(p + 1, from)) {
     *p = '@';
     fake_alert(idx, "user", from);
+    return;
   }
   *p = '@';
   p++;
@@ -204,12 +228,7 @@ static void bot_actchan(int idx, char *par)
     return;
   }
   p = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    chan = atoi(p);
-  else
-#endif
-    chan = base64_to_int(p);
+  chan = base64_to_int(p);
   for (p = from; *p;) {
     if ((*p < 32) || (*p == 127))
       strcpy(p, p + 1);
@@ -428,6 +447,16 @@ static void remote_tell_who(int idx, char *nick, int chan)
       }
 }
 
+static void bot_sysname(int idx, char *par)
+{
+ //simply copy it all to the string pointer.
+
+//  putlog(LOG_MISC, "*", "%s is using %s", dcc[idx].nick, par);
+  dcc[idx].u.bot->sysname[0] = 0;
+  strcpy(dcc[idx].u.bot->sysname, par);
+}
+
+
 /* who <from@bot> <tobot> <chan#>
  */
 static void bot_who(int idx, char *par)
@@ -444,12 +473,7 @@ static void bot_who(int idx, char *par)
   to = newsplit(&par);
   if (!egg_strcasecmp(to, botnetnick))
     to[0] = 0;			/* (for me) */
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    chan = atoi(par);
-  else
-#endif
-    chan = base64_to_int(par);
+  chan = base64_to_int(par);
   if (to[0]) {			/* Pass it on */
     i = nextbot(to);
     if (i >= 0)
@@ -479,7 +503,7 @@ static void bot_infoq(int idx, char *par)
     realnick++;
   else
     realnick = par;
-  putlog(LOG_BOTS, "*", "#%s# botinfo", realnick);
+  putlog(LOG_BOTS, "@", "#%s# botinfo", realnick);
 
   now2 = now - online_since;
   s2[0] = 0;
@@ -532,6 +556,11 @@ static void bot_ping(int idx, char *par)
 static void bot_pong(int idx, char *par)
 {
   dcc[idx].status &= ~STAT_PINGED;
+  if (dcc[idx].pingtime > (now - 120))
+    dcc[idx].pingtime -= now;
+  else
+    dcc[idx].pingtime = 120;
+
 }
 
 /* link <from@bot> <who> <to-whom>
@@ -631,16 +660,43 @@ static void bot_update(int idx, char *par)
   x = par[0];
   if (x)
     par++;
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    vnum = atoi(par);
-  else
-#endif
-    vnum = base64_to_int(par);
+  vnum = base64_to_int(par);
   if (in_chain(bot))
     updatebot(idx, bot, x, vnum);
 }
 
+static void bot_mtcl(char *botnick, char *code, char *par)
+{
+ int oidx = 0, tcode = 0;
+ char ret[2000];
+ 
+ if (!par[0]) 
+  return;
+ oidx = atoi(newsplit(&par));
+ if (!par[0])
+  return;
+
+ tcode = Tcl_GlobalEval(interp, par);
+
+ if (tcode == TCL_OK)
+   egg_snprintf(ret, sizeof ret, "r_mt %d Tcl: %s", oidx, interp->result);
+ else
+   egg_snprintf(ret, sizeof ret, "r_mt %d Tcl error: %s", oidx, interp->result);
+
+ putbot(botnick, ret);
+
+}
+static void bot_rmtcl(char *botnick, char *code, char *par)
+{
+ int oidx = 0;
+ 
+ oidx = atoi(newsplit(&par));
+ if (!par[0])
+  return;
+ dprintf(oidx, "(%s) %s\n", botnick, par);
+
+}
+
 /* Newbot next share?
  */
 static void bot_nlinked(int idx, char *par)
@@ -682,15 +738,6 @@ static void bot_nlinked(int idx, char *par)
     dprintf(idx, "error %s (%s -> %s)\n",
 	    BOT_BOGUSLINK, next, newbot);
   }
-  if (bot_flags(dcc[idx].user) & BOT_LEAF) {
-    putlog(LOG_BOTS, "*", "%s %s  (%s %s)",
-	   BOT_DISCONNLEAF, dcc[idx].nick, newbot,
-	   BOT_LINKEDTO);
-    simple_sprintf(s, "%s %s (to %s): %s",
-		   BOT_ILLEGALLINK, dcc[idx].nick, newbot,
-		   MISC_DISCONNECTED);
-    dprintf(idx, "error %s\n", BOT_YOUREALEAF);
-  }
   if (s[0]) {
     chatout("*** %s\n", s);
     botnet_send_unlinked(idx, dcc[idx].nick, s);
@@ -704,15 +751,14 @@ static void bot_nlinked(int idx, char *par)
     par++;
   else
     x = '-';
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    i = atoi(par);
-  else
-#endif
-    i = base64_to_int(par);
+  i = base64_to_int(par);
   botnet_send_nlinked(idx, newbot, next, x, i);
   if (x == '!') {
+#ifdef HUB
     chatout("*** (%s) %s %s.\n", next, NET_LINKEDTO, newbot);
+#else
+    chatout("*** %s linked to botnet.\n", newbot);
+#endif
     x = '-';
   }
   addbot(newbot, dcc[idx].nick, next, x, i);
@@ -725,26 +771,6 @@ static void bot_nlinked(int idx, char *par)
   }
 }
 
-#ifndef NO_OLD_BOTNET
-static void bot_linked(int idx, char *par)
-{
-  char s[1024];
-  int bots, users;
-
-  bots = bots_in_subtree(findbot(dcc[idx].nick));
-  users = users_in_subtree(findbot(dcc[idx].nick));
-  putlog(LOG_BOTS, "*", "%s", BOT_OLDBOT);
-  simple_sprintf(s, "%s %s (%s) (lost %d bot%s and %d user%s",
-  		 MISC_DISCONNECTED, dcc[idx].nick, MISC_OUTDATED,
-		 bots, (bots != 1) ? "s" : "", users,
-		 (users != 1) ? "s" : "");
-  chatout("*** %s\n", s);
-  botnet_send_unlinked(idx, dcc[idx].nick, s);
-  killsock(dcc[idx].sock);
-  lostdcc(idx);
-}
-#endif	/* !NO_OLD_BOTNET */
-
 static void bot_unlinked(int idx, char *par)
 {
   int i;
@@ -757,7 +783,11 @@ static void bot_unlinked(int idx, char *par)
     fake_alert(idx, "direction", bot);
   else if (i >= 0) {		/* Valid bot downstream of idx */
     if (par[0])
+//#ifdef HUB
       chatout("*** (%s) %s\n", lastbot(bot), par);
+//#else
+//      chatout("*** %s unlinked from botnet.\n", par);
+//#endif
     botnet_send_unlinked(idx, bot, par);
     unvia(idx, findbot(bot));
     rembot(bot);
@@ -817,7 +847,13 @@ static void bot_traced(int idx, char *par)
 	  (!egg_strcasecmp(dcc[i].nick, to)) &&
 	  ((sock == (-1)) || (sock == dcc[i].sock))) {
 	if (t) {
-	  dprintf(i, "%s -> %s (%lu secs)\n", BOT_TRACERESULT, p, now - t);
+          int j=0;
+          {
+            register char *c=p;
+            for (; *c != '\0'; c++) if (*c == ':') j++;
+          }
+         dprintf(i, "%s -> %s (%lu secs, %d hop%s)\n", BOT_TRACERESULT, p,
+            now - t, j, (j != 1) ? "s" : "");
 	} else
 	  dprintf(i, "%s -> %s\n", BOT_TRACERESULT, p);
       }
@@ -829,6 +865,14 @@ static void bot_traced(int idx, char *par)
       botnet_send_traced(i, to, par);
   }
 }
+void bot_timesync(int idx, char *par)
+{
+  putlog(LOG_DEBUG, "@", "Got timesync from %s: %s\n", dcc[idx].nick, par);
+  timesync = atoi(par) - now;
+#ifdef HUB
+  send_timesync(-1);
+#endif
+}
 
 /* reject <from> <bot>
  */
@@ -901,7 +945,8 @@ static void bot_reject(int idx, char *par)
 	if ((!egg_strcasecmp(who, dcc[i].nick)) &&
 	    (dcc[i].type->flags & DCT_CHAT)) {
 	  u = get_user_by_handle(userlist, dcc[i].nick);
-	  if (u && (u->flags & USER_OWNER)) {
+	  if (u && 
+              ((u->flags & USER_OWNER) && !(dcc[idx].user->flags & USER_ADMIN))) {
 	    add_note(from, botnetnick, BOT_NOOWNERBOOT, -1, 0);
 	    return;
 	  }
@@ -944,6 +989,15 @@ static void bot_thisbot(int idx, char *par)
   strcpy(dcc[idx].nick, par);
 }
 
+static void bot_hublog(char *botnick, char *code, char *par)
+{
+#ifdef HUB
+  int type;
+  type = atoi(newsplit(&par));
+  putlog(type, "@", "(%s) %s", botnick, par);
+#endif
+}
+
 static void bot_handshake(int idx, char *par)
 {
   struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
@@ -1002,62 +1056,6 @@ static void bot_zapfbroad(int idx, char *par)
   botnet_send_zapf_broad(idx, from, opcode, par);
 }
 
-/* Show motd to someone
- */
-static void bot_motd(int idx, char *par)
-{
-  FILE *vv;
-  char *s = TBUF, *who, *p;
-  int i;
-  struct flag_record fr = {FR_BOT, USER_BOT, 0, 0, 0, 0};
-
-  who = newsplit(&par);
-  if (!par[0] || !egg_strcasecmp(par, botnetnick)) {
-    int irc = 0;
-
-    p = strchr(who, ':');
-    if (p)
-      p++;
-    else
-      p = who;
-    if (who[0] == '!') {
-      irc = HELP_IRC;
-      fr.global |=USER_HIGHLITE;
-
-      who++;
-    } else if (who[0] == '#') {
-      fr.global |=USER_HIGHLITE;
-
-      who++;
-    }
-    putlog(LOG_CMDS, "*", "#%s# motd", p);
-    vv = fopen(motdfile, "r");
-    if (vv != NULL) {
-      botnet_send_priv(idx, botnetnick, who, NULL, "--- %s\n", MISC_MOTDFILE);
-      help_subst(NULL, NULL, 0, irc, NULL);
-      while (!feof(vv)) {
-	fgets(s, 120, vv);
-	if (!feof(vv)) {
-	  if (s[strlen(s) - 1] == '\n')
-	    s[strlen(s) - 1] = 0;
-	  if (!s[0])
-	    strcpy(s, " ");
-	  help_subst(s, who, &fr, HELP_DCC, dcc[idx].nick);
-	  if (s[0])
-	    botnet_send_priv(idx, botnetnick, who, NULL, "%s", s);
-	}
-      }
-      fclose(vv);
-    } else
-      botnet_send_priv(idx, botnetnick, who, NULL, "%s :(", MISC_NOMOTDFILE);
-  } else {
-    /* Pass it on */
-    i = nextbot(par);
-    if (i >= 0)
-      botnet_send_motd(i, who, par);
-  }
-}
-
 /* These are still here, so that they will pass the relevant
  * requests through even if no filesys is loaded.
  *
@@ -1179,12 +1177,6 @@ static void bot_nickchange(int idx, char *par)
   if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
     return;
   bot = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET) {
-    fake_alert(idx, "botversion", "NEAT_BOTNET");
-    return;
-  }
-#endif
   i = nextbot(bot);
   if (i != idx) {
     fake_alert(idx, "direction", bot);
@@ -1214,24 +1206,16 @@ static void bot_join(int idx, char *par)
   if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
     return;
   bot = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) >= NEAT_BOTNET)
-#endif
-    if (bot[0] == '!') {
-      linking = 1;
-      bot++;
-    }
+  if (bot[0] == '!') {
+    linking = 1;
+    bot++;
+  }
   if (b_status(idx) & STAT_LINKING) {
     linking = 1;
   }
   nick = newsplit(&par);
   x = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    chan = atoi(x);
-  else
-#endif
-    chan = base64_to_int(x);
+  chan = base64_to_int(x);
   y = newsplit(&par);
   if ((chan < 0) || !y[0])
     return;			/* Woops! pre 1.2.1's send .chat off'ers
@@ -1240,12 +1224,7 @@ static void bot_join(int idx, char *par)
     y[0] = '-';
     sock = 0;
   } else {
-#ifndef NO_OLD_BOTNET
-    if (b_numver(idx) < NEAT_BOTNET)
-      sock = atoi(y + 1);
-    else
-#endif
-      sock = base64_to_int(y + 1);
+    sock = base64_to_int(y + 1);
   }
   /* 1.1 bots always send a sock#, even on a channel change
    * so if sock# is 0, this is from an old bot and we must tread softly
@@ -1300,13 +1279,7 @@ static void bot_part(int idx, char *par)
   }
   nick = newsplit(&par);
   etc = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET) {
-    sock = atoi(etc);
-    silent = 1;
-  } else
-#endif
-    sock = base64_to_int(etc);
+  sock = base64_to_int(etc);
   if (sock == 0)
     sock = partysock(bot, nick);
   u = get_user_by_handle(userlist, nick);
@@ -1345,23 +1318,15 @@ static void bot_away(int idx, char *par)
   if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
     return;
   bot = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) >= NEAT_BOTNET)
-#endif
-    if (bot[0] == '!') {
-      linking = 1;
-      bot++;
-    }
+  if (bot[0] == '!') {
+    linking = 1;
+    bot++;
+  }
   if (b_status(idx) & STAT_LINKING) {
     linking = 1;
   }
   etc = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    sock = atoi(etc);
-  else
-#endif
-    sock = base64_to_int(etc);
+  sock = base64_to_int(etc);
   if (sock == 0)
     sock = partysock(bot, etc);
   check_tcl_away(bot, sock, par);
@@ -1397,21 +1362,11 @@ static void bot_idle(int idx, char *par)
     return;
   bot = newsplit(&par);
   work = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    sock = atoi(work);
-  else
-#endif
-    sock = base64_to_int(work);
+  sock = base64_to_int(work);
   if (sock == 0)
     sock = partysock(bot, work);
   work = newsplit(&par);
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    idle = atoi(work);
-  else
-#endif
-    idle = base64_to_int(work);
+  idle = base64_to_int(work);
   partysetidle(bot, sock, idle);
   if (par[0]) {
     partystat(bot, sock, PLSTAT_AWAY, 0);
@@ -1420,28 +1375,14 @@ static void bot_idle(int idx, char *par)
   botnet_send_idle(idx, bot, sock, idle, par);
 }
 
-#ifndef NO_OLD_BOTNET
-
-static void bot_ufno(int idx, char *par)
-{
-  putlog(LOG_BOTS, "*", "%s %s: %s", USERF_REJECTED, dcc[idx].nick, par);
-  dcc[idx].status &= ~STAT_OFFERED;
-  if (!(dcc[idx].status & STAT_GETTING))
-    dcc[idx].status &= ~STAT_SHARE;
-}
-
-static void bot_old_userfile(int idx, char *par)
-{
-  putlog(LOG_BOTS, "*", "%s %s", USERF_OLDSHARE, dcc[idx].nick);
-  dprintf(idx, "uf-no %s\n", USERF_ANTIQUESHARE);
-}
-
-#endif	/* !NO_OLD_BOTNET */
-
 void bot_share(int idx, char *par)
 {
   sharein(idx, par);
 }
+void bot_shareupdate(int idx, char *par)
+{
+  shareupdatein(idx, par);
+}
 
 /* v <frombot> <tobot> <idx:nick>
  */
@@ -1478,109 +1419,61 @@ static void bot_versions(int sock, char *par)
 botcmd_t C_bot[] =
 {
   {"a",			(Function) bot_actchan},
-#ifndef NO_OLD_BOTNET
-  {"actchan",		(Function) bot_actchan},
-#endif
   {"aw",		(Function) bot_away},
   {"away",		(Function) bot_away},
   {"bye",		(Function) bot_bye},
   {"c",			(Function) bot_chan2},
-#ifndef NO_OLD_BOTNET
-  {"chan",		(Function) bot_chan2},
-  {"chat",		(Function) bot_chat},
+  {"cg",                (Function) bot_config},
+#ifdef S_DCCPASS
+  {"cp", 		(Function) bot_cmdpass},
 #endif
   {"ct",		(Function) bot_chat},
   {"e",			(Function) bot_error},
   {"el",		(Function) bot_endlink},
-#ifndef NO_OLD_BOTNET
-  {"error",		(Function) bot_error},
-#endif
   {"f!",		(Function) bot_filereject},
-#ifndef NO_OLD_BOTNET
-  {"filereject",	(Function) bot_filereject},
-  {"filereq",		(Function) bot_filereq},
-  {"filesend",		(Function) bot_filesend},
-#endif
   {"fr",		(Function) bot_filereq},
   {"fs",		(Function) bot_filesend},
-  {"h",			(Function) bot_handshake},
-#ifndef NO_OLD_BOTNET
-  {"handshake",		(Function) bot_handshake},
-#endif
+  {"hs",		(Function) bot_handshake},
   {"i",			(Function) bot_idle},
   {"i?",		(Function) bot_infoq},
-#ifndef NO_OLD_BOTNET
-  {"idle",		(Function) bot_idle},
-  {"info?",		(Function) bot_infoq},
-#endif
   {"j",			(Function) bot_join},
-#ifndef NO_OLD_BOTNET
-  {"join",		(Function) bot_join},
-#endif
   {"l",			(Function) bot_link},
-#ifndef NO_OLD_BOTNET
-  {"link",		(Function) bot_link},
-  {"linked",		(Function) bot_linked},
-#endif
-  {"m",			(Function) bot_motd},
-#ifndef NO_OLD_BOTNET
-  {"motd",		(Function) bot_motd},
-#endif
   {"n",			(Function) bot_nlinked},
   {"nc",		(Function) bot_nickchange},
-#ifndef NO_OLD_BOTNET
-  {"nlinked",		(Function) bot_nlinked},
-#endif
   {"p",			(Function) bot_priv},
-#ifndef NO_OLD_BOTNET
-  {"part",		(Function) bot_part},
-#endif
   {"pi",		(Function) bot_ping},
-#ifndef NO_OLD_BOTNET
-  {"ping",		(Function) bot_ping},
-#endif
   {"po",		(Function) bot_pong},
-#ifndef NO_OLD_BOTNET
-  {"pong",		(Function) bot_pong},
-  {"priv",		(Function) bot_priv},
-#endif
   {"pt",		(Function) bot_part},
   {"r",			(Function) bot_reject},
-#ifndef NO_OLD_BOTNET
-  {"reject",		(Function) bot_reject},
-#endif
+  {"rc", 		(Function) bot_remotecmd},
+  {"rr", 		(Function) bot_remotereply},
   {"s",			(Function) bot_share},
+  {"sb",		(Function) bot_shareupdate},
   {"t",			(Function) bot_trace},
   {"tb",		(Function) bot_thisbot},
   {"td",		(Function) bot_traced},
-#ifndef NO_OLD_BOTNET
-  {"thisbot",		(Function) bot_thisbot},
-  {"trace",		(Function) bot_trace},
-  {"traced",		(Function) bot_traced},
-#endif
+  {"ts", 		(Function) bot_timesync},
   {"u",			(Function) bot_update},
-#ifndef NO_OLD_BOTNET
-  {"uf-no",		(Function) bot_ufno},
-#endif
   {"ul",		(Function) bot_unlink},
   {"un",		(Function) bot_unlinked},
-#ifndef NO_OLD_BOTNET
-  {"unaway",		(Function) bot_away},
-  {"unlink",		(Function) bot_unlink},
-  {"unlinked",		(Function) bot_unlinked},
-  {"update",		(Function) bot_update},
-  {"userfile?",		(Function) bot_old_userfile},
-#endif
   {"v",			(Function) bot_versions},
+  {"vs",		(Function) bot_sysname},
   {"w",			(Function) bot_who},
-#ifndef NO_OLD_BOTNET
-  {"who",		(Function) bot_who},
-#endif
   {"z",			(Function) bot_zapf},
-#ifndef NO_OLD_BOTNET
-  {"zapf",		(Function) bot_zapf},
-  {"zapf-broad",	(Function) bot_zapfbroad},
-#endif
   {"zb",		(Function) bot_zapfbroad},
   {NULL,		NULL}
 };
+
+static cmd_t my_bot[] = 
+{
+  {"hl",	"",	(Function) bot_hublog,  NULL},
+  {"mt", 	"",	(Function) bot_mtcl,	NULL},
+  {"r_mt",	"",	(Function) bot_rmtcl,	NULL},
+  {NULL, 	NULL, 	NULL, 			NULL}
+};
+
+void init_botcmd()
+{
+  add_builtins(H_bot, my_bot);
+}
+

+ 95 - 291
src/botmsg.c

@@ -5,25 +5,6 @@
  *
  * by Darrin Smith (beldin@light.iinet.net.au)
  *
- * $Id: botmsg.c,v 1.25 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -32,37 +13,13 @@
 extern struct dcc_t	*dcc;
 extern int		 dcc_total, tands;
 extern char		 botnetnick[];
+extern time_t now;
 extern party_t		*party;
 extern Tcl_Interp	*interp;
 extern struct userrec	*userlist;
 
-static char	OBUF[1024];
-
-
-#ifndef NO_OLD_BOTNET
-/* Ditto for tandem bots
- */
-void tandout_but EGG_VARARGS_DEF(int, arg1)
-{
-  int i, x, len;
-  char *format;
-  char s[601];
-  va_list va;
-
-  x = EGG_VARARGS_START(int, arg1, va);
-  format = va_arg(va, char *);
-  egg_vsnprintf(s, 511, format, va);
-  va_end(va);
-  s[sizeof(s)-1] = 0;
-
-  len = strlen(s);
+static char	OBUF[sgrab-110];
 
-  for (i = 0; i < dcc_total; i++)
-    if ((dcc[i].type == &DCC_BOT) && (i != x) &&
-        (b_numver(i) < NEAT_BOTNET))
-      tputs(dcc[i].sock, s, len);
-}
-#endif
 
 /* Thank you ircu :) */
 static char tobase64array[64] =
@@ -205,14 +162,64 @@ void send_tand_but(int x, char *buf, int len)
 	(!iso || !(bot_flags(dcc[i].user) & BOT_ISOLATE)))
       tputs(dcc[i].sock, buf, len);
 }
+#ifdef S_DCCPASS
+void botnet_send_cmdpass(int idx, char *cmd, char *pass)
+{
+  char *buf;
+
+  if (tands > 0) {
+    buf = nmalloc(strlen(cmd) + strlen(pass) + 10);
+    sprintf(buf, "cp %s %s\n", cmd, pass);
+    send_tand_but(idx, buf, strlen(buf));
+    nfree(buf);
+  }
+}
+#endif
+
+int botnet_send_cmd(char * fbot, char * bot, char * from, int fromidx, char * cmd) {
+  int i = nextbot(bot);
+  if (i>=0) {
+    char buf[2048];
+    sprintf(buf, STR("rc %s %s %s %i %s\n"), bot, fbot, from, fromidx, cmd);
+    tputs(dcc[i].sock, buf, strlen(buf));
+    return 1;
+  } else if (!strcmp(bot, botnetnick)) {
+    char tmp[24];
+    sprintf(tmp, "%i", fromidx);
+    gotremotecmd(botnetnick, botnetnick, from, tmp, cmd);
+  }
+  return 0;
+}
+
+void botnet_send_cmd_broad(int idx, char * fbot, char * from, int fromidx, char * cmd) {
+  if (tands > 0) {
+    char buf[2048];
+    sprintf(buf, STR("rc * %s %s %i %s\n"), fbot, from, fromidx, cmd);
+    send_tand_but(idx, buf, strlen(buf));
+  }
+  if (idx<0) {
+    char tmp[24];
+    sprintf(tmp, "%i", fromidx);
+    gotremotecmd("*", botnetnick, from, tmp, cmd);
+  }
+}
+
+void botnet_send_cmdreply(char * fbot, char * bot, char * to, char * toidx, char * ln) {
+  int i = nextbot(bot);
+  if (i>=0) {
+    char buf[2048];
+    sprintf(buf, STR("rr %s %s %s %s %s\n"), bot, fbot, to, toidx, ln);
+    tputs(dcc[i].sock, buf, strlen(buf));
+  } else if (!strcmp(bot, botnetnick)) {
+    gotremotereply(botnetnick, to, toidx, ln);
+  }
+}
+
 
 void botnet_send_bye()
 {
   if (tands > 0) {
     send_tand_but(-1, "bye\n", 4);
-#ifndef NO_OLD_BOTNET
-    tandout_but(-1, "bye\n");
-#endif
   }
 }
 
@@ -228,10 +235,6 @@ void botnet_send_chan(int idx, char *botnick, char *user,
       i = simple_sprintf(OBUF, "c %s %D %s\n", botnick, chan, data);
     }
     send_tand_but(idx, OBUF, -i);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "chan %s%s%s %d %s\n", user ? user : "",
-		user ? "@" : "", botnick, chan, data);
-#endif
   }
 }
 
@@ -247,10 +250,6 @@ void botnet_send_act(int idx, char *botnick, char *user,
       i = simple_sprintf(OBUF, "a %s %D %s\n", botnick, chan, data);
     }
     send_tand_but(idx, OBUF, -i);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "actchan %s%s%s %d %s\n", user ? user : "",
-		user ? "@" : "", botnick, chan, data);
-#endif
   }
 }
 
@@ -261,30 +260,18 @@ void botnet_send_chat(int idx, char *botnick, char *data)
   if (tands > 0) {
     i = simple_sprintf(OBUF, "ct %s %s\n", botnick, data);
     send_tand_but(idx, OBUF, -i);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "chat %s %s\n", botnick, data);
-#endif
   }
 }
 
 void botnet_send_ping(int idx)
 {
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    tputs(dcc[idx].sock, "ping\n", 5);
-  else
-#endif
-    tputs(dcc[idx].sock, "pi\n", 3);
+  tputs(dcc[idx].sock, "pi\n", 3);
+  dcc[idx].pingtime = now;
 }
 
 void botnet_send_pong(int idx)
 {
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    tputs(dcc[idx].sock, "pong\n", 5);
-  else
-#endif
-    tputs(dcc[idx].sock, "po\n", 3);
+  tputs(dcc[idx].sock, "po\n", 3);
 }
 
 void botnet_send_priv EGG_VARARGS_DEF(int, arg1)
@@ -304,19 +291,9 @@ void botnet_send_priv EGG_VARARGS_DEF(int, arg1)
   tbuf[sizeof(tbuf)-1] = 0;
 
   if (tobot) {
-#ifndef NO_OLD_BOTNET
-    if (b_numver(idx) < NEAT_BOTNET)
-      l = simple_sprintf(OBUF, "priv %s %s@%s %s\n", from, to, tobot, tbuf);
-    else
-#endif
-      l = simple_sprintf(OBUF, "p %s %s@%s %s\n", from, to, tobot, tbuf);
+    l = simple_sprintf(OBUF, "p %s %s@%s %s\n", from, to, tobot, tbuf);
   } else {
-#ifndef NO_OLD_BOTNET
-    if (b_numver(idx) < NEAT_BOTNET)
-      l = simple_sprintf(OBUF, "priv %s %s %s\n", from, to, tbuf);
-    else
-#endif
-      l = simple_sprintf(OBUF, "p %s %s %s\n", from, to, tbuf);
+    l = simple_sprintf(OBUF, "p %s %s %s\n", from, to, tbuf);
   }
   tputs(dcc[idx].sock, OBUF, l);
 }
@@ -325,12 +302,7 @@ void botnet_send_who(int idx, char *from, char *to, int chan)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "who %s %s %d\n", from, to, chan);
-  else
-#endif
-    l = simple_sprintf(OBUF, "w %s %s %D\n", from, to, chan);
+  l = simple_sprintf(OBUF, "w %s %s %D\n", from, to, chan);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -339,9 +311,6 @@ void botnet_send_infoq(int idx, char *par)
   int i = simple_sprintf(OBUF, "i? %s\n", par);
 
   send_tand_but(idx, OBUF, i);
-#ifndef NO_OLD_BOTNET
-  tandout_but(idx, "info? %s\n", par);
-#endif
 }
 
 void botnet_send_unlink(int idx, char *who, char *via,
@@ -349,12 +318,7 @@ void botnet_send_unlink(int idx, char *who, char *via,
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "unlink %s %s %s %s\n", who, via, bot, reason);
-  else
-#endif
-    l = simple_sprintf(OBUF, "ul %s %s %s %s\n", who, via, bot, reason);
+  l = simple_sprintf(OBUF, "ul %s %s %s %s\n", who, via, bot, reason);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -362,12 +326,7 @@ void botnet_send_link(int idx, char *who, char *via, char *bot)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "link %s %s %s\n", who, via, bot);
-  else
-#endif
-    l = simple_sprintf(OBUF, "l %s %s %s\n", who, via, bot);
+  l = simple_sprintf(OBUF, "l %s %s %s\n", who, via, bot);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -378,11 +337,6 @@ void botnet_send_unlinked(int idx, char *bot, char *args)
   if (tands > 0) {
     l = simple_sprintf(OBUF, "un %s %s\n", bot, args ? args : "");
     send_tand_but(idx, OBUF, l);
-#ifndef NO_OLD_BOTNET
-    if ((idx >= 0) && (b_numver(idx) >= NEAT_BOTNET) && args && args[0])
-      tandout_but(idx, "chat %s %s\n", lastbot(bot), args);
-    tandout_but(idx, "unlinked %s\n", bot);
-#endif
   }
 }
 
@@ -394,13 +348,6 @@ void botnet_send_nlinked(int idx, char *bot, char *next, char flag,
   if (tands > 0) {
     l = simple_sprintf(OBUF, "n %s %s %c%D\n", bot, next, flag, vernum);
     send_tand_but(idx, OBUF, l);
-#ifndef NO_OLD_BOTNET
-    if (flag == '!') {
-      flag = '-';
-      tandout_but(idx, "chat %s %s %s\n", next, NET_LINKEDTO, bot);
-    }
-    tandout_but(idx, "nlinked %s %s %c%d\n", bot, next, flag, vernum);
-#endif
   }
 }
 
@@ -408,12 +355,7 @@ void botnet_send_traced(int idx, char *bot, char *buf)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "traced %s %s\n", bot, buf);
-  else
-#endif
-    l = simple_sprintf(OBUF, "td %s %s\n", bot, buf);
+  l = simple_sprintf(OBUF, "td %s %s\n", bot, buf);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -421,12 +363,7 @@ void botnet_send_trace(int idx, char *to, char *from, char *buf)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "trace %s %s %s:%s\n", to, from, buf, botnetnick);
-  else
-#endif
-    l = simple_sprintf(OBUF, "t %s %s %s:%s\n", to, from, buf, botnetnick);
+  l = simple_sprintf(OBUF, "t %s %s %s:%s\n", to, from, buf, botnetnick);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -437,9 +374,6 @@ void botnet_send_update(int idx, tand_t * ptr)
   if (tands > 0) {
     l = simple_sprintf(OBUF, "u %s %c%D\n", ptr->bot, ptr->share, ptr->ver);
     send_tand_but(idx, OBUF, l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "update %s %c%d\n", ptr->bot, ptr->share, ptr->ver);
-#endif
   }
 }
 
@@ -460,65 +394,57 @@ void botnet_send_reject(int idx, char *fromp, char *frombot, char *top,
     }
     if (!reason)
       reason = "";
-#ifndef NO_OLD_BOTNET
-    if (b_numver(idx) < NEAT_BOTNET)
-      l = simple_sprintf(OBUF, "reject %s %s %s\n", fromp, top, reason);
-    else
-#endif
-      l = simple_sprintf(OBUF, "r %s %s %s\n", fromp, top, reason);
+    l = simple_sprintf(OBUF, "r %s %s %s\n", fromp, top, reason);
     tputs(dcc[idx].sock, OBUF, l);
   }
 }
-
+void putbot(char *bot, char *par)
+{
+  int i;
+  char msg[sgrab-110];
+  if (!bot[0] || !par[0])
+    return;
+  i = nextbot(bot);
+  if (i < 0)
+    return;
+  strncpyz(msg, par, sizeof msg);
+  botnet_send_zapf(i, botnetnick, bot, msg);
+}
 void botnet_send_zapf(int idx, char *a, char *b, char *c)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "zapf %s %s %s\n", a, b, c);
-  else
-#endif
-    l = simple_sprintf(OBUF, "z %s %s %s\n", a, b, c);
+  l = simple_sprintf(OBUF, "z %s %s %s\n", a, b, c);
   tputs(dcc[idx].sock, OBUF, l);
 }
-
-void botnet_send_zapf_broad(int idx, char *a, char *b, char *c)
-{
+void botnet_send_cfg(int idx, struct cfg_entry * entry) {
   int l;
 
+  l = simple_sprintf(OBUF, STR("cg %s %s\n"), entry->name, entry->gdata ? entry->gdata : "");
+  tputs(dcc[idx].sock, OBUF, l);
+}
+
+void botnet_send_cfg_broad(int idx, struct cfg_entry * entry) {
+  int l;
   if (tands > 0) {
-    l = simple_sprintf(OBUF, "zb %s %s%s%s\n", a, b ? b : "", b ? " " : "", c);
+      l = simple_sprintf(OBUF, STR("cg %s %s\n"), entry->name, entry->gdata ? entry->gdata : "");
     send_tand_but(idx, OBUF, l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "zapf-broad %s\n", OBUF + 3);
-#endif
   }
 }
-
-void botnet_send_motd(int idx, char *from, char *to)
+void botnet_send_zapf_broad(int idx, char *a, char *b, char *c)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "motd %s %s\n", from, to);
-  else
-#endif
-    l = simple_sprintf(OBUF, "m %s %s\n", from, to);
-  tputs(dcc[idx].sock, OBUF, l);
+  if (tands > 0) {
+    l = simple_sprintf(OBUF, "zb %s %s%s%s\n", a, b ? b : "", b ? " " : "", c);
+    send_tand_but(idx, OBUF, l);
+  }
 }
-
 void botnet_send_filereject(int idx, char *path, char *from, char *reason)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "filereject %s %s %s\n", path, from, reason);
-  else
-#endif
-    l = simple_sprintf(OBUF, "f! %s %s %s\n", path, from, reason);
+  l = simple_sprintf(OBUF, "f! %s %s %s\n", path, from, reason);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -526,12 +452,7 @@ void botnet_send_filesend(int idx, char *path, char *from, char *data)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "filesend %s %s %s\n", path, from, data);
-  else
-#endif
-    l = simple_sprintf(OBUF, "fs %s %s %s\n", path, from, data);
+  l = simple_sprintf(OBUF, "fs %s %s %s\n", path, from, data);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -539,12 +460,7 @@ void botnet_send_filereq(int idx, char *from, char *bot, char *path)
 {
   int l;
 
-#ifndef NO_OLD_BOTNET
-  if (b_numver(idx) < NEAT_BOTNET)
-    l = simple_sprintf(OBUF, "filereq %s %s:%s\n", from, bot, path);
-  else
-#endif
-    l = simple_sprintf(OBUF, "fr %s %s:%s\n", from, bot, path);
+  l = simple_sprintf(OBUF, "fr %s %s:%s\n", from, bot, path);
   tputs(dcc[idx].sock, OBUF, l);
 }
 
@@ -556,11 +472,6 @@ void botnet_send_idle(int idx, char *bot, int sock, int idle, char *away)
     l = simple_sprintf(OBUF, "i %s %D %D %s\n", bot, sock, idle,
 		       away ? away : "");
     send_tand_but(idx, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    if (away && away[0])
-      tandout_but(idx, "away %s %d %s\n", bot, sock, away);
-    tandout_but(idx, "idle %s %d %d\n", bot, sock, idle);
-#endif
   }
 }
 
@@ -574,37 +485,6 @@ void botnet_send_away(int idx, char *bot, int sock,
 		       ((idx >= 0) && linking) ? "!" : "",
 		       bot, sock, msg ? msg : "");
     send_tand_but(idx, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    if (msg) {
-      if (idx < 0) {
-	tandout_but(idx, "chan %s %d %s is now away: %s.\n", bot,
-		    dcc[linking].u.chat->channel, dcc[linking].nick,
-		    msg);
-      } else if ((b_numver(idx) >= NEAT_BOTNET)) {
-	int partyidx = getparty(bot, sock);
-
-	if (partyidx >= 0)
-	  tandout_but(idx, "chan %s %d %s %s: %s.\n", bot,
-		      party[partyidx].chan, party[partyidx].nick,
-		      NET_AWAY, msg);
-      }
-      tandout_but(idx, "away %s %d %s\n", bot, sock, msg);
-    } else {
-      if (idx < 0) {
-	tandout_but(idx, "chan %s %d %s %s.\n", bot,
-		    dcc[linking].u.chat->channel, dcc[linking].nick,
-		    NET_UNAWAY);
-      } else if (b_numver(idx) >= NEAT_BOTNET) {
-	int partyidx = getparty(bot, sock);
-
-	if (partyidx >= 0)
-	  tandout_but(idx, "chan %s %d %s %s.\n", bot,
-		      party[partyidx].chan, party[partyidx].nick,
-		      NET_UNAWAY);
-      }
-      tandout_but(idx, "unaway %s %d\n", bot, sock);
-    }
-#endif
   }
 }
 
@@ -618,21 +498,6 @@ void botnet_send_join_idx(int useridx, int oldchan)
 		       dcc[useridx].u.chat->channel, geticon(useridx),
 		       dcc[useridx].sock, dcc[useridx].host);
     send_tand_but(-1, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(-1, "join %s %s %d %c%d %s\n", botnetnick,
-		dcc[useridx].nick, dcc[useridx].u.chat->channel,
-		geticon(useridx), dcc[useridx].sock, dcc[useridx].host);
-    tandout_but(-1, "chan %s %d %s %s %s.\n",
-		botnetnick, dcc[useridx].u.chat->channel,
-		dcc[useridx].nick, NET_JOINEDTHE,
-		dcc[useridx].u.chat->channel ? "channel" : "party line");
-    if ((oldchan >= 0) && (oldchan < GLOBAL_CHANS)) {
-      tandout_but(-1, "chan %s %d %s %s %s.\n",
-		  botnetnick, oldchan,
-		  dcc[useridx].nick, NET_LEFTTHE,
-		  oldchan ? "channel" : "party line");
-    }
-#endif
   }
 }
 
@@ -647,25 +512,6 @@ void botnet_send_join_party(int idx, int linking, int useridx, int oldchan)
 		       party[useridx].sock,
 		       party[useridx].from ? party[useridx].from : "");
     send_tand_but(idx, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "join %s %s %d %c%d %s\n", party[useridx].bot,
-		party[useridx].nick, party[useridx].chan,
-		party[useridx].flag, party[useridx].sock,
-		party[useridx].from ? party[useridx].from : "");
-    if ((idx < 0) || (!linking && (b_numver(idx) >= NEAT_BOTNET))) {
-      tandout_but(idx, "chan %s %d %s %s %s.\n",
-		  party[useridx].bot, party[useridx].chan,
-		  party[useridx].nick, NET_JOINEDTHE,
-		  party[useridx].chan ? "channel" : "party line");
-    }
-    if ((oldchan >= 0) && (oldchan < GLOBAL_CHANS) &&
-	((idx < 0) || (b_numver(idx) >= NEAT_BOTNET))) {
-      tandout_but(idx, "chan %s %d %s %s %s.\n",
-		  party[useridx].bot, oldchan, party[useridx].nick,
-		  NET_LEFTTHE,
-		  party[useridx].chan ? "channel" : "party line");
-    }
-#endif
   }
 }
 
@@ -677,15 +523,6 @@ void botnet_send_part_idx(int useridx, char *reason)
 
   if (tands > 0) {
     send_tand_but(-1, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(-1, "part %s %s %d\n", botnetnick,
-		dcc[useridx].nick, dcc[useridx].sock);
-    tandout_but(-1, "chan %s %d %s has left the %s%s%s.\n",
-		botnetnick, dcc[useridx].u.chat->channel,
-		dcc[useridx].nick,
-		dcc[useridx].u.chat->channel ? "channel" : "party line",
-		reason ? ": " : "", reason ? reason : "");
-#endif
   }
 }
 
@@ -700,17 +537,6 @@ void botnet_send_part_party(int idx, int partyidx, char *reason,
 		       party[partyidx].nick, party[partyidx].sock,
 		       reason ? reason : "");
     send_tand_but(idx, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(idx, "part %s %s %d\n", party[partyidx].bot,
-		party[partyidx].nick, party[partyidx].sock);
-    if (((idx < 0) || (b_numver(idx) >= NEAT_BOTNET)) && !silent) {
-      tandout_but(idx, "chan %s %d %s has left the %s%s%s.\n",
-		  party[partyidx].bot, party[partyidx].chan,
-		  party[partyidx].nick,
-		  party[partyidx].chan ? "channel" : "party line",
-		  reason ? ": " : "", reason ? reason : "");
-    }
-#endif
   }
 }
 
@@ -722,16 +548,6 @@ void botnet_send_nkch(int useridx, char *oldnick)
     l = simple_sprintf(OBUF, "nc %s %D %s\n", botnetnick,
 		       dcc[useridx].sock, dcc[useridx].nick);
     send_tand_but(-1, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(-1, "part %s %s %d\n", botnetnick,
-		dcc[useridx].nick, dcc[useridx].sock);
-    tandout_but(-1, "join %s %s %d %c%d %s\n", botnetnick,
-		dcc[useridx].nick, dcc[useridx].u.chat->channel,
-		geticon(useridx), dcc[useridx].sock, dcc[useridx].host);
-    tandout_but(-1, "chan %s %d %s: %s -> %s.\n",
-		botnetnick, dcc[useridx].u.chat->channel,
-		oldnick, NET_NICKCHANGE, dcc[useridx].nick);
-#endif
   }
 }
 
@@ -743,18 +559,6 @@ void botnet_send_nkch_part(int butidx, int useridx, char *oldnick)
     l = simple_sprintf(OBUF, "nc %s %D %s\n", party[useridx].bot,
 		       party[useridx].sock, party[useridx].nick);
     send_tand_but(butidx, OBUF, -l);
-#ifndef NO_OLD_BOTNET
-    tandout_but(butidx, "part %s %s %d\n", party[useridx].bot,
-		party[useridx].nick, party[useridx].sock);
-    tandout_but(butidx, "join %s %s %d %c%d %s\n", party[useridx].bot,
-		party[useridx].nick, party[useridx].chan,
-		party[useridx].flag, party[useridx].sock,
-		party[useridx].from ? party[useridx].from : "");
-    tandout_but(butidx, "chan %s %d %s : %s -> %s.\n",
-		party[useridx].bot, party[useridx].chan,
-		NET_NICKCHANGE,
-		oldnick, party[useridx].nick);
-#endif
   }
 }
 

+ 126 - 86
src/botnet.c

@@ -7,46 +7,29 @@
  *   linking, unlinking, and relaying to another bot
  *   pinging the bots periodically and checking leaf status
  *
- * $Id: botnet.c,v 1.43 2002/07/09 05:40:55 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
 #include "tandem.h"
 
 extern int		 dcc_total, backgrd, connect_timeout, max_dcc,
-			 egg_numver;
+			 egg_numver, cfg_count;
 extern struct userrec	*userlist;
 extern struct dcc_t	*dcc;
 extern time_t		 now;
 extern Tcl_Interp	*interp;
+extern struct cfg_entry ** cfg;
+
 
 tand_t		*tandbot;		/* Keep track of tandem bots on the
 					   botnet */
 party_t		*party;			/* Keep track of people on the botnet */
-static int	 maxparty = 50;		/* Maximum space for party line members
+static int	 maxparty = 200;		/* Maximum space for party line members
 					   currently */
 int		 tands = 0;		/* Number of bots on the botnet */
 int		 parties = 0;		/* Number of people on the botnet */
 char		 botnetnick[HANDLEN + 1] = "";	/* Botnet nickname */
-int		 share_unlinks = 0;	/* Allow remote unlinks of my
+int		 share_unlinks = 1;	/* Allow remote unlinks of my
 					   sharebots? */
 
 
@@ -386,12 +369,32 @@ void unvia(int idx, tand_t * who)
     } else
       bot = bot->next;
   }
-#ifndef NO_OLD_BOTNET
-  /* Every bot unvia's bots behind anyway, so why send msg's for
-   * EVERY one? - will this break things?!
-   */
-  tandout_but(idx, "unlinked %s\n", who->bot);
-#endif
+}
+
+void besthub(char *hub)
+{
+  tand_t *ptr = tandbot;
+  struct userrec *u,
+   *besthub = NULL;
+  char bestlval[20],
+    lval[20];
+
+  hub[0] = 0;
+  strcpy(bestlval, "z");
+  while (ptr) {
+    u = get_user_by_handle(userlist, ptr->bot);
+    if (u) {
+      link_pref_val(u, lval);
+      if (strcmp(lval, bestlval) < 0) {
+        strcpy(bestlval, lval);
+        besthub = u;
+      }
+    }
+    ptr = ptr->next;
+  }
+  if (besthub)
+    strcpy(hub, besthub->handle);
+  return;
 }
 
 /* Return index into dcc list of the bot that connects us to bot <x>
@@ -464,12 +467,19 @@ void answer_local_whom(int idx, int chan)
   if(nicklen < 9) nicklen = 9;
   if(botnicklen < 9) botnicklen = 9;
 
-  snprintf(format, sizeof format, "%%-%us   %%-%us  %%s\n", 
+#ifdef HUB
+  egg_snprintf(format, sizeof format, "%%-%us   %%-%us  %%s\n", 
                                   nicklen, botnicklen);
   dprintf(idx, format, " Nick", 	" Bot",      " Host");
   dprintf(idx, format, "----------",	"---------", "--------------------");
-  snprintf(format, sizeof format, "%%c%%-%us %%c %%-%us  %%s%%s\n", 
+  egg_snprintf(format, sizeof format, "%%c%%-%us %%c %%-%us  %%s%%s\n", 
                                   nicklen, botnicklen);
+#else
+  egg_snprintf(format, sizeof format, "%%-%us\n", nicklen);
+  dprintf(idx, format, " Nick");
+  dprintf(idx, format, "----------");
+  egg_snprintf(format, sizeof format, "%%c%%-%us %%c %%s\n", nicklen);
+#endif
   for (i = 0; i < dcc_total; i++)
     if (dcc[i].type == &DCC_CHAT) {
       if ((chan == (-1)) || ((chan >= 0) && (dcc[i].u.chat->channel == chan))) {
@@ -490,11 +500,18 @@ void answer_local_whom(int idx, int chan)
 	    sprintf(idle, " [idle %lum]", mins);
 	} else
 	  idle[0] = 0;
+
         total++;
+Context;
 	dprintf(idx, format, c, dcc[i].nick, 
 		(dcc[i].u.chat->channel == 0) && (chan == (-1)) ? '+' :
 		(dcc[i].u.chat->channel > GLOBAL_CHANS) &&
+#ifdef HUB
 		(chan == (-1)) ? '*' : ' ', botnetnick, dcc[i].host, idle);
+#else
+		(chan == (-1)) ? '*' : ' ', idle);
+#endif
+Context;
 	if (dcc[i].u.chat->away != NULL)
 	  dprintf(idx, "   AWAY: %s\n", dcc[i].u.chat->away);
       }
@@ -521,9 +538,15 @@ void answer_local_whom(int idx, int chan)
       } else
 	idle[0] = 0;
       total++;
+
       dprintf(idx, format, c, party[i].nick, 
 	      (party[i].chan == 0) && (chan == (-1)) ? '+' : ' ',
+#ifdef HUB
 	      party[i].bot, party[i].from, idle);
+#else
+	      idle);
+#endif
+
       if (party[i].status & PLSTAT_AWAY)
 	dprintf(idx, "   %s: %s\n", MISC_AWAY,
 		party[i].away ? party[i].away : "");
@@ -541,7 +564,7 @@ void tell_bots(int idx)
   tand_t *bot;
 
   if (!tands) {
-    dprintf(idx, "%s\n", BOT_NOBOTSLINKED);
+    dprintf(idx, STR("No bots linked\n"));
     return;
   }
   strcpy(s, botnetnick);
@@ -549,7 +572,7 @@ void tell_bots(int idx)
 
   for (bot = tandbot; bot; bot = bot->next) {
     if (i > (500 - HANDLEN)) {
-      dprintf(idx, "Bots: %s\n", s);
+      dprintf(idx, STR("Bots: %s\n"), s);
       s[0] = 0;
       i = 0;
     }
@@ -561,8 +584,9 @@ void tell_bots(int idx)
     i += strlen(bot->bot);
   }
   if (s[0])
-    dprintf(idx, "Bots: %s\n", s);
-  dprintf(idx, "(%s: %d)\n", MISC_TOTAL, tands + 1);
+    dprintf(idx, STR("Bots: %s\n"), s);
+  dprintf(idx, STR("(Total: %d)\n"), tands + 1);
+
 }
 
 /* Show a simpleton bot tree
@@ -739,13 +763,7 @@ void dump_links(int z)
       p = botnetnick;
     else
       p = bot->uplink->bot;
-#ifndef NO_OLD_BOTNET
-    if (b_numver(z) < NEAT_BOTNET)
-      l = simple_sprintf(x, "nlinked %s %s %c%d\n", bot->bot,
-			 p, bot->share, bot->ver);
-    else
-#endif
-      l = simple_sprintf(x, "n %s %s %c%D\n", bot->bot, p,
+    l = simple_sprintf(x, "n %s %s %c%D\n", bot->bot, p,
 			 bot->share, bot->ver);
     tputs(dcc[z].sock, x, l);
   }
@@ -755,31 +773,12 @@ void dump_links(int z)
       if (dcc[i].type == &DCC_CHAT) {
 	if ((dcc[i].u.chat->channel >= 0) &&
 	    (dcc[i].u.chat->channel < GLOBAL_CHANS)) {
-#ifndef NO_OLD_BOTNET
-	  if (b_numver(z) < NEAT_BOTNET)
-	    l = simple_sprintf(x, "join %s %s %d %c%d %s\n",
-			       botnetnick, dcc[i].nick,
-			       dcc[i].u.chat->channel, geticon(i),
-			       dcc[i].sock, dcc[i].host);
-	  else
-#endif
-	    l = simple_sprintf(x, "j !%s %s %D %c%D %s\n",
+          l = simple_sprintf(x, "j !%s %s %D %c%D %s\n",
 			       botnetnick, dcc[i].nick,
 			       dcc[i].u.chat->channel, geticon(i),
 			       dcc[i].sock, dcc[i].host);
 	  tputs(dcc[z].sock, x, l);
-#ifndef NO_OLD_BOTNET
-	  if (b_numver(z) < NEAT_BOTNET) {
-	    if (dcc[i].u.chat->away) {
-	      l = simple_sprintf(x, "away %s %d %s\n", botnetnick,
-				 dcc[i].sock, dcc[i].u.chat->away);
-	      tputs(dcc[z].sock, x, l);
-	    }
-	    l = simple_sprintf(x, "idle %s %d %d\n", botnetnick,
-			       dcc[i].sock, now - dcc[i].timeval);
-	  } else
-#endif
-	    l = simple_sprintf(x, "i %s %D %D %s\n", botnetnick,
+          l = simple_sprintf(x, "i %s %D %D %s\n", botnetnick,
 			       dcc[i].sock, now - dcc[i].timeval,
 			 dcc[i].u.chat->away ? dcc[i].u.chat->away : "");
 	  tputs(dcc[z].sock, x, l);
@@ -787,32 +786,13 @@ void dump_links(int z)
       }
     }
     for (i = 0; i < parties; i++) {
-#ifndef NO_OLD_BOTNET
-      if (b_numver(z) < NEAT_BOTNET)
-	l = simple_sprintf(x, "join %s %s %d %c%d %s\n",
-			   party[i].bot, party[i].nick,
-			   party[i].chan, party[i].flag,
-			   party[i].sock, party[i].from);
-      else
-#endif
-	l = simple_sprintf(x, "j %s %s %D %c%D %s\n",
+      l = simple_sprintf(x, "j %s %s %D %c%D %s\n",
 			   party[i].bot, party[i].nick,
 			   party[i].chan, party[i].flag,
 			   party[i].sock, party[i].from);
       tputs(dcc[z].sock, x, l);
       if ((party[i].status & PLSTAT_AWAY) || (party[i].timer != 0)) {
-#ifndef NO_OLD_BOTNET
-	if (b_numver(z) < NEAT_BOTNET) {
-	  if (party[i].status & PLSTAT_AWAY) {
-	    l = simple_sprintf(x, "away %s %d %s\n", party[i].bot,
-			       party[i].sock, party[i].away);
-	    tputs(dcc[z].sock, x, l);
-	  }
-	  l = simple_sprintf(x, "idle %s %d %d\n", party[i].bot,
-			     party[i].sock, now - party[i].timer);
-	} else
-#endif
-	  l = simple_sprintf(x, "i %s %D %D %s\n", party[i].bot,
+        l = simple_sprintf(x, "i %s %D %D %s\n", party[i].bot,
 			     party[i].sock, now - party[i].timer,
 			     party[i].away ? party[i].away : "");
 	tputs(dcc[z].sock, x, l);
@@ -1042,7 +1022,7 @@ static void botlink_resolve_failure(int i)
 {
   char s[81];
 
-  putlog(LOG_BOTS, "*", DCC_LINKFAIL, dcc[i].nick);
+//  putlog(LOG_BOTS, "*", DCC_LINKFAIL, dcc[i].nick);
   strcpy(s, dcc[i].nick);
   nfree(dcc[i].u.dns->cptr);
   lostdcc(i);
@@ -1059,6 +1039,7 @@ static void botlink_resolve_success(int i)
   dcc[i].timeval = now;
   strcpy(dcc[i].u.bot->linker, linker);
   strcpy(dcc[i].u.bot->version, "(primitive bot)");
+  strcpy(dcc[i].u.bot->sysname, "*");
   dcc[i].u.bot->numver = idx;
   dcc[i].u.bot->port = dcc[i].port;		/* Remember where i started */
   dcc[i].sock =  getsock(SOCK_STRONGCONN,getprotocol(dcc[i].host));
@@ -1156,8 +1137,10 @@ void tandem_relay(int idx, char *nick, register int i)
   strcpy(dcc[i].nick, nick);
   dcc[i].user = u;
   strcpy(dcc[i].host, bi->address);
+#ifdef HUB
   dprintf(idx, "%s %s @ %s:%d ...\n", BOT_CONNECTINGTO, nick,
 	  bi->address, bi->relay_port);
+#endif
   dprintf(idx, "%s\n", BOT_BYEINFO1);
   dcc[idx].type = &DCC_PRE_RELAY;
   ci = dcc[idx].u.chat;
@@ -1421,7 +1404,8 @@ static void dcc_relay(int idx, char *buf, int j)
      escape sequences. */
   if (!(dcc[j].status & STAT_TELNET)) {
     while (*p != 0) {
-      while (*p != 255 && (*p != '\033' || *(p + 1) != '[') && *p != '\r' && *p)
+//      while (*p != 255 && (*p != '\033' || *(p + 1) != '[') && *p != '\r' && *p)
+      while (*p != 255 && *p != '\r' && *p)
 	p++;			/* Search for IAC, escape sequences and CR. */
       if (*p == 255) {
 	mark = 2;
@@ -1433,13 +1417,15 @@ static void dcc_relay(int idx, char *buf, int j)
 	    mark = 2;		/* Bogus */
 	}
 	strcpy((char *) p, (char *) (p + mark));
+/*
       } else if (*p == '\033') {
 	unsigned char	*e;
 
-	/* Search for the end of the escape sequence. */
+	// Search for the end of the escape sequence.
 	for (e = p + 2; *e != 'm' && *e; e++)
 	  ;
 	strcpy((char *) p, (char *) (e + 1));
+*/
       } else if (*p == '\r')
 	strcpy((char *) p, (char *) (p + 1));
     }
@@ -1652,6 +1638,8 @@ void check_botnet_pings()
 	    killsock(dcc[i].sock);
 	    lostdcc(i);
 	  } else {
+//fix
+            putlog(LOG_MISC, "*", "I am lame, and am now rejecting %s", bot->bot);
 	    botnet_send_reject(i, botnetnick, NULL, bot->bot,
 			       NULL, NULL);
 	    dcc[i].status |= STAT_WARNED;
@@ -1697,3 +1685,55 @@ void restart_chons()
 		   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 lower_bot_linked(int idx)
+{
+  char tmp[5];
+//  int i;
+//  botnet_send_logsettings(idx);
+//  for (i=0;i<cfg_count;i++)
+//    botnet_send_cfg(idx, cfg[i]);
+//  send_channel_sync(dcc[idx].nick, NULL);
+
+  sprintf(tmp, STR("rl %d"), get_role(dcc[idx].nick));
+  botnet_send_zapf(nextbot(dcc[idx].nick), botnetnick, dcc[idx].nick, tmp);
+
+}
+
+void higher_bot_linked(int idx)
+{
+
+}

+ 78 - 52
src/chan.h

@@ -3,25 +3,6 @@
  *   stuff common to chan.c and mode.c
  *   users.h needs to be loaded too
  *
- * $Id: chan.h,v 1.29 2002/06/19 21:13:38 wcc Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_CHAN_H
@@ -30,12 +11,15 @@
 typedef struct memstruct {
   char nick[NICKLEN];
   char userhost[UHOSTLEN];
+  char server[SERVLEN];
+  int hops;
   time_t joined;
   unsigned short flags;
   time_t split;			/* in case they were just netsplit	*/
   time_t last;			/* for measuring idle time		*/
-  time_t delay;			/* for delayed autoop			*/
+  time_t delay;                  /* for delayed autoop                   */
   struct userrec *user;
+  int tried_getuser;
   struct memstruct *next;
 } memberlist;
 
@@ -54,27 +38,23 @@ typedef struct memstruct {
 #define STOPWHO      0x00200
 #define FULL_DELAY   0x00400
 #define STOPCHECK    0x00800
-#define CHANHALFOP   0x01000 /* channel +h                                   */
-#define FAKEHALFOP   0x02000 /* halfop'd by server                           */
-#define SENTHALFOP   0x04000 /* a mode +h was already sent out for this user */
-#define SENTDEHALFOP 0x08000 /* a mode -h was already sent out for this user */
-#define WASHALFOP    0x10000 /* was a halfop before a split                  */
+#define EVOICE       0x01000 /* keeps people -v */
+#define OPER         0x02000
+/*                   0x02000 */
+/*                   0x04000 */
+/*                   0x08000 */
+/*                   0x10000 */
 
 #define chan_hasvoice(x) (x->flags & CHANVOICE)
 #define chan_hasop(x) (x->flags & CHANOP)
-#define chan_hashalfop(x) (x->flags & CHANHALFOP)
 #define chan_fakeop(x) (x->flags & FAKEOP)
-#define chan_fakehalfop(x) (x->flags & FAKEHALFOP)
 #define chan_sentop(x) (x->flags & SENTOP)
 #define chan_sentdeop(x) (x->flags & SENTDEOP)
-#define chan_senthalfop(x) (x->flags & SENTHALFOP)
-#define chan_sentdehalfop(x) (x->flags & SENTDEHALFOP)
 #define chan_sentkick(x) (x->flags & SENTKICK)
 #define chan_sentvoice(x) (x->flags & SENTVOICE)
 #define chan_sentdevoice(x) (x->flags & SENTDEVOICE)
 #define chan_issplit(x) (x->split > 0)
 #define chan_wasop(x) (x->flags & WASOP)
-#define chan_washalfop(x) (x->flags & WASHALFOP)
 #define chan_stopcheck(x) (x->flags & STOPCHECK)
 
 /* Why duplicate this struct for exempts and invites only under another
@@ -98,8 +78,11 @@ typedef struct maskrec {
          lastactive;
   int flags;
 } maskrec;
+#ifdef S_IRCNET
 extern maskrec *global_bans, *global_exempts, *global_invites;
-
+#else
+extern maskrec *global_bans;
+#endif
 #define MASKREC_STICKY 1
 #define MASKREC_PERM   2
 
@@ -107,13 +90,17 @@ extern maskrec *global_bans, *global_exempts, *global_invites;
 struct chan_t {
   memberlist *member;
   masklist *ban;
+#ifdef S_IRCNET
   masklist *exempt;
   masklist *invite;
+#endif
   char *topic;
   char *key;
   unsigned short int mode;
   int maxmembers;
   int members;
+  int do_opreq;
+
 };
 
 #define CHANINV    0x0001	/* +i					*/
@@ -132,6 +119,8 @@ struct chan_t {
 #define CHANNOCTCP 0x2000      /* +C -- QuakeNet's ircu 2.10           */
 #define CHANLONLY  0x4000      /* +r -- ircu 2.10.11                   */
 
+#define MODES_PER_LINE_MAX 6
+
 /* For every channel i'm supposed to be active on */
 struct chanset_t {
   struct chanset_t *next;
@@ -157,21 +146,31 @@ struct chanset_t {
   int flood_ctcp_time;
   int flood_nick_thr;
   int flood_nick_time;
-  int aop_min;
-  int aop_max;
   int status;
   int ircnet_status;
+  int limitraise;
+  int jointime;
+  int parttime;
   int idle_kick;
   int stopnethack_mode;
   int revenge_mode;
+  int ban_time;
+#ifdef S_IRCNET
+  int invite_time;
+  int exempt_time;
+
   maskrec *bans,		/* temporary channel bans		*/
           *exempts,		/* temporary channel exempts		*/
           *invites;		/* temporary channel invites		*/
+#else
+  maskrec *bans;
+#endif
   /* desired channel modes: */
   int mode_pls_prot;		/* modes to enforce			*/
   int mode_mns_prot;		/* modes to reject			*/
   int limit_prot;		/* desired limit			*/
   char key_prot[121];		/* desired password			*/
+  char topic_prot[501];		/* desired topic			*/
   /* queued mode changes: */
   char pls[21];			/* positive mode changes		*/
   char mns[21];			/* negative mode changes		*/
@@ -180,40 +179,57 @@ struct chanset_t {
   int limit;			/* new limit to set			*/
   int bytes;			/* total bytes so far			*/
   int compat;			/* to prevent mixing old/new modes	*/
+  struct {
+    char * target;
+  } opqueue[24];
+  struct {
+    char * target;
+  } deopqueue[24];
   struct {
     char *op;
     int type;
-  } cmode[6];			/* parameter-type mode changes -	*/
+  } cmode[MODES_PER_LINE_MAX];                 /* parameter-type mode changes -        */
   /* detect floods */
   char floodwho[FLOOD_CHAN_MAX][81];
   time_t floodtime[FLOOD_CHAN_MAX];
   int floodnum[FLOOD_CHAN_MAX];
   char deopd[NICKLEN];		/* last person deop'd (must change	*/
+  int opreqtime[5];             /* remember when ops was requested */
+#ifdef G_AUTOLOCK
+  int fighting;
+#endif
+#ifdef G_BACKUP
+  int backup_time;              /* If non-0, set +backup when now>backup_time */
+#endif
+#ifdef HUB
+  char topic[91];
+#endif
+
 };
 
 /* behavior modes for the channel */
 #define CHAN_ENFORCEBANS    0x0001	   /* kick people who match channel bans */
 #define CHAN_DYNAMICBANS    0x0002	   /* only activate bans when needed     */
 #define CHAN_NOUSERBANS     0x0004	   /* don't let non-bots place bans      */
-#define CHAN_OPONJOIN       0x0008	   /* op +o people as soon as they join  */
+#define CHAN_CLOSED         0x0008	   /* Only users +o can join */
 #define CHAN_BITCH          0x0010	   /* be a tightwad with ops             */
-#define CHAN_GREET          0x0020	   /* greet people with their info line  */
+#define CHAN_TAKE 	    0x0020         /* When a bot gets opped, take the chan */
 #define CHAN_PROTECTOPS     0x0040	   /* re-op any +o people who get deop'd */
-#define CHAN_LOGSTATUS      0x0080	   /* log channel status every 5 mins    */
+#define CHAN_NOMOP	    0x0080         /* If a bot sees a mass op, botnet mdops */
 #define CHAN_REVENGE        0x0100	   /* get revenge on bad people          */
 #define CHAN_SECRET         0x0200	   /* don't advertise channel on botnet  */
-#define CHAN_AUTOVOICE      0x0400	   /* dish out voice stuff automatically */
+#define CHAN_MANOP          0x0400         /* manual opping allowed? */
 #define CHAN_CYCLE          0x0800	   /* cycle the channel if possible      */
 #define CHAN_DONTKICKOPS    0x1000	   /* never kick +o flag people -arthur2 */
 #define CHAN_INACTIVE       0x2000	   /* no irc support for this channel
                                          - drummer                           */
 #define CHAN_PROTECTFRIENDS 0x4000	   /* re-op any +f people who get deop'd */
-#define CHAN_SHARED         0x8000	   /* channel is being shared            */
+#define CHAN_VOICE          0x8000	   /* a bot +y|y will voice *, except +q */
 #define CHAN_SEEN           0x10000
 #define CHAN_REVENGEBOT     0x20000	   /* revenge on actions against the bot */
 #define CHAN_NODESYNCH      0x40000
-#define CHAN_AUTOHALFOP     0x80000    /* op +h people on join               */ 
-#define CHAN_PROTECTHALFOPS 0x100000   /* op +h people on join               */ 
+#define CHAN_FASTOP         0x80000        /* Bots will not use +o-b to op (no cookies) */ 
+#define CHAN_PRIVATE         0x100000       /* users need |o to access chan */ 
 #define CHAN_ACTIVE         0x1000000  /* like i'm actually on the channel
                                           and stuff                          */
 #define CHAN_PEND           0x2000000  /* just joined; waiting for end of
@@ -225,7 +241,7 @@ struct chanset_t {
 #define CHAN_JUPED          0x40000000 /* Is channel juped                   */
 #define CHAN_STOP_CYCLE     0x80000000 /* Some efnetservers have defined
                                           NO_CHANOPS_WHEN_SPLIT              */
-
+#ifdef S_IRCNET
 #define CHAN_ASKED_EXEMPTS  0x0001
 #define CHAN_ASKED_INVITED  0x0002
 
@@ -233,7 +249,7 @@ struct chanset_t {
 #define CHAN_NOUSEREXEMPTS  0x0008
 #define CHAN_DYNAMICINVITES 0x0010
 #define CHAN_NOUSERINVITES  0x0020
-
+#endif
 /* prototypes */
 memberlist *ismember(struct chanset_t *, char *);
 struct chanset_t *findchan(const char *name);
@@ -248,33 +264,43 @@ struct chanset_t *findchan_by_dname(const char *name);
 #define channel_pending(chan)  (chan->status & CHAN_PEND)
 #define channel_bitch(chan) (chan->status & CHAN_BITCH)
 #define channel_nodesynch(chan) (chan->status & CHAN_NODESYNCH)
-#define channel_autoop(chan) (chan->status & CHAN_OPONJOIN)
-#define channel_autovoice(chan) (chan->status & CHAN_AUTOVOICE)
-#define channel_autohalfop(chan) (chan->status & CHAN_AUTOHALFOP)
-#define channel_greet(chan) (chan->status & CHAN_GREET)
-#define channel_logstatus(chan) (chan->status & CHAN_LOGSTATUS)
 #define channel_enforcebans(chan) (chan->status & CHAN_ENFORCEBANS)
 #define channel_revenge(chan) (chan->status & CHAN_REVENGE)
 #define channel_dynamicbans(chan) (chan->status & CHAN_DYNAMICBANS)
 #define channel_nouserbans(chan) (chan->status & CHAN_NOUSERBANS)
 #define channel_protectops(chan) (chan->status & CHAN_PROTECTOPS)
-#define channel_protecthalfops(chan) (chan->status & CHAN_PROTECTHALFOPS)
 #define channel_protectfriends(chan) (chan->status & CHAN_PROTECTFRIENDS)
+#define channel_autovoice(chan) (0)
 #define channel_dontkickops(chan) (chan->status & CHAN_DONTKICKOPS)
 #define channel_secret(chan) (chan->status & CHAN_SECRET)
-#define channel_shared(chan) (chan->status & CHAN_SHARED)
-#define channel_static(chan) (chan->status & CHAN_STATIC)
+#define channel_shared(chan) (1)
+//#define channel_static(chan) (chan->status & CHAN_STATIC)
+#define channel_static(chan) (0)
 #define channel_cycle(chan) (chan->status & CHAN_CYCLE)
-#define channel_seen(chan) (chan->status & CHAN_SEEN)
+#define channel_seen(chan) (1)
 #define channel_inactive(chan) (chan->status & CHAN_INACTIVE)
 #define channel_revengebot(chan) (chan->status & CHAN_REVENGEBOT)
+#ifdef S_IRCNET
 #define channel_dynamicexempts(chan) (chan->ircnet_status & CHAN_DYNAMICEXEMPTS)
 #define channel_nouserexempts(chan) (chan->ircnet_status & CHAN_NOUSEREXEMPTS)
 #define channel_dynamicinvites(chan) (chan->ircnet_status & CHAN_DYNAMICINVITES)
 #define channel_nouserinvites(chan) (chan->ircnet_status & CHAN_NOUSERINVITES)
+#endif
 #define channel_juped(chan) (chan->status & CHAN_JUPED)
 #define channel_stop_cycle(chan) (chan->status & CHAN_STOP_CYCLE)
 
+
+#define channel_closed(chan) (chan->status & CHAN_CLOSED)
+#define channel_take(chan) (chan->status & CHAN_TAKE)
+#define channel_nomop(chan) (chan->status & CHAN_NOMOP)
+#define channel_manop(chan) (chan->status & CHAN_MANOP)
+#define channel_voice(chan) (chan->status & CHAN_VOICE)
+#define channel_fastop(chan) (chan->status & CHAN_FASTOP)
+#define channel_private(chan) (chan->status & CHAN_PRIVATE)
+
+
+
+
 struct msgq_head {
   struct msgq *head;
   struct msgq *last;

+ 299 - 80
src/chanprog.c

@@ -7,25 +7,6 @@
  *   telling the current programmed settings
  *   initializing a lot of stuff and loading the tcl scripts
  *
- * $Id: chanprog.c,v 1.32 2002/07/18 20:28:32 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -43,14 +24,19 @@
 extern struct userrec	*userlist;
 extern log_t		*logs;
 extern Tcl_Interp	*interp;
-extern char		 ver[], botnetnick[], firewall[],
+extern char		 ver[], botnetnick[], firewall[], myip[], origbotname[],
 			 motdfile[], userfile[], helpdir[], tempdir[],
-			 moddir[], notify_new[], owner[], configfile[];
+			 notify_new[], owner[], configfile[],
+                         netpass[], botuser[], owners[], hubs[];
+
 extern time_t		 now, online_since;
 extern int		 backgrd, term_z, con_chan, cache_hit, cache_miss,
 			 firewallport, default_flags, max_logs, conmask,
-			 protect_readonly, make_userfile, noshare,
-			 ignore_time;
+			 protect_readonly, noshare,
+#ifdef HUB
+			 my_port,
+#endif
+			 ignore_time, loading;
 
 tcl_timer_t	 *timer = NULL;		/* Minutely timer		*/
 tcl_timer_t	 *utimer = NULL;	/* Secondly timer		*/
@@ -135,7 +121,7 @@ struct userrec *check_chanlist(const char *host)
   uhost = buf;
   nick = splitnick(&uhost);
   for (chan = chanset; chan; chan = chan->next)
-    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 (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
 	return m->user;
   return NULL;
@@ -166,8 +152,11 @@ void clear_chanlist(void)
   register struct chanset_t	*chan;
 
   for (chan = chanset; chan; chan = chan->next)
-    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
       m->user = NULL;
+      m->tried_getuser = 0;
+    }
+
 }
 
 /* Clear the user pointer of a specific nick in the chanlists.
@@ -184,6 +173,7 @@ void clear_chanlist_member(const char *nick)
     for (m = chan->channel.member; m && m->nick[0]; m = m->next)
       if (!rfc_casecmp(m->nick, nick)) {
 	m->user = NULL;
+        m->tried_getuser = 0;
 	break;
       }
 }
@@ -260,7 +250,9 @@ void tell_verbose_status(int idx)
 {
   char s[256], s1[121], s2[81];
   char *vers_t, *uni_t;
+#ifdef HUB
   int i;
+#endif
   time_t now2, hr, min;
 #if HAVE_GETRUSAGE
   struct rusage ru;
@@ -283,13 +275,12 @@ void tell_verbose_status(int idx)
   }
 #endif
 
+#ifdef HUB
   i = count_users(userlist);
   dprintf(idx, "I am %s, running %s:  %d user%s (mem: %uk)\n",
 	  botnetnick, ver, i, i == 1 ? "" : "s",
           (int) (expected_memory() / 1024));
-
-  dprintf(idx, "My Source was IPv6-patched by sb <sb@1shell.net>\n");
-
+#endif
   now2 = now - online_since;
   s[0] = 0;
   if (now2 > 86400) {
@@ -337,7 +328,6 @@ void tell_verbose_status(int idx)
   if (admin[0])
     dprintf(idx, "Admin: %s\n", admin);
 
-  dprintf(idx, "Config file: %s\n", configfile);
   dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
 
   /* info library */
@@ -351,7 +341,6 @@ void tell_verbose_status(int idx)
 	  interp->result : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
 	  interp->result : "*unknown*", MISC_TCLHVERSION,
 	  TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL : "*unknown*");
-
 #if HAVE_TCL_THREADS
   dprintf(idx, "Tcl is threaded\n");
 #endif  
@@ -369,20 +358,21 @@ void tell_settings(int idx)
   dprintf(idx, "Botnet Nickname: %s\n", botnetnick);
   if (firewall[0])
     dprintf(idx, "Firewall: %s, port %d\n", firewall, firewallport);
-  dprintf(idx, "Userfile: %s   Motd: %s\n", userfile, motdfile);
+#ifdef HUB
+  dprintf(idx, "Userfile: %s   \n", userfile);
+#endif
   dprintf(idx, "Directories:\n");
   dprintf(idx, "  Help    : %s\n", helpdir);
   dprintf(idx, "  Temp    : %s\n", tempdir);
-#ifndef STATIC
-  dprintf(idx, "  Modules : %s\n", moddir);
-#endif
   fr.global = default_flags;
 
   build_flags(s, &fr, NULL);
   dprintf(idx, "%s [%s], %s: %s\n", MISC_NEWUSERFLAGS, s,
 	  MISC_NOTIFY, notify_new);
+#ifdef HUB
   if (owner[0])
     dprintf(idx, "%s: %s\n", MISC_PERMOWNER, owner);
+#endif
   for (i = 0; i < max_logs; i++)
     if (logs[i].filename != NULL) {
       dprintf(idx, "Logfile #%d: %s on %s (%s: %s)\n", i + 1,
@@ -397,16 +387,16 @@ void reaffirm_owners()
   char *p, *q, s[121];
   struct userrec *u;
 
-  /* Make sure default owners are +n */
+  /* Make sure default owners are +a */
   if (owner[0]) {
     q = owner;
     p = strchr(q, ',');
     while (p) {
-      strncpyz(s, q, p - q);
+      strncpyz(s, q, (p - q) + 1);
       rmspace(s);
       u = get_user_by_handle(userlist, s);
       if (u)
-	u->flags = sanity_check(u->flags | USER_OWNER);
+	u->flags = sanity_check(u->flags | USER_ADMIN);
       q = p + 1;
       p = strchr(q, ',');
     }
@@ -414,25 +404,231 @@ void reaffirm_owners()
     rmspace(s);
     u = get_user_by_handle(userlist, s);
     if (u)
-      u->flags = sanity_check(u->flags | USER_OWNER);
+      u->flags = sanity_check(u->flags | USER_ADMIN);
+  }
+}
+void load_internal_users()
+{
+  char *p = NULL,
+   *ln,
+   *hand,
+   *ip,
+   *port,
+   *hublevel = NULL,
+   *pass,
+   *hosts,
+    host[250],
+    buf[2048];
+  char *attr;
+  int i;
+  struct bot_addr *bi;
+  struct userrec *u;
+  //struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
+
+//hubs..
+  sprintf(buf, "%s", hubs);
+  p = buf;
+  while (p) {
+    ln = p;
+    p = strchr(p, ',');
+    if (p)
+      *p++ = 0;
+    hand = ln;
+    ip = NULL;
+    port = NULL;
+    hosts = NULL;
+    for (i = 0; ln; i++) {
+      switch (i) {
+      case 0:
+	hand = ln;
+	break;
+      case 1:
+	ip = ln;
+	break;
+      case 2:
+	port = ln;
+	break;
+      case 3:
+        hublevel = ln;
+        break;
+      case 4:
+	if (!get_user_by_handle(userlist, hand)) {
+	  userlist = adduser(userlist, hand, "none", "-", USER_BOT | USER_OP | USER_FRIEND);
+/* no thanks.
+          if (atoi(hublevel) < 999 && strcmp(hand, origbotname)) {
+            u = get_user_by_handle(userlist, hand);
+            fr.bot |= (BOT_PASSIVE | BOT_GLOBAL);
+//            set_user(&USERENTRY_BOTFL, u, (void *) fr.bot);
+            set_user_flagrec(u, &fr, NULL);
+          }
+//          user.bot = BITS;
+*/
+	  bi = user_malloc(sizeof(struct bot_addr));
+
+	  bi->address = user_malloc(strlen(ip) + 1);
+	  strcpy(bi->address, ip);
+	  bi->telnet_port = atoi(port) ? atoi(port) : 0;
+	  bi->relay_port = bi->telnet_port;
+          bi->hublevel = atoi(hublevel);
+#ifdef HUB
+//printf("adding %s with hublevel: %d\n", hand, bi->hublevel ? bi->hublevel : 99);
+
+	  if ((!bi->hublevel) && (!strcmp(hand, botnetnick)))
+	    bi->hublevel = 99;
+#endif
+          bi->uplink = user_malloc(1);
+          bi->uplink[0] = 0;
+	  set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, hand), bi);
+	  set_user(&USERENTRY_PASS, get_user_by_handle(userlist, hand), netpass);
+	}
+      default:
+//	ln = userids for hostlist, add them all 
+	hosts = ln;
+	ln = strchr(ln, ' ');
+	if (ln)
+	  *ln++ = 0;
+	while (hosts) {
+	  sprintf(host, "*!%s@%s", hosts, ip);
+	  set_user(&USERENTRY_HOSTS, get_user_by_handle(userlist, hand), host);
+	  hosts = ln;
+	  if (ln)
+	    ln = strchr(ln, ' ');
+	  if (ln)
+	    *ln++ = 0;
+	}
+	break;
+      }
+      if (ln)
+	ln = strchr(ln, ' ');
+      if (ln) {
+	*ln++ = 0;
+      }
+    }
+  }
+
+//owners..
+  owner[0] = 0;
+//  strcpy(p, owners);
+
+// buf = get_setting(1);
+  sprintf(buf, "%s", owners);
+  p = buf;
+  while (p) {
+    ln = p;
+    p = strchr(p, ',');
+    if (p)
+      *p++ = 0;
+//     name pass hostlist 
+    hand = ln;
+    pass = NULL;
+    attr = NULL;
+    hosts = NULL;
+    for (i = 0; ln; i++) {
+      switch (i) {
+      case 0:
+	hand = ln;
+	break;
+      case 1:
+        pass = ln;
+        break;
+      case 2:
+	hosts = ln;
+	if (owner[0])
+	  strncat(owner, ",", 120);
+	strncat(owner, hand, 120);
+	if (!get_user_by_handle(userlist, hand)) {
+	  userlist = adduser(userlist, hand, "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_FRIEND | USER_OP | USER_PARTY | USER_HUBA | USER_CHUBA);
+	  u = get_user_by_handle(userlist, hand);
+	  set_user(&USERENTRY_PASS, u, pass);
+	  while (hosts) {
+	    ln = strchr(ln, ' ');
+	    if (ln)
+	      *ln++ = 0;
+	    set_user(&USERENTRY_HOSTS, u, hosts);
+	    hosts = ln;
+	  }
+	}
+	break;
+      }
+      if (ln)
+	ln = strchr(ln, ' ');
+      if (ln)
+	*ln++ = 0;
+    }
   }
+
 }
 
 void chanprog()
 {
   int i;
+  char buf[2048];
+  struct bot_addr *bi;
+  struct userrec *u;
+
 
   admin[0] = 0;
   helpdir[0] = 0;
-  tempdir[0] = 0;
   for (i = 0; i < max_logs; i++)
     logs[i].flags |= LF_EXPIRING;
   conmask = 0;
   /* Turn off read-only variables (make them write-able) for rehash */
   protect_readonly = 0;
   /* Now read it */
-  if (!readtclprog(configfile))
-    fatal(MISC_NOCONFIGFILE, 0);
+  if (configfile[0])
+    if (!readtclprog(configfile))
+      fatal(MISC_NOCONFIGFILE, 0);
+
+//now this only checks server shit. (no channels)
+  call_hook(HOOK_REHASH);
+  protect_readonly = 1;
+  if (!botnetnick[0]) {
+    strncpyz(botnetnick, origbotname, HANDLEN + 1);
+  }
+  strcpy(botuser, origbotname);
+  if (!botnetnick[0])
+    fatal("I don't have a botnet nick!!\n", 0);
+#ifdef HUB
+  if (!userfile[0])
+    fatal(MISC_NOUSERFILE2, 0);
+  //setstatic = 0;
+  loading = 1;
+  readuserfile(userfile, &userlist);
+/* old
+  if (!readuserfile(userfile, &userlist)) {
+   char tmp[178];
+   egg_snprintf(tmp, sizeof tmp, MISC_NOUSERFILE, configfile);
+   fatal(tmp, 0);
+  }
+*/
+  loading = 0;
+  //setstatic = 1;
+#endif
+
+  load_internal_users();
+
+  if (!(u = get_user_by_handle(userlist, botnetnick))) {
+    /* I need to be on the userlist... doh. */
+    userlist = adduser(userlist, botnetnick, STR("none"), "-", USER_BOT | USER_OP | USER_FRIEND);
+    u = get_user_by_handle(userlist, botnetnick);
+    bi = user_malloc(sizeof(struct bot_addr));
+
+    bi->address = user_malloc(strlen(myip) + 1);
+    strcpy(bi->address, myip);
+    bi->telnet_port = atoi(buf) ? atoi(buf) : 3333;
+    bi->relay_port = bi->telnet_port;
+#ifdef HUB
+    bi->hublevel = 99;
+#else
+    bi->hublevel = 0;
+#endif
+    bi->uplink = user_malloc(1);
+    bi->uplink[0] = 0;
+    set_user(&USERENTRY_BOTADDR, u, bi);
+  } else {
+    bi = get_user(&USERENTRY_BOTADDR, u);
+  }
+
   for (i = 0; i < max_logs; i++) {
     if (logs[i].flags & LF_EXPIRING) {
       if (logs[i].filename != NULL) {
@@ -451,58 +647,53 @@ void chanprog()
       logs[i].flags = 0;
     }
   }
-  /* We should be safe now */
-  call_hook(HOOK_REHASH);
-  protect_readonly = 1;
-  if (!botnetnick[0]) {
-    strncpyz(botnetnick, origbotname, HANDLEN + 1);
-  }
-  if (!botnetnick[0])
-    fatal("I don't have a botnet nick!!\n", 0);
-  if (!userfile[0])
-    fatal(MISC_NOUSERFILE2, 0);
-  if (!readuserfile(userfile, &userlist)) {
-    if (!make_userfile) {
-      char tmp[178];
 
-      egg_snprintf(tmp, sizeof tmp, MISC_NOUSERFILE, configfile);
-      fatal(tmp, 0);
-    }
-    printf("\n\n%s\n", MISC_NOUSERFILE2);
-    if (module_find("server", 0, 0))
-      printf(MISC_USERFCREATE1, origbotname);
-    printf("%s\n\n", MISC_USERFCREATE2);
-  } else if (make_userfile) {
-     make_userfile = 0;
-     printf("%s\n", MISC_USERFEXISTS);
+  bi = get_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, botnetnick));
+  if (!bi)
+    fatal(STR("I'm added to userlist but without a bot record!"), 0);
+  if (bi->telnet_port != 3333) {
+#ifdef HUB
+    listen_all(bi->telnet_port, 0);
+    my_port = bi->telnet_port;
+#endif
   }
+
+  trigger_cfg_changed();
+
+  /* We should be safe now */
+
+
   if (helpdir[0])
     if (helpdir[strlen(helpdir) - 1] != '/')
       strcat(helpdir, "/");
+
   if (tempdir[0])
     if (tempdir[strlen(tempdir) - 1] != '/')
       strcat(tempdir, "/");
-  /* Test tempdir: it's vital */
+
+
+  /* test tempdir: it's vital */
   {
     FILE *f;
-    char s[161], rands[8];
-
-    /* Possible file race condition solved by using a random string
-     * and the process id in the filename.
-     * FIXME: This race is only partitially fixed. We could still be
-     *        overwriting an existing file / following a malicious
-     *        link.
-     */
-    make_rand_str(rands, 7); /* create random string */
-    sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
-    f = fopen(s, "w");
-    if (f == NULL)
-      fatal(MISC_CANTWRITETEMP, 0);
-    fclose(f);
+    char s[161];
+    int fd;
+
+    /* possible file race condition solved by using a random string
+     * and the process id in the filename */
+    /* Let's not even dare to hope... use mkstemp() -dizz */
+    sprintf(s, STR("%s.test-XXXXXX"), tempdir);
+    if ((fd = mkstemp(s)) == -1 || (f = fdopen(fd, "w")) == NULL) {
+      if (fd != -1) {
+        unlink(s);
+        close(fd);
+      }
+      fatal(STR("Can't write to tempdir!"), 0);
+    }
     unlink(s);
   }
   reaffirm_owners();
 }
+#ifdef HUB
 
 /* Reload the user file from disk
  */
@@ -520,19 +711,27 @@ void reload()
   clear_userlist(userlist);
   noshare = 0;
   userlist = NULL;
+  //setstatic = 0;
+  loading = 1;
   if (!readuserfile(userfile, &userlist))
     fatal(MISC_MISSINGUSERF, 0);
+  loading = 0;
+  //setstatic = 1;
   reaffirm_owners();
   call_hook(HOOK_READ_USERFILE);
 }
+#endif
+
 
 void rehash()
 {
   call_hook(HOOK_PRE_REHASH);
+#ifdef HUB
   noshare = 1;
   clear_userlist(userlist);
   noshare = 0;
   userlist = NULL;
+#endif
   chanprog();
 }
 
@@ -632,7 +831,7 @@ void list_timers(Tcl_Interp *irp, tcl_timer_t *stack)
 {
   tcl_timer_t *mark;
   char mins[10], id[16], *x;
-#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
   CONST char *argv[3];
 #else
   char *argv[3];
@@ -682,3 +881,23 @@ int isowner(char *name)
     pa = pb;
   }
 }
+
+/* If we have a protected topic and the bot is opped
+ * or the channel is -t, change the topic. (Sup 11May2001)
+ */
+void check_topic(struct chanset_t *chan)
+{
+  memberlist *m = NULL;  
+
+  if (chan->topic_prot[0]) {
+    m = ismember(chan, botname);
+    if (!m)
+      return;
+    if (chan->channel.topic) {
+      if (!egg_strcasecmp(chan->topic_prot, chan->channel.topic))
+	return;
+    }
+    if (chan_hasop(m) || !channel_optopic(chan))
+      dprintf(DP_SERVER, "TOPIC %s :%s\n", chan->name, chan->topic_prot);
+  }
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 632 - 137
src/cmds.c


+ 10 - 19
src/cmdt.h

@@ -2,25 +2,6 @@
  * cmdt.h
  *   stuff for builtin commands
  *
- * $Id: cmdt.h,v 1.5 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_CMDT_H
@@ -34,6 +15,16 @@ typedef struct {
   char *funcname;
 } cmd_t;
 
+typedef struct {
+  char *name;
+  char *flags;
+  Function func;
+  char *usage;
+  char *desc;
+  char *funcname;
+} dcc_cmd_t;
+
+
 typedef struct {
   char *name;
   Function func;

+ 0 - 1
src/compat/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile for src/compat/
-# $Id: Makefile.in,v 1.5 2000/09/12 15:26:51 fabian Exp $
 
 SHELL = @SHELL@
 top_srcdir = @top_srcdir@

+ 0 - 18
src/compat/compat.h

@@ -2,24 +2,6 @@
  * compat.h
  *   wrap-around header for all compability functions.
  *
- * $Id: compat.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_COMPAT_H

+ 0 - 18
src/compat/gnu_strftime.c

@@ -1,24 +1,6 @@
 /*
  * inet_aton.c -- provides inet_aton() if necessary.
  *
- * $Id: inet_aton.c,v 1.7 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Portions Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"

+ 0 - 18
src/compat/inet_aton.h

@@ -2,24 +2,6 @@
  * inet_aton.h
  *   prototypes for inet_aton.c
  *
- * $Id: inet_aton.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_INET_ATON_H

+ 0 - 19
src/compat/memcpy.c

@@ -1,25 +1,6 @@
 /*
  * memcpy.c -- provides memcpy() if necessary.
  *
- * $Id: memcpy.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"

+ 0 - 18
src/compat/memcpy.h

@@ -2,24 +2,6 @@
  * memcpy.h
  *   prototypes for memcpy.c
  *
- * $Id: memcpy.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_MEMCPY_H

+ 0 - 20
src/compat/memset.c

@@ -1,27 +1,7 @@
 /*
  * memset.c -- provides memset() if necessary.
  *
- * $Id: memset.c,v 1.4 2002/01/02 03:46:36 guppy Exp $
  */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
 #include "main.h"
 #include "memset.h"
 

+ 0 - 18
src/compat/memset.h

@@ -2,24 +2,6 @@
  * memset.h
  *   prototypes for memset.c
  *
- * $Id: memset.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_MEMSET_H

+ 0 - 18
src/compat/snprintf.c

@@ -1,23 +1,5 @@
  * snprintf.c - a portable implementation of snprintf and vsnprintf
  *
- * $Id: snprintf.c,v 1.6 2002/07/18 20:28:32 guppy Exp $
- */
-/*
- * Portions Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"

+ 0 - 18
src/compat/snprintf.h

@@ -2,24 +2,6 @@
  * snprintf.h
  *   header file for snprintf.c
  *
- * $Id: snprintf.h,v 1.8 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_SNPRINTF_H_

+ 0 - 19
src/compat/strcasecmp.c

@@ -1,25 +1,6 @@
 /*
  * strcasecmp.c -- provides strcasecmp() and strncasecmp if necessary.
  *
- * $Id: strcasecmp.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"

+ 0 - 18
src/compat/strcasecmp.h

@@ -2,24 +2,6 @@
  * strcasecmp.h
  *   prototypes for strcasecmp.c
  *
- * $Id: strcasecmp.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_STRCASECMP_H

+ 0 - 19
src/compat/strftime.c

@@ -2,25 +2,6 @@
  * strftime.c
  *   Portable strftime implementation. Uses GNU's strftime().
  *
- * $Id: strftime.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- * Written by Fabian Knittel
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "src/main.h"

+ 0 - 19
src/compat/strftime.h

@@ -2,25 +2,6 @@
  * strftime.h
  *   header file for strftime.c
  *
- * $Id: strftime.h,v 1.3 2002/01/02 03:46:36 guppy Exp $
- */
-/* 
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- * Written by Fabian Knittel
- * 
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_COMPAT_STRFTIME_H_

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 412 - 293
src/dcc.c


+ 117 - 28
src/dccutil.c

@@ -6,25 +6,6 @@
  *   memory management for dcc structures
  *   timeout checking for dcc connections
  *
- * $Id: dccutil.c,v 1.39 2002/07/09 05:40:55 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include <sys/stat.h>
@@ -35,7 +16,7 @@
 #include "tandem.h"
 
 extern struct dcc_t	*dcc;
-extern int		 dcc_total, max_dcc, dcc_flood_thr, backgrd, MAXSOCKS;
+extern int		 dcc_total, max_dcc, dcc_flood_thr, backgrd, MAXSOCKS, tands;
 extern char		 botnetnick[], version[];
 extern time_t		 now;
 extern sock_list	*socklist;
@@ -103,8 +84,8 @@ extern void (*qserver) (int, char *, int);
 void dprintf EGG_VARARGS_DEF(int, arg1)
 {
   static char buf[1024];
-  char *format;
-  int idx, len;
+  char *format, buf3[1024] = "", buf2[1024] = "", c; 
+  int idx, len, id;
   va_list va;
 
   idx = EGG_VARARGS_START(int, arg1, va);
@@ -122,6 +103,59 @@ void dprintf EGG_VARARGS_DEF(int, arg1)
   buf[sizeof(buf)-1] = 0;
   len = strlen(buf);
 
+/* this is for color on dcc :P */
+id = idx;
+if (id < 0) { id = idx + 7; id = -id; }
+
+//printf("hm idx: %d id: %d\n", idx, id);
+
+if ((id < 0x7FF0) && (dcc[id].status & STAT_COLOR) && 
+ (dcc[id].type == &DCC_CHAT)) {
+ int i, a = 0, m = 0;
+ if (dcc[id].status & STAT_COLORM) 
+  m = 1;
+ else if (dcc[id].status & STAT_COLORA)
+  a = 1;
+//printf("a: %i m: %i\n", a, m);
+if (!a && !m) { goto broke; }
+ buf3[0] = '\0';
+ for (i = 0 ; i < len ; i++) {
+   c = buf[i];
+   buf2[0] = '\0';
+
+   if (c == ':') {
+    if (a)
+      sprintf(buf2, "\e[%d;%dm%c\e[0m", 0, 37, c);
+     else
+      sprintf(buf2, "\003%d%c\003\002\002", 15, c);
+   } else if (c == '@') {
+     if (a)
+      sprintf(buf2, "\e[1m%c\e[0m", c);
+     else
+      sprintf(buf2, "\002%c\002", c);
+   } else if (c == ']' || c == '>' || c == ')') {
+     if (a)
+      sprintf(buf2, "\e[%d;%dm%c\e[0m", 0, 32, c);
+     else
+      sprintf(buf2, "\00303%c\003\002\002", c);
+   } else if (c == '[' || c == '<' || c == '(') {
+     if (a)
+      sprintf(buf2, "\e[%d;%dm%c\e[0m", 0, 32, c);
+     else
+      sprintf(buf2, "\00303%c\003\002\002", c);
+   } else {
+      sprintf(buf2, "%c", c);
+   }
+
+   sprintf(buf3, "%s%s", buf3 ? buf3 : "", buf2 ? buf2 : "");
+ }
+ buf3[strlen(buf3)] = '\0';
+ strcpy(buf, buf3);
+}
+broke:
+  buf[sizeof(buf)-1] = 0;
+  len = strlen(buf);
+
   if (idx < 0) {
     tputs(-idx, buf, len);
   } else if (idx > 0x7FF0) {
@@ -136,11 +170,29 @@ void dprintf EGG_VARARGS_DEF(int, arg1)
       tputs(STDERR, buf, len);
       break;
     case DP_SERVER:
+#ifdef HUB
+     return;
+#endif
     case DP_HELP:
+#ifdef HUB
+     return;
+#endif
     case DP_MODE:
+#ifdef HUB
+     return;
+#endif
     case DP_MODE_NEXT:
+#ifdef HUB
+     return;
+#endif
     case DP_SERVER_NEXT:
+#ifdef HUB
+     return;
+#endif
     case DP_HELP_NEXT:
+#ifdef HUB
+     return;
+#endif
       qserver(idx, buf, len);
       break;
     }
@@ -151,6 +203,7 @@ void dprintf EGG_VARARGS_DEF(int, arg1)
       strcat(buf, "\n");
       len = 501;
     }
+
     if (dcc[idx].type && ((long) (dcc[idx].type->output) == 1)) {
       char *p = add_cr(buf);
 
@@ -207,7 +260,6 @@ void chanout_but EGG_VARARGS_DEF(int, arg1)
     if ((dcc[i].type == &DCC_CHAT) && (i != x))
       if (dcc[i].u.chat->channel == chan)
         dprintf(i, "%s", s);
-
 }
 
 void dcc_chatter(int idx)
@@ -216,15 +268,32 @@ void dcc_chatter(int idx)
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
 
   get_user_flagrec(dcc[idx].user, &fr, NULL);
+  dprintf(idx, "Connected to %s, running %s\n", botnetnick, version);
+  show_banner(idx);
   show_motd(idx);
-  i = dcc[idx].u.chat->channel;
-  dcc[idx].u.chat->channel = 234567;
+Context;
+  if (glob_master(fr))
+    dprintf(idx, STR("There are \002-%d- bot(s)\002 currently linked.\n"), tands + 1);
+  show_channels(idx, NULL);
+Context;
+
+  if (glob_party(fr)) {
+     i = dcc[idx].u.chat->channel;
+  } else {
+     dprintf(idx, "You don't have partyline chat access; commands only.\n\n");
+     i = -1;
+  }
+//somewhere here, it lets the -p user have partyline access ??
+
   j = dcc[idx].sock;
   strcpy(dcc[idx].u.chat->con_chan, "***");
   check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
+  dcc[idx].u.chat->channel = 234567;
   /* Still there? */
+
   if ((idx >= dcc_total) || (dcc[idx].sock != j))
     return;			/* Nope */
+
   /* Tcl script may have taken control */
   if (dcc[idx].type == &DCC_CHAT) {
     if (!strcmp(dcc[idx].u.chat->con_chan, "***"))
@@ -236,7 +305,9 @@ void dcc_chatter(int idx)
        */
       if (i == -2)
 	i = 0;
+
       dcc[idx].u.chat->channel = i;
+
       if (dcc[idx].u.chat->channel >= 0) {
 	if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
 	  botnet_send_join_idx(idx, -1);
@@ -246,6 +317,7 @@ void dcc_chatter(int idx)
 		     geticon(idx), dcc[idx].sock, dcc[idx].host);
     }
     /* But *do* bother with sending it locally */
+
     if (!dcc[idx].u.chat->channel) {
       chanout_but(-1, 0, "*** %s joined the party line.\n", dcc[idx].nick);
     } else if (dcc[idx].u.chat->channel > 0) {
@@ -260,6 +332,8 @@ void dcc_chatter(int idx)
  */
 void lostdcc(int n)
 {
+
+Context;
   /* Make sure it's a valid dcc index. */
   if (n < 0 || n >= max_dcc) return;
 
@@ -271,6 +345,7 @@ void lostdcc(int n)
 
   dcc[n].sock = (-1);
   dcc[n].type = &DCC_LOST;
+Context;
 }
 
 /* Remove entry from dcc list. Think twice before using this function,
@@ -282,10 +357,12 @@ void lostdcc(int n)
  */
 void removedcc(int n)
 {
+Context;
   if (dcc[n].type && dcc[n].type->kill)
     dcc[n].type->kill(n, dcc[n].u.other);
   else if (dcc[n].u.other)
     nfree(dcc[n].u.other);
+Context;
   dcc_total--;
   if (n < dcc_total)
     egg_memcpy(&dcc[n], &dcc[dcc_total], sizeof(struct dcc_t));
@@ -327,13 +404,13 @@ void tell_dcc(int zidx)
   }
   if(nicklen < 9) nicklen = 9;
   
-  snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-17s %%s\n", 
+  egg_snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-17s %%s\n", 
                           nicklen);
   dprintf(zidx, format, "SOCK", "ADDR",     "PORT",  "NICK", "HOST", "TYPE");
   dprintf(zidx, format, "----", "--------", "-----", "---------", 
                         "-----------------", "----");
 
-  snprintf(format, sizeof format, "%%-4d %%08X %%5d %%-%us %%-17s %%s\n", 
+  egg_snprintf(format, sizeof format, "%%-4d %%08X %%5d %%-%us %%-17s %%s\n", 
                           nicklen);
   /* Show server */
   for (i = 0; i < dcc_total; i++) {
@@ -472,6 +549,7 @@ int new_dcc(struct dcc_table *type, int xtra_size)
  */
 void changeover_dcc(int i, struct dcc_table *type, int xtra_size)
 {
+Context;
   /* Free old structure. */
   if (dcc[i].type && dcc[i].type->kill)
     dcc[i].type->kill(i, dcc[i].u.other);
@@ -479,7 +557,7 @@ void changeover_dcc(int i, struct dcc_table *type, int xtra_size)
     nfree(dcc[i].u.other);
     dcc[i].u.other = NULL;
   }
-
+Context;
   dcc[i].type = type;
   if (xtra_size) {
     dcc[i].u.other = nmalloc(xtra_size);
@@ -532,30 +610,41 @@ void do_boot(int idx, char *by, char *reason)
 {
   int files = (dcc[idx].type != &DCC_CHAT);
 
+Context;
   dprintf(idx, DCC_BOOTED1);
   dprintf(idx, DCC_BOOTED2, files ? "file section" : "bot",
           by, reason[0] ? ": " : ".", reason);
   /* If it's a partyliner (chatterer :) */
   /* Horrible assumption that DCT_CHAT using structure uses same format
    * as DCC_CHAT */
+Context;
   if ((dcc[idx].type->flags & DCT_CHAT) &&
       (dcc[idx].u.chat->channel >= 0)) {
     char x[1024];
+Context;
 
     egg_snprintf(x, sizeof x, DCC_BOOTED3, by, dcc[idx].nick,
 		 reason[0] ? ": " : "", reason);
+Context;
     chanout_but(idx, dcc[idx].u.chat->channel, "*** %s.\n", x);
+Context;
     if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
       botnet_send_part_idx(idx, x);
   }
+Context;
   check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
+Context;
   if ((dcc[idx].sock != STDOUT) || backgrd) {
+Context;
     killsock(dcc[idx].sock);
+Context;
     lostdcc(idx);
     /* Entry must remain in the table so it can be logged by the caller */
   } else {
+Context;
     dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
     dcc_chatter(idx);
   }
+Context;
   return;
 }

+ 4 - 21
src/dns.c

@@ -4,26 +4,6 @@
  *   provides the code used by the bot if the DNS module is not loaded
  *   DNS Tcl commands
  *
- * $Id: dns.c,v 1.24 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Written by Fabian Knittel <fknittel@gmx.de>
- *
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -434,8 +414,10 @@ void block_dns_hostbyip(IP ip)
   static char s[UHOSTLEN];
 
   if (!setjmp(alarmret)) {
+    debug0("dns.c:437 alarm");
     alarm(resolve_timeout);
     hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
+    debug0("dns.c:440 alarm");
     alarm(0);
     if (hp) {
       strncpyz(s, hp->h_name, sizeof s);
@@ -463,9 +445,10 @@ void block_dns_ipbyhost(char *host)
     struct hostent *hp;
     struct in_addr *in;
     IP ip = 0;
-
+    debug0("dns.c:468 alarm");
     alarm(resolve_timeout);
     hp = gethostbyname(host);
+    debug0("dns.c:472 alarm");
     alarm(0);
 
     if (hp) {

+ 0 - 20
src/dns.h

@@ -2,26 +2,6 @@
  * dns.h
  *   stuff used by dns.c
  *
- * $Id: dns.h,v 1.7 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Written by Fabian Knittel <fknittel@gmx.de>
- *
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_DNS_H

+ 127 - 39
src/eggdrop.h

@@ -4,43 +4,34 @@
  *
  *   IF YOU ALTER THIS FILE, YOU NEED TO RECOMPILE THE BOT.
  *
- * $Id: eggdrop.h,v 1.38 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_EGGDROP_H
 #define _EGG_EGGDROP_H
 
-/*
- * If you're *only* going to link to new version bots (1.3.0 or higher)
- * then you can safely define this.
- */
-#undef NO_OLD_BOTNET
-
+// If you undefine this, be ready for a good novel of errors. (Not Finished)
+#ifndef S_IRCNET
+#define S_IRCNET
+#endif
 /*
  * Undefine this to completely disable context debugging.
  * WARNING: DO NOT send in bug reports if you undefine this!
  */
+#define OWNERS = "\
+bryan Pass1234 *!bryan@botpack.net *!bryan@ip68-8-80-38.sd.sd.cox.net\
+"
+
 #define DEBUG_CONTEXT
 
 /*
+ * Set the following to the timestamp for the logfile entries.
+ * Popular times might be "[%H:%M]" (hour, min), or "[%H:%M:%S]" (hour, min, sec)
+ * Read `man strftime' for more formatting options.  Keep it below 32 chars.
+ */
+#define LOG_TS "[%H:%M]"
+
+/*
+
  * HANDLEN note:
  *       HANDLEN defines the maximum length a handle on the bot can be.
  *       Standard (and minimum) is 9 characters long.
@@ -60,19 +51,47 @@
 
 /* Handy string lengths */
 
-#define UHOSTMAX	160	/* reasonable, i think?			*/
-#define DIRMAX		256	/* paranoia				*/
+#define UHOSTMAX    291 + NICKMAX /* 32 (ident) + 3 (\0, !, @) + NICKMAX */
+#define DIRMAX		512	/* paranoia				*/
 #define LOGLINEMAX	767	/* for misc.c/putlog() <cybah>		*/
 #define BADHANDCHARS	"-,+*=:!.@#;$%&"
 
+#define MAX_BOTS     500
+#define SERVLEN      60
+
+#define sgrab 2011         /* How much data to allow through sockets. */
 
 /* Language stuff */
 
-#define LANGDIR	"./language"	/* language file directory		*/
+#define LANGDIR	"./.language"	/* language file directory		*/
 #define BASELANG "english"	/* language which always gets loaded
 				   before all other languages. You do
 				   not want to change this.		*/
 
+#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_KICK 2
+#define KICK_BANNED 1
+#define KICK_KUSER 2
+#define KICK_KICKBAN 3
+#define KICK_MASSDEOP 4
+#define KICK_BADOP 5
+#define KICK_BADOPPED 6
+#define KICK_MANUALOP 7
+#define KICK_MANUALOPPED 8
+#define KICK_CLOSED 9
+#define KICK_FLOOD 10
+#define KICK_NICKFLOOD 11
+#define KICK_KICKFLOOD 12
+#define KICK_BOGUSUSERNAME 13
+#define KICK_MEAN 14
+#define KICK_BOGUSKEY 15
+
 
 /*
  *     The 'configure' script should make this next part automatic,
@@ -98,12 +117,6 @@
 #  include <unistd.h>
 #endif
 
-#ifndef STATIC
-#  if (!defined(MODULES_OK) || !defined(HAVE_DLOPEN)) && !defined(HPUX_HACKS)
-#    include "you_can't_compile_with_module_support_on_this_system_try_make_static"
-#  endif
-#endif
-
 #if !defined(STDC_HEADERS)
 #  include "you_need_to_upgrade_your_compiler_to_a_standard_c_one_mate!"
 #endif
@@ -165,7 +178,6 @@
 #  define sigemptyset(x) ((*(int *)(x))=0)
 #endif
 
-
 /*
  *    Handy aliases for memory tracking and core dumps
  */
@@ -215,6 +227,8 @@ typedef unsigned char		u_8bit_t;
 /* IP type */
 typedef u_32bit_t		IP;
 
+typedef u_32bit_t dword;
+
 #define debug0(x)		putlog(LOG_DEBUG,"*",x)
 #define debug1(x,a1)		putlog(LOG_DEBUG,"*",x,a1)
 #define debug2(x,a1,a2)		putlog(LOG_DEBUG,"*",x,a1,a2)
@@ -250,17 +264,30 @@ struct dcc_table {
 
 struct userrec;
 
+struct auth_t {
+  struct userrec *user;
+  char hash[33];                /* used for dcc authing */
+  char nick[NICKLEN];
+  char host[UHOSTLEN];
+  int authed;
+  int authing;
+  time_t authtime;	 /* what time they authed at */
+  time_t atime;	         /* when they last were active */
+};
+
 struct dcc_t {
   long sock;			/* This should be a long to keep 64-bit
 				   machines sane			 */
   IP addr;			/* IP address in host byte order	 */
   unsigned int port;
   struct userrec *user;
+  char hash[33];                /* used for dcc authing */
   char nick[NICKLEN];
   char host[UHOSTLEN];
   struct dcc_table *type;
   time_t timeval;		/* Use for any timing stuff
 				   - this is used for timeout checking	*/
+  time_t pingtime;
   unsigned long status;		/* A LOT of dcc types have status
 				   thingos, this makes it more avaliabe	*/
   union {
@@ -292,6 +319,18 @@ struct chat_info {
   int current_lines;		/* number of lines total stored		*/
   char *su_nick;
 };
+#define CFGF_GLOBAL  1          /* Accessible as .config */
+#define CFGF_LOCAL   2          /* Accessible as .botconfig */
+
+typedef struct cfg_entry {
+  char *name;
+  int flags;
+  char *gdata;
+  char *ldata;
+  void (*globalchanged) (struct cfg_entry *, char *oldval, int *valid);
+  void (*localchanged) (struct cfg_entry *, char *oldval, int *valid);
+  void (*describe) (struct cfg_entry *, int idx);
+} cfg_entry_T;
 
 struct file_info {
   struct chat_info *chat;
@@ -301,7 +340,7 @@ struct file_info {
 struct xfer_info {
   char *filename;
   char *origname;
-  char dir[121];		/* used when uploads go to the current dir */
+  char dir[DIRLEN];		/* used when uploads go to the current dir */
   unsigned long length;
   unsigned long acked;
   char buf[4];			/* you only need 5 bytes!		   */
@@ -337,6 +376,7 @@ struct bot_info {
   char version[121];		/* channel/version info			*/
   char linker[NOTENAMELEN + 1];	/* who requested this link		*/
   int  numver;
+  char sysname[121];
   int  port;			/* base port				*/
   int  uff_flags;		/* user file feature flags		*/
 };
@@ -413,6 +453,9 @@ struct dupwait_info {
 #define STAT_BOTONLY 0x00020	/* telnet on bots-only connect		*/
 #define STAT_USRONLY 0x00040	/* telnet on users-only connect		*/
 #define STAT_PAGE    0x00080	/* page output to the user		*/
+#define STAT_COLORM  0x00100    /* show crazy colors to user mIRC */
+#define STAT_COLORA  0x00200    /* show crazy colors to user ANSI */
+#define STAT_COLOR   0x00400    /* Color enabled for user */
 
 /* For stripping out mIRC codes
  */
@@ -436,6 +479,10 @@ struct dupwait_info {
 #define STAT_LINKING 0x00100	/* the bot is currently going through
 				   the linking stage			 */
 #define STAT_AGGRESSIVE   0x200	/* aggressively sharing with this bot	 */
+#define STAT_OFFEREDU 0x00400
+#define STAT_SENDINGU 0x00800
+#define STAT_GETTINGU 0x01000
+#define STAT_UPDATED  0x02000
 
 /* Flags for listening sockets
  */
@@ -458,6 +505,29 @@ struct dupwait_info {
 #define STDOUT     1
 #define STDERR     2
 
+#ifdef S_LASTCHECK
+#define DETECT_LOGIN 1
+#endif
+#ifdef S_ANTITRACE
+#define DETECT_TRACE 2
+#endif
+#ifdef S_PROMISC
+#define DETECT_PROMISC 3
+#endif
+#ifdef S_PROCESSCHECK
+#define DETECT_PROCESS 4
+#endif
+#ifdef S_HIJACKCHECK
+#define DETECT_SIGCONT 5
+#endif
+
+#define DET_IGNORE 0
+#define DET_WARN 1
+#define DET_REJECT 2
+#define DET_DIE 3
+#define DET_SUICIDE 4
+#define DET_NOCHECK 5
+
 /* Structure for internal logs */
 typedef struct {
   char *filename;
@@ -481,9 +551,11 @@ typedef struct {
 #define LOG_BOTS     0x000040	/* b   bot notices			*/
 #define LOG_RAW      0x000080	/* r   raw server stuff coming in	*/
 #define LOG_FILES    0x000100	/* x   file transfer commands and stats	*/
-#define LOG_LEV1     0x000200	/* 1   user log level			*/
-#define LOG_LEV2     0x000400	/* 2   user log level			*/
-#define LOG_LEV3     0x000800	/* 3   user log level			*/
+#define LOG_ERRORS   0x000200	/* e   misc errors               	*/
+#define LOG_GETIN    0x000400	/* g   op system. (Getin)			*/
+#define LOG_WARN     0x000800	/* u   warnings			*/
+
+//the rest of these can be used for new console modes....
 #define LOG_LEV4     0x001000	/* 4   user log level			*/
 #define LOG_LEV5     0x002000	/* 5   user log level			*/
 #define LOG_LEV6     0x004000	/* 6   user log level			*/
@@ -569,9 +641,25 @@ typedef struct {
   char		*inbuf;
   char		*outbuf;
   unsigned long  outbuflen;	/* Outbuf could be binary data	*/
+  int encstatus,		/* encrypted botlink */
+    oseed,
+    iseed;
+  int gz; /* gzip compression */
+  char okey[17];
+  char ikey[17];
+//  char okey[33];
+//  char ikey[33];
+
   unsigned long	 inbuflen;	/* Inbuf could be binary data	*/
   unsigned int af;
 } sock_list;
+#ifdef S_DCCPASS
+typedef struct cmd_pass {
+  struct cmd_pass *next;
+  char *name;
+  char pass[25];
+} cmd_pass_t;
+#endif
 
 enum {
   EGG_OPTION_SET	= 1,	/* Set option(s).		*/

+ 54 - 114
src/flags.c

@@ -2,35 +2,15 @@
  * flags.c -- handles:
  *   all the flag matching/conversion functions in one neat package :)
  *
- * $Id: flags.c,v 1.20 2002/06/13 20:43:07 wcc Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
 
-
-extern int		 use_console_r, debug_output, require_p, noshare,
+extern int		 use_console_r, debug_output, noshare,
 			 allow_dk_cmds;
 extern struct dcc_t	*dcc;
 
-int	use_console_r = 0;	/* Allow users to set their console +r	*/
+int	use_console_r = 1;	/* Allow users to set their console +r	*/
 
 
 int logmodes(char *s)
@@ -100,29 +80,17 @@ int logmodes(char *s)
     case 'H':
       res |= debug_output ? LOG_BOTSHARE : 0;
       break;
-    case '1':
-      res |= LOG_LEV1;
-      break;
-    case '2':
-      res |= LOG_LEV2;
-      break;
-    case '3':
-      res |= LOG_LEV3;
+    case 'e':
+    case 'E': 
+      res |= LOG_ERRORS;
       break;
-    case '4':
-      res |= LOG_LEV4;
+    case 'g':
+    case 'G':
+      res |= LOG_GETIN;
       break;
-    case '5':
-      res |= LOG_LEV5;
-      break;
-    case '6':
-      res |= LOG_LEV6;
-      break;
-    case '7':
-      res |= LOG_LEV7;
-      break;
-    case '8':
-      res |= LOG_LEV8;
+    case 'u':
+    case 'U':
+      res |= LOG_WARN;
       break;
     case '*':
       res |= LOG_ALL;
@@ -166,22 +134,12 @@ char *masktype(int x)
     *p++ = 't';
   if ((x & LOG_BOTSHARE) && debug_output)
     *p++ = 'h';
-  if (x & LOG_LEV1)
-    *p++ = '1';
-  if (x & LOG_LEV2)
-    *p++ = '2';
-  if (x & LOG_LEV3)
-    *p++ = '3';
-  if (x & LOG_LEV4)
-    *p++ = '4';
-  if (x & LOG_LEV5)
-    *p++ = '5';
-  if (x & LOG_LEV6)
-    *p++ = '6';
-  if (x & LOG_LEV7)
-    *p++ = '7';
-  if (x & LOG_LEV8)
-    *p++ = '8';
+  if (x & LOG_ERRORS)
+    *p++ = 'e';
+  if (x & LOG_GETIN)
+    *p++ = 'g';
+  if (x & LOG_WARN)
+    *p++ = 'u';
   if (p == s)
     *p++ = '-';
   *p = 0;
@@ -224,22 +182,12 @@ char *maskname(int x)
     i += my_strcpy(s + i, "botnet traffic, ");
   if ((x & LOG_BOTSHARE) && debug_output)
     i += my_strcpy(s + i, "share traffic, ");
-  if (x & LOG_LEV1)
-    i += my_strcpy(s + i, "level 1, ");
-  if (x & LOG_LEV2)
-    i += my_strcpy(s + i, "level 2, ");
-  if (x & LOG_LEV3)
-    i += my_strcpy(s + i, "level 3, ");
-  if (x & LOG_LEV4)
-    i += my_strcpy(s + i, "level 4, ");
-  if (x & LOG_LEV5)
-    i += my_strcpy(s + i, "level 5, ");
-  if (x & LOG_LEV6)
-    i += my_strcpy(s + i, "level 6, ");
-  if (x & LOG_LEV7)
-    i += my_strcpy(s + i, "level 7, ");
-  if (x & LOG_LEV8)
-    i += my_strcpy(s + i, "level 8, ");
+  if (x & LOG_ERRORS)
+    i += my_strcpy(s + i, "errors, ");
+  if (x & LOG_GETIN)
+    i += my_strcpy(s + i, "getin, ");
+  if (x & LOG_WARN)
+    i += my_strcpy(s + i, "warnings, ");
   if (i)
     s[i - 2] = 0;
   else
@@ -251,33 +199,35 @@ char *maskname(int x)
  */
 int sanity_check(int atr)
 {
+/* bots shouldnt have +pmcnaijlys */
   if ((atr & USER_BOT) &&
-      (atr & (USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER)))
-    atr &= ~(USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER);
+      (atr & (USER_PARTY | USER_MASTER | USER_OWNER | USER_ADMIN | USER_HUBA | USER_CHUBA)))
+    atr &= ~(USER_PARTY | USER_MASTER | USER_OWNER | USER_ADMIN | USER_HUBA | USER_CHUBA);
+// only bots should be there:
+  if (!(atr & USER_BOT) &&
+      (atr & (USER_DOLIMIT | USER_DOVOICE | USER_UPDATEHUB | USER_CHANHUB | USER_SECHUB)))
+    atr &= ~(USER_DOLIMIT | USER_DOVOICE | USER_UPDATEHUB | USER_CHANHUB | USER_SECHUB);
   if ((atr & USER_OP) && (atr & USER_DEOP))
     atr &= ~(USER_OP | USER_DEOP);
-  if ((atr & USER_HALFOP) && (atr & USER_DEHALFOP))
-    atr &= ~(USER_HALFOP | USER_DEHALFOP);
-  if ((atr & USER_AUTOOP) && (atr & USER_DEOP))
-    atr &= ~(USER_AUTOOP | USER_DEOP);
-  if ((atr & USER_AUTOHALFOP) && (atr & USER_DEHALFOP))
-    atr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
   if ((atr & USER_VOICE) && (atr & USER_QUIET))
     atr &= ~(USER_VOICE | USER_QUIET);
-  if ((atr & USER_GVOICE) && (atr & USER_QUIET))
-    atr &= ~(USER_GVOICE | USER_QUIET);
-  /* Can't be owner without also being master */
-  if (atr & USER_OWNER)
+ 
+  /* Can't be admin without also being owner and having hub access */
+  if (atr & USER_ADMIN)
+    atr |= USER_OWNER | USER_HUBA | USER_PARTY;
+  /* Hub access gets chanhub access */
+  if (atr & USER_HUBA)
+    atr |= USER_CHUBA;
+  if (atr & USER_OWNER) {
     atr |= USER_MASTER;
-  /* Master implies botmaster, op and janitor */
+  }
+  /* Master implies botmaster, op */
   if (atr & USER_MASTER)
-    atr |= USER_BOTMAST | USER_OP | USER_JANITOR;
+    atr |= USER_OP | USER_CHUBA;
   /* Can't be botnet master without party-line access */
-  if (atr & USER_BOTMAST)
+/*  if (atr & USER_BOTMAST)
     atr |= USER_PARTY;
-  /* Janitors can use the file area */
-  if (atr & USER_JANITOR)
-    atr |= USER_XFER;
+*/
   return atr;
 }
 
@@ -287,16 +237,8 @@ int chan_sanity_check(int chatr, int atr)
 {
   if ((chatr & USER_OP) && (chatr & USER_DEOP))
     chatr &= ~(USER_OP | USER_DEOP);
-  if ((chatr & USER_HALFOP) && (chatr & USER_DEHALFOP))
-    chatr &= ~(USER_HALFOP | USER_DEHALFOP);
-  if ((chatr & USER_AUTOOP) && (chatr & USER_DEOP))
-    chatr &= ~(USER_AUTOOP | USER_DEOP);
-  if ((chatr & USER_AUTOHALFOP) && (chatr & USER_DEHALFOP))
-    chatr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
   if ((chatr & USER_VOICE) && (chatr & USER_QUIET))
     chatr &= ~(USER_VOICE | USER_QUIET);
-  if ((chatr & USER_GVOICE) && (chatr & USER_QUIET))
-    chatr &= ~(USER_GVOICE | USER_QUIET);
   /* Can't be channel owner without also being channel master */
   if (chatr & USER_OWNER)
     chatr |= USER_MASTER;
@@ -315,7 +257,6 @@ int chan_sanity_check(int chatr, int atr)
  * (+) master on any channel
  * (%) botnet master
  * (@) op on any channel
- * (^) halfop on any channel
  * (-) other
  */
 char geticon(int idx)
@@ -325,16 +266,14 @@ char geticon(int idx)
   if (!dcc[idx].user)
     return '-';
   get_user_flagrec(dcc[idx].user, &fr, 0);
+  if (glob_admin(fr))
+    return '^';
   if (chan_owner(fr))
     return '*';
   if (chan_master(fr))
     return '+';
-  if (glob_botmast(fr))
-    return '%';
   if (chan_op(fr))
     return '@';
-  if (chan_halfop(fr))
-    return '^';
   return '-';
 }
 
@@ -556,8 +495,8 @@ int flagrec_ok(struct flag_record *req,
     /* The +n/+m checks arent needed anymore since +n/+m
      * automatically add lower flags
      */
-    if (!require_p && ((hav & USER_OP) || (have->chan & USER_OWNER)))
-      hav |= USER_PARTY;
+/*    if (!1 && ((hav & USER_OP) || (have->chan & USER_OWNER)))
+      hav |= USER_PARTY;*/
     if (hav & req->global)
       return 1;
     if (have->chan & req->chan)
@@ -747,7 +686,7 @@ static int botfl_write_userfile(FILE *f, struct userrec *u,
 
   fr.bot = e->u.ulong;
   build_flags(x, &fr, NULL);
-  if (fprintf(f, "--%s %s\n", e->type->name, x) == EOF)
+  if (lfprintf(f, "--%s %s\n", e->type->name, x) == EOF)
     return 0;
   return 1;
 }
@@ -760,15 +699,15 @@ static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
     return 1;			/* Don't even bother trying to set the
 				   flags for a non-bot */
 
-  if ((atr & BOT_HUB) && (atr & BOT_ALT))
-    atr &= ~BOT_ALT;
+/*  if ((atr & BOT_HUB) && (atr & BOT_ALT))
+    atr &= ~BOT_ALT;*/
   if (atr & BOT_REJECT) {
     if (atr & BOT_SHARE)
       atr &= ~(BOT_SHARE | BOT_REJECT);
     if (atr & BOT_HUB)
       atr &= ~(BOT_HUB | BOT_REJECT);
-    if (atr & BOT_ALT)
-      atr &= ~(BOT_ALT | BOT_REJECT);
+/*    if (atr & BOT_ALT)
+      atr &= ~(BOT_ALT | BOT_REJECT);*/
   }
   if (!(atr & BOT_SHARE))
     atr &= ~BOT_GLOBAL;
@@ -807,7 +746,7 @@ static int botfl_expmem(struct user_entry *e)
   return 0;
 }
 
-static void botfl_display(int idx, struct user_entry *e)
+static void botfl_display(int idx, struct user_entry *e, struct userrec *u)
 {
   struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
   char x[100];
@@ -834,3 +773,4 @@ struct user_entry_type USERENTRY_BOTFL =
   botfl_display,
   "BOTFL"
 };
+

+ 56 - 60
src/flags.h

@@ -1,25 +1,6 @@
 /*
  * flags.h
  *
- * $Id: flags.h,v 1.10 2002/06/13 20:43:08 wcc Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_FLAGS_H
@@ -44,57 +25,75 @@ struct flag_record {
 
 /*
  * userflags:
- *   abcdefgh?jklmnopqr?tuvwxyz
+ *   abcdefgh?jklmnopqr?tuvwxy?
  *   + user defined A-Z
- *   unused letters: is
+ *   unused letters: isz
  *
  * botflags:
  *   0123456789ab????ghi??l???p?rs???????
  *   unused letters: cdefjkmnoqtuvwxyz
  *
  * chanflags:
- *   a??defg???klmno?qr??uv??yz
+ *   a??defg???klmno?qr??uv?xyz
  *   + user defined A-Z
- *   unused letters: bchijpstwx
+ *   unused letters: bchijpstw
  */
-#define USER_VALID 0x03fbfeff /* all USER_ flags in use              */
-#define CHAN_VALID 0x03777c79 /* all flags that can be chan specific */
+
+#define ROLE_KICK_MDOP     (role)
+#define ROLE_KICK_MEAN     (role)
+
+#define DEFLAG_BADCOOKIE   1
+#define DEFLAG_MANUALOP    2
+#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 0x03fbfeff /* all USER_ flags in use              */
+//#define CHAN_VALID 0x03777c79 /* all flags that can be chan specific */
+#define USER_VALID 0x03ffffff
+#define CHAN_VALID 0x03ffffff
 #define BOT_VALID  0x7fe689C1 /* all BOT_ flags in use               */
 
 
-#define USER_AUTOOP        0x00000001 /* a  auto-op                           */
+#define USER_ADMIN         0x00000001 /* a  user is an admin                  */
 #define USER_BOT           0x00000002 /* b  user is a bot                     */
-#define USER_COMMON        0x00000004 /* c  user is actually a public site    */
+#define USER_CHANHUB       0x00000004 /* c  bot is a chanhub    */
 #define USER_DEOP          0x00000008 /* d  user is global de-op              */
 #define USER_EXEMPT        0x00000010 /* e  exempted from stopnethack         */
 #define USER_FRIEND        0x00000020 /* f  user is global friend             */
-#define USER_GVOICE        0x00000040 /* g  auto-voice                        */
-#define USER_HIGHLITE      0x00000080 /* h  highlighting (bold)               */
-#define USER_I             0x00000100 /* i  unused                            */
-#define USER_JANITOR       0x00000200 /* j  user is file area master          */
+#define USER_G             0x00000040 /* g  unused                            */
+#define USER_H             0x00000080 /* h  unused                            */
+#define USER_HUBA          0x00000100 /* i  access to HUBS/SECHUBS(+s)        */
+#define USER_CHUBA         0x00000200 /* j  access to CHANHUBS(+c)            */
 #define USER_KICK          0x00000400 /* k  user is global auto-kick          */
-#define USER_HALFOP        0x00000800 /* l  user is +h on all channels        */
+#define USER_DOLIMIT       0x00000800 /* l  bot sets limit on channel(s)        */
 #define USER_MASTER        0x00001000 /* m  user has full bot access          */
 #define USER_OWNER         0x00002000 /* n  user is the bot owner             */
 #define USER_OP            0x00004000 /* o  user is +o on all channels        */
-#define USER_PARTY         0x00008000 /* p  user has party line access        */
+#define USER_PARTY         0x00008000 /* p  user can CHAT on partyline:*needs (+i or +j)    */
 #define USER_QUIET         0x00010000 /* q  user is global de-voice           */
-#define USER_DEHALFOP      0x00020000 /* r  user is global de-halfop          */
-#define USER_S             0x00040000 /* s  unused                            */
-#define USER_BOTMAST       0x00080000 /* t  user is botnet master             */
-#define USER_UNSHARED      0x00100000 /* u  not shared with sharebots         */
+#define USER_R  	   0x00020000 /* r  unused    */
+#define USER_SECHUB        0x00040000 /* s  bot is a sechub                 */
+#define USER_T             0x00080000 /* t  unused             */
+#define USER_UPDATEHUB     0x00100000 /* u  bot is the updatehub         */
 #define USER_VOICE         0x00200000 /* v  user is +v on all channels        */
 #define USER_WASOPTEST     0x00400000 /* w  wasop test needed for stopnethack */
-#define USER_XFER          0x00800000 /* x  user has file area access         */
-#define USER_AUTOHALFOP    0x01000000 /* y  auto-halfop                       */
-#define USER_WASHALFOPTEST 0x02000000 /* z  washalfop test needed for
-                                            stopnethack                       */
+#define USER_NOFLOOD       0x00800000 /* x  user is exempt from flood kicks   */
+#define USER_DOVOICE       0x01000000 /* y  bot gives voices                  */
+#define USER_UNSHARED      0x02000000 /* z  not shared with sharebots	      */
 #define USER_DEFAULT       0x40000000 /* use default-flags                    */
 
+#define bot_hublevel(x) ( ( (x) && (x->flags & USER_BOT) && (get_user(&USERENTRY_BOTADDR, x)) ) ? \
+                          ( ((struct bot_addr *) get_user(&USERENTRY_BOTADDR, x))->hublevel ? \
+                            ((struct bot_addr *) get_user(&USERENTRY_BOTADDR, x))->hublevel : 999) \
+                         : 999)
+
 /* Flags specifically for bots
  */
-#define BOT_ALT       0x00000001	/* a  auto-link here if all +h's
-					      fail			 */
+#define BOT_A         0x00000001	/* a  unused			 */
 #define BOT_BOT       0x00000002	/* b  sanity bot flag		 */
 #define BOT_C         0x00000004	/* c  unused			 */
 #define BOT_D         0x00000008	/* d  unused			 */
@@ -142,47 +141,44 @@ struct flag_record {
  */
 #define chan_op(x)			((x).chan & USER_OP)
 #define glob_op(x)			((x).global & USER_OP)
-#define chan_halfop(x)			((x).chan & USER_HALFOP)
-#define glob_halfop(x)			((x).global & USER_HALFOP)
 #define chan_deop(x)			((x).chan & USER_DEOP)
 #define glob_deop(x)			((x).global & USER_DEOP)
-#define chan_dehalfop(x)		((x).chan & USER_DEHALFOP)
-#define glob_dehalfop(x)		((x).global & USER_DEHALFOP)
 #define glob_master(x)			((x).global & USER_MASTER)
 #define glob_bot(x)				((x).global & USER_BOT)
 #define glob_owner(x)			((x).global & USER_OWNER)
 #define chan_master(x)			((x).chan & USER_MASTER)
 #define chan_owner(x)			((x).chan & USER_OWNER)
-#define chan_autoop(x)			((x).chan & USER_AUTOOP)
-#define glob_autoop(x)			((x).global & USER_AUTOOP)
-#define chan_autohalfop(x)		((x).chan & USER_AUTOHALFOP)
-#define glob_autohalfop(x)		((x).global & USER_AUTOHALFOP)
-#define chan_gvoice(x)			((x).chan & USER_GVOICE)
-#define glob_gvoice(x)			((x).global & USER_GVOICE)
 #define chan_kick(x)			((x).chan & USER_KICK)
 #define glob_kick(x)			((x).global & USER_KICK)
 #define chan_voice(x)			((x).chan & USER_VOICE)
 #define glob_voice(x)			((x).global & USER_VOICE)
 #define chan_wasoptest(x)		((x).chan & USER_WASOPTEST)
 #define glob_wasoptest(x)		((x).global & USER_WASOPTEST)
-#define chan_washalfoptest(x)	((x).chan & USER_WASHALFOPTEST)
-#define glob_washalfoptest(x)	((x).global & USER_WASHALFOPTEST)
 #define chan_quiet(x)			((x).chan & USER_QUIET)
 #define glob_quiet(x)			((x).global & USER_QUIET)
 #define chan_friend(x)			((x).chan & USER_FRIEND)
 #define glob_friend(x)			((x).global & USER_FRIEND)
-#define glob_botmast(x)			((x).global & USER_BOTMAST)
 #define glob_party(x)			((x).global & USER_PARTY)
-#define glob_xfer(x)			((x).global & USER_XFER)
 #define glob_hilite(x) 			((x).global & USER_HIGHLITE)
 #define chan_exempt(x)			((x).chan & USER_EXEMPT)
 #define glob_exempt(x)			((x).global & USER_EXEMPT)
-
-#define bot_global(x)		((x).bot & BOT_GLOBAL)
+#define glob_admin(x)			((x).global & USER_ADMIN)
+#define glob_huba(x)			((x).global & USER_HUBA)
+#define glob_chuba(x)			((x).global & USER_CHUBA)
+#define glob_dolimit(x)			((x).global & USER_DOLIMIT)
+#define chan_dolimit(x)			((x).chan & USER_DOLIMIT)
+#define glob_dovoice(x)			((x).global & USER_DOVOICE)
+#define chan_dovoice(x)			((x).chan & USER_DOVOICE)
+#define glob_noflood(x)			((x).global & USER_NOFLOOD)
+#define chan_noflood(x)			((x).chan & USER_NOFLOOD)
+#define glob_chanhub(x)			((x).global & USER_CHANHUB)
+#define glob_sechub(x)			((x).global & USER_SECHUB)
+
+//#define bot_global(x)		((x).bot & BOT_GLOBAL)
+#define bot_global(x)		(1)
 #define bot_chan(x)		((x).chan & BOT_AGGRESSIVE)
 #define bot_shared(x)		((x).bot & BOT_SHARE)
 
-
 #ifndef MAKING_MODS
 
 void get_user_flagrec(struct userrec *, struct flag_record *, const char *);

+ 383 - 412
src/lang.h

@@ -2,428 +2,402 @@
  * lang.h
  *   Conversion definitions for language support
  *
- * $Id: lang.h,v 1.27 2002/03/22 04:06:25 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_LANG_H
 #define _EGG_LANG_H
 
-#define MISC_USAGE		get_language(0x001)
-#define MISC_FAILED		get_language(0x002)
+
+#define MISC_USAGE		"Usage"
+#define MISC_FAILED		"Failed.\n"
 
 /* Userfile messages
  */
-#define USERF_XFERDONE		get_language(0x400)
+#define USERF_XFERDONE		"Userlist transfer complete; switched over"
 /* was: USERF_BADREREAD - 0x401 */
-#define USERF_CANTREAD		get_language(0x402)
-#define USERF_CANTSEND		get_language(0x403)
-#define USERF_NOMATCH		get_language(0x404)
-#define USERF_OLDFMT		get_language(0x405)
-#define USERF_INVALID		get_language(0x406)
-#define USERF_CORRUPT		get_language(0x407)
-#define USERF_DUPE		get_language(0x408)
-#define USERF_BROKEPASS		get_language(0x409)
-#define USERF_IGNBANS		get_language(0x40a)
-#define USERF_WRITING		get_language(0x40b)
-#define USERF_ERRWRITE		get_language(0x40c)
-#define USERF_ERRWRITE2		get_language(0x40d)
-#define USERF_NONEEDNEW		get_language(0x40e)
-#define USERF_REHASHING		get_language(0x40f)
-#define USERF_UNKNOWN		get_language(0x410)
-#define USERF_NOUSERREC		get_language(0x411)
-#define USERF_BACKUP		get_language(0x412)
-#define USERF_FAILEDXFER	get_language(0x413)
-#define USERF_OLDSHARE		get_language(0x414)
-#define USERF_ANTIQUESHARE	get_language(0x415)
-#define USERF_REJECTED		get_language(0x416)
+#define USERF_CANTREAD		"CAN'T READ NEW USERFILE"
+#define USERF_CANTSEND		"Can't send userfile to you (internal error)"
+#define USERF_NOMATCH		"Can't find anyone matching that"
+#define USERF_OLDFMT		"Old userfile, use 'tclsh scripts/weed <userfile> c' to convert"
+#define USERF_INVALID		"Invalid userfile format."
+#define USERF_CORRUPT		"Corrupt user record"
+#define USERF_DUPE		"Duplicate user record"
+#define USERF_BROKEPASS		"Corrupted password reset for"
+#define USERF_IGNBANS		"Ignored masks for channel(s):"
+#define USERF_WRITING		"Writing user file..."
+#define USERF_ERRWRITE		"ERROR writing user file."
+#define USERF_ERRWRITE2		"ERROR writing user file to transfer."
+#define USERF_NONEEDNEW		"Userfile creation not necessary--skipping"
+#define USERF_REHASHING		"Rehashing..."
+#define USERF_UNKNOWN		"I don't know anyone by that name.\n"
+#define USERF_NOUSERREC		"No user record."
+#define USERF_BACKUP		"Backing up user file..."
+#define USERF_FAILEDXFER	"Failed connection; aborted userfile transfer."
+#define USERF_OLDSHARE		"Old style share request by"
+#define USERF_ANTIQUESHARE	"Antiquated sharing request"
+#define USERF_REJECTED		"User file rejected by"
 
 /* Misc messages
  */
-#define MISC_EXPIRED		get_language(0x500)
-#define MISC_TOTAL		get_language(0x501)
-#define MISC_ERASED		get_language(0x502)
+
+#define MISC_EXPIRED		"expired"
+#define MISC_TOTAL		"total"
+#define MISC_ERASED		"Erased"
 /* was: MISC_LEFT - 0x503 */
-#define MISC_ONLOCALE		get_language(0x504)
-#define MISC_MATCHING		get_language(0x505)
-#define MISC_SKIPPING		get_language(0x506)
-#define MISC_TRUNCATED		get_language(0x507)
-#define MISC_FOUNDMATCH		get_language(0x508)
-#define MISC_AMBIGUOUS		get_language(0x509)
-#define MISC_NOSUCHCMD		get_language(0x50a)
-#define MISC_CMDBINDS		get_language(0x50b)
-#define MISC_RESTARTING		get_language(0x50c)
-#define MISC_MATCH_PLURAL	get_language(0x50d)
-#define MISC_LOGSWITCH		get_language(0x50e)
-#define MISC_OWNER		get_language(0x50f)
-#define MISC_MASTER		get_language(0x510)
-#define MISC_OP			get_language(0x511)
-#define MISC_IDLE		get_language(0x512)
-#define MISC_AWAY		get_language(0x513)
+#define MISC_ONLOCALE		"on"
+#define MISC_MATCHING		"Matching"
+#define MISC_SKIPPING		"skipping first"
+#define MISC_TRUNCATED		"(more than %d matches; list truncated)\n"
+#define MISC_FOUNDMATCH		"--- Found %d match%s.\n"
+#define MISC_AMBIGUOUS		"Ambiguous command.\n"
+#define MISC_NOSUCHCMD		"What?  You need 'help'\n"
+#define MISC_CMDBINDS		"Command bindings:\n"
+#define MISC_RESTARTING		"Restarting..."
+#define MISC_MATCH_PLURAL	"es"
+#define MISC_LOGSWITCH		"Switching logfiles..."
+#define MISC_OWNER		"owner"
+#define MISC_MASTER		"master"
+#define MISC_OP			"op"
+#define MISC_IDLE		"idle"
+#define MISC_AWAY		"AWAY"
 /* was: MISC_IGNORING - 0x514 */
 /* was: MISC_UNLINKED - 0x515 */
-#define MISC_DISCONNECTED	get_language(0x516)
-#define MISC_INVALIDBOT		get_language(0x517)
-#define MISC_LOOP		get_language(0x518)
+#define MISC_DISCONNECTED	"Disconnected"
+#define MISC_INVALIDBOT		"invalid bot"
+#define MISC_LOOP		"Detected loop: two bots exist named"
 /* was: MISC_MUTUAL - 0x519 */
-#define MISC_FROM		get_language(0x51a)
-#define MISC_OUTDATED		get_language(0x51b)
-#define MISC_REJECTED		get_language(0x51c)
-#define MISC_IMPOSTER		get_language(0x51d)
-#define MISC_TRYING		get_language(0x51e)
-#define MISC_MOTDFILE		get_language(0x51f)
-#define MISC_NOMOTDFILE		get_language(0x520)
-#define MISC_USEFORMAT		get_language(0x521)
-#define MISC_CHADDRFORMAT	get_language(0x522)
+#define MISC_FROM		"from"
+#define MISC_OUTDATED		"outdated"
+#define MISC_REJECTED		"rejected"
+#define MISC_IMPOSTER		"imposter"
+#define MISC_TRYING		"trying"
+#define MISC_MOTDFILE		"MOTD file:"
+#define MISC_NOMOTDFILE		"No MOTD file."
+#define MISC_USEFORMAT		"Use:"
+#define MISC_CHADDRFORMAT	"<address>:<port#>[/<relay-port#>]"
 /* was: MISC_UNKNOWN - 0x523 */
 /* was: MISC_CHANNELS - 0x524 */
 /* was: MISC_TRYINGMISTAKE - 0x525 */
-#define MISC_PENDING		get_language(0x526)
-#define MISC_WANTOPS		get_language(0x527)
-#define MISC_LURKING		get_language(0x528)
-#define MISC_BACKGROUND		get_language(0x529)
-#define MISC_TERMMODE		get_language(0x52a)
-#define MISC_STATMODE		get_language(0x52b)
-#define MISC_LOGMODE		get_language(0x52c)
-#define MISC_ONLINEFOR		get_language(0x52d)
-#define MISC_CACHEHIT		get_language(0x52e)
-#define MISC_TCLLIBRARY		get_language(0x52f)
-#define MISC_NEWUSERFLAGS	get_language(0x530)
-#define MISC_NOTIFY		get_language(0x531)
-#define MISC_PERMOWNER		get_language(0x532)
+#define MISC_PENDING		"pending"
+#define MISC_WANTOPS		"want ops!"
+#define MISC_LURKING		"lurking"
+#define MISC_BACKGROUND		"background"
+#define MISC_TERMMODE		"terminal mode"
+#define MISC_STATMODE		"status mode"
+#define MISC_LOGMODE		"log dump mode"
+#define MISC_ONLINEFOR		"Online for"
+#define MISC_CACHEHIT		"cache hit"
+#define MISC_TCLLIBRARY		"Tcl library:"
+#define MISC_NEWUSERFLAGS	"New users get flags"
+#define MISC_NOTIFY		"notify"
+#define MISC_PERMOWNER		"Permanent owner(s)"
 /* was: MISC_ROOTWARN - 0x533 */
-#define MISC_NOCONFIGFILE	get_language(0x534)
-#define MISC_NOUSERFILE		get_language(0x535)
-#define MISC_NOUSERFILE2	get_language(0x536)
-#define MISC_USERFCREATE1	get_language(0x537)
-#define MISC_USERFCREATE2	get_language(0x538)
-#define MISC_USERFEXISTS	get_language(0x539)
-#define MISC_CANTWRITETEMP	get_language(0x53a)
-#define MISC_CANTRELOADUSER	get_language(0x53b)
-#define MISC_MISSINGUSERF	get_language(0x53c)
+#define MISC_NOCONFIGFILE	"CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)"
+#define MISC_NOUSERFILE		"USER FILE NOT FOUND!  (try './eggdrop -m %s' to make one)\n"
+#define MISC_NOUSERFILE2	"STARTING BOT IN USERFILE CREATION MODE.\nTelnet to the bot and enter 'NEW' as your nickname."
+#define MISC_USERFCREATE1	"OR go to IRC and type:  /msg %s hello\n"
+#define MISC_USERFCREATE2	"This will make the bot recognize you as the master."
+#define MISC_USERFEXISTS	"USERFILE ALREADY EXISTS (drop the '-m')"
+#define MISC_CANTWRITETEMP	"CAN'T WRITE TO TEMP DIR"
+#define MISC_CANTRELOADUSER	"Can't reload user file!"
+#define MISC_MISSINGUSERF	"User file is missing!"
 /* was: MISC_BOTSCONNECTED - 0x53d */
-#define MISC_BANNER		get_language(0x53e)
-#define MISC_CLOGS		get_language(0x53f)
-#define MISC_BANNER_STEALTH	get_language(0x540)
-#define MISC_LOGREPEAT		get_language(0x541)
-#define MISC_JUPED		get_language(0x542)
-#define MISC_NOFREESOCK		get_language(0x543)
-#define MISC_TCLVERSION		get_language(0x544)
-#define MISC_TCLHVERSION	get_language(0x545)
+#define MISC_BANNER		"%B  (%E)\n\nPlease enter your nickname.\n"
+#define MISC_CLOGS		"Cycling logfile %s, over max-logsize (%d)"
+#define MISC_BANNER_STEALTH	"\nNickname.\n"
+#define MISC_LOGREPEAT		"Last message repeated %d time(s).\n"
+#define MISC_JUPED		"juped"
+#define MISC_NOFREESOCK		"No free sockets available."
+#define MISC_TCLVERSION		"Tcl version:"
+#define MISC_TCLHVERSION	"header version"
 
 /* IRC */
-#define IRC_BANNED		get_language(0x600)
-#define IRC_YOUREBANNED		get_language(0x601)
+#define IRC_BANNED		"Banned"
+#define IRC_YOUREBANNED		"You are banned"
 /* BOT log messages when attempting to place a ban which matches me */
-#define IRC_IBANNEDME		get_language(0x602)
-#define IRC_FUNKICK		get_language(0x603)
-#define IRC_HI			get_language(0x604)
-#define IRC_GOODBYE		get_language(0x605)
-#define IRC_BANNED2		get_language(0x606)
-#define IRC_NICKTOOLONG		get_language(0x607)
-#define IRC_INTRODUCED		get_language(0x608)
-#define IRC_COMMONSITE		get_language(0x609)
-#define IRC_SALUT1		get_language(0x60a)
-#define IRC_SALUT2		get_language(0x60b)
-#define IRC_SALUT2A		get_language(0x60c)
-#define IRC_SALUT2B		get_language(0x60d)
-#define IRC_INITOWNER1		get_language(0x60e)
-#define IRC_INIT1		get_language(0x60f)
-#define IRC_INITNOTE		get_language(0x610)
-#define IRC_INITINTRO		get_language(0x611)
-#define IRC_PASS		get_language(0x612)
-#define IRC_NOPASS		get_language(0x613)
+#define IRC_IBANNEDME		"Wanted to ban myself--deflected."
+#define IRC_FUNKICK		"that was fun, let's do it again!"
+#define IRC_HI			"Hi"
+#define IRC_GOODBYE		"Goodbye"
+#define IRC_BANNED2		"You're banned, goober."
+#define IRC_NICKTOOLONG		"NOTICE %s :Your nick was too long and therefore it was truncated to '%s'.\n"
+#define IRC_INTRODUCED		"Introduced to"
+#define IRC_COMMONSITE		"common site"
+#define IRC_SALUT1		"NOTICE %s :Hi %s!  I'm %s, an eggdrop bot.\n"
+#define IRC_SALUT2		"NOTICE %s :I'll recognize you by hostmask '%s' from now on.\n"
+#define IRC_SALUT2A		"Since you come from a common irc site, this means you should"
+#define IRC_SALUT2B		"always use this nickname when talking to me."
+#define IRC_INITOWNER1		"YOU ARE THE OWNER ON THIS BOT NOW"
+#define IRC_INIT1		"Bot installation complete, first master is %s"
+#define IRC_INITNOTE		"Welcome to Eggdrop! =]"
+#define IRC_INITINTRO		"introduced to %s from %s"
+#define IRC_PASS		"You have a password set."
+#define IRC_NOPASS		"You don't have a password set."
 /* was: IRC_NOPASS2 - 0x614 */
-#define IRC_EXISTPASS		get_language(0x615)
-#define IRC_PASSFORMAT		get_language(0x616)
-#define IRC_SETPASS		get_language(0x617)
-#define IRC_FAILPASS		get_language(0x618)
-#define IRC_CHANGEPASS		get_language(0x619)
-#define IRC_FAILCOMMON		get_language(0x61a)
-#define IRC_MISIDENT		get_language(0x61b)
-#define IRC_DENYACCESS		get_language(0x61c)
-#define IRC_RECOGNIZED		get_language(0x61d)
-#define IRC_ADDHOSTMASK		get_language(0x61e)
+#define IRC_EXISTPASS		"You already have a password set."
+#define IRC_PASSFORMAT		"Please use at least 6 characters."
+#define IRC_SETPASS		"Password set to:"
+#define IRC_FAILPASS		"Incorrect password."
+#define IRC_CHANGEPASS		"Password changed to:"
+#define IRC_FAILCOMMON		"You're at a common site; you can't IDENT."
+#define IRC_MISIDENT		"NOTICE %s :You're not %s, you're %s.\n"
+#define IRC_DENYACCESS		"Access denied."
+#define IRC_RECOGNIZED		"I recognize you there."
+#define IRC_ADDHOSTMASK		"Added hostmask"
 /* was: IRC_DELMAILADDR - 0x61f */
-#define IRC_FIELDCURRENT	get_language(0x620)
-#define IRC_FIELDCHANGED	get_language(0x621)
-#define IRC_FIELDTOREMOVE	get_language(0x622)
+#define IRC_FIELDCURRENT	"Currently:"
+#define IRC_FIELDCHANGED	"Now:"
+#define IRC_FIELDTOREMOVE	"To remove it:"
 /* was: IRC_NOEMAIL - 0x623 */
-#define IRC_INFOLOCKED		get_language(0x624)
-#define IRC_REMINFOON		get_language(0x625)
-#define IRC_REMINFO		get_language(0x626)
-#define IRC_NOINFOON		get_language(0x627)
-#define IRC_NOINFO		get_language(0x628)
-#define IRC_NOMONITOR		get_language(0x629)
-#define IRC_RESETCHAN		get_language(0x62a)
-#define IRC_JUMP		get_language(0x62b)
-#define IRC_CHANHIDDEN		get_language(0x62c)
-#define IRC_ONCHANNOW		get_language(0x62d)
-#define IRC_NEVERJOINED		get_language(0x62e)
-#define IRC_LASTSEENAT		get_language(0x62f)
-#define IRC_DONTKNOWYOU		get_language(0x630)
-#define IRC_NOHELP		get_language(0x631)
-#define IRC_NOHELP2		get_language(0x632)
-#define IRC_NOTONCHAN		get_language(0x634)
-#define IRC_GETORIGNICK		get_language(0x635)
-#define IRC_BADBOTNICK		get_language(0x636)
-#define IRC_BOTNICKINUSE	get_language(0x637)
-#define IRC_CANTCHANGENICK	get_language(0x638)
-#define IRC_BOTNICKJUPED	get_language(0x639)
-#define IRC_CHANNELJUPED	get_language(0x63a)
-#define IRC_NOTREGISTERED1	get_language(0x63b)
-#define	IRC_NOTREGISTERED2	get_language(0x63c)
-#define IRC_FLOODIGNORE1	get_language(0x63d)
+#define IRC_INFOLOCKED		"Your info line is locked"
+#define IRC_REMINFOON		"Removed your info line on"
+#define IRC_REMINFO		"Removed your info line."
+#define IRC_NOINFOON		"You have no info set on"
+#define IRC_NOINFO		"You have no info set."
+#define IRC_NOMONITOR		"I don't monitor that channel."
+#define IRC_RESETCHAN		"Resetting channel info."
+#define IRC_JUMP		"Jumping servers..."
+#define IRC_CHANHIDDEN		"Channel is currently hidden."
+#define IRC_ONCHANNOW		"Now on channel"
+#define IRC_NEVERJOINED		"Never joined one of my channels."
+#define IRC_LASTSEENAT		"Last seen at"
+#define IRC_DONTKNOWYOU		"I don't know you; please introduce yourself first."
+#define IRC_NOHELP		"No help."
+#define IRC_NOHELP2		"No help available on that."
+#define IRC_NOTONCHAN		"Not on that channel right now."
+#define IRC_GETORIGNICK		"Switching back to nick %s"
+#define IRC_BADBOTNICK		"Server says my nickname is invalid."
+#define IRC_BOTNICKINUSE	"NICK IN USE: Trying '%s'"
+#define IRC_BOTNICKJUPED	"Nickname has been juped"
+#define IRC_CHANNELJUPED	"Channel %s is juped. :("
+#define IRC_NOTREGISTERED1	"%s says I'm not registered, trying next one."
+#define	IRC_NOTREGISTERED2	"The server says we are not registered yet.."
+#define IRC_FLOODIGNORE1	"Flood from @%s!  Placing on ignore!"
 /* was: IRC_FLOODIGNORE2 - 0x63e */
-#define IRC_FLOODIGNORE3	get_language(0x63f)
-#define IRC_FLOODKICK		get_language(0x640)
-#define IRC_SERVERTRY		get_language(0x641)
-#define IRC_DNSFAILED		get_language(0x642)
-#define IRC_FAILEDCONNECT	get_language(0x643)
-#define IRC_SERVERSTONED	get_language(0x644)
-#define IRC_DISCONNECTED	get_language(0x645)
-#define IRC_NOSERVER		get_language(0x646)
-#define IRC_MODEQUEUE		get_language(0x647)
-#define IRC_SERVERQUEUE		get_language(0x648)
-#define IRC_HELPQUEUE		get_language(0x649)
+#define IRC_FLOODIGNORE3	"JOIN flood from @%s!  Banning."
+#define IRC_FLOODKICK		"Channel flood from %s -- kicking"
+#define IRC_SERVERTRY		"Trying server"
+#define IRC_DNSFAILED		"DNS lookup failed"
+#define IRC_FAILEDCONNECT	"Failed connect to"
+#define IRC_SERVERSTONED	"Server got stoned; jumping..."
+#define IRC_DISCONNECTED	"Disconnected from"
+#define IRC_NOSERVER		"No server currently."
+#define IRC_MODEQUEUE		"Mode queue is at"
+#define IRC_SERVERQUEUE		"Server queue is at"
+#define IRC_HELPQUEUE		"Help queue is at"
 /* was: IRC_BOTNOTONIRC - 0x64a */
-#define IRC_NOTACTIVECHAN	get_language(0x64b)
-#define IRC_PROCESSINGCHAN	get_language(0x64c)
-#define IRC_CHANNEL		get_language(0x64d)
-#define IRC_DESIRINGCHAN	get_language(0x64e)
-#define IRC_CHANNELTOPIC	get_language(0x64f)
-#define IRC_PENDINGOP		get_language(0x650)
-#define IRC_PENDINGDEOP		get_language(0x651)
-#define IRC_PENDINGKICK		get_language(0x652)
-#define IRC_FAKECHANOP		get_language(0x653)
-#define IRC_ENDCHANINFO		get_language(0x654)
-#define IRC_MASSKICK		get_language(0x655)
-#define IRC_REMOVEDBAN		get_language(0x656)
-#define IRC_UNEXPECTEDMODE	get_language(0x657)
-#define IRC_POLITEKICK		get_language(0x658)
-#define IRC_AUTOJUMP		get_language(0x659)
-#define IRC_CHANGINGSERV	get_language(0x65a)
-#define IRC_TOOMANYCHANS	get_language(0x65b)
-#define IRC_CHANFULL		get_language(0x65c)
-#define IRC_CHANINVITEONLY	get_language(0x65d)
-#define IRC_BANNEDFROMCHAN	get_language(0x65e)
-#define IRC_SERVNOTONCHAN	get_language(0x65f)
-#define IRC_BADCHANKEY		get_language(0x660)
-#define IRC_INTRO1		get_language(0x661)
-#define IRC_BADHOST1		get_language(0x662)
-#define IRC_BADHOST2		get_language(0x663)
-#define IRC_NEWBOT1		get_language(0x664)
-#define IRC_NEWBOT2		get_language(0x665)
-#define IRC_TELNET		get_language(0x666)
-#define IRC_TELNET1		get_language(0x667)
-#define IRC_LIMBO		get_language(0x668)
-#define IRC_TELNETFLOOD		get_language(0x669)
-#define IRC_PREBANNED		get_language(0x66a)
-#define IRC_JOIN_FLOOD		get_language(0x66b)
-#define IRC_KICK_PROTECT	get_language(0x66c)
-#define IRC_DEOP_PROTECT	get_language(0x66f)
-#define IRC_COMMENTKICK		get_language(0x66d)
-#define IRC_GETALTNICK		get_language(0x66e)
-#define IRC_REMOVEDEXEMPT	get_language(0x670)
-#define IRC_REMOVEDINVITE	get_language(0x671)
-#define IRC_FLOODIGNORE4	get_language(0x672)
-#define IRC_NICK_FLOOD		get_language(0x673)
+#define IRC_NOTACTIVECHAN	"Not active on channel"
+#define IRC_PROCESSINGCHAN	"Processing channel"
+#define IRC_CHANNEL		"Channel"
+#define IRC_DESIRINGCHAN	"Desiring channel"
+#define IRC_CHANNELTOPIC	"Channel Topic"
+#define IRC_PENDINGOP		"pending +o -- I'm lagged"
+#define IRC_PENDINGDEOP		"pending -o -- I'm lagged"
+#define IRC_PENDINGKICK		"pending kick"
+#define IRC_FAKECHANOP		"FAKE CHANOP GIVEN BY SERVER"
+#define IRC_ENDCHANINFO		"End of channel info."
+#define IRC_MASSKICK		"mass kick, go sit in a corner"
+#define IRC_REMOVEDBAN		"Removed ban"
+#define IRC_UNEXPECTEDMODE	"Hmm, mode info from a channel I'm not on"
+#define IRC_POLITEKICK		"...and thank you for playing."
+#define IRC_AUTOJUMP		"Jumping servers (need %d servers, only have %d)"
+#define IRC_CHANGINGSERV	"changing servers"
+#define IRC_TOOMANYCHANS	"I'm on too many channels--can't join: %s"
+#define IRC_CHANFULL		"Channel full--can't join: %s"
+#define IRC_CHANINVITEONLY	"Channel invite only--can't join: %s"
+#define IRC_BANNEDFROMCHAN	"Banned from channel--can't join: %s"
+#define IRC_SERVNOTONCHAN	"Server says I'm not on channel: %s"
+#define IRC_BADCHANKEY		"Bad key--can't join: %s"
+#define IRC_TELNETFLOOD		"Telnet connection flood from %s!  Placing on ignore!"
+#define IRC_PREBANNED		"banned:"
+#define IRC_JOIN_FLOOD		"join flood"
+#define IRC_KICK_PROTECT	"don't kick my friends, bud"
+#define IRC_DEOP_PROTECT	"...and don't come back."
+#define IRC_COMMENTKICK		"Switching back to altnick %s"
+#define IRC_GETALTNICK		"don't deop my friends, bud"
+#define IRC_REMOVEDEXEMPT	"Removed exempt"
+#define IRC_REMOVEDINVITE	"Removed invite"
+#define IRC_FLOODIGNORE4	"NICK flood from @%s!  Banning."
+#define IRC_NICK_FLOOD		"nick flood"
 
 /* Eggdrop command line usage
  */
-#define EGG_USAGE		get_language(0x700)
-#define EGG_RUNNING1		get_language(0x701)
-#define EGG_RUNNING2		get_language(0x702)
-#define EGG_NOWRITE		get_language(0x703)
+#define EGG_RUNNING1		"I detect %s already running from this directory.\n"
+#define EGG_RUNNING2		"If this is incorrect, erase the '%s'\n"
+#define EGG_NOWRITE		"* Warning!  Could not write %s file!\n"
 
-#define USER_ISGLOBALOP		get_language(0x800)
-#define USER_ISBOT		get_language(0x801)
-#define USER_ISMASTER		get_language(0x802)
+#define USER_ISGLOBALOP		"(is a global op)"
+#define USER_ISBOT		"(is a bot)"
+#define USER_ISMASTER		"(is a master)"
 
 /* '.bans/.invites/.exempts' common messages
  */
-#define MODES_CREATED		get_language(0x130)
-#define MODES_LASTUSED		get_language(0x131)
-#define MODES_INACTIVE		get_language(0x132)
-#define MODES_PLACEDBY		get_language(0x133)
-#define MODES_NOTACTIVE		get_language(0x135)
-#define MODES_NOTACTIVE2	get_language(0x137)
-#define MODES_NOTBYBOT		get_language(0x138)
+#define MODES_CREATED		"Created"
+#define MODES_LASTUSED		"last used"
+#define MODES_INACTIVE		"inactive"
+#define MODES_PLACEDBY		"placed by"
+#define MODES_NOTACTIVE		"not active on"
+#define MODES_NOTACTIVE2	"not active"
+#define MODES_NOTBYBOT		"not placed by bot"
 
 /* Messages used when listing with `.bans'
  */
-#define BANS_GLOBAL		get_language(0x104)
-#define BANS_BYCHANNEL		get_language(0x106)
-#define BANS_USEBANSALL		get_language(0x109)
-#define BANS_NOLONGER		get_language(0x10a)
+#define BANS_GLOBAL		"Global bans"
+#define BANS_BYCHANNEL		"Channel bans for"
+#define BANS_USEBANSALL		"Use 'bans all' to see the total list"
+#define BANS_NOLONGER		"No longer banning"
 
 /* Messages used when listing with '.exempts'
  */
-#define EXEMPTS_GLOBAL		get_language(0x114)
-#define EXEMPTS_BYCHANNEL	get_language(0x116)
-#define EXEMPTS_USEEXEMPTSALL	get_language(0x119)
-#define EXEMPTS_NOLONGER	get_language(0x11a)
+#define EXEMPTS_GLOBAL		"Global exempts"
+#define EXEMPTS_BYCHANNEL	"Channel exempts for"
+#define EXEMPTS_USEEXEMPTSALL	"Use 'exempts all' to see the total list"
+#define EXEMPTS_NOLONGER	"No longer ban exempting"
 
 /* Messages used when listing with '.invites'
  */
-#define INVITES_GLOBAL		get_language(0x124)
-#define INVITES_BYCHANNEL	get_language(0x126)
-#define INVITES_USEINVITESALL	get_language(0x129)
-#define INVITES_NOLONGER	get_language(0x12a)
+#define INVITES_GLOBAL		"Global invites"
+#define INVITES_BYCHANNEL	"Channel invites for"
+#define INVITES_USEINVITESALL	"Use 'invites all' to see the total list"
+#define INVITES_NOLONGER	"No longer inviting"
 
 
 /* Messages referring to channels
  */
-#define CHAN_NOSUCH		get_language(0x900)
-#define CHAN_BADCHANMODE	get_language(0x902)
-#define CHAN_MASSDEOP		get_language(0x903)
-#define CHAN_MASSDEOP_KICK	get_language(0x904)
-#define CHAN_FORCEJOIN		get_language(0x907)
-#define CHAN_FAKEMODE		get_language(0x908)
-#define CHAN_FAKEMODE_KICK	get_language(0x909)
-#define CHAN_DESYNCMODE		get_language(0x90a)
-#define CHAN_DESYNCMODE_KICK	get_language(0x90b)
-#define CHAN_FLOOD		get_language(0x90c)
+#define CHAN_NOSUCH		"No such channel defined"
+#define CHAN_BADCHANMODE	"* Mode change on %s for nonexistant %s!"
+#define CHAN_MASSDEOP		"Mass deop on %s by %s"
+#define CHAN_MASSDEOP_KICK	"Mass deop.  Go sit in a corner."
+#define CHAN_FORCEJOIN		"Oops.   Someone made me join %s... leaving..."
+#define CHAN_FAKEMODE		"Mode change by fake op on %s!  Reversing..."
+#define CHAN_FAKEMODE_KICK	"Abusing ill-gained server ops"
+#define CHAN_DESYNCMODE		"Mode change by non-chanop on %s!  Reversing..."
+#define CHAN_DESYNCMODE_KICK	"Abusing desync"
+#define CHAN_FLOOD		"flood"
 
 /* Messages referring to ignores
  */
-#define IGN_NONE		get_language(0xa00)
-#define IGN_CURRENT		get_language(0xa01)
-#define IGN_NOLONGER		get_language(0xa02)
+#define IGN_NONE		"No ignores"
+#define IGN_CURRENT		"Currently ignorin"
+#define IGN_NOLONGER		"No longer ignoring"
 
 /* Messages referring to bots
  */
-#define BOT_NOTHERE		get_language(0xb00)
-#define BOT_NONOTES		get_language(0xb01)
-#define BOT_USERAWAY		get_language(0xb02)
-#define BOT_NOTEARRIVED		get_language(0xb07)
-#define BOT_MSGDIE		get_language(0xb18)
-#define BOT_NOSUCHUSER		get_language(0xb19)
-#define BOT_NOCHANNELS		get_language(0xb1a)
-#define BOT_PARTYMEMBS		get_language(0xb1b)
-#define BOT_BOTSCONNECTED	get_language(0xb1c)
-#define BOT_OTHERPEOPLE		get_language(0xb1d)
+#define BOT_NOTHERE		"That bot isn't here.\n"
+#define BOT_NONOTES		"That's a bot.  You can't leave notes for a bot.\n"
+#define BOT_USERAWAY		"is away"
+#define BOT_NOTEARRIVED		"Note arrived for you"
+#define BOT_MSGDIE		"Bot shut down beginning...."
+#define BOT_NOSUCHUSER		"No such user"
+#define BOT_NOCHANNELS		"no channels"
+#define BOT_PARTYMEMBS		"Party line members:"
+#define BOT_BOTSCONNECTED	"Bots connected"
+#define BOT_OTHERPEOPLE		"Other people on the bot"
 /* was: BOT_OUTDATEDWHOM - 0xb1e */
-#define BOT_LINKATTEMPT		get_language(0xb1f)
-#define BOT_NOTESTORED2		get_language(0xb20)
-#define BOT_NOTEBOXFULL		get_language(0xb21)
-#define BOT_NOTEISAWAY		get_language(0xb22)
-#define BOT_NOTESENTTO		get_language(0xb23)
-#define BOT_DISCONNECTED	get_language(0xb24)
-#define BOT_PEOPLEONCHAN	get_language(0xb25)
-#define BOT_CANTLINKTHERE	get_language(0xb26)
-#define BOT_CANTUNLINK		get_language(0xb27)
-#define BOT_LOOPDETECT		get_language(0xb28)
-#define BOT_BOGUSLINK		get_language(0xb29)
+#define BOT_LINKATTEMPT		"Attempting to link"
+#define BOT_NOTESTORED2		"Not online; note stored."
+#define BOT_NOTEBOXFULL		"Notebox is full, sorry."
+#define BOT_NOTEISAWAY		"is away; note stored."
+#define BOT_NOTESENTTO		"Note sent to"
+#define BOT_DISCONNECTED	"Disconnected from:"
+#define BOT_PEOPLEONCHAN	"People on channel"
+#define BOT_CANTLINKTHERE	"Can't link there"
+#define BOT_CANTUNLINK		"Can't unlink"
+#define BOT_LOOPDETECT		"Loop detected"
+#define BOT_BOGUSLINK		"Bogus link notice from"
 /* was: BOT_BOGUSLINK2 - 0xb2a */
-#define BOT_DISCONNLEAF		get_language(0xb2b)
-#define BOT_LINKEDTO		get_language(0xb2c)
-#define BOT_ILLEGALLINK		get_language(0xb2d)
-#define BOT_YOUREALEAF		get_language(0xb2e)
-#define BOT_REJECTING		get_language(0xb2f)
-#define BOT_OLDBOT		get_language(0xb30)
-#define BOT_TRACERESULT		get_language(0xb31)
-#define BOT_DOESNTEXIST		get_language(0xb32)
-#define BOT_NOREMOTEBOOT	get_language(0xb33)
-#define BOT_NOOWNERBOOT		get_language(0xb34)
-#define BOT_XFERREJECTED	get_language(0xb35)
+#define BOT_DISCONNLEAF		"Disconnected left"
+#define BOT_LINKEDTO		"Linked to"
+#define BOT_ILLEGALLINK		"Illegal link by leaf"
+#define BOT_YOUREALEAF		"You are supposed to be a leaf!"
+#define BOT_REJECTING		"Rejecting bot"
+#define BOT_OLDBOT		"Older bot detected (unsupported)"
+#define BOT_TRACERESULT		"Trace result"
+#define BOT_DOESNTEXIST		"doesn't exist"
+#define BOT_NOREMOTEBOOT	"Remote boots are not allowed."
+#define BOT_NOOWNERBOOT		"Can't boot the bot owner."
+#define BOT_XFERREJECTED	"FILE TRANSFER REJECTED"
 /* was: BOT_NOFILESYS - 0xb36 */
-#define BOT_BOTNETUSERS		get_language(0xb37)
-#define BOT_PARTYLINE		get_language(0xb38)
-#define BOT_LOCALCHAN		get_language(0xb39)
-#define BOT_USERSONCHAN		get_language(0xb3a)
-#define BOT_NOBOTSLINKED	get_language(0xb3b)
-#define BOT_NOTRACEINFO		get_language(0xb3c)
-#define BOT_COMPLEXTREE		get_language(0xb3d)
-#define BOT_UNLINKALL		get_language(0xb3e)
-#define BOT_KILLLINKATTEMPT	get_language(0xb3f)
-#define BOT_ENDLINKATTEMPT	get_language(0xb40)
-#define BOT_BREAKLINK		get_language(0xb41)
-#define BOT_UNLINKEDFROM	get_language(0xb42)
-#define BOT_NOTCONNECTED	get_language(0xb43)
-#define BOT_WIPEBOTTABLE	get_language(0xb44)
-#define BOT_BOTUNKNOWN		get_language(0xb45)
-#define BOT_CANTLINKMYSELF	get_language(0xb46)
-#define BOT_ALREADYLINKED	get_language(0xb47)
-#define BOT_NOTELNETADDY	get_language(0xb48)
-#define BOT_LINKING		get_language(0xb49)
-#define BOT_CANTFINDRELAYUSER	get_language(0xb4a)
-#define BOT_CANTLINKTO		get_language(0xb4b)
-#define BOT_CANTRELAYMYSELF	get_language(0xb4c)
-#define BOT_CONNECTINGTO	get_language(0xb4d)
-#define BOT_BYEINFO1		get_language(0xb4e)
-#define BOT_ABORTRELAY1		get_language(0xb4f)
-#define BOT_ABORTRELAY2		get_language(0xb50)
-#define BOT_ABORTRELAY3		get_language(0xb51)
+#define BOT_BOTNETUSERS		"Users across the botnet"
+#define BOT_PARTYLINE		"Party line"
+#define BOT_LOCALCHAN		"Local channel"
+#define BOT_USERSONCHAN		"Users on channel"
+#define BOT_NOBOTSLINKED	"No bots linked."
+#define BOT_NOTRACEINFO		"No trace info for:"
+#define BOT_COMPLEXTREE		"Tree too complex!"
+#define BOT_UNLINKALL		"Unlinking all bots..."
+#define BOT_KILLLINKATTEMPT	"Killed link attempt to"
+#define BOT_ENDLINKATTEMPT	"No longer trying to link:"
+#define BOT_BREAKLINK		"Breaking link with"
+#define BOT_UNLINKEDFROM	"Unlinked from:"
+#define BOT_NOTCONNECTED	"Not connected to that bot."
+#define BOT_WIPEBOTTABLE	"Smooshing bot tables and assocs..."
+#define BOT_BOTUNKNOWN		"is not a known bot."
+#define BOT_CANTLINKMYSELF	"Link to myself?  Oh boy, Freud would have a field day."
+#define BOT_ALREADYLINKED	"That bot is already connected up."
+#define BOT_NOTELNETADDY	"Invalid telnet address:port stored for"
+#define BOT_LINKING		"Linking to"
+#define BOT_CANTFINDRELAYUSER	"Can't find user for relay!"
+#define BOT_CANTLINKTO		"Could not link to"
+#define BOT_CANTRELAYMYSELF	"Relay to myself?  What on EARTH would be the point?!"
+#define BOT_CONNECTINGTO	"Connecting to"
+#define BOT_BYEINFO1		"(Type *BYE* on a line by itself to abort.)"
+#define BOT_ABORTRELAY1		"Aborting relay attempt to"
+#define BOT_ABORTRELAY2		"You are now back on"
+#define BOT_ABORTRELAY3		"Relay aborted:"
 /* was: BOT_PARTYJOINED - 0xb52 */
-#define BOT_LOSTDCCUSER		get_language(0xb53)
-#define BOT_DROPPINGRELAY	get_language(0xb54)
-#define BOT_RELAYSUCCESS	get_language(0xb55)
-#define BOT_BYEINFO2		get_language(0xb56)
-#define BOT_RELAYLINK		get_language(0xb57)
-#define BOT_PARTYLEFT		get_language(0xb58)
-#define BOT_ENDRELAY1		get_language(0xb59)
-#define BOT_ENDRELAY2		get_language(0xb5a)
-#define BOT_PARTYREJOINED	get_language(0xb5b)
-#define BOT_DROPPEDRELAY	get_language(0xb5c)
-#define BOT_BREAKRELAY		get_language(0xb5d)
-#define BOT_RELAYBROKEN		get_language(0xb5e)
-#define BOT_PINGTIMEOUT		get_language(0xb5f)
-#define BOT_BOTNOTLEAFLIKE	get_language(0xb60)
-#define BOT_BOTDROPPED		get_language(0xb61)
-#define BOT_ALREADYLINKING	get_language(0xb62)
+#define BOT_LOSTDCCUSER		"Lost dcc connection to"
+#define BOT_DROPPINGRELAY	"Dropping relay attempt to"
+#define BOT_RELAYSUCCESS	"Success!\n\nNOW CONNECTED TO RELAY BOT"
+#define BOT_BYEINFO2		"(You can type *BYE* to prematurely close the connection.)"
+#define BOT_RELAYLINK		"Relay link:"
+#define BOT_PARTYLEFT		"left the party line."
+#define BOT_ENDRELAY1		"Ended relay link"
+#define BOT_ENDRELAY2		"RELAY CONNECTION DROPPED.\nYou are now back on"
+#define BOT_PARTYREJOINED	"rejoined the party line."
+#define BOT_DROPPEDRELAY	"Dropping relay link to"
+#define BOT_BREAKRELAY		"Breaking connection to"
+#define BOT_RELAYBROKEN		"Relay broken"
+#define BOT_PINGTIMEOUT		"Ping timeout"
+#define BOT_BOTNOTLEAFLIKE	"unleaflike behavior"
+#define BOT_BOTDROPPED		"Dropped bot"
+#define BOT_ALREADYLINKING	"Already linking to that bot."
 
 /* Messages pertaining to MODULES
  */
-#define MOD_ALREADYLOAD		get_language(0x200)
-#define MOD_BADCWD		get_language(0x201)
-#define MOD_NOSTARTDEF		get_language(0x202)
-#define MOD_NEEDED		get_language(0x204)
-#define MOD_NOCLOSEDEF		get_language(0x205)
-#define MOD_UNLOADED		get_language(0x206)
-#define MOD_NOSUCH		get_language(0x207)
+#define MOD_ALREADYLOAD		"Already loaded."
+#define MOD_BADCWD		"Can't determine current directory"
+#define MOD_NOSTARTDEF		"No start function defined"
+#define MOD_NEEDED		"Needed by another module"
+#define MOD_NOCLOSEDEF		"No close function"
+#define MOD_UNLOADED		"Module unloaded:"
+#define MOD_NOSUCH		"No such module"
 /* was: MOD_NOINFO - 0x208 */
-#define MOD_LOADERROR		get_language(0x209)
-#define MOD_UNLOADERROR		get_language(0x20a)
-#define MOD_CANTLOADMOD		get_language(0x20b)
-#define MOD_STAGNANT		get_language(0x20c)
-#define MOD_NOCRYPT		get_language(0x20d)
-#define MOD_NOFILESYSMOD	get_language(0x20e)
-#define MOD_LOADED_WITH_LANG	get_language(0x20f)
-#define MOD_LOADED		get_language(0x210)
+#define MOD_LOADERROR		"Error loading module:"
+#define MOD_UNLOADERROR		"Error unloading module:"
+#define MOD_CANTLOADMOD		"Can't load modules"
+#define MOD_STAGNANT		"Stagnant module; there WILL be memory leaks!"
+#define MOD_NOCRYPT		"You have installed modules but have not selected an encryption\nmodule, please consult the default config file for info.\n"
+#define MOD_NOFILESYSMOD	"Filesys module not loaded."
+#define MOD_LOADED_WITH_LANG	"Module loaded: %-16s (with lang support)"
+#define MOD_LOADED		"Module loaded: %-16s"
 
-#define DCC_NOSTRANGERS		get_language(0xc00)
-#define DCC_REFUSED		get_language(0xc01)
-#define DCC_REFUSED2		get_language(0xc02)
-#define DCC_REFUSED3		get_language(0xc03)
-#define DCC_REFUSED4		get_language(0xc04)
-#define DCC_REFUSED5		get_language(0xc05)
+
+#define DCC_NOSTRANGERS		"I don't accept DCC chats from strangers."
+#define DCC_REFUSED		"Refused DCC chat (no access)"
+#define DCC_REFUSED2		"No access"
+#define DCC_REFUSED3		"You must have a password set."
+#define DCC_REFUSED4		"Refused DCC chat (no password)"
+#define DCC_REFUSED5		"Refused DCC chat (+x but no file area)"
 /* was: DCC_REFUSED6 - 0xc06 */
-#define DCC_REFUSED7		get_language(0xc21)
-#define DCC_TOOMANY		get_language(0xc07)
+#define DCC_REFUSED7		"Refused DCC chat (invalid port)"
+#define DCC_TOOMANY		"Too many people are in the file area right now."
 /* was: DCC_TRYLATER - 0xc08 */
 /* was: DCC_REFUSEDTAND - 0xc09 */
 /* was: DCC_NOSTRANGERFILES1 - 0xc0a */
 /* was: DCC_NOSTRANGERFILES2 - 0xc0b */
-#define DCC_TOOMANYDCCS1	get_language(0xc0c)
-#define DCC_TOOMANYDCCS2	get_language(0xc0d)
+#define DCC_TOOMANYDCCS1	"Sorry, too many DCC connections."
+#define DCC_TOOMANYDCCS2	"DCC connections full: %s %s (%s!%s)"
 /* was: DCC_DCCNOTSUPPORTED - 0xc0e */
 /* was: DCC_REFUSEDNODCC - 0xc0f */
 /* was: DCC_FILENAMEBADSLASH - 0xc10 */
@@ -435,15 +409,15 @@
 /* was: DCC_REFUSEDNODCC3 - 0xc16 */
 /* was: DCC_FILETOOLARGE - 0xc17 */
 /* was: DCC_FILETOOLARGE2 - 0xc18 */
-#define DCC_CONNECTFAILED1	get_language(0xc19)
-#define DCC_CONNECTFAILED2	get_language(0xc1a)
-#define DCC_CONNECTFAILED3	get_language(0xc22)
+#define DCC_CONNECTFAILED1	"Failed to connect"
+#define DCC_CONNECTFAILED2	"DCC connection failed"
+#define DCC_CONNECTFAILED3	"DCC invalid port"
 /* was: DCC_FILESYSBROKEN - 0xc1b */
-#define DCC_ENTERPASS		get_language(0xc1c)
-#define DCC_FLOODBOOT		get_language(0xc1d)
-#define DCC_BOOTED1		get_language(0xc1e)
-#define DCC_BOOTED2		get_language(0xc1f)
-#define DCC_BOOTED3		get_language(0xc20)
+#define DCC_ENTERPASS		"Enter your password"
+#define DCC_FLOODBOOT		"%s has been forcibly removed for flooding.\n"
+#define DCC_BOOTED1		"-=- poof -=-\n"
+#define DCC_BOOTED2		"You've been booted from the %s by %s%s%s\n"
+#define DCC_BOOTED3		"%s booted %s from the party line%s%s"
 
 /* Stuff from chan.c
  */
@@ -451,60 +425,57 @@
 
 /* BOTNET messages
  */
-#define NET_FAKEREJECT		get_language(0xe00)
-#define NET_LINKEDTO		get_language(0xe01)
-#define NET_WRONGBOT		get_language(0xe02)
-#define NET_LEFTTHE		get_language(0xe03)
-#define NET_JOINEDTHE		get_language(0xe04)
-#define NET_AWAY		get_language(0xe05)
-#define NET_UNAWAY		get_language(0xe06)
-#define NET_NICKCHANGE		get_language(0xe07)
+#define NET_FAKEREJECT		"Fake message rejected"
+#define NET_LINKEDTO		"Linked to"
+#define NET_WRONGBOT		"Wrong bot--wanted %s, got %s"
+#define NET_LEFTTHE		"has left the"
+#define NET_JOINEDTHE		"has joined the"
+#define NET_AWAY		"is now away"
+#define NET_UNAWAY		"is no longer away"
+#define NET_NICKCHANGE		"Nick Change:"
 
 /* Stuff from dcc.c
  */
-#define DCC_REJECT		get_language(0xe08)
-#define DCC_LINKED		get_language(0xe09)
-#define DCC_LINKFAIL		get_language(0xe0a)
-#define DCC_BADPASS		get_language(0xe0b)
-#define DCC_PASSREQ		get_language(0xe0c)
-#define DCC_LINKERROR		get_language(0xe0d)
-#define DCC_LOSTBOT		get_language(0xe0e)
-#define DCC_TIMEOUT		get_language(0xe0f)
-#define DCC_LOGGEDIN		get_language(0xe10)
-#define DCC_BADLOGIN		get_language(0xe11)
-#define DCC_HOUSTON		get_language(0xe12)
-#define DCC_JOIN		get_language(0xe13)
-#define DCC_LOSTDCC		get_language(0xe14)
-#define DCC_PWDTIMEOUT		get_language(0xe15)
-#define DCC_CLOSED		get_language(0xe16)
-#define DCC_FAILED		get_language(0xe17)
-#define DCC_BADSRC		get_language(0xe18)
+#define DCC_REJECT		"Rejecting link from %s"
+#define DCC_LINKED		"Linked to %s."
+#define DCC_LINKFAIL		"Failed link to %s."
+#define DCC_BADPASS		"Bad password on connect attempt to %s."
+#define DCC_PASSREQ		"Password required for connection to %s."
+#define DCC_LINKERROR		"ERROR linking %s: %s"
+#define DCC_LOSTBOT		"Lost Bot: %s"
+#define DCC_TIMEOUT		"Timeout: bot link to %s at %s:%d"
+#define DCC_LOGGEDIN		"Logged in: %s (%s/%d)"
+#define DCC_BADLOGIN		"Bad Password: [%s]%s/%d"
+#define DCC_BADAUTH		"Bad Auth: [%s]%s/%d"
+#define DCC_HOUSTON		"Negative on that, Houston.\n"
+#define DCC_JOIN		"*** %s has joined the party line.\n"
+#define DCC_LOSTDCC		"Lost dcc connection to %s (%s/%d)"
+#define DCC_PWDTIMEOUT		"Password timeout on dcc chat: [%s]%s"
+#define DCC_SPWDTIMEOUT		"Auth timeout on dcc chat: [%s]%s"
+#define DCC_CLOSED		"DCC connection closed (%s!%s)"
+#define DCC_FAILED		"Failed TELNET incoming (%s)"
+#define DCC_BADSRC		"Refused %s/%d (bad src port)"
 /* was: DCC_BADIP 0xe19 */
-#define DCC_BADHOST		get_language(0xe1a)
-#define DCC_TELCONN		get_language(0xe1b)
-#define DCC_IDENTFAIL		get_language(0xe1c)
-#define DCC_PORTDIE		get_language(0xe1d)
-#define DCC_BADNICK		get_language(0xe1e)
-#define DCC_NONBOT		get_language(0xe1f)
-#define DCC_NONUSER		get_language(0xe20)
-#define DCC_INVHANDLE		get_language(0xe21)
-#define DCC_DUPLICATE		get_language(0xe22)
-#define DCC_NOPASS		get_language(0xe23)
-#define DCC_LOSTCON		get_language(0xe24)
-#define DCC_TTIMEOUT		get_language(0xe25)
-#define DCC_INSTCOMPL		get_language(0xe26)
-#define DCC_NEWUSER		get_language(0xe27)
-#define DCC_LOSTNEWUSER		get_language(0xe28)
-#define DCC_LOSTNEWUSR2		get_language(0xe29)
-#define DCC_TIMEOUTUSER		get_language(0xe2a)
-#define DCC_TIMEOUTUSR2		get_language(0xe2b)
-#define DCC_TCLERROR		get_language(0xe2c)
-#define DCC_DEADSOCKET		get_language(0xe2d)
-#define DCC_LOSTCONN		get_language(0xe2e)
-#define DCC_EOFIDENT		get_language(0xe2f)
-#define DCC_LOSTIDENT		get_language(0xe30)
-#define DCC_NOACCESS		get_language(0xe31)
-#define DCC_MYBOTNETNICK	get_language(0xe32)
-#define DCC_LOSTDUP		get_language(0xe33)
+
+#define DCC_BADHOST		"Refused %s (bad hostname)"
+#define DCC_TELCONN		"Telnet connection: %s/%d"
+#define DCC_IDENTFAIL		"Ident failed for %s: %s"
+#define DCC_PORTDIE		"(!) Listening port %d abruptly died."
+#define DCC_BADNICK		"Refused %s (bad nick)"
+#define DCC_NONBOT		"Refused %s (non-bot)"
+#define DCC_NONUSER		"Refused %s (non-user)"
+#define DCC_INVHANDLE		"Refused %s (invalid handle: %s)"
+#define DCC_DUPLICATE		"Refused telnet connection from %s (duplicate)"
+#define DCC_NOPASS		"Refused [%s]%s (no password)"
+#define DCC_LOSTCON		"Lost telnet connection to %s/%d"
+#define DCC_TTIMEOUT		"Ident timeout on telnet: %s"
+#define DCC_TCLERROR		"Tcl error [%s]: %s"
+#define DCC_DEADSOCKET		"*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED"
+#define DCC_LOSTCONN		"Lost connection while identing [%s/%d]"
+#define DCC_EOFIDENT		"Timeout/EOF ident connection"
+#define DCC_LOSTIDENT		"Lost ident wait telnet socket!!"
+#define DCC_NOACCESS		"Denied telnet: %s, No Access"
+#define DCC_MYBOTNETNICK	"Refused telnet connection from %s (tried using my botnetnick)"
+#define DCC_LOSTDUP		"Lost telnet connection from %s while checking for duplicate"
 
 #endif				/* _EGG_LANG_H */

+ 3 - 350
src/language.c

@@ -2,25 +2,6 @@
  * language.c -- handles:
  *   language support code
  *
- * $Id: language.c,v 1.17 2002/01/16 03:24:17 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 /*
@@ -89,17 +70,13 @@ static lang_tab	*langtab[64];
 static lang_sec	*langsection = NULL;
 static lang_pri	*langpriority = NULL;
 
-static int del_lang(char *);
 static int add_message(int, char *);
-static void recheck_lang_sections(void);
 static void read_lang(char *);
 void add_lang_section(char *);
 int del_lang_section(char *);
 int exist_lang_section(char *);
 static char *get_specific_langfile(char *, lang_sec *);
 static char *get_langfile(lang_sec *);
-static int split_lang(char *, char **, char **);
-int cmd_loadlanguage(struct userrec *, int, char *);
 
 
 /* Add a new preferred language to the list of languages. Newly added
@@ -137,32 +114,6 @@ void add_lang(char *lang)
   debug1("LANG: Language loaded: %s", lang);
 }
 
-/* Remove a language from the list of preferred languages.
- */
-static int del_lang(char *lang)
-{
-  lang_pri *lp = langpriority, *lpo = NULL;
-
-  while (lp) {
-    /* Found the language? */
-    if (!strcmp(lang, lp->lang)) {
-      if (lpo)
-	lpo->next = lp->next;
-      else
-        langpriority = lp->next;
-      if (lp->lang)
-        nfree(lp->lang);
-      nfree(lp);
-      debug1("LANG: Language unloaded: %s", lang);
-      return 1;
-    }
-    lpo = lp;
-    lp = lp->next;
-  }
-  /* Language not found */
-  return 0;
-}
-
 static int add_message(int lidx, char *ltext)
 {
   lang_tab *l = langtab[lidx & 63];
@@ -190,24 +141,6 @@ static int add_message(int lidx, char *ltext)
   return 0;
 }
 
-/* Recheck all sections and check if any language files are available
- * which match the preferred language(s) more closely
- */
-static void recheck_lang_sections(void)
-{
-  lang_sec *ls;
-  char *langfile;
-
-  for (ls = langsection; ls && ls->section; ls = ls->next) {
-      langfile = get_langfile(ls);
-      /* Found a language with a more preferred language? */
-      if (langfile) {
-        read_lang(langfile);
-        nfree(langfile);
-      }
-    }
-}
-
 /* Parse a language file
  */
 static void read_lang(char *langfile)
@@ -344,9 +277,8 @@ void add_lang_section(char *section)
   /* Now overwrite base language with a more preferred one */
   langfile = get_langfile(ls);
   if (!langfile) {
-    if (!ok)
-      putlog(LOG_MISC, "*", "LANG: No lang files found for section %s.",
-	     section);
+//    if (!ok)
+//      putlog(LOG_MISC, "*", "LANG: No lang files found for section %s.",section);
     return;
   }
   read_lang(langfile);
@@ -418,139 +350,6 @@ static char *get_langfile(lang_sec *sec)
   return NULL;
 }
 
-/* Split up a string /path/<section>.<language>.lang into the
- * needed information for the new language system.
- * Only needed for compability functions.
- */
-static int split_lang(char *par, char **lang, char **section)
-{
-  char *p;
-
-  p = strrchr(par, '/');
-  /* path attached? */
-  if (p)
-    *section = p + 1;
-  else
-    *section = par;
-  p = strchr(*section, '.');
-  if (p)
-    p[0] = 0;
-  else
-    return 0;
-  *lang = p + 1;
-  p = strstr(*lang, ".lang");
-  if (p)
-    p[0] = 0;
-  return 1;
-}
-
-/* Compability function to allow users/modules to use the old command.
- */
-int cmd_loadlanguage(struct userrec *u, int idx, char *par)
-{
-  char *section, *lang, *buf;
-
-  dprintf(idx, "Note: This command is obsoleted by +lang.\n");
-  if (!par || !par[0]) {
-    dprintf(idx, "Usage: language <section>.<language>\n");
-    return 0;
-  }
-  if (idx != DP_LOG)
-    putlog(LOG_CMDS, "*", "#%s# language %s", dcc[idx].nick, par);
-  buf = nmalloc(strlen(par)+1);
-  strcpy(buf, par);
-  if (!split_lang(buf, &lang, &section)) {
-    nfree(buf);
-    dprintf(idx, "Invalid parameter %s.\n", par);
-    return 0;
-  }
-  add_lang(lang);
-  add_lang_section(section);
-  nfree(buf);
-  recheck_lang_sections();
-  return 0;
-}
-
-static int cmd_plslang(struct userrec *u, int idx, char *par)
-{
-  if (!par || !par[0]) {
-    dprintf(idx, "Usage: +lang <language>\n");
-    return 0;
-  }
-  putlog(LOG_CMDS, "*", "#%s# +lang %s", dcc[idx].nick, par);
-  add_lang(par);
-  recheck_lang_sections();
-  return 0;
-}
-
-static int cmd_mnslang(struct userrec *u, int idx, char *par)
-{
-  if (!par || !par[0]) {
-    dprintf(idx, "Usage: -lang <language>\n");
-    return 0;
-  }
-  putlog(LOG_CMDS, "*", "#%s# -lang %s", dcc[idx].nick, par);
-  if (!del_lang(par))
-    dprintf(idx, "Language %s not found.\n", par);
-  else
-    recheck_lang_sections();
-  return 0;
-}
-
-static int cmd_plslsec(struct userrec *u, int idx, char *par)
-{
-  if (!par || !par[0]) {
-    dprintf(idx, "Usage: +lsec <section>\n");
-    return 0;
-  }
-  putlog(LOG_CMDS, "*", "#%s# +lsec %s", dcc[idx].nick, par);
-  add_lang_section(par);
-  return 0;
-}
-
-static int cmd_mnslsec(struct userrec *u, int idx, char *par)
-{
-  if (!par || !par[0]) {
-    dprintf(idx, "Usage: -lsec <section>\n");
-    return 0;
-  }
-  putlog(LOG_CMDS, "*", "#%s# -lsec %s", dcc[idx].nick, par);
-  if (!del_lang_section(par))
-    dprintf(idx, "Section %s not found.\n", par);
-  return 0;
-}
-
-static int cmd_relang(struct userrec *u, int idx, char *par)
-{
-  dprintf(idx, "Rechecking language sections...\n");
-  recheck_lang_sections();
-  return 0;
-}
-
-static int cmd_languagedump(struct userrec *u, int idx, char *par)
-{
-  lang_tab *l;
-  char ltext2[512];
-  int idx2, i;
-
-  putlog(LOG_CMDS, "*", "#%s# ldump %s", dcc[idx].nick, par);
-  if (par[0]) {
-    /* atoi (hence strtol) don't work right here for hex */
-    if (strlen(par) > 2 && par[0] == '0' && par[1] == 'x')
-      sscanf(par, "%x", &idx2);
-    else
-      idx2 = (int) strtol(par, (char **) NULL, 10);
-    strcpy(ltext2, get_language(idx2));
-    dprintf(idx, "0x%x: %s\n", idx2, ltext2);
-    return 0;
-  }
-  dprintf(idx, " LANGIDX TEXT\n");
-  for (i = 0; i < 64; i++)
-    for (l = langtab[i]; l; l = l->next)
-      dprintf(idx, "0x%x   %s\n", l->idx, l->text);
-  return 0;
-}
-
 static char text[512];
 char *get_language(int idx)
 {
@@ -592,149 +391,6 @@ int expmem_language()
   return size;
 }
 
-/* A report on the module status - only for debugging purposes
- */
-static int cmd_languagestatus(struct userrec *u, int idx, char *par)
-{
-  int ltexts = 0;
-  register int i, c, maxdepth = 0, used = 0, empty = 0;
-  lang_tab *l;
-  lang_sec *ls = langsection;
-  lang_pri *lp = langpriority;
-
-  putlog(LOG_CMDS, "*", "#%s# lstat %s", dcc[idx].nick, par);
-  for (i = 0; i < 64; i++) {
-    c = 0;
-    for (l = langtab[i]; l; l = l->next)
-      c++;
-    if (c > maxdepth)
-      maxdepth = c;
-    if (c)
-      used++;
-    else
-      empty++;
-    ltexts += c;
-  }
-  dprintf(idx, "Language code report:\n");
-  dprintf(idx, "   Table size   : %d bytes\n", expmem_language());
-  dprintf(idx, "   Text messages: %d\n", ltexts);
-  dprintf(idx, "   %d used, %d unused, maxdepth %d, avg %f\n",
-	  used, empty, maxdepth, (float) ltexts / 64.0);
-  if (lp) {
-    int c = 0;
-
-    dprintf(idx, "   Supported languages:");
-    for (; lp; lp = lp->next) {  
-      dprintf(idx, "%s %s", c ? "," : "", lp->lang);
-      c = 1;
-    }
-    dprintf(idx, "\n");
-  }
-  if (ls) {
-    dprintf(idx, "\n   SECTION              LANG\n");
-    dprintf(idx, "   ==============================\n");
-    for (; ls; ls = ls->next)
-      dprintf(idx, "   %-20s %s\n", ls->section,
-	      ls->lang ? ls->lang : "<none>");
-  }
-  return 0;
-}
-
-/* Compability function to allow scripts to use the old command.
- */
-static int tcl_language STDVAR
-{
-  char *lang, *section, *buf;
-
-  putlog(LOG_MISC, "*", "The Tcl command 'language' is obsolete. Use 'addlang' instead.");
-  BADARGS(2, 2, " language");
-
-  buf = nmalloc(strlen(argv[1])+1);
-  strcpy(buf, argv[1]);
-  if (!split_lang(buf, &lang, &section)) {
-    Tcl_AppendResult(irp, "Invalid parameter", NULL);
-    nfree(buf);
-    return TCL_ERROR;
-  }
-  add_lang(lang);
-  add_lang_section(section);
-  nfree(buf);
-  recheck_lang_sections();
-  return TCL_OK;
-}
-
-static int tcl_plslang STDVAR
-{
-  BADARGS(2, 2, " language");
-
-  add_lang(argv[1]);
-  recheck_lang_sections();
-
-  return TCL_OK;
-}
-
-static int tcl_mnslang STDVAR
-{
-  BADARGS(2, 2, " language");
-
-  if (!del_lang(argv[1])) {
-    Tcl_AppendResult(irp, "Language not found.", NULL);
-    return TCL_ERROR;
-  }
-  recheck_lang_sections();
-
-  return TCL_OK;
-}
-
-static int tcl_addlangsection STDVAR
-{
-  BADARGS(2, 2, " section");
-
-  add_lang_section(argv[1]);
-  return TCL_OK;
-}
-
-static int tcl_dellangsection STDVAR
-{
-  BADARGS(2, 2, " section");
-
-  if (!del_lang_section(argv[1])) {
-    Tcl_AppendResult(irp, "Section not found", NULL);
-    return TCL_ERROR;
-  }
-  return TCL_OK;
-}
-
-static int tcl_relang STDVAR
-{
-  recheck_lang_sections();
-  return TCL_OK;
-}
-
-static cmd_t langdcc[] =
-{
-  {"language",	"n",	cmd_loadlanguage,	NULL},
-  {"+lang",	"n",	cmd_plslang,		NULL},
-  {"-lang",	"n",	cmd_mnslang,		NULL},
-  {"+lsec",	"n",	cmd_plslsec,		NULL},
-  {"-lsec",	"n",	cmd_mnslsec,		NULL},
-  {"ldump",	"n",	cmd_languagedump,	NULL},
-  {"lstat",	"n",	cmd_languagestatus,	NULL},
-  {"relang",	"n",	cmd_relang,		NULL},
-  {NULL,	NULL,	NULL,			NULL}
-};
-
-static tcl_cmds langtcls[] =
-{
-  {"language",		tcl_language},
-  {"addlang",		tcl_plslang},
-  {"dellang",		tcl_mnslang},
-  {"addlangsection",	tcl_addlangsection},
-  {"dellangsection",	tcl_dellangsection},
-  {"relang",		tcl_relang},
-  {NULL,		NULL}
-};
-
 void init_language(int flag)
 {
   int i;
@@ -752,8 +408,5 @@ void init_language(int flag)
     if (deflang)
       add_lang(deflang);
     add_lang_section("core");
-  } else {
-    add_tcl_commands(langtcls);
-    add_builtins(H_dcc, langdcc);
-  }
+  } 
 }

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 806 - 122
src/main.c


+ 40 - 21
src/main.h

@@ -2,36 +2,47 @@
  * main.h
  *   include file to include most other include files
  *
- * $Id: main.h,v 1.19 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MAIN_H
 #define _EGG_MAIN_H
 
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
+#include "lush.h" /* We seem to need this everywhere... */
+
+#if (((TCL_MAJOR_VERSION == 7) && (TCL_MINOR_VERSION >= 5)) || (TCL_MAJOR_VERSION > 7))
+#  define USE_TCL_EVENTS
+#  define USE_TCL_FINDEXEC
+#  define USE_TCL_PACKAGE
+#  define USE_TCL_VARARGS
+#endif
+
+#if (TCL_MAJOR_VERSION >= 8)
+#  define USE_TCL_OBJ
+#endif
+
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1)) || (TCL_MAJOR_VERSION > 8))
+#  define USE_TCL_BYTE_ARRAYS
+#  define USE_TCL_ENCODING
+#endif
+
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
+#  ifdef CONST
+#    define EGG_CONST CONST
+#  else
+#    define EGG_CONST
+#  endif
+#else
+#  define EGG_CONST
+#endif
+
+
 /* UGH! Why couldn't Tcl pick a standard? */
-#if !defined(HAVE_PRE7_5_TCL) && defined(__STDC__)
+#if defined(USE_TCL_VARARGS) && (defined(__STDC__) || defined(HAS_STDARG))
 #  ifdef HAVE_STDARG_H
 #    include <stdarg.h>
 #  else
@@ -60,6 +71,7 @@
 #include "lang.h"
 #include "eggdrop.h"
 #include "flags.h"
+
 #ifndef MAKING_MODS
 #  include "proto.h"
 #endif
@@ -109,8 +121,15 @@ extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_LOST, DCC_SCRIPT, DCC_BOT_NEW,
 
 /* For net.c */
 #  define O_NONBLOCK	00000004    /* POSIX non-blocking I/O		   */
-
 #endif				/* BORGUBES */
 
+#define strncpy0(a,b,c) { strncpy(a, b, c-1); (a)[c-1]=0; }
+
+#ifdef strncpy
+#undef strncpy
+#endif
+
+
+#include "md5/md5.h"
 
 #endif				/* _EGG_MAIN_H */

+ 99 - 239
src/match.c

@@ -1,11 +1,8 @@
-/* 
+/*
  * match.c
  *   wildcard matching functions
- *   (rename to reg.c for ircII)
- * 
- * $Id: match.c,v 1.5 2000/01/30 19:26:20 fabian Exp $
- */
-/* 
+ *
+ *
  * Once this code was working, I added support for % so that I could
  * use the same code both in Eggdrop and in my IrcII client.
  * Pleased with this, I added the option of a fourth wildcard, ~,
@@ -22,300 +19,163 @@
  *     crf@cfox.bchs.uh.edu
  * 
  * I hereby release this code into the public domain
- * 
- */
-
-/* 
- * This will get us around most of the mess and replace the chunk that
- * was removed from the middle of this file.   --+ Dagmar
- */
-/* 
- * You'll also want to grab the rfc1459.c file or change all rfc_*()
- * calls to the standard library call to make this work with ircII
- * derivatives now.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-/* Remove the next line to use this in IrcII */
-#define EGGDROP
-
-/* 
- * Best to leave stuff after this point alone, but go on and change
- * it if you're adventurous...
- */
-
-/* The quoting character -- what overrides wildcards (do not undef) */
-#define QUOTE '\\'
-
-/* The "matches ANYTHING" wildcard (do not undef) */
-#define WILDS '*'
-
-/* The "matches ANY NUMBER OF NON-SPACE CHARS" wildcard (do not undef) */
-#define WILDP '%'
-
-/* The "matches EXACTLY ONE CHARACTER" wildcard (do not undef) */
-#define WILDQ '?'
-
-/* The "matches AT LEAST ONE SPACE" wildcard (undef me to disable!) */
-#define WILDT '~'
-
-/* 
- * This makes sure WILDT doesn't get used in in the IrcII version of
- * this code.  If ya wanna live dangerously, you can remove these 3
- * lines, but WARNING: IT WOULD MAKE THIS CODE INCOMPATIBLE WITH THE
- * CURRENT reg.c OF IrcII!!!  Support for ~ is NOT in the reg.c of
- * IrcII, and adding it may cause compatibility problems, especially
- * in scripts.  If you don't think you have to worry about that, go
- * for it!
- */
-#ifndef EGGDROP
-#undef WILDT
-#endif
-
-/* 
- * If you edit below this line and it stops working, don't even THINK
- * about whining to *ME* about it!
+ *
  */
+#include "main.h"
 
-/* 
- * No problem, you got it wrong anyway, Chris.  You should have gone to
- * uppercase instead of lowercase.  (A really minor mistake)
- */
+#define QUOTE '\\' /* quoting character (overrides wildcards) */
+#define WILDS '*'  /* matches 0 or more characters (including spaces) */
+#define WILDP '%'  /* matches 0 or more non-space characters */
+#define WILDQ '?'  /* matches ecactly one character */
+#define WILDT '~'  /* matches 1 or more spaces */
 
-/* Changing these is probably counter-productive :) */
-#define MATCH (match+saved+sofar)
 #define NOMATCH 0
+#define MATCH (match+sofar)
+#define PERMATCH (match+saved+sofar)
 
-/* 
- * EGGDROP:   wild_match_per(char *m, char *n)
- * IrcII:     wild_match(char *m, char *n)
- * 
- * Features:  Forward, case-insensitive, ?, *, %, ~(optional)
- * Best use:  Generic string matching, such as in IrcII-esque bindings
- */
-#ifdef EGGDROP
-static int wild_match_per(register unsigned char *m, register unsigned char *n)
-#else
-int wild_match(register unsigned char *m, register unsigned char *n)
-#endif
+int _wild_match_per(register unsigned char *m, register unsigned char *n)
 {
   unsigned char *ma = m, *lsm = 0, *lsn = 0, *lpm = 0, *lpn = 0;
-  int match = 1, saved = 0;
+  int match = 1, saved = 0, space;
   register unsigned int sofar = 0;
 
-#ifdef WILDT
-  int space;
-#endif
-
-  /* take care of null strings (should never match) */
+  /* null strings should never match */
   if ((m == 0) || (n == 0) || (!*n))
     return NOMATCH;
-  /* (!*m) test used to be here, too, but I got rid of it.  After all,
-   * If (!*n) was false, there must be a character in the name (the
-   * second string), so if the mask is empty it is a non-match.  Since
-   * the algorithm handles this correctly without testing for it here
-   * and this shouldn't be called with null masks anyway, it should be
-   * a bit faster this way */
 
   while (*n) {
-    /* Used to test for (!*m) here, but this scheme seems to work better */
-#ifdef WILDT
-    if (*m == WILDT) {		/* Match >=1 space */
-      space = 0;		/* Don't need any spaces */
+    if (*m == WILDT) {          /* Match >=1 space */
+      space = 0;                /* Don't need any spaces */
       do {
-	m++;
-	space++;
-      }				/* Tally 1 more space ... */
-      while ((*m == WILDT) || (*m == ' '));	/*  for each space or ~ */
-      sofar += space;		/* Each counts as exact */
+        m++;
+        space++;
+      }                         /* Tally 1 more space ... */
+      while ((*m == WILDT) || (*m == ' '));     /*  for each space or ~ */
+      sofar += space;           /* Each counts as exact */
       while (*n == ' ') {
-	n++;
-	space--;
-      }				/* Do we have enough? */
+        n++;
+        space--;
+      }                         /* Do we have enough? */
       if (space <= 0)
-	continue;		/* Had enough spaces! */
+        continue;               /* Had enough spaces! */
     }
     /* Do the fallback       */
     else {
-#endif
       switch (*m) {
       case 0:
-	do
-	  m--;			/* Search backwards */
-	while ((m > ma) && (*m == '?'));	/* For first non-? char */
-	if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
-	  return MATCH;		/* nonquoted * = match */
-	break;
+        do
+          m--;                  /* Search backwards */
+        while ((m > ma) && (*m == '?'));        /* For first non-? char */
+        if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
+          return PERMATCH;      /* nonquoted * = match */
+        break;
       case WILDP:
-	while (*(++m) == WILDP);	/* Zap redundant %s */
-	if (*m != WILDS) {	/* Don't both if next=* */
-	  if (*n != ' ') {	/* WILDS can't match ' ' */
-	    lpm = m;
-	    lpn = n;		/* Save '%' fallback spot */
-	    saved += sofar;
-	    sofar = 0;		/* And save tally count */
-	  }
-	  continue;		/* Done with '%' */
-	}
-	/* FALL THROUGH */
+        while (*(++m) == WILDP);        /* Zap redundant %s */
+        if (*m != WILDS) {      /* Don't both if next=* */
+          if (*n != ' ') {      /* WILDS can't match ' ' */
+            lpm = m;
+            lpn = n;            /* Save '%' fallback spot */
+            saved += sofar;
+            sofar = 0;          /* And save tally count */
+          }
+          continue;             /* Done with '%' */
+        }
+        /* FALL THROUGH */
       case WILDS:
-	do
-	  m++;			/* Zap redundant wilds */
-	while ((*m == WILDS) || (*m == WILDP));
-	lsm = m;
-	lsn = n;
-	lpm = 0;		/* Save '*' fallback spot */
-	match += (saved + sofar);	/* Save tally count */
-	saved = sofar = 0;
-	continue;		/* Done with '*' */
+        do
+          m++;                  /* Zap redundant wilds */
+        while ((*m == WILDS) || (*m == WILDP));
+        lsm = m;
+        lsn = n;
+        lpm = 0;                /* Save '*' fallback spot */
+        match += (saved + sofar);       /* Save tally count */
+        saved = sofar = 0;
+        continue;               /* Done with '*' */
       case WILDQ:
-	m++;
-	n++;
-	continue;		/* Match one char */
+        m++;
+        n++;
+        continue;               /* Match one char */
       case QUOTE:
-	m++;			/* Handle quoting */
+        m++;                    /* Handle quoting */
       }
-      if (rfc_toupper(*m) == rfc_toupper(*n)) {		/* If matching */
-	m++;
-	n++;
-	sofar++;
-	continue;		/* Tally the match */
+      if (rfc_toupper(*m) == rfc_toupper(*n)) { /* If matching */
+        m++;
+        n++;
+        sofar++;
+        continue;               /* Tally the match */
       }
 #ifdef WILDT
     }
 #endif
-    if (lpm) {			/* Try to fallback on '%' */
+    if (lpm) {                  /* Try to fallback on '%' */
       n = ++lpn;
       m = lpm;
-      sofar = 0;		/* Restore position */
+      sofar = 0;                /* Restore position */
       if ((*n | 32) == 32)
-	lpm = 0;		/* Can't match 0 or ' ' */
-      continue;			/* Next char, please */
+        lpm = 0;                /* Can't match 0 or ' ' */
+      continue;                 /* Next char, please */
     }
-    if (lsm) {			/* Try to fallback on '*' */
+    if (lsm) {                  /* Try to fallback on '*' */
       n = ++lsn;
-      m = lsm;			/* Restore position */
-      /* Used to test for (!*n) here but it wasn't necessary so it's gone */
+      m = lsm;                  /* Restore position */
       saved = sofar = 0;
-      continue;			/* Next char, please */
+      continue;                 /* Next char, please */
     }
-    return NOMATCH;		/* No fallbacks=No match */
+    return NOMATCH;             /* No fallbacks=No match */
   }
   while ((*m == WILDS) || (*m == WILDP))
-    m++;			/* Zap leftover %s & *s */
-  return (*m) ? NOMATCH : MATCH;	/* End of both = match */
-}
-
-#ifndef EGGDROP
-
-/* For IrcII compatibility */
-
-int _wild_match(ma, na)
-register unsigned char *ma, *na;
-{
-  return wild_match(ma, na) - 1;	/* Don't think IrcII's code
-					 * actually uses this directly,
-					 * but just in case */
+    m++;                        /* Zap leftover %s & *s */
+  return (*m) ? NOMATCH : PERMATCH;     /* End of both = match */
 }
 
-int match(ma, na)
-register unsigned char *ma, *na;
-{
-  return wild_match(ma, na) ? 1 : 0;	/* Returns 1 for match,
-					 * 0 for non-match */
-}
-
-#else
-
-/* 
- * Remaining code is not used by IrcII
- */
-
-/* 
- * For this matcher, sofar's high bit is used as a flag of whether or
- * not we are quoting.  The other matchers don't need this because
- * when you're going forward, you just skip over the quote char.
- */
-#define UNQUOTED (0x7FFF)
-#define QUOTED   (0x8000)
-
-#undef MATCH
-#define MATCH ((match+sofar)&UNQUOTED)
-
-/* 
- * EGGDROP:   wild_match(char *ma, char *na)
- * IrcII:     NOT USED
- * 
- * Features:  Backwards, case-insensitive, ?, *
- * Best use:  Matching of hostmasks (since they are likely to begin
- *            with a * rather than end with one).
- */
 int _wild_match(register unsigned char *m, register unsigned char *n)
 {
   unsigned char *ma = m, *na = n, *lsm = 0, *lsn = 0;
   int match = 1;
   register int sofar = 0;
 
-  /* take care of null strings (should never match) */
+  /* null strings should never match */
   if ((ma == 0) || (na == 0) || (!*ma) || (!*na))
     return NOMATCH;
   /* find the end of each string */
   while (*(++m));
-    m--;
+  m--;
   while (*(++n));
-    n--;
+  n--;
 
   while (n >= na) {
-    if ((m <= ma) || (m[-1] != QUOTE)) {	/* Only look if no quote */
-      switch (*m) {
-      case WILDS:		/* Matches anything */
-	do
-	  m--;			/* Zap redundant wilds */
-	while ((m >= ma) && ((*m == WILDS) || (*m == WILDP)));
-	if ((m >= ma) && (*m == '\\'))
-	  m++;			/* Keep quoted wildcard! */
-	lsm = m;
-	lsn = n;
-	match += sofar;
-	sofar = 0;		/* Update fallback pos */
-	continue;		/* Next char, please */
-      case WILDQ:
-	m--;
-	n--;
-	continue;		/* '?' always matches */
-      }
-      sofar &= UNQUOTED;	/* Remember not quoted */
-    } else
-      sofar |= QUOTED;		/* Remember quoted */
-    if (rfc_toupper(*m) == rfc_toupper(*n)) {	/* If matching char */
+    switch (*m) {
+    case WILDS:                /* Matches anything */
+      do
+        m--;                    /* Zap redundant wilds */
+      while ((m >= ma) && (*m == WILDS));
+      lsm = m;
+      lsn = n;
+      match += sofar;
+      sofar = 0;                /* Update fallback pos */
+      continue;                 /* Next char, please */
+    case WILDQ:
       m--;
       n--;
-      sofar++;			/* Tally the match */
-      if (sofar & QUOTED)
-	m--;			/* Skip the quote char */
-      continue;			/* Next char, please */
+      continue;                 /* '?' always matches */
     }
-    if (lsm) {			/* To to fallback on '*' */
+    if (rfc_toupper(*m) == rfc_toupper(*n)) {   /* If matching char */
+      m--;
+      n--;
+      sofar++;                  /* Tally the match */
+      continue;                 /* Next char, please */
+    }
+    if (lsm) {                  /* To to fallback on '*' */
       n = --lsn;
       m = lsm;
       if (n < na)
-	lsm = 0;		/* Rewind to saved pos */
+        lsm = 0;                /* Rewind to saved pos */
       sofar = 0;
-      continue;			/* Next char, please */
+      continue;                 /* Next char, please */
     }
-    return NOMATCH;		/* No fallback=No match */
+    return NOMATCH;             /* No fallback=No match */
   }
-  while ((m >= ma) && ((*m == WILDS) || (*m == WILDP)))
-    m--;			/* Zap leftover %s & *s */
-  return (m >= ma) ? NOMATCH : MATCH;	/* Start of both = match */
+  while ((m >= ma) && (*m == WILDS))
+    m--;                        /* Zap leftover %s & *s */
+  return (m >= ma) ? NOMATCH : MATCH;   /* Start of both = match */
 }
-
-/* 
- * For this matcher, no "saved" is used to track "%" and no special quoting
- * ability is needed, so we just have (match+sofar) as the result.
- */
-
-#endif

+ 0 - 1
src/md5/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile for src/md5/
-# $Id: Makefile.in,v 1.9 2000/09/12 15:26:51 fabian Exp $
 
 SHELL = @SHELL@
 top_srcdir = @top_srcdir@

+ 39 - 0
src/md5/global.h

@@ -0,0 +1,39 @@
+/* 
+ * global.h
+ *   RSAREF types and constants
+ * 
+ */
+
+#ifndef _EGG_MD5_GLOBAL_H
+#define _EGG_MD5_GLOBAL_H
+
+/* 
+ * PROTOTYPES should be set to one if and only if the compiler
+ * supports function argument prototyping.
+ */
+/* 
+ * The following makes PROTOTYPES default to 1 if it has not
+ * already been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#  define PROTOTYPES 1
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT4 defines a four byte word */
+typedef u_32bit_t UINT4;
+
+/* 
+ * PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+ * If using PROTOTYPES, then PROTO_LIST returns the list,
+ * otherwise it returns an empty list.
+ */
+#if PROTOTYPES
+#  define PROTO_LIST(list) list
+#else
+#  define PROTO_LIST(list) ()
+#endif
+
+#endif				/* _EGG_MD5_GLOBAL_H */

+ 2 - 0
src/md5/md5.h

@@ -22,5 +22,7 @@ typedef struct {
 extern void MD5_Init(MD5_CTX *ctx);
 extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
 extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+extern char *md5sum(char *);
+extern char *MD5Data (const unsigned char *, unsigned int, char *);
 
 #endif

+ 43 - 0
src/md5/md5c.c

@@ -18,6 +18,7 @@
 #include <string.h>
 
 #include "md5.h"
+//#include "global.h"
 
 /*
  * The basic MD5 functions.
@@ -268,3 +269,45 @@ void MD5_Final(unsigned char *result, MD5_CTX *ctx)
 
 	memset(ctx, 0, sizeof(ctx));
 }
+
+char * MD5Data (const unsigned char *data, unsigned int len, char *buf)
+{
+    MD5_CTX ctx;
+    char *ret = NULL;
+
+    MD5_Init(&ctx);
+    MD5_Update(&ctx, &data, len);
+    MD5_Final(ret, &ctx);
+    return ret;
+//    MD5COUNT(&ctx,len);
+//    return MD5End(&ctx, buf);
+}
+/* DIE
+char *md5sum (char *filename) 
+{
+    unsigned char buffer[BUFSIZ];
+    unsigned char md5out[33];
+    char md5string[33];
+
+    MD5_CTX ctx;
+    int f,i,j;
+
+    MD5_Init(&ctx);
+    f = open(filename,O_RDONLY);
+    if (f < 0) return 0;
+    while ((i = read(f,buffer,sizeof buffer)) > 0) {
+        MD5_Update(&ctx,buffer,i);
+        MD5COUNT(&ctx, (unsigned int)i);
+    }
+    j = errno;
+    close(f);
+    errno = j;
+    if (i < 0) return 0;
+
+    MD5_final(md5out, &ctx);
+    for(i=0; i<16; i++)
+      sprintf(md5string + (i*2), "%.2x", md5out[i]);
+  
+    return md5string;
+}
+*/

+ 2 - 19
src/mem.c

@@ -3,25 +3,6 @@
  *   memory allocation and deallocation
  *   keeping track of what memory is being used by whom
  *
- * $Id: mem.c,v 1.17 2002/01/02 03:46:35 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #define MEMTBLSIZE 25000	/* yikes! */
@@ -35,6 +16,8 @@
 
 #include "mod/modvals.h"
 
+#define STR(x) x
+
 
 extern module_entry	*module_list;
 

+ 2042 - 787
src/misc.c

@@ -4,52 +4,58 @@
  *   logging things
  *   queueing output for the bot (msg and help)
  *   resync buffers for sharebots
- *   help system
  *   motd display and %var substitution
  *
- * $Id: misc.c,v 1.48 2002/07/09 05:43:27 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
 #include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include "chan.h"
 #include "tandem.h"
 #include "modules.h"
+#include <pwd.h>
+#include <errno.h>
+#ifdef S_ANTITRACE
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#endif
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <signal.h>
+
+
 #ifdef HAVE_UNAME
 #  include <sys/utsname.h>
 #endif
 #include "stat.h"
+#include "bg.h"
 
+extern struct userrec *userlist;
 extern struct dcc_t	*dcc;
 extern struct chanset_t	*chanset;
-extern char		 helpdir[], version[], origbotname[], botname[],
+extern tand_t *tandbot;
+
+extern char		 version[], origbotname[], botname[],
 			 admin[], network[], motdfile[], ver[], botnetnick[],
-			 bannerfile[], logfile_suffix[], textdir[];
-extern int		 backgrd, con_chan, term_z, use_stderr, dcc_total,
-			 keep_all_logs, quick_logs, strict_host;
+			 bannerfile[], logfile_suffix[], textdir[], userfile[],  
+                         *binname, pid_file[], netpass[], tempdir[];
+
+extern int		 backgrd, con_chan, term_z, use_stderr, dcc_total, timesync,
+#ifdef HUB
+                         my_port,
+#endif
+			 keep_all_logs, quick_logs, strict_host, loading,
+                         localhub;
 extern time_t		 now;
 extern Tcl_Interp	*interp;
 
+void detected(int, char *);
 
 int	 shtime = 1;		/* Whether or not to display the time
 				   with console output */
@@ -57,42 +63,451 @@ log_t	*logs = 0;		/* Logfiles */
 int	 max_logs = 5;		/* Current maximum log files */
 int	 max_logsize = 0;	/* Maximum logfile size, 0 for no limit */
 int	 conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
-int	 debug_output = 0;	/* Disply output to server to LOG_SERVEROUT */
+int	 debug_output = 1;	/* Disply output to server to LOG_SERVEROUT */
 
-struct help_list_t {
-  struct help_list_t *next;
-  char *name;
-  int type;
+int auth_total = 0;
+int max_auth = 100;
+
+struct auth_t *auth = 0;
+
+
+char authkey[121];
+char cmdprefix[1] = "+";
+
+struct cfg_entry CFG_MOTD = {
+  "motd", CFGF_GLOBAL, NULL, NULL,
+  NULL, NULL, NULL
 };
 
-static struct help_ref {
-  char *name;
-  struct help_list_t *first;
-  struct help_ref *next;
-} *help_list = NULL;
+void authkey_describe(struct cfg_entry * entry, int idx) {
+  dprintf(idx, "authkey is used for authing, give to your users if they are to use DCC chat or IRC cmds. (can be bot specific)\n");
+}
+
+void authkey_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+  if (entry->ldata) {
+    strncpy0(authkey, (char *) entry->ldata, sizeof authkey);
+  } else if (entry->gdata) {
+    strncpy0(authkey, (char *) entry->gdata, sizeof authkey);
+  }
+}
+
+struct cfg_entry CFG_AUTHKEY = {
+  "authkey", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  authkey_changed, authkey_changed, authkey_describe
+};
+
+void cmdprefix_describe(struct cfg_entry *entry, int idx) {
+  dprintf(idx, "cmdprefix is the prefix used for msg cmds, ie: !op or .op\n");
+}
+
+void cmdprefix_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+  if (entry->ldata) {
+    strncpy0(cmdprefix, (char *) entry->ldata, sizeof cmdprefix);
+  } else if (entry->gdata) {
+    strncpy0(cmdprefix, (char *) entry->gdata, sizeof cmdprefix);
+  }
+}
+struct cfg_entry CFG_CMDPREFIX = {
+  "cmdprefix", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  cmdprefix_changed, cmdprefix_changed, cmdprefix_describe
+};
+
+
+void misc_describe(struct cfg_entry *cfgent, int idx)
+{
+  int i = 0;
+
+  if (!strcmp(cfgent->name, STR("fork-interval"))) {
+    dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
+    i = 1;
+#ifdef S_LASTCHECK
+  } else if (!strcmp(cfgent->name, STR("login"))) {
+    dprintf(idx, STR("login sets how to handle someone logging in to the shell\n"));
+#endif
+#ifdef S_ANTITRACE
+  } else if (!strcmp(cfgent->name, STR("trace"))) {
+    dprintf(idx, STR("trace sets how to handle someone tracing/debugging the bot\n"));
+#endif
+#ifdef S_PROMISC
+  } else if (!strcmp(cfgent->name, STR("promisc"))) {
+    dprintf(idx, STR("promisc sets how to handle when a interface is set to promiscous mode\n"));
+#endif
+#ifdef S_PROCESSCHECK
+  } else if (!strcmp(cfgent->name, STR("bad-process"))) {
+    dprintf(idx, STR("bad-process sets how to handle when a running process not listed in process-list is detected\n"));
+  } else if (!strcmp(cfgent->name, STR("process-list"))) {
+    dprintf(idx, STR("process-list is a comma-separated list of \"expected processes\" running on the bots uid\n"));
+    i = 1;
+#endif
+#ifdef S_HIJACKCHECK
+  } else if (!strcmp(cfgent->name, STR("hijack"))) {
+    dprintf(idx, STR("hijack sets how to handle when a commonly used hijack method attempt is detected. (recommended: die)\n"));
+#endif
+  }
+  if (!i)
+    dprintf(idx, STR("Valid settings are: nocheck, ignore, warn, die, reject, suicide\n"));
+}
+
+
+void fork_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
+  if (!cfgent->ldata)
+    return;
+  if (atoi(cfgent->ldata)<=0)
+    *valid=0;
+}
+
+void fork_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
+  if (!cfgent->gdata)
+    return;
+  if (atoi(cfgent->gdata)<=0)
+    *valid=0;
+}
+
+void fork_describe(struct cfg_entry * cfgent, int idx) {
+  dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
+}
+
+struct cfg_entry CFG_FORKINTERVAL = {
+  "fork-interval", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  fork_gchanged, fork_lchanged, fork_describe
+};
+
+void detect_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
+  char * p = cfgent->ldata;
+  if (!p)
+    *valid=1;
+  else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
+           && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
+    *valid=0;
+}
+
+void detect_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
+  char * p = (char *) cfgent->ldata;
+  if (!p)
+    *valid=1;
+  else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
+           && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
+    *valid=0;
+}
+
+
+#ifdef S_LASTCHECK
+struct cfg_entry CFG_LOGIN = {
+  "login", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  detect_gchanged, detect_lchanged, misc_describe
+};
+#endif
+#ifdef S_HIJACKCHECK
+struct cfg_entry CFG_HIJACK = {
+  "hijack", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  detect_gchanged, detect_lchanged, misc_describe
+};
+#endif
+#ifdef S_ANTITRACE
+struct cfg_entry CFG_TRACE = {
+  "trace", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  detect_gchanged, detect_lchanged, misc_describe
+};
+#endif
+#ifdef S_PROMISC
+struct cfg_entry CFG_PROMISC = {
+  "promisc", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  detect_gchanged, detect_lchanged, misc_describe
+};
+#endif
+#ifdef S_PROCESSCHECK
+struct cfg_entry CFG_BADPROCESS = {
+  "bad-process", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  detect_gchanged, detect_lchanged, misc_describe
+};
+
+struct cfg_entry CFG_PROCESSLIST = {
+  "process-list", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
+  NULL, NULL, misc_describe
+};
+#endif
+
+#ifdef S_DCCPASS
+struct cmd_pass *cmdpass = NULL;
+#endif
+/* unixware has no strcasecmp() without linking in a hefty library */
+#define upcase(c) (((c)>='a' && (c)<='z') ? (c)-'a'+'A' : (c))
+
+#if !HAVE_STRCASECMP
+#define strcasecmp strcasecmp2
+#endif
+
+int strcasecmp2(char *s1, char *s2)
+{
+  while ((*s1) && (*s2) && (upcase(*s1) == upcase(*s2))) {
+    s1++;
+    s2++;
+  }
+  return upcase(*s1) - upcase(*s2);
+}
+
+/* this is cfg shit from servers/irc/ctcp because hub doesnt load
+ * these mods */
+#ifdef HUB
+void servers_describe(struct cfg_entry * entry, int idx) {
+  dprintf(idx, STR("servers is a comma-separated list of servers the bot will use\n"));
+}
+void servers_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+}
+void servers6_describe(struct cfg_entry * entry, int idx) {
+  dprintf(idx, STR("servers6 is a comma-separated list of servers the bot will use (FOR IPv6)\n"));
+}
+void servers6_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+}
+void nick_describe(struct cfg_entry * entry, int idx) {
+  dprintf(idx, "nick is the bots preferred nick when connecting/using .resetnick\n");
+}
+void nick_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+}
+void realname_describe(struct cfg_entry * entry, int idx) {
+  dprintf(idx, STR("realname is the bots \"real name\" when connecting\n"));
+}
+
+void realname_changed(struct cfg_entry * entry, char * olddata, int * valid) {
+}
+struct cfg_entry CFG_SERVERS = {
+  "servers", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  servers_changed, servers_changed, servers_describe
+};
+struct cfg_entry CFG_SERVERS6 = {
+  "servers6", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  servers6_changed, servers6_changed, servers6_describe
+};
+
+struct cfg_entry CFG_NICK = {
+  "nick", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  nick_changed, nick_changed, nick_describe
+};
+
+struct cfg_entry CFG_REALNAME = {
+  "realname", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
+  realname_changed, realname_changed, realname_describe
+};
+
+void getin_describe(struct cfg_entry *cfgent, int idx)
+{
+  if (!strcmp(cfgent->name, STR("op-bots")))
+    dprintf(idx, STR("op-bots is number of bots to ask every time a oprequest is to be made\n"));
+  else if (!strcmp(cfgent->name, STR("in-bots")))
+    dprintf(idx, STR("in-bots is number of bots to ask every time a inrequest is to be made\n"));
+  else if (!strcmp(cfgent->name, STR("op-requests")))
+    dprintf(idx, STR("op-requests (requests:seconds) limits how often the bot will ask for ops\n"));
+  else if (!strcmp(cfgent->name, STR("lag-threshold")))
+    dprintf(idx, STR("lag-threshold is maximum acceptable server lag for the bot to send/honor requests\n"));
+  else if (!strcmp(cfgent->name, STR("op-time-slack")))
+    dprintf(idx, STR("op-time-slack is number of seconds a opcookies encoded time value can be off from the bots current time\n"));
+  else if (!strcmp(cfgent->name, STR("lock-threshold")))
+    dprintf(idx, STR("Format H:L. When at least H hubs but L or less leafs are linked, lock all channels\n"));
+  else if (!strcmp(cfgent->name, STR("kill-threshold")))
+    dprintf(idx, STR("When more than kill-threshold bots have been killed/k-lined the last minute, channels are locked\n"));
+  else if (!strcmp(cfgent->name, STR("fight-threshold")))
+    dprintf(idx, STR("When more than fight-threshold ops/deops/kicks/bans/unbans altogether have happened on a channel in one minute, the channel is locked\n"));
+  else {
+    dprintf(idx, STR("No description for %s ???\n"), cfgent->name);
+    putlog(LOG_ERRORS, "*", STR("getin_describe() called with unknown config entry %s"), cfgent->name);
+  }
+}
+
+void getin_changed(struct cfg_entry *cfgent, char *oldval, int *valid)
+{
+  int i;
+
+  if (!cfgent->gdata)
+    return;
+  *valid = 0;
+  if (!strcmp(cfgent->name, STR("op-requests"))) {
+    int L,
+      R;
+    char *value = cfgent->gdata;
+
+    L = atoi(value);
+    value = strchr(value, ':');
+    if (!value)
+      return;
+    value++;
+    R = atoi(value);
+    if ((R >= 60) || (R <= 3) || (L < 1) || (L > R))
+      return;
+    *valid = 1;
+    return;
+  }
+  if (!strcmp(cfgent->name, STR("lock-threshold"))) {
+    int L,
+      R;
+    char *value = cfgent->gdata;
+
+    L = atoi(value);
+    value = strchr(value, ':');
+    if (!value)
+      return;
+    value++;
+    R = atoi(value);
+    if ((R >= 1000) || (R < 0) || (L < 0) || (L > 100))
+      return;
+    *valid = 1;
+    return;
+  }
+  i = atoi(cfgent->gdata);
+  if (!strcmp(cfgent->name, STR("op-bots"))) {
+    if ((i < 1) || (i > 10))
+      return;
+  } else if (!strcmp(cfgent->name, STR("invite-bots"))) {
+    if ((i < 1) || (i > 10))
+      return;
+  } else if (!strcmp(cfgent->name, STR("key-bots"))) {
+    if ((i < 1) || (i > 10))
+      return;
+  } else if (!strcmp(cfgent->name, STR("limit-bots"))) {
+    if ((i < 1) || (i > 10))
+      return;
+  } else if (!strcmp(cfgent->name, STR("unban-bots"))) {
+    if ((i < 1) || (i > 10))
+      return;
+  } else if (!strcmp(cfgent->name, STR("lag-threshold"))) {
+    if ((i < 3) || (i > 60))
+      return;
+  } else if (!strcmp(cfgent->name, STR("fight-threshold"))) {
+    if (i && ((i < 50) || (i > 1000)))
+      return;
+  } else if (!strcmp(cfgent->name, STR("kill-threshold"))) {
+    if ((i < 0) || (i >= 200))
+      return;
+  } else if (!strcmp(cfgent->name, STR("op-time-slack"))) {
+    if ((i < 30) || (i > 1200))
+      return;
+  }
+  *valid = 1;
+  return;
+}
+
+struct cfg_entry CFG_OPBOTS = {
+  "op-bots", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_INBOTS = {
+  "in-bots", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_LAGTHRESHOLD = {
+  "lag-threshold", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_OPREQUESTS = {
+  "op-requests", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_OPTIMESLACK = {
+  "op-time-slack", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+#ifdef G_AUTOLOCK
+struct cfg_entry CFG_LOCKTHRESHOLD = {
+  "lock-threshold", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_KILLTHRESHOLD = {
+  "kill-threshold", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+
+struct cfg_entry CFG_FIGHTTHRESHOLD = {
+  "fight-threshold", CFGF_GLOBAL, NULL, NULL,
+  getin_changed, NULL, getin_describe
+};
+#endif /* G_AUTOLOCK */
+
+
+/* cloak
+void cloak_describe(struct cfg_entry *cfgent, int idx)
+{
+  dprintf(idx, STR("cloak-script decides which BitchX script the bot cloaks. If set to 6, a random script will be cloaked.\n"));
+  dprintf(idx, STR("Available: 0=crackrock, 1=neonapple, 2=tunnelvision, 3=argon, 4=evolver, 5=prevail\n"));
+}
+void cloak_changed(struct cfg_entry *cfgent, char * oldval, int * valid) {
+  char * p;
+  int i;
+  p = cfgent->ldata ? cfgent->ldata : cfgent->gdata;
+  if (!p)
+    return;
+  i=atoi(p);
+#ifdef LEAF
+  if (i>=6)
+    i = random() % 6;
+#endif
+  *valid = ( (i>=0) && (i<=6));
+  if (*valid)
+    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
+};
+*/
+#endif
+/* end hub compat cfg */
+
+int cfg_count=0;
+struct cfg_entry ** cfg = NULL;
+int cfg_noshare=0;
 
 /* Expected memory usage
  */
 int expmem_misc()
 {
-  struct help_ref *current;
-  struct help_list_t *item;
-  int tot = 0;
+#ifdef S_DCCPASS
+  struct cmd_pass *cp = NULL;
+#endif
 
-  for (current = help_list; current; current = current->next) {
-    tot += sizeof(struct help_ref) + strlen(current->name) + 1;
+  int tot = 0, i;
 
-    for (item = current->first; item; item = item->next)
-      tot += sizeof(struct help_list_t) + strlen(item->name) + 1;
+  for (i=0;i<cfg_count;i++) {
+    tot += sizeof(void *);
+    if (cfg[i]->gdata)
+      tot += strlen(cfg[i]->gdata) + 1;
+    if (cfg[i]->ldata)
+      tot += strlen(cfg[i]->ldata) + 1;
   }
+#ifdef S_DCCPASS
+  for (cp=cmdpass;cp;cp=cp->next) {
+    tot += sizeof(struct cmd_pass) + strlen(cp->name)+1;
+  }
+#endif
+  tot = sizeof(struct auth_t) * max_auth;
+
   return tot + (max_logs * sizeof(log_t));
 }
+void init_auth_max()
+{
+  if (max_auth < 1)
+    max_auth = 1;
+  if (auth)
+    auth = nrealloc(auth, sizeof(struct auth_t) * max_auth);
+  else
+    auth = nmalloc(sizeof(struct auth_t) * max_auth);
 
+}
 void init_misc()
 {
+
   static int last = 0;
 
+  init_auth_max();
+
   if (max_logs < 1)
     max_logs = 1;
   if (logs)
@@ -109,6 +524,46 @@ void init_misc()
     /* Added by rtc  */
     logs[last].flags = 0;
   }
+
+  add_cfg(&CFG_AUTHKEY);
+//  add_cfg(&CFG_CMDPREFIX);
+  add_cfg(&CFG_MOTD);
+  add_cfg(&CFG_FORKINTERVAL);
+#ifdef S_LASTCHECK
+  add_cfg(&CFG_LOGIN);
+#endif
+#ifdef S_HIJACKCHECK
+  add_cfg(&CFG_HIJACK);
+#endif
+#ifdef S_ANTITRACE
+  add_cfg(&CFG_TRACE);
+#endif
+#ifdef S_PROMISC
+  add_cfg(&CFG_PROMISC);
+#endif
+#ifdef S_PROCESSCHECK
+  add_cfg(&CFG_BADPROCESS);
+  add_cfg(&CFG_PROCESSLIST);
+#endif
+#ifdef HUB
+  add_cfg(&CFG_NICK);
+  add_cfg(&CFG_SERVERS);
+  add_cfg(&CFG_SERVERS6);
+  add_cfg(&CFG_REALNAME);
+  set_cfg_str(NULL, STR("realname"), "A deranged product of evil coders");
+  add_cfg(&CFG_OPBOTS);
+  add_cfg(&CFG_INBOTS);
+  add_cfg(&CFG_LAGTHRESHOLD);
+  add_cfg(&CFG_OPREQUESTS);
+  add_cfg(&CFG_OPTIMESLACK);
+#ifdef G_AUTOLOCK
+  add_cfg(&CFG_LOCKTHRESHOLD);
+  add_cfg(&CFG_KILLTHRESHOLD);
+  add_cfg(&CFG_FIGHTTHRESHOLD);
+#endif
+
+//cloak  add_cfg(&CFG_CLOAK_SCRIPT);
+#endif
 }
 
 
@@ -470,7 +925,90 @@ void daysdur(time_t now, time_t then, char *out)
   sprintf(s, "%02d:%02d", hrs, mins);
   strcat(out, s);
 }
+/* show l33t banner */
+void show_banner(int idx)
+{
+  dprintf(idx, "                    _ _   _     \n");
+  dprintf(idx, "__      ___ __ __ _(_) |_| |__  \n");
+  dprintf(idx, "\\ \\ /\\ / / '__/ _` | | __| '_ \\ \n");
+  dprintf(idx, " \\ V  V /| | | (_| | | |_| | | |\n");
+  dprintf(idx, "  \\_/\\_/ |_|  \\__,_|_|\\__|_| |_|\n");
+  dprintf(idx, "           by bryan          \n");
+}
+
+/* show motd to dcc chatter */
+void show_motd(int idx)
+{
+
+  dprintf(idx, STR("Motd: "));
+  if (CFG_MOTD.gdata && *(char *) CFG_MOTD.gdata)
+    dprintf(idx, STR("%s\n"), (char *) CFG_MOTD.gdata);
+  else
+    dprintf(idx, STR("none\n"));
+}
+void show_channels(int idx, char *handle)
+{
+  struct chanset_t *chan;
+  struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0, 0 };
+  struct userrec *u;
+  int first = 0, l = 0;
+  char format[120];
+
+  for (chan = chanset;chan;chan = chan->next)
+    if (l < strlen(chan->dname))
+      l = strlen(chan->dname);
+
+Context;
+  if (handle)
+    u = get_user_by_handle(userlist, handle);
+  else
+    u = dcc[idx].user;
+
+Context;
+
+  egg_snprintf(format, sizeof format, "  %%-%us %%-s%%-s%%-s%%-s\n", (l+2));
+
+  for (chan = chanset;chan;chan = chan->next) {
+    get_user_flagrec(u, &fr, chan->dname);
+
+Context;
+    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
+       (glob_owner(fr) || ((glob_op(fr) || chan_op(fr)) && !(chan_deop(fr) || glob_deop(fr))))) {
+        if (!first) { 
+          dprintf(idx, STR("%s %s access to these channels:\n"), handle ? u->handle : "You", handle ? "has" : "have");
+          
+          first = 1;
+        }
+        dprintf(idx, format, chan->dname, channel_inactive(chan) ? "(inactive) " : "", 
+           channel_private(chan) ? "(private)  " : "", !channel_manop(chan) ? "(no manop) " : "", 
+           channel_bitch(chan) ? "(bitch)" : "");
+    }
+  }
+  if (!first)
+    dprintf(idx, "You do not have access to any channels.\n");
+Context;
+
+}
+int getting_users()
+{
+  int i;
+
+  for (i = 0; i < dcc_total; i++)
+    if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_GETTING))
+      return 1;
+  return 0;
+}
+
+int prand(int *seed, int range)
+{
+  long long i1;
 
+  i1 = *seed;
+  i1 = (i1 * 0x08088405 + 1) & 0xFFFFFFFF;
+  *seed = i1;
+  i1 = (i1 * range) >> 32;
+  return i1;
+}
 
 /*
  *    Logging functions
@@ -481,30 +1019,47 @@ void daysdur(time_t now, time_t then, char *out)
  */
 void putlog EGG_VARARGS_DEF(int, arg1)
 {
-  int i, type;
-  char *format, *chname, s[LOGLINELEN], s1[256], *out;
-  time_t tt;
-  char ct[81], *s2;
-  struct tm *t = localtime(&now);
+  int i, type, tsl = 0, dohl = 0; //hl
+  char *format, *chname, s[LOGLINELEN], s1[256], *out, ct[81], *s2, stamp[34], buf2[LOGLINELEN]; // *hub, hublog[20], mys[256]
   va_list va;
-
+#ifdef HUB
+  time_t now2 = time(NULL);
+#endif
+  struct tm *t;
+  t = 0;
   type = EGG_VARARGS_START(int, arg1, va);
   chname = va_arg(va, char *);
   format = va_arg(va, char *);
+//The putlog should not be broadcast over bots, @ is *.
+  if ((chname[0] == '*'))
+    dohl = 1;
+#ifdef HUB
+  if (shtime) {
+    t = localtime(&now2);
+    egg_strftime(stamp, sizeof(stamp) - 2, LOG_TS, t);
+    strcat(stamp, " ");
+   tsl = strlen(stamp);
+  }
+#endif
+ 
+
+  /* Format log entry at offset 'tsl,' then i can prepend the timestamp */
+  out = s+tsl;
 
-  /* Format log entry at offset 8, then i can prepend the timestamp */
-  out = &s[8];
   /* No need to check if out should be null-terminated here,
    * just do it! <cybah>
    */
-  egg_vsnprintf(out, LOGLINEMAX - 8, format, va);
-  out[LOGLINEMAX - 8] = 0;
-  tt = now;
+
+  egg_vsnprintf(out, LOGLINEMAX - tsl, format, va);
+//  egg_vsnprintf(hub, LOGLINEMAX - hl, format, va);
+
+  out[LOGLINEMAX - tsl] = 0;
+//  hub[LOGLINEMAX - hl] = 0;
   if (keep_all_logs) {
     if (!logfile_suffix[0])
-      egg_strftime(ct, 12, ".%d%b%Y", localtime(&tt));
+      egg_strftime(ct, 12, ".%d%b%Y", t);
     else {
-      egg_strftime(ct, 80, logfile_suffix, localtime(&tt));
+      egg_strftime(ct, 80, logfile_suffix, t);
       ct[80] = 0;
       s2 = ct;
       /* replace spaces by underscores */
@@ -515,16 +1070,22 @@ void putlog EGG_VARARGS_DEF(int, arg1)
       }
     }
   }
+  /* Place the timestamp in the string to be printed */
   if ((out[0]) && (shtime)) {
-    egg_strftime(s1, 9, "[%H:%M] ", localtime(&tt));
-    strncpy(&s[0], s1, 8);
+    strncpy(s, stamp, tsl);
     out = s;
   }
+  /* if (hub[0]) {
+    strncpy(mys, hublog, hl);
+    hub = mys;
+  }*/
+
   strcat(out, "\n");
+//  strcat(hub, "\n");
   if (!use_stderr) {
     for (i = 0; i < max_logs; i++) {
       if ((logs[i].filename != NULL) && (logs[i].mask & type) &&
-	  ((chname[0] == '*') || (logs[i].chname[0] == '*') ||
+	  ((chname[0] == '@') || (chname[0] == '*') || (logs[i].chname[0] == '*') ||
 	   (!rfc_casecmp(chname, logs[i].chname)))) {
 	if (logs[i].f == NULL) {
 	  /* Open this logfile */
@@ -538,10 +1099,10 @@ void putlog EGG_VARARGS_DEF(int, arg1)
 	  /* Check if this is the same as the last line added to
 	   * the log. <cybah>
 	   */
-	  if (!egg_strcasecmp(out + 8, logs[i].szlast)) {
+          if (!egg_strcasecmp(out + tsl, logs[i].szlast))
 	    /* It is a repeat, so increment repeats */
 	    logs[i].repeats++;
-	  } else {
+	  else {
 	    /* Not a repeat, check if there were any repeat
 	     * lines previously...
 	     */
@@ -550,28 +1111,45 @@ void putlog EGG_VARARGS_DEF(int, arg1)
 	       * then reset repeats. We want the current time here,
 	       * so put that in the file first.
 	       */
-	      if (t) {
-		fprintf(logs[i].f, "[%2.2d:%2.2d] ", t->tm_hour, t->tm_min);
-		fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
-	      } else {
-		fprintf(logs[i].f, "[??:??] ");
-		fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
-	      }
+              fprintf(logs[i].f, stamp);
+	      fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
+	      
 	      logs[i].repeats = 0;
 	      /* No need to reset logs[i].szlast here
 	       * because we update it later on...
 	       */
 	    }
 	    fputs(out, logs[i].f);
-	    strncpyz(logs[i].szlast, out + 8, LOGLINEMAX);
+           strncpyz(logs[i].szlast, out + tsl, LOGLINEMAX);
 	  }
 	}
       }
     }
   }
+/* echo line to hubs (not if it was on a +h though)*/
+
+  if (dohl) {
+    tand_t *bot;
+    struct userrec *ubot;
+Context;
+    sprintf(buf2, "hl %d %s", type, out);
+    if (userlist && !loading) {
+      for (bot = tandbot ;bot ; bot = bot->next) {
+        ubot = get_user_by_handle(userlist, bot->bot);
+        if (ubot) {
+          if (bot_hublevel(ubot) < 999) {
+            putbot(ubot->handle, buf2);
+          }
+        }
+      }
+    } else {
+      botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
+    }
+  }
+
   for (i = 0; i < dcc_total; i++)
     if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->con_flags & type)) {
-      if ((chname[0] == '*') || (dcc[i].u.chat->con_chan[0] == '*') ||
+      if ((chname[0] == '@') || (chname[0] == '*') || (dcc[i].u.chat->con_chan[0] == '*') ||
 	  (!rfc_casecmp(chname, dcc[i].u.chat->con_chan)))
 	dprintf(i, "%s", out);
     }
@@ -579,7 +1157,7 @@ void putlog EGG_VARARGS_DEF(int, arg1)
     dprintf(DP_STDOUT, "%s", out);
   else if ((type & LOG_MISC) && use_stderr) {
     if (shtime)
-      out += 8;
+      out += tsl;
     dprintf(DP_STDERR, "%s", s);
   }
   va_end(va);
@@ -646,7 +1224,6 @@ void check_logsize()
 void flushlogs()
 {
   int i;
-  struct tm *t = localtime(&now);
 
   /* Logs may not be initialised yet. */
   if (!logs)
@@ -657,17 +1234,14 @@ void flushlogs()
    */
   for (i = 0; i < max_logs; i++) {
     if (logs[i].f != NULL) {
-       if ((logs[i].repeats > 0) && quick_logs) {
+      if ((logs[i].repeats > 0) && quick_logs) {
          /* Repeat.. if quicklogs used then display 'last message
           * repeated x times' and reset repeats.
 	  */
-	if (t) {
-	  fprintf(logs[i].f, "[%2.2d:%2.2d] ", t->tm_hour, t->tm_min);
-	  fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
-	} else {
-	  fprintf(logs[i].f, "[??:??] ");
-	  fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
-	}
+         char stamp[32];
+         egg_strftime(&stamp[0], 32, LOG_TS, localtime(&now));
+         fprintf(logs[i].f, "%s ", stamp);
+	 fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
 	/* Reset repeats */
 	logs[i].repeats = 0;
       }
@@ -677,823 +1251,1504 @@ void flushlogs()
 }
 
 
-/*
- *     String substitution functions
+char *extracthostname(char *hostmask)
+{
+  char *p = strrchr(hostmask, '@');
+  return p ? p + 1 : "";
+}
+
+/* Create a string with random letters and digits
  */
+void make_rand_str(char *s, int len)
+{
+  int j, r = 0;
+
+Context;
+  for (j = 0; j < len; j++) {
+    r = random();
+Context;
+    if (r % 4 == 0)
+      s[j] = '0' + (random() % 10);
+    else if (r % 4 == 1)
+      s[j] = 'a' + (random() % 26);
+    else if (r % 4 == 2)
+      s[j] = 'A' + (random() % 26);
+    else
+      s[j] = '!' + (random() % 15);
+
+    if (s[j] == 37) //take out % because mIRC is lame and bugged with % in $md5(text)
+      s[j] = 35;
+  }
 
-static int	 cols = 0;
-static int	 colsofar = 0;
-static int	 blind = 0;
-static int	 subwidth = 70;
-static char	*colstr = NULL;
 
+  s[len] = '\0';
+//  s[len] = 0;
+Context;
+}
 
-/* Add string to colstr
+/* Convert an octal string into a decimal integer value.  If the string
+ * is empty or contains non-octal characters, -1 is returned.
  */
-static void subst_addcol(char *s, char *newcol)
-{
-  char *p, *q;
-  int i, colwidth;
-
-  if ((newcol[0]) && (newcol[0] != '\377'))
-    colsofar++;
-  colstr = nrealloc(colstr, strlen(colstr) + strlen(newcol) +
-		    (colstr[0] ? 2 : 1));
-  if ((newcol[0]) && (newcol[0] != '\377')) {
-    if (colstr[0])
-      strcat(colstr, "\377");
-    strcat(colstr, newcol);
-  }
-  if ((colsofar == cols) || ((newcol[0] == '\377') && (colstr[0]))) {
-    colsofar = 0;
-    strcpy(s, "     ");
-    colwidth = (subwidth - 5) / cols;
-    q = colstr;
-    p = strchr(colstr, '\377');
-    while (p != NULL) {
-      *p = 0;
-      strcat(s, q);
-      for (i = strlen(q); i < colwidth; i++)
-	strcat(s, " ");
-      q = p + 1;
-      p = strchr(q, '\377');
-    }
-    strcat(s, q);
-    nfree(colstr);
-    colstr = (char *) nmalloc(1);
-    colstr[0] = 0;
-  }
+int oatoi(const char *octal)
+{
+  register int i;
+
+  if (!*octal)
+    return -1;
+  for (i = 0; ((*octal >= '0') && (*octal <= '7')); octal++)
+    i = (i * 8) + (*octal - '0');
+  if (*octal)
+    return -1;
+  return i;
 }
 
-/* Substitute %x codes in help files
+/* Return an allocated buffer which contains a copy of the string
+ * 'str', with all 'div' characters escaped by 'mask'. 'mask'
+ * characters are escaped too.
  *
- * %B = bot nickname
- * %V = version
- * %C = list of channels i monitor
- * %E = eggdrop banner
- * %A = admin line
- * %n = network name
- * %T = current time ("14:15")
- * %N = user's nickname
- * %U = display system name if possible
- * %{+xy}     require flags to read this section
- * %{-}       turn of required flag matching only
- * %{center}  center this line
- * %{cols=N}  start of columnated section (indented)
- * %{help=TOPIC} start a section for a particular command
- * %{end}     end of section
+ * Remember to free the returned memory block.
  */
-#define HELP_BUF_LEN 256
-#define HELP_BOLD  1
-#define HELP_REV   2
-#define HELP_UNDER 4
-#define HELP_FLASH 8
-
-void help_subst(char *s, char *nick, struct flag_record *flags,
-		int isdcc, char *topic)
+char *str_escape(const char *str, const char div, const char mask)
 {
-  char xx[HELP_BUF_LEN + 1], sub[161], *current, *q, chr, *writeidx,
-  *readidx, *towrite;
-  struct chanset_t *chan;
-  int i, j, center = 0;
-  static int help_flags;
-#ifdef HAVE_UNAME
-  struct utsname uname_info;
-#endif
+  const int	 len = strlen(str);
+  int		 buflen = (2 * len), blen = 0;
+  char		*buf = nmalloc(buflen + 1), *b = buf;
+  const char	*s;
 
-  if (s == NULL) {
-    /* Used to reset substitutions */
-    blind = 0;
-    cols = 0;
-    subwidth = 70;
-    if (colstr != NULL) {
-      nfree(colstr);
-      colstr = NULL;
-    }
-    help_flags = isdcc;
-    return;
-  }
-  strncpyz(xx, s, sizeof xx);
-  readidx = xx;
-  writeidx = s;
-  current = strchr(readidx, '%');
-  while (current) {
-    /* Are we about to copy a chuck to the end of the buffer?
-     * if so return
-     */
-    if ((writeidx + (current - readidx)) >= (s + HELP_BUF_LEN)) {
-      strncpy(writeidx, readidx, (s + HELP_BUF_LEN) - writeidx);
-      s[HELP_BUF_LEN] = 0;
-      return;
-    }
-    chr = *(current + 1);
-    *current = 0;
-    if (!blind)
-      writeidx += my_strcpy(writeidx, readidx);
-    towrite = NULL;
-    switch (chr) {
-    case 'b':
-      if (glob_hilite(*flags)) {
-	if (help_flags & HELP_IRC) {
-	  towrite = "\002";
-	} else if (help_flags & HELP_BOLD) {
-	  help_flags &= ~HELP_BOLD;
-	  towrite = "\033[0m";
-	} else {
-	  help_flags |= HELP_BOLD;
-	  towrite = "\033[1m";
-	}
-      }
-      break;
-    case 'v':
-      if (glob_hilite(*flags)) {
-	if (help_flags & HELP_IRC) {
-	  towrite = "\026";
-	} else if (help_flags & HELP_REV) {
-	  help_flags &= ~HELP_REV;
-	  towrite = "\033[0m";
-	} else {
-	  help_flags |= HELP_REV;
-	  towrite = "\033[7m";
-	}
-      }
-      break;
-    case '_':
-      if (glob_hilite(*flags)) {
-	if (help_flags & HELP_IRC) {
-	  towrite = "\037";
-	} else if (help_flags & HELP_UNDER) {
-	  help_flags &= ~HELP_UNDER;
-	  towrite = "\033[0m";
-	} else {
-	  help_flags |= HELP_UNDER;
-	  towrite = "\033[4m";
-	}
-      }
-      break;
-    case 'f':
-      if (glob_hilite(*flags)) {
-	if (help_flags & HELP_FLASH) {
-	  if (help_flags & HELP_IRC) {
-	    towrite = "\002\037";
-	  } else {
-	    towrite = "\033[0m";
-	  }
-	  help_flags &= ~HELP_FLASH;
-	} else {
-	  help_flags |= HELP_FLASH;
-	  if (help_flags & HELP_IRC) {
-	    towrite = "\037\002";
-	  } else {
-	    towrite = "\033[5m";
-	  }
-	}
-      }
-      break;
-    case 'U':
-#ifdef HAVE_UNAME
-      if (uname(&uname_info) >= 0) {
-	egg_snprintf(sub, sizeof sub, "%s %s", uname_info.sysname,
-		       uname_info.release);
-	towrite = sub;
-      } else
-#endif
-	towrite = "*UNKNOWN*";
-      break;
-    case 'B':
-      towrite = (isdcc ? botnetnick : botname);
-      break;
-    case 'V':
-      towrite = ver;
-      break;
-    case 'E':
-      towrite = version;
-      break;
-    case 'A':
-      towrite = admin;
-      break;
-    case 'n':
-      towrite = network;
-      break;
-    case 'T':
-      egg_strftime(sub, 6, "%H:%M", localtime(&now));
-      towrite = sub;
-      break;
-    case 'N':
-      towrite = strchr(nick, ':');
-      if (towrite)
-	towrite++;
-      else
-	towrite = nick;
-      break;
-    case 'C':
-      if (!blind)
-	for (chan = chanset; chan; chan = chan->next) {
-	  if ((strlen(chan->dname) + writeidx + 2) >=
-	      (s + HELP_BUF_LEN)) {
-	    strncpy(writeidx, chan->dname, (s + HELP_BUF_LEN) - writeidx);
-	    s[HELP_BUF_LEN] = 0;
-	    return;
-	  }
-	  writeidx += my_strcpy(writeidx, chan->dname);
-	  if (chan->next) {
-	    *writeidx++ = ',';
-	    *writeidx++ = ' ';
-	  }
-	}
-      break;
-    case '{':
-      q = current;
-      current++;
-      while ((*current != '}') && (*current))
-	current++;
-      if (*current) {
-	*current = 0;
-	current--;
-	q += 2;
-	/* Now q is the string and p is where the rest of the fcn expects */
-	if (!strncmp(q, "help=", 5)) {
-	  if (topic && egg_strcasecmp(q + 5, topic))
-	    blind |= 2;
-	  else
-	    blind &= ~2;
-	} else if (!(blind & 2)) {
-	  if (q[0] == '+') {
-	    struct flag_record fr =
-	    {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
-
-	    break_down_flags(q + 1, &fr, NULL);
-	    if (!flagrec_ok(&fr, flags))
-	      blind |= 1;
-	    else
-	      blind &= ~1;
-	  } else if (q[0] == '-') {
-	    blind &= ~1;
-	  } else if (!egg_strcasecmp(q, "end")) {
-	    blind &= ~1;
-	    subwidth = 70;
-	    if (cols) {
-	      sub[0] = 0;
-	      subst_addcol(sub, "\377");
-	      nfree(colstr);
-	      colstr = NULL;
-	      cols = 0;
-	      towrite = sub;
-	    }
-	  } else if (!egg_strcasecmp(q, "center"))
-	    center = 1;
-	  else if (!strncmp(q, "cols=", 5)) {
-	    char *r;
-
-	    cols = atoi(q + 5);
-	    colsofar = 0;
-	    colstr = (char *) nmalloc(1);
-	    colstr[0] = 0;
-	    r = strchr(q + 5, '/');
-	    if (r != NULL)
-	      subwidth = atoi(r + 1);
-	  }
-	}
-      } else
-	current = q;		/* no } so ignore */
-      break;
-    default:
-      if (!blind) {
-	*writeidx++ = chr;
-	if (writeidx >= (s + HELP_BUF_LEN)) {
-	  *writeidx = 0;
-	  return;
-	}
-      }
-    }
-    if (towrite && !blind) {
-      if ((writeidx + strlen(towrite)) >= (s + HELP_BUF_LEN)) {
-	strncpy(writeidx, towrite, (s + HELP_BUF_LEN) - writeidx);
-	s[HELP_BUF_LEN] = 0;
-	return;
-      }
-      writeidx += my_strcpy(writeidx, towrite);
+  if (!buf)
+    return NULL;
+  for (s = str; *s; s++) {
+    /* Resize buffer. */
+    if ((buflen - blen) <= 3) {
+      buflen = (buflen * 2);
+      buf = nrealloc(buf, buflen + 1);
+      if (!buf)
+	return NULL;
+      b = buf + blen;
     }
-    if (chr) {
-      readidx = current + 2;
-      current = strchr(readidx, '%');
+
+    if (*s == div || *s == mask) {
+      sprintf(b, "%c%02x", mask, *s);
+      b += 3;
+      blen += 3;
     } else {
-      readidx = current + 1;
-      current = NULL;
-    }
-  }
-  if (!blind) {
-    i = strlen(readidx);
-    if (i && ((writeidx + i) >= (s + HELP_BUF_LEN))) {
-      strncpy(writeidx, readidx, (s + HELP_BUF_LEN) - writeidx);
-      s[HELP_BUF_LEN] = 0;
-      return;
-    }
-    strcpy(writeidx, readidx);
-  } else
-    *writeidx = 0;
-  if (center) {
-    strcpy(xx, s);
-    i = 35 - (strlen(xx) / 2);
-    if (i > 0) {
-      s[0] = 0;
-      for (j = 0; j < i; j++)
-	s[j] = ' ';
-      strcpy(s + i, xx);
+      *(b++) = *s;
+      blen++;
     }
   }
-  if (cols) {
-    strcpy(xx, s);
-    s[0] = 0;
-    subst_addcol(s, xx);
+  *b = 0;
+  return buf;
+}
+
+/* Search for a certain character 'div' in the string 'str', while
+ * ignoring escaped characters prefixed with 'mask'.
+ *
+ * The string
+ *
+ *   "\\3a\\5c i am funny \\3a):further text\\5c):oink"
+ *
+ * as str, '\\' as mask and ':' as div would change the str buffer
+ * to
+ *
+ *   ":\\ i am funny :)"
+ *
+ * and return a pointer to "further text\\5c):oink".
+ *
+ * NOTE: If you look carefully, you'll notice that strchr_unescape()
+ *       behaves differently than strchr().
+ */
+char *strchr_unescape(char *str, const char div, register const char esc_char)
+{
+  char		 buf[3];
+  register char	*s, *p;
+
+  buf[3] = 0;
+  for (s = p = str; *s; s++, p++) {
+    if (*s == esc_char) {	/* Found escape character.		*/
+      /* Convert code to character. */
+      buf[0] = s[1], buf[1] = s[2];
+      *p = (unsigned char) strtol(buf, NULL, 16);
+      s += 2;
+    } else if (*s == div) {
+      *p = *s = 0;
+      return (s + 1);		/* Found searched for character.	*/
+    } else
+      *p = *s;
   }
+  *p = 0;
+  return NULL;
+}
+
+/* As strchr_unescape(), but converts the complete string, without
+ * searching for a specific delimiter character.
+ */
+void str_unescape(char *str, register const char esc_char)
+{
+  (void) strchr_unescape(str, 0, esc_char);
+}
+
+/* Kills the bot. s1 is the reason shown to other bots, 
+ * s2 the reason shown on the partyline. (Sup 25Jul2001)
+ */
+void kill_bot(char *s1, char *s2)
+{
+#ifdef HUB
+  write_userfile(-1);
+#endif
+  call_hook(HOOK_DIE);
+  chatout("*** %s\n", s1);
+  botnet_send_chat(-1, botnetnick, s1);
+  botnet_send_bye();
+  fatal(s2, 0);
+}
+int isupdatehub()
+{
+#ifdef HUB
+  struct userrec *buser;
+  buser = get_user_by_handle(userlist, botnetnick);
+  if ((buser) && (buser->flags & USER_UPDATEHUB))
+    return 1;
+  else
+#endif
+    return 0;
+
+}
+int ischanhub()
+{
+
+  struct userrec *buser;
+  buser = get_user_by_handle(userlist, botnetnick);
+  if ((buser) && (buser->flags & USER_CHANHUB))
+    return 1;
+  else
+    return 0;
 }
 
-static void scan_help_file(struct help_ref *current, char *filename, int type)
+int issechub()
+{
+
+  struct userrec *buser;
+  buser = get_user_by_handle(userlist, botnetnick);
+  if ((buser) && (buser->flags & USER_SECHUB))
+    return 1;
+  else
+    return 0;
+ 
+}
+#ifdef S_DCCPASS
+int check_cmd_pass(char *cmd, char *pass) 
 {
-  FILE *f;
-  char s[HELP_BUF_LEN + 1], *p, *q;
-  struct help_list_t *list;
+  struct cmd_pass *cp;
 
-  if (is_file(filename) && (f = fopen(filename, "r"))) {
-    while (!feof(f)) {
-      fgets(s, HELP_BUF_LEN, f);
-      if (!feof(f)) {
-	p = s;
-	while ((q = strstr(p, "%{help="))) {
-	  q += 7;
-	  if ((p = strchr(q, '}'))) {
-	    *p = 0;
-	    list = nmalloc(sizeof(struct help_list_t));
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!strcasecmp2(cmd, cp->name)) {
+      char tmp[32];
 
-	    list->name = nmalloc(p - q + 1);
-	    strcpy(list->name, q);
-	    list->next = current->first;
-	    list->type = type;
-	    current->first = list;
-	    p++;
-	  } else
-	    p = "";
-	}
-      }
+      encrypt_pass(pass, tmp);
+      if (!strcmp(tmp, cp->pass))
+        return 1;
+      return 0;
     }
-    fclose(f);
-  }
+  return 0;
 }
 
-void add_help_reference(char *file)
+int has_cmd_pass(char *cmd) 
 {
-  char s[1024];
-  struct help_ref *current;
+  struct cmd_pass *cp;
+
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!strcasecmp2(cmd, cp->name))
+      return 1;
+  return 0;
+}
 
-  for (current = help_list; current; current = current->next)
-    if (!strcmp(current->name, file))
-      return;			/* Already exists, can't re-add :P */
-  current = nmalloc(sizeof(struct help_ref));
+void set_cmd_pass(char *ln, int shareit) {
+  struct cmd_pass *cp;
+  char *cmd;
 
-  current->name = nmalloc(strlen(file) + 1);
-  strcpy(current->name, file);
-  current->next = help_list;
-  current->first = NULL;
-  help_list = current;
-  egg_snprintf(s, sizeof s, "%smsg/%s", helpdir, file);
-  scan_help_file(current, s, 0);
-  egg_snprintf(s, sizeof s, "%s%s", helpdir, file);
-  scan_help_file(current, s, 1);
-  egg_snprintf(s, sizeof s, "%sset/%s", helpdir, file);
-  scan_help_file(current, s, 2);
+  cmd = newsplit(&ln);
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (!strcmp(cmd, cp->name))
+      break;
+  if (cp)
+    if (ln[0]) {
+      /* change */
+      strcpy(cp->pass, ln);
+      if (shareit)
+        botnet_send_cmdpass(-1, cp->name, cp->pass);
+    } else {
+      if (cp == cmdpass)
+        cmdpass = cp->next;
+      else {
+        struct cmd_pass *cp2;
+
+        cp2 = cmdpass;
+        while (cp2->next != cp)
+          cp2 = cp2->next;
+        cp2->next = cp->next;
+      }
+      if (shareit)
+        botnet_send_cmdpass(-1, cp->name, "");
+      nfree(cp->name);
+      nfree(cp);
+  } else if (ln[0]) {
+    /* create */
+    cp = nmalloc(sizeof(struct cmd_pass));
+    cp->next = cmdpass;
+    cmdpass = cp;
+    cp->name = nmalloc(strlen(cmd) + 1);
+    strcpy(cp->name, cmd);
+    strcpy(cp->pass, ln);
+    if (shareit)
+      botnet_send_cmdpass(-1, cp->name, cp->pass);
+  }
 }
+#endif
 
-void rem_help_reference(char *file)
-{
-  struct help_ref *current, *last = NULL;
-  struct help_list_t *item;
+#ifdef S_LASTCHECK
+char last_buf[128]="";
+#endif
+
+void check_last() {
+#ifdef S_LASTCHECK
+  char user[20];
+  struct passwd *pw;
+
+  if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "", STR("nocheck")))
+    return;
 
-  for (current = help_list; current; last = current, current = current->next)
-    if (!strcmp(current->name, file)) {
-      while ((item = current->first)) {
-	current->first = item->next;
-	nfree(item->name);
-	nfree(item);
+Context;
+  pw = getpwuid(geteuid());
+Context;
+  if (!pw) return;
+
+  strncpy0(user, pw->pw_name ? pw->pw_name : "" , sizeof(user));
+  if (user[0]) {
+    char *out;
+    char buf[50];
+
+    sprintf(buf, STR("last %s"), user);
+    if (shell_exec(buf, NULL, &out, NULL)) {
+      if (out) {
+        char *p;
+
+        p = strchr(out, '\n');
+        if (p)
+          *p = 0;
+        if (strlen(out) > 10) {
+          if (last_buf[0]) {
+            if (strncmp(last_buf, out, sizeof(last_buf))) {
+              char wrk[16384];
+
+              sprintf(wrk, STR("Login: %s"), out);
+              detected(DETECT_LOGIN, wrk);
+            }
+          }
+          strncpy0(last_buf, out, sizeof(last_buf));
+        }
+        nfree(out);
       }
-      nfree(current->name);
-      if (last)
-	last->next = current->next;
-      else
-	help_list = current->next;
-      nfree(current);
-      return;
     }
+  }
+#endif
 }
 
-void reload_help_data(void)
+void check_processes()
 {
-  struct help_ref *current = help_list, *next;
-  struct help_list_t *item;
+#ifdef S_PROCESSCHECK
+  char *proclist,
+   *out,
+   *p,
+   *np,
+   *curp,
+    buf[1024],
+    bin[128];
+
+  if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "", STR("nocheck")))
+    return;
 
-  help_list = NULL;
-  while (current) {
-    while ((item = current->first)) {
-      current->first = item->next;
-      nfree(item->name);
-      nfree(item);
+  proclist = (char *) (CFG_PROCESSLIST.ldata && ((char *) CFG_PROCESSLIST.ldata)[0] ?
+                       CFG_PROCESSLIST.ldata : CFG_PROCESSLIST.gdata && ((char *) CFG_PROCESSLIST.gdata)[0] ? CFG_PROCESSLIST.gdata : NULL);
+  if (!proclist)
+    return;
+
+  if (!shell_exec(STR("ps x"), NULL, &out, NULL))
+    return;
+
+  /* Get this binary's filename */
+  strncpy0(buf, binname, sizeof(buf));
+  p = strrchr(buf, '/');
+  if (p) {
+    p++;
+    strncpy0(bin, p, sizeof(bin));
+  } else {
+    bin[0] = 0;
+  }
+  /* Fix up the "permitted processes" list */
+  p = nmalloc(strlen(proclist) + strlen(bin) + 6);
+  strcpy(p, proclist);
+  strcat(p, " ");
+  strcat(p, bin);
+  strcat(p, " ");
+  proclist = p;
+  curp = out;
+  while (curp) {
+    np = strchr(curp, '\n');
+    if (np)
+      *np++ = 0;
+    if (atoi(curp) > 0) {
+      char *pid,
+       *tty,
+       *stat,
+       *time,
+        cmd[512],
+        line[2048];
+
+      strncpy0(line, curp, sizeof(line));
+      /* it's a process line */
+      /* Assuming format: pid tty stat time cmd */
+      pid = newsplit(&curp);
+      tty = newsplit(&curp);
+      stat = newsplit(&curp);
+      time = newsplit(&curp);
+      strncpy0(cmd, curp, sizeof(cmd));
+      /* skip any <defunct> procs "/bin/sh -c" crontab stuff and binname crontab stuff */
+      if (!strstr(cmd, STR("<defunct>")) && !strncmp(cmd, STR("/bin/sh -c"), 10)
+          && !strncmp(cmd, binname, strlen(binname))) {
+        /* get rid of any args */
+        if ((p = strchr(cmd, ' ')))
+          *p = 0;
+        /* remove [] or () */
+        if (strlen(cmd)) {
+          p = cmd + strlen(cmd) - 1;
+          if (((cmd[0] == '(') && (*p == ')')) || ((cmd[0] == '[') && (*p == ']'))) {
+            *p = 0;
+            strcpy(buf, cmd + 1);
+            strcpy(cmd, buf);
+          }
+        }
+
+        /* remove path */
+        if ((p = strrchr(cmd, '/'))) {
+          p++;
+          strcpy(buf, p);
+          strcpy(cmd, buf);
+        }
+
+        /* skip "ps" */
+        if (strcmp(cmd, "ps")) {
+          /* see if proc's in permitted list */
+          strcat(cmd, " ");
+          if ((p = strstr(proclist, cmd))) {
+            /* Remove from permitted list */
+            while (*p != ' ')
+              *p++ = 1;
+          } else {
+            char wrk[16384];
+
+            sprintf(wrk, STR("Unexpected process: %s"), line);
+            detected(DETECT_PROCESS, wrk);
+          }
+        }
+      }
     }
-    add_help_reference(current->name);
-    nfree(current->name);
-    next = current->next;
-    nfree(current);
-    current = next;
+    curp = np;
   }
+  nfree(proclist);
+  if (out)
+    nfree(out);
+#endif /* S_PROCESSCHECK */
 }
 
-void debug_help(int idx)
+void check_promisc()
 {
-  struct help_ref *current;
-  struct help_list_t *item;
-
-  for (current = help_list; current; current = current->next) {
-    dprintf(idx, "HELP FILE(S): %s\n", current->name);
-    for (item = current->first; item; item = item->next) {
-      dprintf(idx, "   %s (%s)\n", item->name, (item->type == 0) ? "msg/" :
-	      (item->type == 1) ? "" : "set/");
+#ifdef S_PROMISC
+#ifdef SIOCGIFCONF
+  char buf[8192];
+  struct ifreq ifreq,
+   *ifr;
+  struct ifconf ifcnf;
+  char *cp,
+   *cplim;
+  int sock;
+
+  if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "", STR("nocheck")))
+    return;
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  ifcnf.ifc_len = 8191;
+  ifcnf.ifc_buf = buf;
+  if (ioctl(sock, SIOCGIFCONF, (char *) &ifcnf) < 0) {
+    close(sock);
+    return;
+  }
+  ifr = ifcnf.ifc_req;
+  cplim = buf + ifcnf.ifc_len;
+  for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
+    ifr = (struct ifreq *) cp;
+    ifreq = *ifr;
+    if (!ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq)) {
+      if (ifreq.ifr_flags & IFF_PROMISC) {
+        close(sock);
+        detected(DETECT_PROMISC, STR("Detected promiscous mode"));
+        return;
+      }
     }
   }
+  close(sock);
+#endif /* SIOCGIFCONF */
+#endif /* S_PROMISC */
 }
 
-FILE *resolve_help(int dcc, char *file)
-{
-
-  char s[1024];
-  FILE *f;
-  struct help_ref *current;
-  struct help_list_t *item;
-
-  /* Somewhere here goes the eventual substituation */
-  if (!(dcc & HELP_TEXT))
-  {
-    for (current = help_list; current; current = current->next)
-      for (item = current->first; item; item = item->next)
-	if (!strcmp(item->name, file)) {
-	  if (!item->type && !dcc) {
-	    egg_snprintf(s, sizeof s, "%smsg/%s", helpdir, current->name);
-	    if ((f = fopen(s, "r")))
-	      return f;
-	  } else if (dcc && item->type) {
-	    if (item->type == 1)
-	      egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
-	    else
-	      egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
-	    if ((f = fopen(s, "r")))
-	      return f;
-	  }
-	}
-    /* No match was found, so we better return NULL */
-    return NULL;
+#ifdef S_ANTITRACE
+int traced = 0;
+
+void got_trace(int z)
+{
+  traced = 0;
+}
+#endif
+
+void check_trace(int n)
+{
+#ifdef S_ANTITRACE
+  int x,
+    parent,
+    i;
+  struct sigaction sv,
+   *oldsv = NULL;
+
+  if (n && !strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "", STR("nocheck")))
+    return;
+  parent = getpid();
+#ifdef __linux__
+  egg_bzero(&sv, sizeof(sv));
+  sv.sa_handler = got_trace;
+  sigemptyset(&sv.sa_mask);
+  oldsv = NULL;
+  sigaction(SIGTRAP, &sv, oldsv);
+  traced = 1;
+  asm("INT3");
+  sigaction(SIGTRAP, oldsv, NULL);
+  if (traced)
+    detected(DETECT_TRACE, STR("I'm being traced!"));
+  else {
+    x = fork();
+    if (x == -1)
+      return;
+    else if (x == 0) {
+      i = ptrace(PTRACE_ATTACH, parent, 0, 0);
+      if (i == (-1) && errno == EPERM)
+        detected(DETECT_TRACE, STR("I'm being traced!"));
+      else {
+        waitpid(parent, &i, 0);
+        kill(parent, SIGCHLD);
+        ptrace(PTRACE_DETACH, parent, 0, 0);
+        kill(parent, SIGCHLD);
+      }
+      exit(0);
+    } else
+      wait(&i);
   }
-  /* Since we're not dealing with help files, we should just prepend the filename with textdir */
-  simple_sprintf(s, "%s%s", textdir, file);
-  if (is_file(s))
-    return fopen(s, "r");
-  else
-    return NULL;
+#endif
+#ifdef __FreeBSD__
+  x = fork();
+  if (x == -1)
+    return;
+  else if (x == 0) {
+    i = ptrace(PT_ATTACH, parent, 0, 0);
+    if (i == (-1) && errno == EBUSY)
+      detected(DETECT_TRACE, STR("I'm being traced"));
+    else {
+      wait(&i);
+      i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
+      kill(parent, SIGCHLD);
+      wait(&i);
+      i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
+      wait(&i);
+    }
+    exit(0);
+  } else
+    waitpid(x, NULL, 0);
+#endif /* __FreeBSD__ */
+#ifdef __OpenBD__
+  x = fork();
+  if (x == -1)
+    return;
+  else if (x == 0) {
+    i = ptrace(PT_ATTACH, parent, 0, 0);
+    if (i == (-1) && errno == EBUSY)
+      detected(DETECT_TRACE, STR("I'm being traced"));
+    else {
+      wait(&i);
+      i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
+      kill(parent, SIGCHLD);
+      wait(&i);
+      i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
+      wait(&i);
+    }
+    exit(0);
+  } else
+    waitpid(x, NULL, 0);
+#endif /* __OpenBSD__ */
+#endif /* S_ANTITRACE */
+}
+
+
+struct cfg_entry *check_can_set_cfg(char *target, char *entryname)
+{
+  int i;
+  struct userrec *u;
+  struct cfg_entry *entry = NULL;
+
+  for (i = 0; i < cfg_count; i++)
+    if (!strcmp(cfg[i]->name, entryname)) {
+      entry = cfg[i];
+      break;
+    }
+  if (!entry)
+    return 0;
+  if (target) {
+    if (!(entry->flags & CFGF_LOCAL))
+      return 0;
+    if (!(u = get_user_by_handle(userlist, target)))
+      return 0;
+    if (!(u->flags & USER_BOT))
+      return 0;
+  } else {
+    if (!(entry->flags & CFGF_GLOBAL))
+      return 0;
+  }
+  return entry;
 }
 
-void showhelp(char *who, char *file, struct flag_record *flags, int fl)
-{
-  int lines = 0;
-  char s[HELP_BUF_LEN + 1];
-  FILE *f = resolve_help(fl, file);
-
-  if (f) {
-    help_subst(NULL, NULL, 0, HELP_IRC, NULL);	/* Clear flags */
-    while (!feof(f)) {
-      fgets(s, HELP_BUF_LEN, f);
-      if (!feof(f)) {
-	if (s[strlen(s) - 1] == '\n')
-	  s[strlen(s) - 1] = 0;
-	if (!s[0])
-	  strcpy(s, " ");
-	help_subst(s, who, flags, 0, file);
-	if ((s[0]) && (strlen(s) > 1)) {
-	  dprintf(DP_HELP, "NOTICE %s :%s\n", who, s);
-	  lines++;
+void set_cfg_str(char *target, char *entryname, char *data)
+{
+  struct cfg_entry *entry;
+  int free = 0;
+
+  if (!(entry = check_can_set_cfg(target, entryname)))
+    return;
+  if (data && !strcmp(data, "-"))
+    data = NULL;
+  if (data && (strlen(data) >= 1024))
+    data[1023] = 0;
+  if (target) {
+    struct userrec *u = get_user_by_handle(userlist, target);
+    struct xtra_key *xk;
+    char *olddata = entry->ldata;
+
+    if (u && !strcmp(botnetnick, u->handle)) {
+      if (data) {
+	entry->ldata = nmalloc(strlen(data) + 1);
+	strcpy(entry->ldata, data);
+      } else
+	entry->ldata = NULL;
+      if (entry->localchanged) {
+	int valid = 1;
+
+	entry->localchanged(entry, olddata, &valid);
+	if (!valid) {
+	  if (entry->ldata)
+	    nfree(entry->ldata);
+	  entry->ldata = olddata;
+	  data = olddata;
+	  olddata = NULL;
 	}
       }
     }
-    fclose(f);
-  }
-  if (!lines && !(fl & HELP_TEXT))
-    dprintf(DP_HELP, "NOTICE %s :%s\n", who, IRC_NOHELP2);
-}
-
-static int display_tellhelp(int idx, char *file, FILE *f,
-			    struct flag_record *flags)
-{
-  char s[HELP_BUF_LEN + 1];
-  int lines = 0;
-
-  if (f) {
-    help_subst(NULL, NULL, 0,
-	       (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
-    while (!feof(f)) {
-      fgets(s, HELP_BUF_LEN, f);
-      if (!feof(f)) {
-	if (s[strlen(s) - 1] == '\n')
-	  s[strlen(s) - 1] = 0;
-	if (!s[0])
-	  strcpy(s, " ");
-	help_subst(s, dcc[idx].nick, flags, 1, file);
-	if (s[0]) {
-	  dprintf(idx, "%s\n", s);
-	  lines++;
-	}
+    xk = nmalloc(sizeof(struct xtra_key));
+    egg_bzero(xk, sizeof(struct xtra_key));
+    xk->key = nmalloc(strlen(entry->name) + 1);
+    strcpy(xk->key, entry->name);
+    if (data) {
+      xk->data = nmalloc(strlen(data) + 1);
+      strcpy(xk->data, data);
+    }
+    set_user(&USERENTRY_CONFIG, u, xk);
+    if (olddata)
+      nfree(olddata);
+  } else {
+    char *olddata = entry->gdata;
+
+    if (data) {
+      free = 1;
+      entry->gdata = nmalloc(strlen(data) + 1);
+      strcpy(entry->gdata, data);
+    } else
+      entry->gdata = NULL;
+    if (entry->globalchanged) {
+      int valid = 1;
+
+      entry->globalchanged(entry, olddata, &valid);
+      if (!valid) {
+	if (entry->gdata)
+	  nfree(entry->gdata);
+	entry->gdata = olddata;
+	olddata = NULL;
       }
     }
-    fclose(f);
+    if (!cfg_noshare)
+      botnet_send_cfg_broad(-1, entry);
+    if (olddata)
+      nfree(olddata);
   }
-  return lines;
+
+//  if (free)
+//    nfree(entry->gdata);
 }
 
-void tellhelp(int idx, char *file, struct flag_record *flags, int fl)
+void userfile_cfg_line(char *ln)
 {
-  int lines = 0;
-  FILE *f = resolve_help(HELP_DCC | fl, file);
+  char *name;
+  int i;
+  struct cfg_entry *cfgent = NULL;
+
+  name = newsplit(&ln);
+  for (i = 0; !cfgent && (i < cfg_count); i++)
+    if (!strcmp(cfg[i]->name, name))
+      cfgent = cfg[i];
+  if (cfgent) {
+    set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
+  } else
+    putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
 
-  if (f)
-    lines = display_tellhelp(idx, file, f, flags);
-  if (!lines && !(fl & HELP_TEXT))
-    dprintf(idx, "%s\n", IRC_NOHELP2);
 }
 
-/* Same as tellallhelp, just using wild_match instead of strcmp
- */
-void tellwildhelp(int idx, char *match, struct flag_record *flags)
-{
-  struct help_ref *current;
-  struct help_list_t *item;
-  FILE *f;
-  char s[1024];
-
-  s[0] = '\0';
-  for (current = help_list; current; current = current->next)
-    for (item = current->first; item; item = item->next)
-      if (wild_match(match, item->name) && item->type) {
-	if (item->type == 1)
-	  egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
-	else
-	  egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
-	if ((f = fopen(s, "r")))
-	  display_tellhelp(idx, item->name, f, flags);
-      }
-  if (!s[0])
-    dprintf(idx, "%s\n", IRC_NOHELP2);
+void got_config_share(int idx, char *ln)
+{
+  char *name;
+  int i;
+  struct cfg_entry *cfgent = NULL;
+
+  cfg_noshare++;
+  name = newsplit(&ln);
+  for (i = 0; !cfgent && (i < cfg_count); i++)
+    if (!strcmp(cfg[i]->name, name))
+      cfgent = cfg[i];
+  if (cfgent) {
+    set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
+    botnet_send_cfg_broad(idx, cfgent);
+  } else
+    putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
+  cfg_noshare--;
 }
 
-/* Same as tellwildhelp, just using strcmp instead of wild_match
- */
-void tellallhelp(int idx, char *match, struct flag_record *flags)
+void add_cfg(struct cfg_entry *entry)
 {
-  struct help_ref *current;
-  struct help_list_t *item;
-  FILE *f;
-  char s[1024];
+  cfg = (void *) user_realloc(cfg, sizeof(void *) * (cfg_count + 1));
+  cfg[cfg_count] = entry;
+  cfg_count++;
+  entry->ldata = NULL;
+  entry->gdata = NULL;
+}
 
-  s[0] = '\0';
-  for (current = help_list; current; current = current->next)
-    for (item = current->first; item; item = item->next)
-      if (!strcmp(match, item->name) && item->type) {
+void trigger_cfg_changed()
+{
+  int i;
+  struct userrec *u;
+  struct xtra_key *xk;
+
+  u = get_user_by_handle(userlist, botnetnick);
+
+  for (i = 0; i < cfg_count; i++) {
+    if (cfg[i]->flags & CFGF_LOCAL) {
+      xk = get_user(&USERENTRY_CONFIG, u);
+      while (xk && strcmp(xk->key, cfg[i]->name))
+	xk = xk->next;
+      if (xk) {
+	putlog(LOG_DEBUG, "*", STR("trigger_cfg_changed for %s"), cfg[i]->name ? cfg[i]->name : "(null)");
+	if (!strcmp(cfg[i]->name, xk->key ? xk->key : "")) {
+	  set_cfg_str(botnetnick, cfg[i]->name, xk->data);
+	}
+      }
+    }
+  }
+}
 
-	if (item->type == 1)
-	  egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
-	else
-	  egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
-	if ((f = fopen(s, "r")))
-	  display_tellhelp(idx, item->name, f, flags);
+
+
+int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
+{
+  FILE *inpFile,
+   *outFile,
+   *errFile;
+  char tmpfile[161];
+  int x,
+    fd;
+
+  if (!cmdline)
+    return 0;
+  /* Set up temp files */
+  /* always use mkstemp() when handling temp filess! -dizz */
+  sprintf(tmpfile, STR("%s.in-XXXXXX"), tempdir);
+  if ((fd = mkstemp(tmpfile)) == -1 || (inpFile = fdopen(fd, "w+")) == NULL) {
+    if (fd != -1) {
+      unlink(tmpfile);
+      close(fd);
+    }
+    putlog(LOG_ERRORS, "*" , STR("exec: Couldn't open %s"), tmpfile);
+    return 0;
+  }
+  unlink(tmpfile);
+  if (input) {
+    if (fwrite(input, 1, strlen(input), inpFile) != strlen(input)) {
+      fclose(inpFile);
+      putlog(LOG_ERRORS, "*", STR("exec: Couldn't write to %s"), tmpfile);
+      return 0;
+    }
+    fseek(inpFile, 0, SEEK_SET);
+  }
+  unlink(tmpfile);
+  sprintf(tmpfile, STR("%s.err-XXXXXX"), tempdir);
+  if ((fd = mkstemp(tmpfile)) == -1 || (errFile = fdopen(fd, "w+")) == NULL) {
+    if (fd != -1) {
+      unlink(tmpfile);
+      close(fd);
+    }
+    putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
+    return 0;
+  }
+  unlink(tmpfile);
+  sprintf(tmpfile, STR("%s.out-XXXXXX"), tempdir);
+  if ((fd = mkstemp(tmpfile)) == -1 || (outFile = fdopen(fd, "w+")) == NULL) {
+    if (fd != -1) {
+      unlink(tmpfile);
+      close(fd);
+    }
+    putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
+    return 0;
+  }
+  unlink(tmpfile);
+  x = fork();
+  if (x == -1) {
+    putlog(LOG_ERRORS, "*", STR("exec: fork() failed"));
+    fclose(inpFile);
+    fclose(errFile);
+    fclose(outFile);
+    return 0;
+  }
+  if (x) {
+    /* Parent: wait for the child to complete */
+    int st = 0;
+
+    waitpid(x, &st, 0);
+    /* Now read the files into the buffers */
+    fclose(inpFile);
+    fflush(outFile);
+    fflush(errFile);
+    if (erroutput) {
+      char *buf;
+      int fs;
+
+      fseek(errFile, 0, SEEK_END);
+      fs = ftell(errFile);
+      if (fs == 0) {
+        (*erroutput) = NULL;
+      } else {
+        buf = nmalloc(fs + 1);
+        fseek(errFile, 0, SEEK_SET);
+        fread(buf, 1, fs, errFile);
+        buf[fs] = 0;
+        (*erroutput) = buf;
+      }
+    }
+    fclose(errFile);
+    if (output) {
+      char *buf;
+      int fs;
+
+      fseek(outFile, 0, SEEK_END);
+      fs = ftell(outFile);
+      if (fs == 0) {
+        (*output) = NULL;
+      } else {
+        buf = nmalloc(fs + 1);
+        fseek(outFile, 0, SEEK_SET);
+        fread(buf, 1, fs, outFile);
+        buf[fs] = 0;
+        (*output) = buf;
       }
-  if (!s[0])
-    dprintf(idx, "%s\n", IRC_NOHELP2);
+    }
+    fclose(outFile);
+    return 1;
+  } else {
+    /* Child: make fd's and set them up as std* */
+    int ind,
+      outd,
+      errd;
+    char *argv[4];
+
+    ind = fileno(inpFile);
+    outd = fileno(outFile);
+    errd = fileno(errFile);
+    if (dup2(ind, STDIN_FILENO) == (-1)) {
+      exit(1);
+    }
+    if (dup2(outd, STDOUT_FILENO) == (-1)) {
+      exit(1);
+    }
+    if (dup2(errd, STDERR_FILENO) == (-1)) {
+      exit(1);
+    }
+    argv[0] = STR("/bin/sh");
+    argv[1] = STR("-c");
+    argv[2] = cmdline;
+    argv[3] = NULL;
+    execvp(argv[0], &argv[0]);
+    exit(1);
+  }
+
 }
 
-/* Substitute vars in a lang text to dcc chatter
- */
-void sub_lang(int idx, char *text)
-{
-  char s[1024];
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
-
-  get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
-  help_subst(NULL, NULL, 0,
-	     (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
-  strncpyz(s, text, sizeof s);
-  if (s[strlen(s) - 1] == '\n')
-    s[strlen(s) - 1] = 0;
-  if (!s[0])
-    strcpy(s, " ");
-  help_subst(s, dcc[idx].nick, &fr, 1, botnetnick);
-  if (s[0])
-    dprintf(idx, "%s\n", s);
-}
-
-/* This will return a pointer to the first character after the @ in the
- * string given it.  Possibly it's time to think about a regexp library
- * for eggdrop...
- */
-char *extracthostname(char *hostmask)
+
+
+
+int ucnt = 0;
+static void updatelocal(void)
 {
-  char *p = strrchr(hostmask, '@');
-  return p ? p + 1 : "";
+#ifdef LEAF
+  module_entry *me;
+#endif
+  Context;
+  if (ucnt < 300) {
+    ucnt++;
+    return;
+  } 
+  del_hook(HOOK_SECONDLY, (Function) updatelocal);
+  ucnt = 0;
+
+  /* let's drop the server connection ASAP */
+#ifdef LEAF
+  if ((me = module_find("server", 0, 0))) {
+    Function *func = me->funcs;
+    (func[SERVER_NUKESERVER]) ("Updating...");
+  }
+#endif
+
+  botnet_send_chat(-1, botnetnick, "Updating...");
+  botnet_send_bye();
+
+  fatal("Updating...", 1);
+  usleep(2000 * 500);
+  bg_send_quit(BG_ABORT);
+  unlink(pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
+  system(binname); //start new bot. 
+  exit(0);
 }
 
-/* Show motd to dcc chatter
- */
-void show_motd(int idx)
+int updatebin (int idx, char *par, int autoi)
 {
-  FILE *vv;
-  char s[1024];
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
+  char *path = NULL,
+   *newbin;
+  char buf[2048], old[1024];
+  struct stat sb;
+  int i;
+#ifdef LEAF
+  module_entry *me;
+#endif
 
-  if (!is_file(motdfile))
-    return;
+  path = newsplit(&par);
+  par = path;
+  if (!par[0]) {
+    if (idx)
+      dprintf(idx, "Not enough parameters.\n");
+    return 1;
+  }
+  path = nmalloc(strlen(binname) + strlen(par));
+  strcpy(path, binname);
+  newbin = strrchr(path, '/');
+  if (!newbin) {
+    nfree(path);
+    if (idx)
+      dprintf(idx, "Don't know current binary name\n");
+    return 1;
+  }
+  newbin++;
+  if (strchr(par, '/')) {
+    *newbin = 0;
+    if (idx)
+      dprintf(idx, "New binary must be in %s and name must be specified without path information\n", path);
+    nfree(path);
+    return 1;
+  }
+  strcpy(newbin, par);
+  if (!strcmp(path, binname)) {
+    nfree(path);
+    if (idx)
+      dprintf(idx, "Can't update with the current binary\n");
+    return 1;
+  }
+  if (stat(path, &sb)) {
+    if (idx)
+      dprintf(idx, "%s can't be accessed\n", path);
+    nfree(path);
+    return 1;
+  }
+  if (chmod(path, S_IRUSR | S_IWUSR | S_IXUSR)) {
+    if (idx)
+      dprintf(idx, "Can't set mode 0600 on %s\n", path);
+    nfree(path);
+    return 1;
+  }
 
-  vv = fopen(motdfile, "r");
-  if (!vv)
-    return;
+  //make a backup just in case.
 
-  get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
-  dprintf(idx, "\n");
-  /* reset the help_subst variables to their defaults */
-  help_subst(NULL, NULL, 0,
-	     (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
-  while (!feof(vv)) {
-    fgets(s, 120, vv);
-    if (!feof(vv)) {
-      if (s[strlen(s) - 1] == '\n')
-	s[strlen(s) - 1] = 0;
-      if (!s[0])
-	strcpy(s, " ");
-      help_subst(s, dcc[idx].nick, &fr, 1, botnetnick);
-      if (s[0])
-	dprintf(idx, "%s\n", s);
-    }
+  egg_snprintf(old, sizeof old, "%s.bin.old", tempdir);
+  copyfile(binname, old);
+
+  if (movefile(path, binname)) {
+    if (idx)
+      dprintf(idx, "Can't rename %s to %s\n", path, binname);
+    nfree(path);
+    return 1;
   }
-  fclose(vv);
-  dprintf(idx, "\n");
-}
 
-/* Show banner to telnet user 
- */
-void show_banner(int idx) {
-  FILE *vv;
-  char s[1024];
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
+  sprintf(buf, "%s", binname);
+  
+#ifdef LEAF
+  if (localhub) {
+    /* if localhub = 1, this is the spawn bot and controls
+     * the spawning of new bots. */
 
-  if (!is_file(bannerfile))
-    return;
+    sprintf(buf, "%s -P %d", buf, getpid());
+  } 
+#endif
 
-  vv = fopen(bannerfile, "r");
-  if (!vv)
-    return;
+  //safe to run new binary..
+#ifdef LEAF
+  if (!autoi && !localhub) //dont delete pid for auto update!!!
+#endif
+    unlink(pid_file); //delete pid so new binary doesnt exit.
+#ifdef HUB
+  listen_all(my_port, 1); //close the listening port...
+#endif
+  i = system(buf);
+  if (i == -1 || i == 1) {
+    if (idx)
+      dprintf(idx, "Couldn't restart new binary (error %d)\n", i);
+      putlog(LOG_MISC, "*", "Couldn't restart new binary (error %d)\n", i);
+    return i;
 
-  get_user_flagrec(dcc[idx].user, &fr,dcc[idx].u.chat->con_chan);
-  /* reset the help_subst variables to their defaults */
-  help_subst(NULL, NULL, 0, 0, NULL);
-  while(!feof(vv)) {
-    fgets(s, 120, vv);
-    if (!feof(vv)) {
-      if (!s[0])
-	strcpy(s, " \n");
-      help_subst(s, dcc[idx].nick, &fr, 0, botnetnick);
-      dprintf(idx, "%s", s);
+  } else {
+
+#ifdef LEAF
+    if (!autoi && !localhub) {
+      /* let's drop the server connection ASAP */
+      if ((me = module_find("server", 0, 0))) {
+        Function *func = me->funcs;
+        (func[SERVER_NUKESERVER]) ("Updating...");
+      }
+#endif
+      if (idx)
+        dprintf(idx, "Updating...bye\n");
+      putlog(LOG_MISC, "*", "Updating...\n");
+      botnet_send_chat(-1, botnetnick, "Updating...");
+      botnet_send_bye();
+      fatal("Updating...", 1);
+      usleep(2000 * 500);
+      bg_send_quit(BG_ABORT);
+
+      exit(0);
+      //No need to return :)
+#ifdef LEAF
+    } else {
+      if (localhub && autoi) {
+        add_hook(HOOK_SECONDLY, (Function) updatelocal);
+        return 0;
+      }
     }
+#endif
   }
-  fclose(vv);
+  //This shouldn't happen...
+  return 2;
 }
 
-/* Create a string with random letters and digits
- */
-void make_rand_str(char *s, int len)
+void EncryptFile(char *infile, char *outfile)
 {
-  int j;
+  char  buf[8192];
+//  char *temps;
+  FILE *f, *f2;
+Context;
+  f  = fopen(infile, "r");
+  if(!f)
+    return;      
+  f2 = fopen(outfile, "w");
+  if (!f2)
+    return;
+Context;
 
-  for (j = 0; j < len; j++) {
-    if (random() % 3 == 0)
-      s[j] = '0' + (random() % 10);
-    else
-      s[j] = 'a' + (random() % 26);
+  while (fscanf(f,"%[^\n]\n",buf) != EOF) {
+Context;
+    lfprintf(f2, "%s\n", buf);
+Context;
+  }
+  fclose(f);
+  fclose(f2);
+}
+void DecryptFile(char *infile, char *outfile)
+{
+  char  buf[8192], *temps;
+  FILE *f, *f2;
+
+  f  = fopen(infile, "r");
+  if (!f)
+    return;      
+  f2 = fopen(outfile, "w");
+  if (!f2)
+    return;
+
+  while (fscanf(f,"%[^\n]\n",buf) != EOF) {
+    temps = (char *) decrypt_string(netpass, decryptit(buf));
+    fprintf(f2, "%s\n",temps);
+    nfree(temps);
   }
-  s[len] = 0;
+  fclose(f);
+  fclose(f2);
 }
 
-/* Convert an octal string into a decimal integer value.  If the string
- * is empty or contains non-octal characters, -1 is returned.
- */
-int oatoi(const char *octal)
+int bot_aggressive_to(struct userrec *u)
 {
-  register int i;
+  char mypval[20],
+    botpval[20];
 
-  if (!*octal)
-    return -1;
-  for (i = 0; ((*octal >= '0') && (*octal <= '7')); octal++)
-    i = (i * 8) + (*octal - '0');
-  if (*octal)
-    return -1;
-  return i;
+  link_pref_val(u, botpval);
+  link_pref_val(get_user_by_handle(userlist, botnetnick), mypval);
+
+//printf("vals: my: %s them: %s\n", mypval, botpval);
+
+  if (strcmp(mypval, botpval) < 0)
+    return 1;
+  else
+    return 0;
 }
 
-/* Return an allocated buffer which contains a copy of the string
- * 'str', with all 'div' characters escaped by 'mask'. 'mask'
- * characters are escaped too.
- *
- * Remember to free the returned memory block.
- */
-char *str_escape(const char *str, const char div, const char mask)
+void detected(int code, char *msg)
 {
-  const int	 len = strlen(str);
-  int		 buflen = (2 * len), blen = 0;
-  char		*buf = nmalloc(buflen + 1), *b = buf;
-  const char	*s;
+#ifdef LEAF
+  module_entry *me;
+#endif
+  char *p = NULL;
+  char tmp[512];
+  struct userrec *u;
+  struct flag_record fr = { FR_GLOBAL, 0, 0 };
+  int act;
+
+  u = get_user_by_handle(userlist, botnetnick);
+#ifdef S_LASTCHECK
+  if (code == DETECT_LOGIN)
+    p = (char *) (CFG_LOGIN.ldata ? CFG_LOGIN.ldata : (CFG_LOGIN.gdata ? CFG_LOGIN.gdata : NULL));
+#endif
+#ifdef S_ANTITRACE
+  if (code == DETECT_TRACE)
+    p = (char *) (CFG_TRACE.ldata ? CFG_TRACE.ldata : (CFG_TRACE.gdata ? CFG_TRACE.gdata : NULL));
+#endif
+#ifdef S_PROMISC
+  if (code == DETECT_PROMISC)
+    p = (char *) (CFG_PROMISC.ldata ? CFG_PROMISC.ldata : (CFG_PROMISC.gdata ? CFG_PROMISC.gdata : NULL));
+#endif
+#ifdef S_PROCESSCHECK
+  if (code == DETECT_PROCESS)
+    p = (char *) (CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : (CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : NULL));
+#endif
+#ifdef S_HIJACKCHECK
+  if (code == DETECT_SIGCONT)
+    p = (char *) (CFG_HIJACK.ldata ? CFG_HIJACK.ldata : (CFG_HIJACK.gdata ? CFG_HIJACK.gdata : NULL));
+#endif
 
-  if (!buf)
-    return NULL;
-  for (s = str; *s; s++) {
-    /* Resize buffer. */
-    if ((buflen - blen) <= 3) {
-      buflen = (buflen * 2);
-      buf = nrealloc(buf, buflen + 1);
-      if (!buf)
-	return NULL;
-      b = buf + blen;
+  if (!p)
+    act = DET_WARN;
+  else if (!strcmp(p, STR("die")))
+    act = DET_DIE;
+  else if (!strcmp(p, STR("reject")))
+    act = DET_REJECT;
+  else if (!strcmp(p, STR("suicide")))
+    act = DET_SUICIDE;
+  else if (!strcmp(p, STR("nocheck")))
+    act = DET_NOCHECK;
+  else if (!strcmp(p, STR("ignore")))
+    act = DET_IGNORE;
+  else
+    act = DET_WARN;
+  switch (act) {
+  case DET_IGNORE:
+    break;
+  case DET_WARN:
+    putlog(LOG_WARN, "*", msg);
+    break;
+  case DET_REJECT:
+    do_fork();
+    putlog(LOG_WARN, "*", STR("Setting myself +d: %s"), msg);
+    sprintf(tmp, STR("+d: %s"), msg);
+    set_user(&USERENTRY_COMMENT, u, tmp);
+    get_user_flagrec(u, &fr, 0);
+    fr.global = USER_DEOP | USER_BOT;
+
+    set_user_flagrec(u, &fr, 0);
+    sleep(1);
+    break;
+  case DET_DIE:
+    putlog(LOG_WARN, "*", STR("Dying: %s"), msg);
+    sprintf(tmp, STR("Dying: %s"), msg);
+    set_user(&USERENTRY_COMMENT, u, tmp);
+#ifdef LEAF
+    if ((me = module_find("server", 0, 0))) {
+      Function *func = me->funcs;
+      (func[SERVER_NUKESERVER]) ("BBL");
+    }
+#endif
+    sleep(1);
+    fatal(msg, 0);
+    break;
+  case DET_SUICIDE:
+    putlog(LOG_WARN, "*", STR("Comitting suicide: %s"), msg);
+    sprintf(tmp, STR("Suicide: %s"), msg);
+    set_user(&USERENTRY_COMMENT, u, tmp);
+#ifdef LEAF
+    if ((me = module_find("server", 0, 0))) {
+      Function *func = me->funcs;
+      (func[SERVER_NUKESERVER]) ("HARAKIRI!!");
     }
+#endif
+    sleep(1);
+    unlink(binname);
+#ifdef HUB
+    unlink(userfile);
+    sprintf(tmp, STR("%s~"), userfile);
+    unlink(tmp);
+//    unlink(logfile);
+//    sprintf(tmp, STR("%s~"), logfile);
+//    unlink(tmp);
+#endif
+    fatal(msg, 0);
+    break;
+  case DET_NOCHECK:
+    break;
+  }
+}
 
-    if (*s == div || *s == mask) {
-      sprintf(b, "%c%02x", mask, *s);
-      b += 3;
-      blen += 3;
-    } else {
-      *(b++) = *s;
-      blen++;
+
+
+char * kickreason(int kind) {
+  int r;
+  r=random();
+  switch (kind) {
+  case KICK_BANNED:
+    switch (r % 6) {
+    case 0: return STR("bye");
+    case 1: return STR("banned");
+    case 2: return STR("bummer");
+    case 3: return STR("go away");
+    case 4: return STR("cya around looser");
+    case 5: return STR("unwanted!");
+    }
+  case KICK_KUSER:
+    switch (r % 4) {
+    case 0: return STR("not wanted");
+    case 1: return STR("something tells me you're annoying");
+    case 2: return STR("don't bug me looser");
+    case 3: return STR("creep");
+    }
+  case KICK_KICKBAN:
+    switch (r % 4) {
+    case 0: return STR("gone");
+    case 1: return STR("stupid");
+    case 2: return STR("looser");
+    case 3: return STR("...");
+    }     
+  case KICK_MASSDEOP:
+    switch (r % 8) {
+    case 0: return STR("spammer!");
+    case 1: return STR("easy on the modes now");
+    case 2: return STR("mode this");
+    case 3: return STR("nice try");
+    case 4: return STR("really?");
+    case 5: return STR("mIRC sux for mdop kiddo");
+    case 6: return STR("scary... really scary...");
+    case 7: return STR("you lost the game!");
+    }
+  case KICK_BADOP:
+    switch (r % 5) {
+    case 0: return STR("neat...");
+    case 1: return STR("oh, no you don't. go away.");
+    case 2: return STR("didn't you forget something now?");
+    case 3: return STR("no");
+    case 4: return STR("hijack this");
+    }
+  case KICK_BADOPPED:
+    switch (r % 5) {
+    case 0: return STR("buggar off kid");
+    case 1: return STR("asl?");
+    case 2: return STR("whoa... what a hacker... skills!");
+    case 3: return STR("yes! yes! yes! hit me baby one more time!");
+    case 4: return STR("with your skills, you're better off jacking off than hijacking");
+    }
+  case KICK_MANUALOP:
+    switch (r % 6) {
+    case 0: return STR("naughty kid");
+    case 1: return STR("didn't someone tell you that is bad?");
+    case 2: return STR("want perm?");
+    case 3: return STR("see how much good that did you?");
+    case 4: return STR("not a smart move...");
+    case 5: return STR("jackass!");
+    }
+  case KICK_MANUALOPPED:
+    switch (r % 8) {
+    case 0: return STR("your pal got mean friends. like me.");
+    case 1: return STR("uhh now.. don't wake me up...");
+    case 2: return STR("hi hun. missed me?");
+    case 3: return STR("spammer! die!");
+    case 4: return STR("boo!");
+    case 5: return STR("that @ was useful, don't ya think?");
+    case 6: return STR("not in my book");
+    case 7: return STR("lol, really?");
+    }
+  case KICK_CLOSED:
+    switch (r % 17) {
+    case 0: return STR("locked");
+    case 1: return STR("later");
+    case 2: return STR("closed for now");
+    case 3: return STR("sorry, but it's getting late, locking channel. cya around");
+    case 4: return STR("better safe than sorry");
+    case 5: return STR("cleanup, come back later");
+    case 6: return STR("this channel is closed");
+    case 7: return STR("shutting down for now");
+    case 8: return STR("lockdown");
+    case 9: return STR("reopening later");
+    case 10: return STR("not for the public atm");
+    case 11: return STR("private channel for now");
+    case 12: return STR("might reopen soon, might reopen later");
+    case 13: return STR("you're not supposed to be here right now");
+    case 14: return STR("sorry, closed");
+    case 15: return STR("try us later, atm we're locked down");
+    case 16: return STR("closed. try tomorrow");
     }
+  case KICK_FLOOD:
+    switch (r % 7) {
+    case 0: return STR("so much bullshit in such a short time. amazing.");
+    case 1: return STR("slow down. i'm trying to read here.");
+    case 2: return STR("uhm... you actually think irc is for talking?");
+    case 3: return STR("talk talk talk");
+    case 4: return STR("blabbering are we?");
+    case 5: return STR("... and i don't even like you!");
+    case 6: return STR("and you're outa here...");
+
+    }
+  case KICK_NICKFLOOD:
+    switch (r % 7) {
+    case 0: return STR("make up your mind?");
+    case 1: return STR("be schizofrenic elsewhere");
+    case 2: return STR("I'm loosing track of you... not!");
+    case 3: return STR("that is REALLY annoying");
+    case 4: return STR("try this: /NICK looser");
+    case 5: return STR("playing hide 'n' seek?");
+    case 6: return STR("gotcha!");
+    }
+  case KICK_KICKFLOOD:
+    switch (r % 6) {
+    case 0: return STR("easier to just leave if you wan't to be alone");
+    case 1: return STR("cool down");
+    case 2: return STR("don't be so damned aggressive. that's my job.");
+    case 3: return STR("kicking's fun, isn't it?");
+    case 4: return STR("what's the rush?");
+    case 5: return STR("next time you do that, i'll kick you again");
+
+    }
+  case KICK_BOGUSUSERNAME:
+    return STR("bogus username");
+  case KICK_MEAN:
+    switch (r % 11) {
+    case 0: return STR("hey! that wasn't very nice!");
+    case 1: return STR("don't fuck with my pals");
+    case 2: return STR("meanie!");
+    case 3: return STR("I can be a bitch too...");
+    case 4: return STR("leave the bots alone, will ya?");
+    case 5: return STR("not very clever");
+    case 6: return STR("watch it");
+    case 7: return STR("fuck off");
+    case 8: return STR("easy now. that's a friend.");
+    case 9: return STR("abuse of power. leave that to me, will ya?");      
+    case 10: return STR("there as some things you cannot do, and that was one of them...");
+    }
+  case KICK_BOGUSKEY:
+    return STR("I have a really hard time reading that key");
+  default:
+    return "OMFG@YUO";    
   }
-  *b = 0;
-  return buf;
+
 }
 
-/* Search for a certain character 'div' in the string 'str', while
- * ignoring escaped characters prefixed with 'mask'.
- *
- * The string
- *
- *   "\\3a\\5c i am funny \\3a):further text\\5c):oink"
- *
- * as str, '\\' as mask and ':' as div would change the str buffer
- * to
- *
- *   ":\\ i am funny :)"
- *
- * and return a pointer to "further text\\5c):oink".
- *
- * NOTE: If you look carefully, you'll notice that strchr_unescape()
- *       behaves differently than strchr().
- */
-char *strchr_unescape(char *str, const char div, register const char esc_char)
+
+
+char kickprefix[25] = "";
+char bankickprefix[25] = "";
+
+void makeplaincookie(char *chname, char *nick, char *buf)
 {
-  char		 buf[3];
-  register char	*s, *p;
+  /*
+     plain cookie:
+     Last 6 digits of time
+     Last 5 chars of nick
+     Last 4 regular chars of chan
+   */
+  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);
+}
 
-  buf[3] = 0;
-  for (s = p = str; *s; s++, p++) {
-    if (*s == esc_char) {	/* Found escape character.		*/
-      /* Convert code to character. */
-      buf[0] = s[1], buf[1] = s[2];
-      *p = (unsigned char) strtol(buf, NULL, 16);
-      s += 2;
-    } else if (*s == div) {
-      *p = *s = 0;
-      return (s + 1);		/* Found searched for character.	*/
-    } else
-      *p = *s;
+int goodpass(char *pass, int idx, char *nick)
+{
+  int i, nalpha = 0, lcase = 0, ucase = 0, ocase = 0, tc;
+
+  char *tell;
+  tell = nmalloc(300);
+
+  if (!pass[0]) 
+    return 0;
+
+  for (i = 0; i < strlen(pass); i++) {
+    tc = (int) pass[i];
+    if (tc < 58 && tc > 47)
+      ocase++; //number
+    else if (tc < 91 && tc > 64)
+      ucase++; //upper case
+    else if (tc < 123 && tc > 96)
+      lcase++; //lower case
+    else
+       nalpha++; //non-alphabet/number
   }
-  *p = 0;
-  return NULL;
+
+  if (ocase < 1 || lcase < 2 || ucase < 2 || nalpha < 1 || strlen(pass) < 8) {
+
+    sprintf(tell, "Insecure pass, must be: ");
+
+    if (ocase < 1)
+      strcat(tell, "\002>= 1 number\002, ");
+    else
+      strcat(tell, ">= 1 number, ");
+
+    if (lcase < 2)
+      strcat(tell, "\002>= 2 lcase\002, ");
+    else
+      strcat(tell, ">= 2 lowercase, ");
+
+    if (ucase < 2)
+      strcat(tell, "\002>= 2 ucase\002, ");
+    else
+      strcat(tell, ">= 2 uppercase, ");
+
+    if (nalpha < 1)
+      strcat(tell, "\002>= 1 non-alpha/num\002, ");
+    else
+      strcat(tell, ">= 1 non-alpha/num, ");
+
+    if (strlen(pass) < 8)
+      strcat(tell, "\002>= 8 chars.\002");
+    else
+      strcat(tell, ">= 8 chars.");
+
+    if (idx)
+      dprintf(idx, "%s\n", tell);
+    else if (nick[0])
+      dprintf(DP_HELP, "NOTICE %s :%s\n", nick, tell);
+    
+    return 0;
+  }
+  
+
+  return 1;
 }
 
-/* As strchr_unescape(), but converts the complete string, without
- * searching for a specific delimiter character.
- */
-void str_unescape(char *str, register const char esc_char)
+//strcpy(dcc[idx].nick, char *string);
+//.nick is char nick[uhostlen]
+
+char *makehash(struct userrec *u, char *rand)
 {
-  (void) strchr_unescape(str, 0, esc_char);
+  int i = 0;
+  MD5_CTX ctx;
+  unsigned char md5out[33];
+  char md5string[33], hash[500], *ret = NULL;
+
+
+Context;
+//    strcpy(hash, rand);
+Context;
+//    strcat(hash, get_user(&USERENTRY_SECPASS, u));
+ 
+    sprintf(hash, "%s%s%s", rand, (char *) get_user(&USERENTRY_SECPASS, u), authkey ? authkey : "");
+
+    putlog(LOG_DEBUG, "*", "Making hash from %s %s: %s", rand, get_user(&USERENTRY_SECPASS, u), hash);
+
+    MD5_Init(&ctx);
+    MD5_Update(&ctx, hash, strlen(hash));
+    MD5_Final(md5out, &ctx);
+
+    for(i=0; i<16; i++)
+      sprintf(md5string + (i*2), "%.2x", md5out[i]);
+   
+    putlog(LOG_DEBUG, "*", "MD5 of hash: %s", md5string);
+Context;
+    ret = md5string;
+Context;
+//    sprintf(ret, "%s", md5string);
+    return ret;
 }
 
-/* Kills the bot. s1 is the reason shown to other bots, 
- * s2 the reason shown on the partyline. (Sup 25Jul2001)
- */
-void kill_bot(char *s1, char *s2)
+
+int new_auth(void)
 {
-  call_hook(HOOK_DIE);
-  chatout("*** %s\n", s1);
-  botnet_send_chat(-1, botnetnick, s1);
-  botnet_send_bye();
-  write_userfile(-1);
-  fatal(s2, 0);
+  int i = auth_total;
+
+Context;
+  if (auth_total == max_auth)
+    return -1;
+
+  auth_total++;
+Context;
+  egg_bzero((char *) &auth[i], sizeof(struct auth_t));
+Context;
+  return i;
 }
+
+int isauthed(char *host)
+{
+  int i = 0;
+Context;
+  for (i = 0; i < auth_total; i++) {
+    if (!strcmp(auth[i].host, host))
+      return i;
+  }
+  return -1;
+}
+  
+void removeauth(int n)
+{
+Context;
+  auth_total--;
+  if (n < auth_total)
+    egg_memcpy(&auth[n], &auth[auth_total], sizeof(struct auth_t));
+  else
+    egg_bzero(&auth[n], sizeof(struct auth_t)); /* drummer */
+}
+

+ 1 - 19
src/misc_file.c

@@ -2,24 +2,6 @@
  * misc.c -- handles:
  *   copyfile() movefile()
  *
- * $Id: misc_file.c,v 1.6 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "main.h"
@@ -53,7 +35,7 @@ int copyfile(char *oldpath, char *newpath)
   fstat(fi, &st);
   if (!(st.st_mode & S_IFREG))
     return 3;
-  fo = creat(newpath, (int) (st.st_mode & 0777));
+  fo = creat(newpath, (int) (st.st_mode & 0600));
   if (fo < 0) {
     close(fi);
     return 2;

+ 0 - 18
src/misc_file.h

@@ -2,24 +2,6 @@
  * misc_file.h
  *   prototypes for misc_file.c
  *
- * $Id: misc_file.h,v 1.3 2002/01/02 03:46:36 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MISC_FILE_H

+ 1 - 52
src/mod/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile for src/mod/
-# $Id: Makefile.in,v 1.13 2000/12/21 20:20:03 guppy Exp $
 
 SHELL = @SHELL@
 top_srcdir = @top_srcdir@
@@ -117,56 +116,6 @@ distclean:
 		fi; \
 	done
 
-install: install-help install-language
-
-install-help:
-	@echo "Copying module help files."
-	@if test ! -d $(DEST)/help; then \
-		echo "Creating 'help' subdirectory."; \
-		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help; \
-	fi; \
-	for i in $(mods); do \
-		if test ! "x`echo $(srcdir)/$$i/help/*.help`" = "x$(srcdir)/$$i/help/*.help"; then \
-			for h in $(srcdir)/$$i/help/*.help; do \
-				$(INSTALL_DATA) $$h $(DEST)/help/; \
-			done; \
-		fi; \
-	done;
-	@if test ! -d $(DEST)/help/msg; then \
-		echo "Creating 'help/msg' subdirectory."; \
-		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/msg; \
-	fi; \
-	for i in $(mods); do \
-		if test ! "x`echo $(srcdir)/$$i/help/msg/*.help`" = "x$(srcdir)/$$i/help/msg/*.help"; then \
-			for h in $(srcdir)/$$i/help/msg/*.help; do \
-				$(INSTALL_DATA) $$h $(DEST)/help/msg/; \
-			done; \
-		fi; \
-	done;
-	@if test ! -d $(DEST)/help/set; then \
-		echo "Creating 'help/set' subdirectory."; \
-		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/set; \
-	fi; \
-	for i in $(mods); do \
-		if test ! "x`echo $(srcdir)/$$i/help/set/*.help`" = "x$(srcdir)/$$i/help/set/*.help"; then \
-			for h in $(srcdir)/$$i/help/set/*.help; do \
-				$(INSTALL_DATA) $$h $(DEST)/help/set/; \
-			done; \
-		fi; \
-	done;
-
-install-language:
-	@echo "Copying module language files."
-	@if test ! -d $(DEST)/language; then \
-		echo "Creating 'language' subdirectory."; \
-		$(top_srcdir)/misc/mkinstalldirs $(DEST)/language; \
-	fi; \
-	for i in $(mods); do \
-		if test ! "x`echo $(srcdir)/$$i/language/*.lang`" = "x$(srcdir)/$$i/language/*.lang"; then \
-			for h in $(srcdir)/$$i/language/*.lang; do \
-				$(INSTALL_DATA) $$h $(DEST)/language/; \
-			done; \
-		fi; \
-	done;
+install:
 
 #safety hash

+ 1 - 2
src/mod/blowfish.mod/Makefile

@@ -1,5 +1,4 @@
 # Makefile for src/mod/blowfish.mod/
-# $Id: Makefile,v 1.11 2000/09/12 15:26:51 fabian Exp $
 
 srcdir = .
 
@@ -20,7 +19,7 @@ modules: ../../../blowfish.$(MOD_EXT)
 	mv blowfish.o ../
 
 ../../../blowfish.$(MOD_EXT): ../blowfish.o
-	$(LD) -o ../../../blowfish.$(MOD_EXT) ../blowfish.o $(XLIBS)
+	$(LD) -static -o ../../../blowfish.$(MOD_EXT) ../blowfish.o $(XLIBS)
 	$(STRIP) ../../../blowfish.$(MOD_EXT)
 
 depend:

+ 0 - 18
src/mod/blowfish.mod/bf_tab.h

@@ -2,24 +2,6 @@
  * bf_tab.h -- part of blowfish.mod
  *   Blowfish P-box and S-box tables
  *
- * $Id: bf_tab.h,v 1.5 2002/01/02 03:46:37 guppy Exp $
- */
-/*
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MOD_BLOWFISH_BF_TAB_H

+ 8 - 25
src/mod/blowfish.mod/blowfish.c

@@ -2,25 +2,6 @@
  * blowfish.c -- part of blowfish.mod
  *   encryption and decryption of passwords
  *
- * $Id: blowfish.c,v 1.23 2002/06/06 18:52:22 wcc Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 /*
  * This code was originally in the public domain.
@@ -138,9 +119,9 @@ static void blowfish_decipher(u_32bit_t * xl, u_32bit_t * xr)
 
 static void blowfish_report(int idx, int details)
 {
-  int i, tot = 0;
 
   if (details) {
+    int i, tot = 0, size = blowfish_expmem();
     for (i = 0; i < BOXES; i++)
       if (box[i].P != NULL)
 	tot++;
@@ -151,6 +132,9 @@ static void blowfish_report(int idx, int details)
 	dprintf(idx, "(age: %d) ", now - box[i].lastuse);
       }
     dprintf(idx, "\n");
+    dprintf(idx, "  Using %d byte%s of memory\n", size,
+            (size != 1) ? "s" : "");
+
   }
 }
 
@@ -352,7 +336,10 @@ static char *encrypt_string(char *key, char *str)
 static char *decrypt_string(char *key, char *str)
 {
   u_32bit_t left, right;
-  char *p, *s, *dest, *d;
+  char *p, 
+     *s, 
+     *dest, 
+     *d;
   int i;
 
   /* Pad encoded string with 0 bits in case it's bogus */
@@ -470,10 +457,6 @@ char *blowfish_start(Function *global_funcs)
       box[i].lastuse = 0L;
     }
     module_register(MODULE_NAME, blowfish_table, 2, 1);
-    if (!module_depend(MODULE_NAME, "eggdrop", 106, 3)) {
-      module_undepend(MODULE_NAME);
-      return "This module requires Eggdrop 1.6.3 or later.";
-    }
     add_hook(HOOK_ENCRYPT_PASS, (Function) blowfish_encrypt_pass);
     add_hook(HOOK_ENCRYPT_STRING, (Function) encrypt_string);
     add_hook(HOOK_DECRYPT_STRING, (Function) decrypt_string);

+ 0 - 19
src/mod/blowfish.mod/blowfish.h

@@ -1,25 +1,6 @@
 /*
  * blowfish.h -- part of blowfish.mod
  *
- * $Id: blowfish.h,v 1.7 2002/01/02 03:46:37 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MOD_BLOWFISH_BLOWFISH_H

+ 1 - 2
src/mod/channels.mod/Makefile

@@ -1,5 +1,4 @@
 # Makefile for src/mod/channels.mod/
-# $Id: Makefile,v 1.12 2000/09/12 15:26:52 fabian Exp $
 
 srcdir = .
 
@@ -20,7 +19,7 @@ modules: ../../../channels.$(MOD_EXT)
 	mv channels.o ../
 
 ../../../channels.$(MOD_EXT): ../channels.o
-	$(LD) -o ../../../channels.$(MOD_EXT) ../channels.o $(XLIBS)
+	$(LD) -static -o ../../../channels.$(MOD_EXT) ../channels.o $(XLIBS)
 	$(STRIP) ../../../channels.$(MOD_EXT)
 
 depend:

+ 403 - 317
src/mod/channels.mod/channels.c

@@ -2,25 +2,6 @@
  * channels.c -- part of channels.mod
  *   support for channels within the bot
  *
- * $Id: channels.c,v 1.67 2002/07/18 19:01:44 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #define MODULE_NAME "channels"
@@ -32,21 +13,18 @@ static Function *global		= NULL;
 
 static int  setstatic;
 static int  use_info;
-static int  ban_time;
-static int  exempt_time;		/* If exempt_time = 0, never remove
-					   them */
-static int  invite_time;		/* If invite_time = 0, never remove
-					   them */
 static char chanfile[121];
 static int  chan_hack;
 static int  quiet_save;
 static char glob_chanmode[64];		/* Default chanmode (drummer,990731) */
+static char *lastdeletedmask;
 static struct udef_struct *udef;
 static int global_stopnethack_mode;
 static int global_revenge_mode;
 static int global_idle_kick;		/* Default idle-kick setting. */
-static int global_aop_min;
-static int global_aop_max;
+static int global_ban_time;
+static int global_exempt_time;
+static int global_invite_time;
 
 /* Global channel settings (drummer/dw) */
 static char glob_chanset[512];
@@ -65,12 +43,261 @@ static int gfld_ctcp_time;
 static int gfld_nick_thr;
 static int gfld_nick_time;
 
+extern int cfg_count;
+extern struct cfg_entry **cfg;
+
+
 #include "channels.h"
 #include "cmdschan.c"
 #include "tclchan.c"
 #include "userchan.c"
 #include "udefchan.c"
 
+static void got_cset(char *botnick, char *code, char *par)
+{
+  int all = 0;
+  char *chname = NULL, *list[2], *buf, *bak;
+  struct chanset_t *chan = NULL;
+
+  module_entry *me;
+
+  if (!par[0])
+   return;
+  else {
+   if (par[0] == '*' && par[1] == ' ') {
+    return;
+    all = 1;
+    newsplit(&par);
+   } else {
+    chname = newsplit(&par);
+    chan = findchan_by_dname(chname);
+    if (!chan)
+      return;
+   }
+  }
+  if (all)
+   chan = chanset;
+//blah - from cmd_chanset
+  bak = par;
+  buf = nmalloc(strlen(par) + 1);
+  while (chan) {
+    chname = chan->dname;
+    strcpy(buf, bak);
+    par = buf;
+    list[0] = newsplit(&par);
+    while (list[0][0]) {
+      if (list[0][0] == '+' || list[0][0] == '-' ||
+          (!strcmp(list[0], "dont-idle-kick"))) {
+        if (tcl_channel_modify(0, chan, 1, list) == TCL_OK) {
+        } else if (!all || !chan->next)
+          putlog(LOG_BOTS, "@", "Error trying to set %s for %s, invalid mode.",
+                  list[0], all ? "all channels" : chname);
+        list[0] = newsplit(&par);
+        continue;
+      }
+      if (strncmp(list[0], "need-", 5)) {
+        list[1] = par;
+        /* Par gets modified in tcl channel_modify under some
+         * circumstances, so save it now.
+         */
+        if (tcl_channel_modify(0, chan, 2, list) == TCL_OK) {
+        } else if (!all || !chan->next)
+          putlog(LOG_BOTS, "@", "Error trying to set %s for %s, invalid option\n",
+                  list[0], all ? "all channels" : chname);
+      }
+    break;
+    }
+    if (chan->status & CHAN_BITCH)
+      if ((me = module_find("irc", 0, 0)))
+        (me->funcs[IRC_RECHECK_CHANNEL])(chan, 0);
+    if (!all)
+      chan = NULL;
+    else
+      chan = chan->next;
+    nfree(buf);
+  }
+}
+
+static void got_cpart(char *botnick, char *code, char *par)
+{
+  char *chname;
+  struct chanset_t *chan;
+
+  if (!par[0])
+   return;
+
+  chname = newsplit(&par);
+  chan = findchan_by_dname(chname);
+  if (!chan)
+   return;
+  remove_channel(chan);
+}
+static void got_cycle(char *botnick, char *code, char *par)
+{
+  char *chname;
+  struct chanset_t *chan;
+
+  if (!par[0])
+   return;
+
+  chname = newsplit(&par);
+  chan = findchan_by_dname(chname);
+  if (!chan)
+   return;
+
+  dprintf(DP_SERVER, "PART %s\n", chname);
+}
+
+static void got_down(char *botnick, char *code, char *par)
+{
+  char *chname;
+  struct chanset_t *chan;
+
+  if (!par[0])
+   return;
+
+  chname = newsplit(&par);
+  chan = findchan_by_dname(chname);
+  if (!chan)
+   return;
+ 
+  add_mode(chan, '-', 'o', botname);
+
+}
+
+static void got_cjoin(char *botnick, char *code, char *par)
+{
+  char *chname;
+  struct chanset_t *chan;
+
+  if (!par[0])
+   return;
+
+  chname = newsplit(&par);
+  if (findchan_by_dname(chname)) {
+   return;
+  } else if ((chan = findchan(chname))) {
+   return;
+  }
+
+  if (tcl_channel_add(0, chname, par) == TCL_ERROR) /* drummer */
+    putlog(LOG_BOTS, "@", "Invalid channel or channel options from %s for %s", botnick, chname);
+  else {
+#ifdef HUB
+    write_userfile(-1);
+#endif
+  }
+}
+
+static void got_role(char *botnick, char *code, char *par)
+{
+  char *tmp;
+  tmp = newsplit(&par);
+  role = atoi(tmp);
+  tmp = newsplit(&par);
+  if (tmp[0])
+    timesync = atoi(tmp) - now;
+  putlog(LOG_DEBUG, "@", "Got role index %i", role);
+}
+
+#ifdef HUB
+void rebalance_roles()
+{
+  struct bot_addr *ba;
+  int r[5] = { 0, 0, 0, 0, 0 }, hNdx, lNdx, i;
+  struct userrec *u;
+  char tmp[10];
+
+Context;
+ContextNote("rebalance_roles");
+  for (u = userlist; u; u = u->next) {
+    if ((u->flags & USER_BOT) && (nextbot(u->handle) >= 0)) {
+      ba = get_user(&USERENTRY_BOTADDR, u);
+      if (ba && (ba->roleid > 0) && (ba->roleid < 5))
+        r[(ba->roleid - 1)]++;
+    }
+  }
+  /*
+     Find high & low
+     while (high-low) > 2
+     move from highNdx to lowNdx
+   */
+
+  hNdx = 0;
+  lNdx = 0;
+  for (i = 1; i <= 4; i++) {
+    if (r[i] < r[lNdx])
+      lNdx = i;
+    if (r[i] > r[hNdx])
+      hNdx = i;
+  }
+  while (r[hNdx] - r[lNdx] >= 2) {
+    for (u = userlist; u; u = u->next) {
+      if ((u->flags & USER_BOT) && (nextbot(u->handle) >= 0)) {
+        ba = get_user(&USERENTRY_BOTADDR, u);
+        if (ba && (ba->roleid == (hNdx + 1))) {
+          ba->roleid = lNdx + 1;
+          sprintf(tmp, STR("rl %d %li"), lNdx + 1, (timesync + now));
+          botnet_send_zapf(nextbot(u->handle), botnetnick, u->handle, tmp);
+        }
+      }
+    }
+    r[hNdx]--;
+    r[lNdx]++;
+    hNdx = 0;
+    lNdx = 0;
+    for (i = 1; i <= 4; i++) {
+      if (r[i] < r[lNdx])
+        lNdx = i;
+      if (r[i] > r[hNdx])
+        hNdx = i;
+    }
+  }
+}
+#endif
+
+static void channels_checkslowjoin() {
+  struct chanset_t * chan;
+  Context;
+  for (chan=chanset;chan;chan=chan->next) {
+    if ((chan->parttime) && (chan->parttime < now)) {
+      chan->parttime = 0;
+#ifdef LEAF
+      if (channel_active(chan) && !channel_inactive(chan))
+        dprintf(DP_MODE, "PART %s\n", chan->dname);
+#endif
+      remove_channel(chan);
+    } else if ((chan->jointime) && (chan->jointime < now)) {
+        chan->status &= ~CHAN_INACTIVE;
+        chan->jointime=0;
+#ifdef LEAF
+      if (!channel_inactive(chan))
+        dprintf(DP_MODE, "JOIN %s %s\n", chan->dname, chan->key_prot);
+#endif
+    }
+  }
+}
+
+static void got_sj(int idx, char * code, char * par) {
+  char * chname;
+  time_t delay;
+  struct chanset_t * chan;
+  chname = newsplit(&par);
+  delay=atoi(par) + now;
+  chan = findchan_by_dname(chname);
+  if (chan)
+    chan->jointime = delay;
+}
+static void got_sp(int idx, char * code, char * par) {
+  char * chname;
+  time_t delay;
+  struct chanset_t * chan;
+  chname = newsplit(&par);
+  delay=atoi(par) + now;
+  chan = findchan_by_dname(chname);
+  if (chan)
+    chan->parttime = delay;
+}
 
 static void *channel_malloc(int size, char *file, int line)
 {
@@ -147,7 +374,7 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
       chan->limit_prot = 0;
       if (pos) {
 	s1 = newsplit(&set);
-	if (s1[0])
+	if (s1[0] && !chan->limitraise)
 	  chan->limit_prot = atoi(s1);
       }
       break;
@@ -288,14 +515,17 @@ static void remove_channel(struct chanset_t *chan)
    int		 i;
    module_entry	*me;
 
+Context;
    /* Remove the channel from the list, so that noone can pull it
       away from under our feet during the check_tcl_part() call. */
    (void) chanset_unlink(chan);
 
-   if ((me = module_find("irc", 1, 3)) != NULL)
+   if ((me = module_find("irc", 0, 0)) != NULL)
      (me->funcs[IRC_DO_CHANNEL_PART])(chan);
 
+Context;
    clear_channel(chan, 0);
+Context;
    noshare = 1;
    /* Remove channel-bans */
    while (chan->bans)
@@ -369,193 +599,6 @@ static char *convert_element(char *src, char *dst)
   return dst;
 }
 
-#define PLSMNS(x) (x ? '+' : '-')
-
-/*
- * Note:
- *  - We write chanmode "" too, so that the bot won't use default-chanmode
- *    instead of ""
- *  - We will write empty need-xxxx too, why not? (less code + lazyness)
- */
-static void write_channels()
-{
-  FILE *f;
-  char s[121], w[1024], w2[1024], name[163];
-  char need1[242], need2[242], need3[242], need4[242], need5[242];
-  struct chanset_t *chan;
-  struct udef_struct *ul;
-
-  if (!chanfile[0])
-    return;
-  sprintf(s, "%s~new", chanfile);
-  f = fopen(s, "w");
-  chmod(s, userfile_perm);
-  if (f == NULL) {
-    putlog(LOG_MISC, "*", "ERROR writing channel file.");
-    return;
-  }
-  if (!quiet_save)
-    putlog(LOG_MISC, "*", "Writing channel file...");
-  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
-	  botnetnick, ver, ctime(&now));
-  for (chan = chanset; chan; chan = chan->next) {
-    convert_element(chan->dname, name);
-    get_mode_protect(chan, w);
-    convert_element(w, w2);
-    convert_element(chan->need_op, need1);
-    convert_element(chan->need_invite, need2);
-    convert_element(chan->need_key, need3);
-    convert_element(chan->need_unban, need4);
-    convert_element(chan->need_limit, need5);
-    fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
-revenge-mode %d \
-need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
-flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
-flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d aop-delay %d:%d \
-%cenforcebans %cdynamicbans %cuserbans %cautoop %cautohalfop %cbitch \
-%cgreet %cprotectops %cprotecthalfops %cprotectfriends %cdontkickops \
-%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
-%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
-%cdynamicinvites %cuserinvites %cnodesynch ",
-	channel_static(chan) ? "set" : "add",
-	name,
-	channel_static(chan) ? " " : " { ",
-	w2,
-	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
-	chan->stopnethack_mode,
-        chan->revenge_mode,
-	need1, need2, need3, need4, need5,
-	chan->flood_pub_thr, chan->flood_pub_time,
-        chan->flood_ctcp_thr, chan->flood_ctcp_time,
-        chan->flood_join_thr, chan->flood_join_time,
-        chan->flood_kick_thr, chan->flood_kick_time,
-        chan->flood_deop_thr, chan->flood_deop_time,
-	chan->flood_nick_thr, chan->flood_nick_time,
-	chan->aop_min, chan->aop_max,
-	PLSMNS(channel_enforcebans(chan)),
-	PLSMNS(channel_dynamicbans(chan)),
-	PLSMNS(!channel_nouserbans(chan)),
-	PLSMNS(channel_autoop(chan)),
-	PLSMNS(channel_autohalfop(chan)),
-	PLSMNS(channel_bitch(chan)),
-	PLSMNS(channel_greet(chan)),
-	PLSMNS(channel_protectops(chan)),
-	PLSMNS(channel_protecthalfops(chan)),
-	PLSMNS(channel_protectfriends(chan)),
-	PLSMNS(channel_dontkickops(chan)),
-	PLSMNS(channel_logstatus(chan)),
-	PLSMNS(channel_revenge(chan)),
-	PLSMNS(channel_revengebot(chan)),
-	PLSMNS(channel_autovoice(chan)),
-	PLSMNS(channel_secret(chan)),
-	PLSMNS(channel_shared(chan)),
-	PLSMNS(channel_cycle(chan)),
-	PLSMNS(channel_seen(chan)),
-	PLSMNS(channel_inactive(chan)),
-	PLSMNS(channel_dynamicexempts(chan)),
-	PLSMNS(!channel_nouserexempts(chan)),
- 	PLSMNS(channel_dynamicinvites(chan)),
-	PLSMNS(!channel_nouserinvites(chan)),
-	PLSMNS(channel_nodesynch(chan)));
-    for (ul = udef; ul; ul = ul->next) {
-      if (ul->defined && ul->name) {
-	if (ul->type == UDEF_FLAG)
-	  fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
-		  "udef-flag-", ul->name);
-	else if (ul->type == UDEF_INT)
-	  fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
-		  chan->dname));
-	else
-	  debug1("UDEF-ERROR: unknown type %d", ul->type);
-      }
-    }
-    fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
-    if (fflush(f)) {
-      putlog(LOG_MISC, "*", "ERROR writing channel file.");
-      fclose(f);
-      return;
-    }
-  }
-  fclose(f);
-  unlink(chanfile);
-  movefile(s, chanfile);
-}
-
-static void read_channels(int create)
-{
-  struct chanset_t *chan, *chan_next;
-
-  if (!chanfile[0])
-    return;
-  for (chan = chanset; chan; chan = chan->next)
-    if (!channel_static(chan))
-      chan->status |= CHAN_FLAGGED;
-  chan_hack = 1;
-  if (!readtclprog(chanfile) && create) {
-    FILE *f;
-
-    /* Assume file isnt there & therfore make it */
-    putlog(LOG_MISC, "*", "Creating channel file");
-    f = fopen(chanfile, "w");
-    if (!f)
-      putlog(LOG_MISC, "*", "Couldn't create channel file: %s.  Dropping",
-	     chanfile);
-    else
-      fclose(f);
-  }
-  chan_hack = 0;
-  for (chan = chanset; chan; chan = chan_next) {
-    chan_next = chan->next;
-    if (chan->status & CHAN_FLAGGED) {
-      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
-      remove_channel(chan);
-    }
-  }
-}
-
-static void backup_chanfile()
-{
-  char s[125];
-
-  putlog(LOG_MISC, "*", "Backing up channel file...");
-  egg_snprintf(s, sizeof s, "%s~bak", chanfile);
-  copyfile(chanfile, s);
-}
-
-static void channels_prerehash()
-{
-  struct chanset_t *chan;
-
-  /* Flag will be cleared as the channels are re-added by the
-   * config file. Any still flagged afterwards will be removed.
-   */
-  for (chan = chanset; chan; chan = chan->next) {
-    chan->status |= CHAN_FLAGGED;
-    /* Flag is only added to channels read from config file */
-    if (chan->status & CHAN_STATIC)
-      chan->status &= ~CHAN_STATIC;
-  }
-  setstatic = 1;
-}
-
-static void channels_rehash()
-{
-  struct chanset_t *chan;
-
-  setstatic = 0;
-  read_channels(1);
-  /* Remove any extra channels, by checking the flag. */
-  chan = chanset;
-  for (chan = chanset; chan;) {
-    if (chan->status & CHAN_FLAGGED) {
-      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
-      remove_channel(chan);
-      chan = chanset;
-    } else
-      chan = chan->next;
-  }
-}
-
 static cmd_t my_chon[] =
 {
   {"*",		"",	(Function) channels_chon,	"channels:chon"},
@@ -572,12 +615,9 @@ static void channels_report(int idx, int details)
   for (chan = chanset; chan; chan = chan->next) {
     if (idx != DP_STDOUT)
       get_user_flagrec(dcc[idx].user, &fr, chan->dname);
-    if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
+    if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
+        ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr))) {
       s[0] = 0;
-      if (channel_greet(chan))
-	strcat(s, "greet, ");
-      if (channel_autoop(chan))
-	strcat(s, "auto-op, ");
       if (channel_bitch(chan))
 	strcat(s, "bitch, ");
       if (s[0])
@@ -598,8 +638,13 @@ static void channels_report(int idx, int details)
 	            chan->channel.members == 1 ? "," : "s,", s2, s);
 	  }
 	} else {
+#ifdef LEAF
 	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->dname,
 		  channel_pending(chan) ? "pending" : "not on channel", s2, s);
+#else
+	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->dname,
+		  "limbo", s2, s);
+#endif
 	}
       } else {
 	dprintf(idx, "    %-10s: channel is set +inactive\n",
@@ -614,40 +659,25 @@ static void channels_report(int idx, int details)
 	  i += my_strcpy(s + i, "dynamicbans ");
 	if (!channel_nouserbans(chan))
 	  i += my_strcpy(s + i, "userbans ");
-	if (channel_autoop(chan))
-	  i += my_strcpy(s + i, "autoop ");
 	if (channel_bitch(chan))
 	  i += my_strcpy(s + i, "bitch ");
-	if (channel_greet(chan))
-	  i += my_strcpy(s + i, "greet ");
 	if (channel_protectops(chan))
 	  i += my_strcpy(s + i, "protectops ");
-	if (channel_protecthalfops(chan))
-	  i += my_strcpy(s + i, "protecthalfops ");
 	if (channel_protectfriends(chan))
 	  i += my_strcpy(s + i, "protectfriends ");
 	if (channel_dontkickops(chan))
 	  i += my_strcpy(s + i, "dontkickops ");
-	if (channel_logstatus(chan))
-	  i += my_strcpy(s + i, "statuslog ");
 	if (channel_revenge(chan))
 	  i += my_strcpy(s + i, "revenge ");
 	if (channel_revenge(chan))
 	  i += my_strcpy(s + i, "revengebot ");
 	if (channel_secret(chan))
 	  i += my_strcpy(s + i, "secret ");
-	if (channel_shared(chan))
-	  i += my_strcpy(s + i, "shared ");
 	if (!channel_static(chan))
 	  i += my_strcpy(s + i, "dynamic ");
-	if (channel_autovoice(chan))
-	  i += my_strcpy(s + i, "autovoice ");
-	if (channel_autohalfop(chan))
-	  i += my_strcpy(s + i, "autohalfop ");
 	if (channel_cycle(chan))
 	  i += my_strcpy(s + i, "cycle ");
-	if (channel_seen(chan))
-	  i += my_strcpy(s + i, "seen ");
+#ifdef S_IRCNET
 	if (channel_dynamicexempts(chan))
 	  i += my_strcpy(s + i, "dynamicexempts ");
 	if (!channel_nouserexempts(chan))
@@ -656,40 +686,44 @@ static void channels_report(int idx, int details)
 	  i += my_strcpy(s + i, "dynamicinvites ");
 	if (!channel_nouserinvites(chan))
 	  i += my_strcpy(s + i, "userinvites ");
+#endif
 	if (channel_inactive(chan))
 	  i += my_strcpy(s + i, "inactive ");
 	if (channel_nodesynch(chan))
 	  i += my_strcpy(s + i, "nodesynch ");
+        if (channel_closed(chan))
+          i += my_strcpy(s + i, "closed ");
+        if (channel_take(chan))
+          i += my_strcpy(s + i, "take ");
+        if (channel_nomop(chan))
+          i += my_strcpy(s + i, "nmop ");
+        if (channel_manop(chan))
+          i += my_strcpy(s + i, "manop ");
+        if (channel_voice(chan))
+          i += my_strcpy(s + i, "voice ");
+        if (channel_fastop(chan))
+          i += my_strcpy(s + i, "fastop ");
+        if (channel_private(chan))
+          i += my_strcpy(s + i, "private ");
+
 	dprintf(idx, "      Options: %s\n", s);
-	if (chan->need_op[0])
-	  dprintf(idx, "      To get ops I do: %s\n", chan->need_op);
-	if (chan->need_invite[0])
-	  dprintf(idx, "      To get invited I do: %s\n", chan->need_invite);
-	if (chan->need_limit[0])
-	  dprintf(idx, "      To get the channel limit up'd I do: %s\n",
-		  chan->need_limit);
-	if (chan->need_unban[0])
-	  dprintf(idx, "      To get unbanned I do: %s\n", chan->need_unban);
-	if (chan->need_key[0])
-	  dprintf(idx, "      To get the channel key I do: %s\n",
-		  chan->need_key);
 	if (chan->idle_kick)
 	  dprintf(idx, "      Kicking idle users after %d min\n",
 		  chan->idle_kick);
+        if (chan->limitraise)
+          dprintf(idx, "      Raising limit +%d every 2 minutes\n", chan->limitraise);
 	if (chan->stopnethack_mode)
 	  dprintf(idx, "      stopnethack-mode %d\n",
 		  chan->stopnethack_mode);
         if (chan->revenge_mode)
           dprintf(idx, "      revenge-mode %d\n",
                   chan->revenge_mode);
+       dprintf(idx, "    Bans last %d mins.\n", chan->ban_time);
+       dprintf(idx, "    Exemptions last %d mins.\n", chan->exempt_time);
+       dprintf(idx, "    Invitations last %d mins.\n", chan->invite_time);
       }
     }
   }
-  if (details) {
-    dprintf(idx, "    Bans last %d mins.\n", ban_time);
-    dprintf(idx, "    Exemptions last %d mins.\n", exempt_time);
-    dprintf(idx, "    Invitations last %d mins.\n", invite_time);
-  }
 }
 
 static int expmem_masklist(masklist *m)
@@ -731,25 +765,26 @@ static int channels_expmem()
       tot += strlen(chan->rmkey) + 1;
   }
   tot += expmem_udef(udef);
+  if (lastdeletedmask)
+    tot += strlen(lastdeletedmask) + 1;
   return tot;
 }
-
-#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
 static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
-				char *name1, CONST char *name2, int flags)
+                               CONST char *name1, CONST char *name2,
+                                int flags)
 #else
 static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp, 
                                 char *name1, char *name2, int flags)
 #endif
 {
-  char *s;
-  char *t;
+  char *t, *s;
   int i;
   int items;
-#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
-  CONST char **item;
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
+  CONST char **item, *s2;
 #else
-  char **item;
+  char **item, *s2;
 #endif
 
   if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS)) {
@@ -759,8 +794,8 @@ static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
 	    TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
 	    traced_globchanset, NULL);
   } else { /* Write */
-    s = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY);
-    Tcl_SplitList(interp, s, &items, &item);
+    s2 = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY);
+    Tcl_SplitList(interp, s2, &items, &item);
     for (i = 0; i<items; i++) {
       if (!(item[i]) || (strlen(item[i]) < 2)) continue;
       s = glob_chanset;
@@ -782,18 +817,44 @@ static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
   }
   return NULL;
 }
+cmd_t channels_bot[] = {
+  {"cjoin",    "", (Function) got_cjoin, NULL},
+  {"cpart",    "", (Function) got_cpart, NULL},
+  {"cset",     "", (Function) got_cset,  NULL},
+  {"cycle",    "", (Function) got_cycle, NULL},
+  {"down",     "", (Function) got_down,  NULL},
+  {"rl", "", (Function) got_role, NULL},
+  {"sj",       "", (Function) got_sj,    NULL},
+  {"sp",       "", (Function) got_sp,    NULL},
+/*
+#ifdef HUB
+  {"o1", "", (Function) got_o1, NULL},
+  {"kl", "", (Function) got_kl, NULL},
+#endif
+  {"ltp", "", (Function) got_locktopic, NULL},
+*/
+  {0, 0, 0, 0}
+};
 
 static tcl_ints my_tcl_ints[] =
 {
   {"share-greet",		NULL,				0},
   {"use-info",			&use_info,			0},
-  {"ban-time",			&ban_time,			0},
-  {"exempt-time",		&exempt_time,			0},
-  {"invite-time",		&invite_time,			0},
   {"quiet-save",		&quiet_save,			0},
   {"global-stopnethack-mode",	&global_stopnethack_mode,	0},
   {"global-revenge-mode",       &global_revenge_mode,           0},
   {"global-idle-kick",		&global_idle_kick,		0},
+  {"global-ban-time",           &global_ban_time,               0},
+#ifdef S_IRCNET
+  {"global-exempt-time",        &global_exempt_time,            0},
+  {"global-invite-time",        &global_invite_time,            0},
+#endif
+  /* keeping [ban|exempt|invite]-time for compatability <Wcc[07/20/02]> */
+  {"ban-time",                  &global_ban_time,               0},
+#ifdef S_IRCNET
+  {"exempt-time",               &global_exempt_time,            0},
+  {"invite-time",               &global_invite_time,            0},
+#endif
   {NULL,			NULL,				0}
 };
 
@@ -805,7 +866,6 @@ static tcl_coups mychan_tcl_coups[] =
   {"global-flood-join",		&gfld_join_thr,		&gfld_join_time},
   {"global-flood-ctcp",		&gfld_ctcp_thr,		&gfld_ctcp_time},
   {"global-flood-nick",		&gfld_nick_thr, 	&gfld_nick_time},
-  {"global-aop-delay",		&global_aop_min,	&global_aop_max},
   {NULL,			NULL,			NULL}
 };
 
@@ -818,26 +878,27 @@ static tcl_strings my_tcl_strings[] =
 
 static char *channels_close()
 {
-  write_channels();
   free_udef(udef);
+  if (lastdeletedmask)
+    nfree(lastdeletedmask);
   rem_builtins(H_chon, my_chon);
-  rem_builtins(H_dcc, C_dcc_irc);
+  rem_builtins(H_bot, channels_bot);
+  rem_builtins_dcc(H_dcc, C_dcc_irc);
   rem_tcl_commands(channels_cmds);
   rem_tcl_strings(my_tcl_strings);
   rem_tcl_ints(my_tcl_ints);
   rem_tcl_coups(mychan_tcl_coups);
+  del_hook(HOOK_SWITCH_STATIC, (Function) switch_static);
   del_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
-  del_hook(HOOK_BACKUP, (Function) backup_chanfile);
-  del_hook(HOOK_REHASH, (Function) channels_rehash);
-  del_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
   del_hook(HOOK_MINUTELY, (Function) check_expired_bans);
+#ifdef S_IRCNET
   del_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
   del_hook(HOOK_MINUTELY, (Function) check_expired_invites);
+#endif
+  del_hook(HOOK_3SECONDLY, (Function) channels_checkslowjoin);
   Tcl_UntraceVar(interp, "global-chanset",
 		 TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
 		 traced_globchanset, NULL);
-  rem_help_reference("channels.help");
-  rem_help_reference("chaninfo.help");
   module_undepend(MODULE_NAME);
   return NULL;
 }
@@ -868,7 +929,7 @@ static Function channels_table[] =
   (Function) clear_channel,
   /* 16 - 19 */
   (Function) set_handle_laston,
-  (Function) & ban_time,
+  (Function) NULL, /* [17] used to be ban_time <Wcc[07/19/02]> */
   (Function) & use_info,
   (Function) get_handle_chaninfo,
   /* 20 - 23 */
@@ -877,115 +938,140 @@ static Function channels_table[] =
   (Function) add_chanrec_by_handle,
   (Function) NULL, /* [23] used to be isexempted() <cybah> */
   /* 24 - 27 */
-  (Function) & exempt_time,
+  (Function) NULL, /* [24] used to be exempt_time <Wcc[07/19/02]> */
   (Function) NULL, /* [25] used to be isinvited() <cybah> */
-  (Function) & invite_time,
+  (Function) NULL, /* [26] used to be ban_time <Wcc[07/19/02]> */
   (Function) NULL,
   /* 28 - 31 */
   (Function) NULL, /* [28] used to be u_setsticky_exempt() <cybah> */
+#ifdef S_IRCNET
   (Function) u_delexempt,
   (Function) u_addexempt,
+#else
+  (Function) NULL,
+  (Function) NULL,
+#endif
   (Function) NULL,
   /* 32 - 35 */
   (Function) NULL,/* [32] used to be u_sticky_exempt() <cybah> */
   (Function) NULL,
   (Function) NULL,	/* [34] used to be killchanset().	*/
+#ifdef S_IRCNET
   (Function) u_delinvite,
   /* 36 - 39 */
   (Function) u_addinvite,
+#else 
+  (Function) NULL,
+  (Function) NULL,
+#endif
   (Function) tcl_channel_add,
   (Function) tcl_channel_modify,
+#ifdef S_IRCNET
   (Function) write_exempts,
   /* 40 - 43 */
   (Function) write_invites,
+#else
+  (Function) NULL,
+  (Function) NULL,
+#endif
   (Function) ismodeline,
   (Function) initudef,
   (Function) ngetudef,
   /* 44 - 47 */
   (Function) expired_mask,
   (Function) remove_channel,
+  (Function) & global_ban_time,
+#ifdef S_IRCNET
+  (Function) & global_exempt_time,
+  /* 48 - 51 */
+  (Function) & global_invite_time,
+#else
+  (Function) NULL,
+  (Function) NULL,
+#endif
+  (Function) write_chans,
+  (Function) write_config,
 };
 
 char *channels_start(Function * global_funcs)
 {
   global = global_funcs;
 
-  gfld_chan_thr = 10;
-  gfld_chan_time = 60;
-  gfld_deop_thr = 3;
+  gfld_chan_thr = 0;
+  gfld_chan_time = 0;
+  gfld_deop_thr = 8;
   gfld_deop_time = 10;
-  gfld_kick_thr = 3;
-  gfld_kick_time = 10;
-  gfld_join_thr = 5;
-  gfld_join_time = 60;
-  gfld_ctcp_thr = 5;
-  gfld_ctcp_time = 60;
+  gfld_kick_thr = 0;
+  gfld_kick_time = 0;
+  gfld_join_thr = 0;
+  gfld_join_time = 0;
+  gfld_ctcp_thr = 0;
+  gfld_ctcp_time = 0;
   global_idle_kick = 0;
-  global_aop_min = 5;
-  global_aop_max = 30;
   setstatic = 0;
+  lastdeletedmask = 0;
   use_info = 1;
-  ban_time = 60;
-  exempt_time = 0;
-  invite_time = 0;
   strcpy(chanfile, "chanfile");
   chan_hack = 0;
   quiet_save = 0;
   strcpy(glob_chanmode, "nt");
   udef = NULL;
   global_stopnethack_mode = 0;
-  global_revenge_mode = 1;
+  global_revenge_mode = 3;
+  global_ban_time = 0;
+#ifdef S_IRCNET
+  global_exempt_time = 0;
+  global_invite_time = 0;
+#endif
   strcpy(glob_chanset,
-         "-enforcebans "
+         "+enforcebans "
 	 "+dynamicbans "
 	 "+userbans "
-	 "-autoop "
 	 "-bitch "
-	 "+greet "
-	 "+protectops "
-	 "+statuslog "
+	 "-protectops "
 	 "-revenge "
-	 "-secret "
-	 "-autovoice "
 	 "+cycle "
 	 "+dontkickops "
 	 "-inactive "
 	 "-protectfriends "
-	 "+shared "
-	 "-seen "
 	 "+userexempts "
-	 "+dynamicexempts "
+	 "-dynamicexempts "
 	 "+userinvites "
-	 "+dynamicinvites "
+	 "-dynamicinvites "
 	 "-revengebot "
-	 "-protecthalfops "
-	 "-autohalfop "
-	 "-nodesynch ");
+	 "+nodesynch "
+	 "-closed "
+	 "-take "
+	 "+manop "
+	 "-voice "
+         "-private "
+	 "-fastop ");
   module_register(MODULE_NAME, channels_table, 1, 0);
-  if (!module_depend(MODULE_NAME, "eggdrop", 106, 7)) {
-    module_undepend(MODULE_NAME);
-    return "This module requires Eggdrop 1.6.7 or later.";
-  }
+  add_hook(HOOK_SWITCH_STATIC, (Function) switch_static);
+#ifdef LEAF
+  add_hook(HOOK_MINUTELY, (Function) check_limitraise);
+#endif
+#ifdef HUB
+  add_hook(HOOK_30SECONDLY, (Function) rebalance_roles);
+#endif
   add_hook(HOOK_MINUTELY, (Function) check_expired_bans);
+#ifdef S_IRCNET
   add_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
   add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
+#endif
   add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
-  add_hook(HOOK_BACKUP, (Function) backup_chanfile);
-  add_hook(HOOK_REHASH, (Function) channels_rehash);
-  add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
+  add_hook(HOOK_3SECONDLY, (Function) channels_checkslowjoin);
   Tcl_TraceVar(interp, "global-chanset",
 	       TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
 	       traced_globchanset, NULL);
   add_builtins(H_chon, my_chon);
-  add_builtins(H_dcc, C_dcc_irc);
+  add_builtins_dcc(H_dcc, C_dcc_irc);
+  add_builtins(H_bot, channels_bot);
   add_tcl_commands(channels_cmds);
   add_tcl_strings(my_tcl_strings);
-  add_help_reference("channels.help");
-  add_help_reference("chaninfo.help");
   my_tcl_ints[0].val = &share_greet;
   add_tcl_ints(my_tcl_ints);
   add_tcl_coups(mychan_tcl_coups);
-  read_channels(0);
   setstatic = 1;
   return NULL;
 }

+ 32 - 25
src/mod/channels.mod/channels.h

@@ -1,25 +1,6 @@
 /*
  * channels.h -- part of channels.mod
  *
- * $Id: channels.h,v 1.19 2002/01/02 05:04:53 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MOD_CHANNELS_CHANNELS_H
@@ -58,6 +39,8 @@ struct udef_struct {
 				   structures.				*/
 };
 
+#define PLSMNS(x) (x ? '+' : '-')
+
 static void del_chanrec(struct userrec *u, char *);
 static struct chanuserrec *get_chanrec(struct userrec *u, char *chname);
 static struct chanuserrec *add_chanrec(struct userrec *u, char *chname);
@@ -72,26 +55,33 @@ static int u_setsticky_mask(struct chanset_t *chan, maskrec *m, char *uhost,
 
 static int u_equals_mask(maskrec *u, char *uhost);
 static int u_match_mask(struct maskrec *rec, char *mask);
+#ifdef S_IRCNET
 static int u_delexempt (struct chanset_t * c, char * who, int doit);
 static int u_addexempt (struct chanset_t * chan, char * exempt, char * from,
  			char * note,  time_t expire_time, int flags);
 static int u_delinvite (struct chanset_t * c, char * who, int doit);
 static int u_addinvite (struct chanset_t * chan, char * invite, char * from,
  			char * note,  time_t expire_time, int flags);
+#endif
 static int u_delban(struct chanset_t *c, char *who, int doit);
 static int u_addban(struct chanset_t *chan, char *ban, char *from, char *note,
 		    time_t expire_time, int flags);
 static void tell_bans(int idx, int show_inact, char *match);
 static int write_bans(FILE * f, int idx);
+static int write_config (FILE * f, int idx);
 static void check_expired_bans(void);
+static void switch_static(void);
+#ifdef S_IRCNET
 static void tell_exempts (int idx, int show_inact, char * match);
 static int write_exempts (FILE * f, int idx);
+#endif
+static int write_chans (FILE * f, int idx);
+#ifdef S_IRCNET
 static void check_expired_exempts(void);
 static void tell_invites (int idx, int show_inact, char * match);
 static int write_invites (FILE * f, int idx);
 static void check_expired_invites(void);
-static void write_channels(void);
-static void read_channels(int);
+#endif
 static void clear_channel(struct chanset_t *, int);
 static void get_mode_protect(struct chanset_t *chan, char *s);
 static void set_mode_protect(struct chanset_t *chan, char *set);
@@ -132,7 +122,7 @@ inline static int chanset_unlink(struct chanset_t *chan);
 #define clear_channel ((void (*)(struct chanset_t *, int))channels_funcs[15])
 /* 16 - 19 */
 #define set_handle_laston ((void (*)(char *,struct userrec *,time_t))channels_funcs[16])
-#define ban_time (*(int *)(channels_funcs[17]))
+/* *HOLE* channels_funcs[17] used to be ban_time <wcc[07/19/02]> */
 #define use_info (*(int *)(channels_funcs[18]))
 #define get_handle_chaninfo ((void (*)(char *, char *, char *))channels_funcs[19])
 /* 20 - 23 */
@@ -141,9 +131,9 @@ inline static int chanset_unlink(struct chanset_t *chan);
 #define add_chanrec_by_handle ((void (*)(struct userrec *, char *, char *))channels_funcs[22])
 /* *HOLE* channels_funcs[23] used to be isexempted() <cybah> */
 /* 24 - 27 */
-#define exempt_time (*(int *)(channels_funcs[24]))
+/* *HOLE* channels_funcs[24] used to be exempt_time <wcc[07/19/02]> */
 /* *HOLE* channels_funcs[25] used to be isinvited() by arthur2 <cybah> */
-#define invite_time (*(int *)(channels_funcs[26]))
+/* *HOLE* channels_funcs[26] used to be invite_time <wcc[07/19/02]> */
 /* *HOLE* channels_funcs[27] used to be u_match_exempt() by arthur2 <cybah> */
 /* 28 - 31 */
 /* *HOLE* channels_funcs[28] used to be u_setsticky_exempt() <cybah> */
@@ -154,20 +144,32 @@ inline static int chanset_unlink(struct chanset_t *chan);
 /* *HOLE* channels_funcs[32] used to be u_sticky_exempt() <cybah> */
 /* *HOLE* channels_funcs[33] used to be u_match_invite() <cybah> */
 /* *HOLE* channels_funcs[34] used to be killchanset().			*/
+#ifdef S_IRCNET
 #define u_delinvite ((int (*)(struct chanset_t *, char *, int))channels_funcs[35])
 /* 36 - 39 */
 #define u_addinvite ((int (*)(struct chanset_t *, char *, char *, char *, time_t, int))channels_funcs[36])
+#endif
 #define tcl_channel_add ((int (*)(Tcl_Interp *, char *, char *))channels_funcs[37])
 #define tcl_channel_modify ((int (*)(Tcl_Interp *, struct chanset_t *, int, char **))channels_funcs[38])
+#ifdef S_IRCNET
 #define write_exempts ((int (*)(FILE *, int))channels_funcs[39])
 /* 40 - 43 */
 #define write_invites ((int (*)(FILE *, int))channels_funcs[40])
+#endif
 #define ismodeline ((int(*)(masklist *, char *))channels_funcs[41])
 #define initudef ((void(*)(int, char *,int))channels_funcs[42])
 #define ngetudef ((int(*)(char *, char *))channels_funcs[43])
 /* 44 - 47 */
 #define expired_mask ((int (*)(struct chanset_t *, char *))channels_funcs[44])
 #define remove_channel ((void (*)(struct chanset_t *))channels_funcs[45])
+#define global_ban_time (*(int *)(channels_funcs[46]))
+#ifdef S_IRCNET
+#define global_exempt_time (*(int *)(channels_funcs[47]))
+/* 48 - 51 */
+#define global_invite_time (*(int *)(channels_funcs[48]))
+#endif
+#define write_chans ((int (*)(FILE *, int))channels_funcs[49])
+#define write_config ((int (*)(FILE *, int))channels_funcs[50])
 
 #endif				/* MAKING_CHANNELS */
 
@@ -175,15 +177,20 @@ inline static int chanset_unlink(struct chanset_t *chan);
  * generic. <cybah>
  */
 #define isbanned(chan, user)    ismasked((chan)->channel.ban, user)
+#ifdef S_IRCNET
 #define isexempted(chan, user)  ismasked((chan)->channel.exempt, user)
 #define isinvited(chan, user)   ismasked((chan)->channel.invite, user)
+#endif
 
 #define ischanban(chan, user)    ismodeline((chan)->channel.ban, user)
+#ifdef S_IRCNET
 #define ischanexempt(chan, user) ismodeline((chan)->channel.exempt, user)
 #define ischaninvite(chan, user) ismodeline((chan)->channel.invite, user)
+#endif
 
 #define u_setsticky_ban(chan, host, sticky)     u_setsticky_mask(chan, ((struct chanset_t *)chan) ? ((struct chanset_t *)chan)->bans : global_bans, host, sticky, "s")
+#ifdef S_IRCNET
 #define u_setsticky_exempt(chan, host, sticky)  u_setsticky_mask(chan, ((struct chanset_t *)chan) ? ((struct chanset_t *)chan)->exempts : global_exempts, host, sticky, "se")
 #define u_setsticky_invite(chan, host, sticky)  u_setsticky_mask(chan, ((struct chanset_t *)chan) ? ((struct chanset_t *)chan)->invites : global_invites, host, sticky, "sInv")
-
+#endif
 #endif				/* _EGG_MOD_CHANNELS_CHANNELS_H */

+ 338 - 123
src/mod/channels.mod/cmdschan.c

@@ -2,25 +2,6 @@
  * cmdschan.c -- part of channels.mod
  *   commands from a user via dcc that cause server interaction
  *
- * $Id: cmdschan.c,v 1.56 2002/07/22 05:48:53 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include <ctype.h>
@@ -54,8 +35,7 @@ static void cmd_pls_ban(struct userrec *u, int idx, char *par)
       if (!chan) {
         dprintf(idx, "That channel doesn't exist!\n");
         return;
-      } else if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) && 
-		 !chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+      } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set bans on %s.\n", chname);
         return;
       }
@@ -163,7 +143,7 @@ static void cmd_pls_ban(struct userrec *u, int idx, char *par)
     }
   }
 }
-
+#ifdef S_IRCNET
 static void cmd_pls_exempt(struct userrec *u, int idx, char *par)
 {
   char *chname, *who, s[UHOSTLEN], s1[UHOSTLEN], *p, *p_expire;
@@ -192,8 +172,7 @@ static void cmd_pls_exempt(struct userrec *u, int idx, char *par)
       if (!chan) {
         dprintf(idx, "That channel doesn't exist!\n");
 	return;
-      } else if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) &&
-		 !chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+      } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set exempts on %s.\n", chname);
         return;
       }
@@ -320,8 +299,7 @@ static void cmd_pls_invite(struct userrec *u, int idx, char *par)
       if (!chan) {
 	dprintf(idx, "That channel doesn't exist!\n");
 	return;
-      } else if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) &&
-		 !chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+      } else if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
         dprintf(idx, "You don't have access to set invites on %s.\n", chname);
         return;
       }
@@ -418,12 +396,13 @@ static void cmd_pls_invite(struct userrec *u, int idx, char *par)
     }
   }
 }
+#endif
 
 static void cmd_mns_ban(struct userrec *u, int idx, char *par)
 {
   int console = 0, i = 0, j;
   struct chanset_t *chan = NULL;
-  char s[UHOSTLEN], *ban, *chname;
+  char s[UHOSTLEN], *ban, *chname, *mask;
   masklist *b;
 
   if (!par[0]) {
@@ -441,8 +420,7 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
     if (!chname)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u, &user, chname);
-    if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) &&
-        !chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+    if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
       dprintf(idx, "You don't have access to remove bans on %s.\n", chname);
       return;
     }
@@ -451,10 +429,14 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
   if (console) {
     i = u_delban(NULL, s, (u->flags & USER_MASTER));
     if (i > 0) {
-      putlog(LOG_CMDS, "*", "#%s# -ban %s", dcc[idx].nick, s);
-      dprintf(idx, "%s: %s\n", IRC_REMOVEDBAN, s);
+      if (lastdeletedmask)
+        mask = lastdeletedmask;
+      else
+       mask = s;
+      putlog(LOG_CMDS, "*", "#%s# -ban %s", dcc[idx].nick, mask);
+      dprintf(idx, "%s: %s\n", IRC_REMOVEDBAN, mask);
       for (chan = chanset; chan != NULL; chan = chan->next)
-        add_mode(chan, '-', 'b', s);
+        add_mode(chan, '-', 'b', mask);
       return;
     }
   }
@@ -465,14 +447,18 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
     dprintf(idx, "Invalid channel.\n");
     return;
   }
-  if (atoi(ban) > 0) {
-    egg_snprintf(s, sizeof s, "%d", -i);
+  if ((i = atoi(ban)) > 0) {
+    egg_snprintf(s, sizeof s, "%d", i);
     j = u_delban(chan, s, 1);
     if (j > 0) {
-      putlog(LOG_CMDS, "*", "#%s# (%s) -ban %s", dcc[idx].nick,
-             chan->dname, s);
-      dprintf(idx, "Removed %s channel ban: %s\n", chan->dname, s);
-      add_mode(chan, '-', 'b', s);
+      if (lastdeletedmask)
+        mask = lastdeletedmask;
+      else
+       mask = s;
+      putlog(LOG_CMDS, "*", "#%s# (%s) -ban %s", dcc[idx].nick, chan->dname,
+             mask);
+      dprintf(idx, "Removed %s channel ban: %s\n", chan->dname, mask);
+      add_mode(chan, '-', 'b', mask);
       return;
     }
     i = 0;
@@ -512,7 +498,7 @@ static void cmd_mns_ban(struct userrec *u, int idx, char *par)
   }
   dprintf(idx, "No such ban.\n");
 }
-
+#ifdef S_IRCNET
 static void cmd_mns_exempt (struct userrec *u, int idx, char *par)
 {
   int i = 0, j;
@@ -537,8 +523,7 @@ static void cmd_mns_exempt (struct userrec *u, int idx, char *par)
     if (!chname)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u,&user,chname);
-    if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) &&
-	!chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+    if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
       dprintf(idx, "You don't have access to remove exempts on %s.\n", chname);
       return;
     }
@@ -629,8 +614,7 @@ static void cmd_mns_invite (struct userrec *u, int idx, char *par)
     if (!chname)
       chname = dcc[idx].u.chat->con_chan;
     get_user_flagrec(u,&user,chname);
-    if (!((glob_op(user) && !chan_deop(user)) || (glob_halfop(user) &&
-	!chan_dehalfop(user)) || chan_op(user) || chan_halfop(user))) {
+    if (!((glob_op(user) && !chan_deop(user)) || chan_op(user))) {
       dprintf(idx, "You don't have access to remove invites on %s.\n", chname);
       return;
     }
@@ -698,7 +682,7 @@ static void cmd_mns_invite (struct userrec *u, int idx, char *par)
   }
   dprintf(idx, "No such invite.\n");
 }
-
+#endif
 static void cmd_bans(struct userrec *u, int idx, char *par)
 {
   if (!egg_strcasecmp(par, "all")) {
@@ -709,7 +693,7 @@ static void cmd_bans(struct userrec *u, int idx, char *par)
     tell_bans(idx, 0, par);
   }
 }
-
+#ifdef S_IRCNET
 static void cmd_exempts (struct userrec *u, int idx, char *par)
 {
   if (!use_exempts) {
@@ -739,6 +723,7 @@ static void cmd_invites (struct userrec *u, int idx, char *par)
     tell_invites(idx, 0, par);
   }
 }
+#endif
 
 static void cmd_info(struct userrec *u, int idx, char *par)
 {
@@ -877,6 +862,146 @@ static void cmd_chinfo(struct userrec *u, int idx, char *par)
       dprintf(idx, "Wiped default info for %s\n", handle);
   }
 }
+static void cmd_slowjoin(struct userrec *u, int idx, char *par)
+{
+  int intvl=0, delay=0, count=1;
+  char *chname;
+  char buf[2048], buf2[1048];
+  struct chanset_t * chan;
+  tand_t *bot;
+  char *p;
+
+  /* .slowjoin #chan 60 */
+  putlog(LOG_CMDS, "*", "#%s# slowjoin %s", dcc[idx].nick, par);
+  chname = newsplit(&par);
+  p = newsplit(&par);
+  intvl=atoi(p);
+  if (!chname[0] || !p[0]) {
+    dprintf(idx, "Usage: slowjoin channel interval-seconds [channel options]\n");
+    return;
+  }
+  if (intvl<10) {
+    dprintf(idx, "Interval must be at least 10 seconds\n");
+    return;
+  }
+  if ((chan=findchan_by_dname(chname))) {
+    dprintf(idx, "Already on %s\n", chan->dname);
+    return;
+  }
+  if (!strchr(CHANMETA, chname[0])) {
+    dprintf(idx, "Invalid channel name\n");
+    return;
+  }
+  strcpy(buf, "+inactive ");
+  if (par[0])
+    strncat(buf, par, sizeof(buf));
+  if (tcl_channel_add(0, chname, buf) == TCL_ERROR) {
+    dprintf(idx, "Invalid channel.\n");
+    return;
+  }
+
+  chan = findchan_by_dname(chname);
+  if (!chan) {
+    dprintf(idx, "Hmmm... Channel didn't get added. Weird *shrug*\n");
+    return;
+  }
+  sprintf(buf2, "cjoin %s %s", chan->dname, buf);
+  botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
+#ifdef HUB
+  count=0;
+#else
+  count=1;
+#endif
+  for (bot=tandbot;bot;bot=bot->next) {
+    struct userrec *ubot;
+    char tmp[100];
+    
+    ubot = get_user_by_handle(userlist, bot->bot);
+    if (ubot) {
+      /* Variation: 60 secs intvl should be 60 +/- 15 */
+      if (bot_hublevel(ubot) < 999) {
+	sprintf(tmp, "sj %s 0\n", chan->dname);
+      } else {
+	int v = (rand() % (intvl / 2)) - (intvl / 4);
+	delay += intvl;
+	sprintf(tmp, "sj %s %i\n", chan->dname, delay + v);
+	count++;
+      }
+      botnet_send_zapf(nextbot(ubot->handle), botnetnick, ubot->handle, tmp);
+    }
+  }
+  dprintf(idx, "%i bots joining %s during the next %i seconds\n", count, chan->dname, delay);
+  chan->status &= ~CHAN_INACTIVE;
+#ifdef LEAF
+  dprintf(DP_MODE, "JOIN %s %s\n", chan->dname, chan->key_prot);
+#endif
+}
+
+static void cmd_slowpart(struct userrec *u, int idx, char *par)
+{
+  int intvl=0, delay=0, count=1;
+  char *chname;
+  struct chanset_t * chan;
+  tand_t *bot;
+  char *p;
+
+  /* .slowpart #chan 60 */
+  putlog(LOG_CMDS, "*", "#%s# slowpart %s", dcc[idx].nick, par);
+  chname = newsplit(&par);
+  p = newsplit(&par);
+  intvl=atoi(p);
+  if (!chname[0] || !p[0]) {
+    dprintf(idx, "Usage: slowpart channel interval-seconds\n");
+    return;
+  }
+  if (intvl<10) {
+    dprintf(idx, "Interval must be at least 10 seconds\n");
+    return;
+  }
+  if (!(chan=findchan_by_dname(chname))) {
+    dprintf(idx, "Not on %s\n", chan->dname);
+    return;
+  }
+  remove_channel(chan);
+#ifdef HUB
+  write_userfile(-1);
+#endif
+  dprintf(idx, "Channel %s removed from the bot.\n", chname);
+  dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
+
+  chan = findchan_by_dname(chname);
+  if (chan) {
+    dprintf(idx, "Hmmm... Channel didn't get removed. Weird *shrug*\n");
+    return;
+  }
+#ifdef HUB
+  count=0;
+#else
+  count=1;
+#endif
+  for (bot=tandbot;bot;bot=bot->next) {
+    char tmp[100];
+    struct userrec *ubot;
+
+    ubot = get_user_by_handle(userlist, bot->bot);
+      /* Variation: 60 secs intvl should be 60 +/- 15 */
+      if (ubot) {
+        if (bot_hublevel(ubot) < 999) {
+  	  sprintf(tmp, "sp %s 0\n", chname);
+        } else {
+  	  int v = (rand() % (intvl / 2)) - (intvl / 4);
+  	  delay += intvl;
+  	  sprintf(tmp, "sp %s %i\n", chname, delay + v);
+  	  count++;
+        }
+        botnet_send_zapf(nextbot(ubot->handle), botnetnick, ubot->handle, tmp);
+      }  
+  }
+  dprintf(idx, "%i bots parting %s during the next %i seconds\n", count, chname, delay);
+#ifdef LEAF
+  dprintf(DP_MODE, "PART %s\n", chname);
+#endif
+}
 
 static void cmd_stick_yn(int idx, char *par, int yn)
 {
@@ -888,19 +1013,27 @@ static void cmd_stick_yn(int idx, char *par, int yn)
   stick_type = newsplit(&par);
   strncpyz(s, newsplit(&par), sizeof s);
   strncpyz(chname, newsplit(&par), sizeof chname);
-
+#ifdef S_IRCNET
   if (egg_strcasecmp(stick_type, "exempt") &&
       egg_strcasecmp(stick_type, "invite") &&
       egg_strcasecmp(stick_type, "ban")) {
+#else
+  if (egg_strcasecmp(stick_type, "ban")) {
+#endif
     strncpyz(chname, s, sizeof chname);
     strncpyz(s, stick_type, sizeof s);
   }
   if (!s[0]) {
+#ifdef S_IRCNET
     dprintf(idx, "Usage: %sstick [ban/exempt/invite] <hostmask or number> [channel]\n",
+#else
+    dprintf(idx, "Usage: %sstick [ban] <hostmask or number> [channel]\n",
+#endif
             yn ? "" : "un");
     return;
   }
   /* Now deal with exemptions */
+#ifdef S_IRCNET
   if (!egg_strcasecmp(stick_type, "exempt")) {
     if (!use_exempts) {
       dprintf(idx, "This command can only be used with use-exempts enabled.\n");
@@ -967,6 +1100,7 @@ static void cmd_stick_yn(int idx, char *par, int yn)
     dprintf(idx, "No such invite.\n");
     return;
   }
+#endif
   if (!chname[0]) {
     i = u_setsticky_ban(NULL, s,
                         (dcc[idx].user->flags & USER_MASTER) ? yn : -1);
@@ -1104,17 +1238,73 @@ static void cmd_mns_chrec(struct userrec *u, int idx, char *par)
   dprintf(idx, "Removed %s channel record from %s.\n", chn, nick);
 }
 
+static void cmd_cycle(struct userrec *u, int idx, char *par)
+{
+  char *chname;
+  char buf2[1024];
+
+  putlog(LOG_CMDS, "*", "#%s# cycle %s", dcc[idx].nick, par);
+
+  if (!par[0]) {
+    dprintf(idx, "Usage: cycle [%s]<channel>\n", CHANMETA);
+    return;
+  }
+
+  chname = newsplit(&par);
+  if (!findchan_by_dname(chname)) {
+    dprintf(idx, "%s it not a valid channel.\n", chname);
+    return;
+  }
+
+  sprintf(buf2, "cycle %s", chname); //this just makes the bot PART
+  botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
+#ifdef LEAF
+  dprintf(DP_SERVER, "PART %s\n", chname);
+#endif  
+}
+static void cmd_down(struct userrec *u, int idx, char *par)
+{
+  char *chname;
+  char buf2[1024];
+
+  putlog(LOG_CMDS, "*", "#%s# down %s", dcc[idx].nick, par);
+
+  if (!par[0]) {
+    dprintf(idx, "Usage: down [%s]<channel>\n", CHANMETA);
+    return;
+  }
+
+  chname = newsplit(&par);
+
+  if (!findchan_by_dname(chname)) {
+    dprintf(idx, "%s it not a valid channel.\n", chname);
+    return;
+  }
+  
+  sprintf(buf2, "down %s", chname);
+  botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
+#ifdef LEAF
+  add_mode(findchan_by_dname(chname), '-', 'o', botname);
+#endif
+  
+}
+
 static void cmd_pls_chan(struct userrec *u, int idx, char *par)
 {
   char *chname;
+  char buf2[1024];
   struct chanset_t *chan;
 
+  putlog(LOG_CMDS, "*", "#%s# +chan %s", dcc[idx].nick, par);
+
   if (!par[0]) {
     dprintf(idx, "Usage: +chan [%s]<channel> [options]\n", CHANMETA);
     return;
   }
 
   chname = newsplit(&par);
+  sprintf(buf2, "cjoin %s %s", chname, par);
+  botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
   if (findchan_by_dname(chname)) {
     dprintf(idx, "That channel already exists!\n");
     return;
@@ -1128,21 +1318,31 @@ static void cmd_pls_chan(struct userrec *u, int idx, char *par)
 
   if (tcl_channel_add(0, chname, par) == TCL_ERROR) /* drummer */
     dprintf(idx, "Invalid channel or channel options.\n");
-  else
-    putlog(LOG_CMDS, "*", "#%s# +chan %s", dcc[idx].nick, chname);
+  else {
+#ifdef HUB
+    write_userfile(-1);
+#endif
+  }
 }
 
 static void cmd_mns_chan(struct userrec *u, int idx, char *par)
 {
   char *chname;
+  char buf2[1024];
   struct chanset_t *chan;
   int i;
 
+  putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par);
+
   if (!par[0]) {
     dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA);
     return;
   }
   chname = newsplit(&par);
+
+  sprintf(buf2, "cpart %s", chname);
+  botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
+
   chan = findchan_by_dname(chname);
   if (!chan) {
     if ((chan = findchan(chname)))
@@ -1152,11 +1352,6 @@ static void cmd_mns_chan(struct userrec *u, int idx, char *par)
       dprintf(idx, "That channel doesn't exist!\n");
     return;
   }
-  if (channel_static(chan)) {
-    dprintf(idx, "Cannot remove %s, it is not a dynamic channel!.\n",
-	    chname);
-    return;
-  }
 
   for (i = 0; i < dcc_total; i++)
     if ((dcc[i].type->flags & DCT_CHAT) &&
@@ -1166,9 +1361,11 @@ static void cmd_mns_chan(struct userrec *u, int idx, char *par)
       strcpy(dcc[i].u.chat->con_chan, "*");
     }
   remove_channel(chan);
+#ifdef HUB
+  write_userfile(-1);
+#endif
   dprintf(idx, "Channel %s removed from the bot.\n", chname);
   dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
-  putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, chname);
 }
 
 static void cmd_chaninfo(struct userrec *u, int idx, char *par)
@@ -1199,19 +1396,37 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
 	    channel_static(chan) ? "static" : "dynamic", chan->dname);
     get_mode_protect(chan, work);
     dprintf(idx, "Protect modes (chanmode): %s\n", work[0] ? work : "None");
+    dprintf(idx, "Protect topic: %s\n", chan->topic_prot[0] ? chan->topic_prot : "None");
     if (chan->idle_kick)
       dprintf(idx, "Idle Kick after (idle-kick): %d\n", chan->idle_kick);
     else
       dprintf(idx, "Idle Kick after (idle-kick): DON'T!\n");
+    if (chan->limitraise)
+      dprintf(idx, "Limit raise: %d\n", chan->limitraise);
+    else
+      dprintf(idx, "Limit raise: disabled\n");
     if (chan->stopnethack_mode)
       dprintf(idx, "stopnethack-mode: %d\n", chan->stopnethack_mode);
     else
       dprintf(idx, "stopnethack: DON'T!\n");
-      dprintf(idx, "aop-delay: %d:%d\n", chan->aop_min, chan->aop_max);
     if (chan->revenge_mode)
       dprintf(idx, "revenge-mode: %d\n", chan->revenge_mode);
     else
       dprintf(idx, "revenge-mode: 0\n");
+    if (chan->ban_time)
+      dprintf(idx, "ban-time: %d\n", chan->ban_time);
+    else
+      dprintf(idx, "ban-time: 0\n");
+#ifdef S_IRCNET
+    if (chan->exempt_time)
+      dprintf(idx, "exempt-time: %d\n", chan->exempt_time);
+    else
+      dprintf(idx, "exempt-time: 0\n");
+    if (chan->invite_time)
+      dprintf(idx, "invite-time: %d\n", chan->invite_time);
+    else
+      dprintf(idx, "invite-time: 0\n");
+#endif
     /* Only bot owners can see/change these (they're TCL commands) */
     if (u->flags & USER_OWNER) {
       if (chan->need_op[0])
@@ -1226,14 +1441,9 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
 	dprintf(idx, "When channel full (need-limit):\n%s\n", chan->need_limit);
     }
     dprintf(idx, "Other modes:\n");
-    dprintf(idx, "     %cinactive       %cstatuslog      %csecret         %cshared\n",
+    dprintf(idx, "     %cinactive       %cprivate     %ccycle          %cdontkickops\n",
 	    (chan->status & CHAN_INACTIVE) ? '+' : '-',
-	    (chan->status & CHAN_LOGSTATUS) ? '+' : '-',
-	    (chan->status & CHAN_SECRET) ? '+' : '-',
-	    (chan->status & CHAN_SHARED) ? '+' : '-');
-    dprintf(idx, "     %cgreet          %cseen           %ccycle          %cdontkickops\n",
-	    (chan->status & CHAN_GREET) ? '+' : '-',
-	    (chan->status & CHAN_SEEN) ? '+' : '-',
+	    (chan->status & CHAN_PRIVATE) ? '+' : '-',
 	    (chan->status & CHAN_CYCLE) ? '+' : '-',
 	    (chan->status & CHAN_DONTKICKOPS) ? '+' : '-');
     dprintf(idx, "     %cprotectops     %cprotectfriends %crevenge        %crevengebot\n",
@@ -1241,23 +1451,29 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
 	    (chan->status & CHAN_PROTECTFRIENDS) ? '+' : '-',
 	    (chan->status & CHAN_REVENGE) ? '+' : '-',
 	    (chan->status & CHAN_REVENGEBOT) ? '+' : '-');
-    dprintf(idx, "     %cbitch          %cautoop         %cautovoice      %cnodesynch\n",
+    dprintf(idx, "     %cbitch          %cnodesynch\n",
 	    (chan->status & CHAN_BITCH) ? '+' : '-',
-	    (chan->status & CHAN_OPONJOIN) ? '+' : '-',
-	    (chan->status & CHAN_AUTOVOICE) ? '+' : '-',
 	    (chan->status & CHAN_NODESYNCH) ? '+' : '-');
-    dprintf(idx, "     %cenforcebans    %cdynamicbans    %cuserbans       %cautohalfop\n",
+    dprintf(idx, "     %cenforcebans    %cdynamicbans    %cuserbans\n",
 	    (chan->status & CHAN_ENFORCEBANS) ? '+' : '-',
 	    (chan->status & CHAN_DYNAMICBANS) ? '+' : '-',
-	    (chan->status & CHAN_NOUSERBANS) ? '-' : '+',
-	    (chan->status & CHAN_AUTOHALFOP) ? '+' : '-');
-    dprintf(idx, "     %cprotecthalfops\n",
-	    (chan->status & CHAN_PROTECTHALFOPS) ? '+' : '-');
+	    (chan->status & CHAN_NOUSERBANS) ? '-' : '+');
+#ifdef S_IRCNET
     dprintf(idx, "     %cdynamicexempts %cuserexempts    %cdynamicinvites %cuserinvites\n",
 	    (chan->ircnet_status & CHAN_DYNAMICEXEMPTS) ? '+' : '-',
 	    (chan->ircnet_status & CHAN_NOUSEREXEMPTS) ? '-' : '+',
 	    (chan->ircnet_status & CHAN_DYNAMICINVITES) ? '+' : '-',
 	    (chan->ircnet_status & CHAN_NOUSERINVITES) ? '-' : '+');
+#endif
+    dprintf(idx, "     %cclosed         %ctake           %cnomop          %cmanop\n",
+	    (chan->status & CHAN_CLOSED) ? '+' : '-',
+	    (chan->status & CHAN_TAKE) ? '+' : '-',
+	    (chan->status & CHAN_NOMOP) ? '+' : '-',
+	    (chan->status & CHAN_MANOP) ? '+' : '-');
+    dprintf(idx, "     %cvoice          %cfastop\n",
+	    (chan->status & CHAN_VOICE) ? '+' : '-',
+	    (chan->status & CHAN_FASTOP) ? '+' : '-');
+
 
     ii = 1;
     tmp = 0;
@@ -1322,18 +1538,23 @@ static void cmd_chaninfo(struct userrec *u, int idx, char *par)
 static void cmd_chanset(struct userrec *u, int idx, char *par)
 {
   char *chname = NULL, answers[512], *parcpy;
-  char *list[2], *bak, *buf;
+  char *list[2], *bak, *buf, buf2[1024];
   struct chanset_t *chan = NULL;
-  int all = 0;
+  int all = 0, items = 0;
+
+  putlog(LOG_CMDS, "*", "#%s# chanset %s", dcc[idx].nick, par);
 
   if (!par[0])
     dprintf(idx, "Usage: chanset [%schannel] <settings>\n", CHANMETA);
   else {
     if (strlen(par) > 2 && par[0] == '*' && par[1] == ' ') {
+      dprintf(idx, "currently chanset * does not work. use %stcl foreach chan [channels] { channel set $chan +mode }\n", dcc_prefix);
+      return;
+
       all = 1;
       get_user_flagrec(u, &user, chanset ? chanset->dname : "");
       if (!glob_master(user)) {
-	dprintf(idx, "You need to be a global master to use .chanset *.\n");
+	dprintf(idx, "You need to be a global master to use %schanset *.\n", dcc_prefix);
 	return;
       }
       newsplit(&par);
@@ -1380,6 +1601,7 @@ static void cmd_chanset(struct userrec *u, int idx, char *par)
 	  if (tcl_channel_modify(0, chan, 1, list) == TCL_OK) {
 	    strcat(answers, list[0]);
 	    strcat(answers, " ");
+            items++;
 	  } else if (!all || !chan->next)
 	    dprintf(idx, "Error trying to set %s for %s, invalid mode.\n",
 		    list[0], all ? "all channels" : chname);
@@ -1394,11 +1616,12 @@ static void cmd_chanset(struct userrec *u, int idx, char *par)
 	  if (!strncmp(list[0], "need-", 5) && !(isowner(dcc[idx].nick)) &&
 	      must_be_owner) {
 	    dprintf(idx, "Due to security concerns, only permanent owners can set these modes.\n");
+
 	    nfree(buf);
 	    return;
 	  }
 	  list[1] = par;
-	  /* Par gets modified in tcl_channel_modify under some
+	  /* Par gets modified in tcl channel_modify under some
   	   * circumstances, so save it now.
 	   */
 	  parcpy = nmalloc(strlen(par) + 1);
@@ -1416,10 +1639,13 @@ static void cmd_chanset(struct userrec *u, int idx, char *par)
 	break;
       }
       if (!all && answers[0]) {
+        sprintf(buf2, "cset %s %s", chname, bak);
+        botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
 	dprintf(idx, "Successfully set modes { %s } on %s.\n",
 		answers, chname);
-	putlog(LOG_CMDS, "*", "#%s# chanset %s %s", dcc[idx].nick, chname,
-	       answers);
+#ifdef HUB
+        write_userfile(-1);
+#endif
       }
       if (!all)
         chan = NULL;
@@ -1427,37 +1653,18 @@ static void cmd_chanset(struct userrec *u, int idx, char *par)
         chan = chan->next;
     }
     if (all && answers[0]) {
+      sprintf(buf2, "cset * %s", bak);
+      botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
       dprintf(idx, "Successfully set modes { %s } on all channels.\n",
 	      answers);
-      putlog(LOG_CMDS, "*", "#%s# chanset * %s", dcc[idx].nick, answers);
+#ifdef HUB
+      write_userfile(-1);
+#endif
     }
     nfree(buf);
   }
 }
 
-static void cmd_chansave(struct userrec *u, int idx, char *par)
-{
-  if (!chanfile[0])
-    dprintf(idx, "No channel saving file defined.\n");
-  else {
-    dprintf(idx, "Saving all dynamic channel settings.\n");
-    putlog(LOG_CMDS, "*", "#%s# chansave", dcc[idx].nick);
-    write_channels();
-  }
-}
-
-static void cmd_chanload(struct userrec *u, int idx, char *par)
-{
-  if (!chanfile[0])
-    dprintf(idx, "No channel saving file defined.\n");
-  else {
-    dprintf(idx, "Reloading all dynamic channel settings.\n");
-    putlog(LOG_CMDS, "*", "#%s# chanload", dcc[idx].nick);
-    setstatic = 0;
-    read_channels(1);
-  }
-}
-
 /* DCC CHAT COMMANDS
  *
  * Function call should be:
@@ -1465,28 +1672,36 @@ static void cmd_chanload(struct userrec *u, int idx, char *par)
  *
  * NOTE: As with msg commands, the function is responsible for any logging.
  */
-static cmd_t C_dcc_irc[] =
+static dcc_cmd_t C_dcc_irc[] =
 {
-  {"+ban",	"ol|ol",	(Function) cmd_pls_ban,		NULL},
-  {"+exempt",	"ol|ol",	(Function) cmd_pls_exempt,	NULL},
-  {"+invite",	"ol|ol",	(Function) cmd_pls_invite,	NULL},
-  {"+chan",	"n",	(Function) cmd_pls_chan,	NULL},
-  {"+chrec",	"m|m",	(Function) cmd_pls_chrec,	NULL},
-  {"-ban",	"ol|ol",	(Function) cmd_mns_ban,		NULL},
-  {"-chan",	"n",	(Function) cmd_mns_chan,	NULL},
-  {"-chrec",	"m|m",	(Function) cmd_mns_chrec,	NULL},
-  {"bans",	"ol|ol",	(Function) cmd_bans,		NULL},
-  {"-exempt",	"ol|ol",	(Function) cmd_mns_exempt,	NULL},
-  {"-invite",	"ol|ol",	(Function) cmd_mns_invite,	NULL},
-  {"exempts",	"ol|ol",	(Function) cmd_exempts,		NULL},
-  {"invites",	"ol|ol",	(Function) cmd_invites,		NULL},
-  {"chaninfo",	"m|m",	(Function) cmd_chaninfo,	NULL},
-  {"chanload",	"n|n",	(Function) cmd_chanload,	NULL},
-  {"chanset",	"n|n",	(Function) cmd_chanset,		NULL},
-  {"chansave",	"n|n",	(Function) cmd_chansave,	NULL},
-  {"chinfo",	"m|m",	(Function) cmd_chinfo,		NULL},
-  {"info",	"",	(Function) cmd_info,		NULL},
-  {"stick",	"ol|ol",	(Function) cmd_stick,		NULL},
-  {"unstick",	"ol|ol",	(Function) cmd_unstick,		NULL},
-  {NULL,	NULL,	NULL,				NULL}
+  {"+ban",	"o|o",	(Function) cmd_pls_ban,		NULL,        NULL},
+#ifdef S_IRCNET
+  {"+exempt",	"o|o",	(Function) cmd_pls_exempt,	NULL,        NULL},
+  {"+invite",	"o|o",	(Function) cmd_pls_invite,	NULL,        NULL},
+#endif
+  {"+chan",	"n",	(Function) cmd_pls_chan,	NULL,        NULL},
+  {"+chrec",	"m|m",	(Function) cmd_pls_chrec,	NULL,        NULL},
+  {"-ban",	"o|o",	(Function) cmd_mns_ban,		NULL,        NULL},
+  {"-chan",	"n",	(Function) cmd_mns_chan,	NULL,        NULL},
+  {"-chrec",	"m|m",	(Function) cmd_mns_chrec,	NULL,        NULL},
+#ifdef S_IRCNET
+  {"-exempt",	"o|o",	(Function) cmd_mns_exempt,	NULL,        NULL},
+  {"-invite",	"o|o",	(Function) cmd_mns_invite,	NULL,        NULL},
+#endif
+  {"bans",	"o|o",	(Function) cmd_bans,		NULL,        NULL},
+#ifdef S_IRCNET
+  {"exempts",	"o|o",	(Function) cmd_exempts,		NULL,        NULL},
+  {"invites",	"o|o",	(Function) cmd_invites,		NULL,        NULL},
+#endif
+  {"chaninfo",	"m|m",	(Function) cmd_chaninfo,	NULL,        NULL},
+  {"chanset",	"m|m",	(Function) cmd_chanset,		NULL,        NULL},
+  {"chinfo",	"m|m",	(Function) cmd_chinfo,		NULL,        NULL},
+  {"cycle", 	"n|n",	(Function) cmd_cycle,		NULL,        NULL},
+  {"down",	"n|n",	(Function) cmd_down,		NULL,        NULL},
+  {"info",	"",	(Function) cmd_info,		NULL,        NULL},
+  {"slowjoin",  "n",    (Function) cmd_slowjoin,        NULL,        NULL},
+  {"slowpart",  "n|n",  (Function) cmd_slowpart,        NULL,        NULL},
+  {"stick",	"o|o",	(Function) cmd_stick,		NULL,        NULL},
+  {"unstick",	"o|o",	(Function) cmd_unstick,		NULL,        NULL},
+  {NULL,	NULL,	NULL,				NULL,      NULL}
 };

+ 247 - 147
src/mod/channels.mod/tclchan.c

@@ -1,25 +1,6 @@
 /*
  * tclchan.c -- part of channels.mod
  *
- * $Id: tclchan.c,v 1.61 2002/07/18 19:01:44 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 static int tcl_killban STDVAR
@@ -509,8 +490,12 @@ static int tcl_newchanban STDVAR
   strncpyz(ban, argv[2], sizeof ban);
   strncpyz(from, argv[3], sizeof from);
   strncpyz(cmt, argv[4], sizeof cmt);
-  if (argc == 5)
-    expire_time = now + (60 * ban_time);
+  if (argc == 5) {
+    if (chan->ban_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * chan->ban_time);
+  }
   else {
     if (atoi(argv[5]) == 0)
       expire_time = 0L;
@@ -545,8 +530,12 @@ static int tcl_newban STDVAR
   strncpyz(ban, argv[1], sizeof ban);
   strncpyz(from, argv[2], sizeof from);
   strncpyz(cmt, argv[3], sizeof cmt);
-  if (argc == 4)
-    expire_time = now + (60 * ban_time);
+  if (argc == 4) {
+    if (global_ban_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * global_ban_time);
+  }
   else {
     if (atoi(argv[4]) == 0)
       expire_time = 0L;
@@ -586,8 +575,12 @@ static int tcl_newchanexempt STDVAR
   strncpyz(exempt, argv[2], sizeof exempt);
   strncpyz(from, argv[3], sizeof from);
   strncpyz(cmt, argv[4], sizeof cmt);
-  if (argc == 5)
-    expire_time = now + (60 * exempt_time);
+  if (argc == 5) {
+    if (chan->exempt_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * chan->exempt_time);
+  }
   else {
     if (atoi(argv[5]) == 0)
       expire_time = 0L;
@@ -620,8 +613,12 @@ static int tcl_newexempt STDVAR
   strncpyz(exempt, argv[1], sizeof exempt);
   strncpyz(from, argv[2], sizeof from);
   strncpyz(cmt, argv[3], sizeof cmt);
-  if (argc == 4)
-    expire_time = now + (60 * exempt_time);
+  if (argc == 4) {
+    if (global_exempt_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * global_exempt_time);
+  }
   else {
     if (atoi(argv[4]) == 0)
       expire_time = 0L;
@@ -660,8 +657,12 @@ static int tcl_newchaninvite STDVAR
   strncpyz(invite, argv[2], sizeof invite);
   strncpyz(from, argv[3], sizeof from);
   strncpyz(cmt, argv[4], sizeof cmt);
-  if (argc == 5)
-    expire_time = now + (60 * invite_time);
+  if (argc == 5) {
+    if (chan->invite_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * chan->invite_time);
+  }
   else {
     if (atoi(argv[5]) == 0)
       expire_time = 0L;
@@ -694,8 +695,12 @@ static int tcl_newinvite STDVAR
   strncpyz(invite, argv[1], sizeof invite);
   strncpyz(from, argv[2], sizeof from);
   strncpyz(cmt, argv[3], sizeof cmt);
-  if (argc == 4)
-     expire_time = now + (60 * invite_time);
+  if (argc == 4) {
+    if (global_invite_time == 0)
+      expire_time = 0L;
+    else
+      expire_time = now + (60 * global_invite_time);
+  }
   else {
     if (atoi(argv[4]) == 0)
       expire_time = 0L;
@@ -710,13 +715,20 @@ static int tcl_newinvite STDVAR
 
 static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
 {
-  char s[121];
+  char a[121], b[121], s[121];
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
+  CONST char *args[2];
+#else
+  char *args[2];
+#endif
   struct udef_struct *ul;
 
   get_mode_protect(chan, s);
   Tcl_AppendElement(irp, s);
   simple_sprintf(s, "%d", chan->idle_kick);
   Tcl_AppendElement(irp, s);
+  simple_sprintf(s, "%d", chan->limitraise);
+  Tcl_AppendElement(irp, s);
   simple_sprintf(s, "%d", chan->stopnethack_mode);
   Tcl_AppendElement(irp, s);
   simple_sprintf(s, "%d", chan->revenge_mode);
@@ -738,8 +750,14 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
   Tcl_AppendElement(irp, s);
   simple_sprintf(s, "%d:%d", chan->flood_nick_thr, chan->flood_nick_time);
   Tcl_AppendElement(irp, s);
-  simple_sprintf(s, "%d:%d", chan->aop_min, chan->aop_max);
+  simple_sprintf(s, "%d", chan->ban_time);
+  Tcl_AppendElement(irp, s);
+#ifdef S_IRCNET
+  simple_sprintf(s, "%d", chan->exempt_time);
+  Tcl_AppendElement(irp, s);
+  simple_sprintf(s, "%d", chan->invite_time);
   Tcl_AppendElement(irp, s);
+#endif
   if (chan->status & CHAN_ENFORCEBANS)
     Tcl_AppendElement(irp, "+enforcebans");
   else
@@ -752,30 +770,14 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
     Tcl_AppendElement(irp, "-userbans");
   else
     Tcl_AppendElement(irp, "+userbans");
-  if (chan->status & CHAN_OPONJOIN)
-    Tcl_AppendElement(irp, "+autoop");
-  else
-    Tcl_AppendElement(irp, "-autoop");
-  if (chan->status & CHAN_AUTOHALFOP)
-    Tcl_AppendElement(irp, "+autohalfop");
-  else
-    Tcl_AppendElement(irp, "-autohalfop");
   if (chan->status & CHAN_BITCH)
     Tcl_AppendElement(irp, "+bitch");
   else
     Tcl_AppendElement(irp, "-bitch");
-  if (chan->status & CHAN_GREET)
-    Tcl_AppendElement(irp, "+greet");
-  else
-    Tcl_AppendElement(irp, "-greet");
   if (chan->status & CHAN_PROTECTOPS)
     Tcl_AppendElement(irp, "+protectops");
   else
     Tcl_AppendElement(irp, "-protectops");
-  if (chan->status & CHAN_PROTECTHALFOPS)
-    Tcl_AppendElement(irp, "+protecthalfops");
-  else
-    Tcl_AppendElement(irp, "-protecthalfops");
   if (chan->status & CHAN_PROTECTFRIENDS)
     Tcl_AppendElement(irp, "+protectfriends");
   else
@@ -788,10 +790,6 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
     Tcl_AppendElement(irp, "+inactive");
   else
     Tcl_AppendElement(irp, "-inactive");
-  if (chan->status & CHAN_LOGSTATUS)
-    Tcl_AppendElement(irp, "+statuslog");
-  else
-    Tcl_AppendElement(irp, "-statuslog");
   if (chan->status & CHAN_REVENGE)
     Tcl_AppendElement(irp, "+revenge");
   else
@@ -804,22 +802,11 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
     Tcl_AppendElement(irp, "+secret");
   else
     Tcl_AppendElement(irp, "-secret");
-  if (chan->status & CHAN_SHARED)
-    Tcl_AppendElement(irp, "+shared");
-  else
-    Tcl_AppendElement(irp, "-shared");
-  if (chan->status & CHAN_AUTOVOICE)
-    Tcl_AppendElement(irp, "+autovoice");
-  else
-    Tcl_AppendElement(irp, "-autovoice");
   if (chan->status & CHAN_CYCLE)
     Tcl_AppendElement(irp, "+cycle");
   else
     Tcl_AppendElement(irp, "-cycle");
-  if (chan->status & CHAN_SEEN)
-    Tcl_AppendElement(irp, "+seen");
-  else
-    Tcl_AppendElement(irp, "-seen");
+#ifdef S_IRCNET
   if (chan->ircnet_status& CHAN_DYNAMICEXEMPTS)
     Tcl_AppendElement(irp, "+dynamicexempts");
   else
@@ -836,10 +823,40 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
     Tcl_AppendElement(irp, "-userinvites");
   else
     Tcl_AppendElement(irp, "+userinvites");
+#endif
   if (chan->status & CHAN_NODESYNCH)
     Tcl_AppendElement(irp, "+nodesynch");
   else
     Tcl_AppendElement(irp, "-nodesynch");
+  if (chan->status & CHAN_CLOSED)
+    Tcl_AppendElement(irp, "+closed");
+  else
+    Tcl_AppendElement(irp, "-closed");
+  if (chan->status & CHAN_TAKE)
+    Tcl_AppendElement(irp, "+take");
+  else
+    Tcl_AppendElement(irp, "-take");
+  if (chan->status & CHAN_NOMOP)
+    Tcl_AppendElement(irp, "+nomop");
+  else
+    Tcl_AppendElement(irp, "-nomop");
+  if (chan->status & CHAN_MANOP)
+    Tcl_AppendElement(irp, "+manop");
+  else
+    Tcl_AppendElement(irp, "-manop");
+  if (chan->status & CHAN_VOICE)
+    Tcl_AppendElement(irp, "+voice");
+  else
+    Tcl_AppendElement(irp, "-voice");
+  if (chan->status & CHAN_FASTOP)
+    Tcl_AppendElement(irp, "+fastop");
+  else
+    Tcl_AppendElement(irp, "-fastop");
+  if (chan->status & CHAN_PRIVATE)
+    Tcl_AppendElement(irp, "+private");
+  else
+    Tcl_AppendElement(irp, "-private");
+
   for (ul = udef; ul; ul = ul->next) {
       /* If it's undefined, skip it. */
       if (!ul->defined || !ul->name) continue;
@@ -849,7 +866,14 @@ static int tcl_channel_info(Tcl_Interp * irp, struct chanset_t *chan)
 		       ul->name);
         Tcl_AppendElement(irp, s);
       } else if (ul->type == UDEF_INT) {
-        simple_sprintf(s, "%s %d", ul->name, getudef(ul->values, chan->dname));
+        char *x;
+        egg_snprintf(a, sizeof a, "%s", ul->name);
+        egg_snprintf(b, sizeof b, "%d", getudef(ul->values, chan->dname));
+        args[0] = a;
+        args[1] = b;
+        x = Tcl_Merge(2, args);
+        egg_snprintf(s, sizeof s, "%s", x);
+        Tcl_Free((char *) x);
         Tcl_AppendElement(irp, s);
       } else
         debug1("UDEF-ERROR: unknown type %d", ul->type);
@@ -882,42 +906,46 @@ static int tcl_channel_get(Tcl_Interp * irp, struct chanset_t *chan, char *setti
   else if (CHECK("need-limit"))  { strncpy(s, chan->need_limit, 120); s[120] = 0;  }
 
   else if (CHECK("idle-kick"))     simple_sprintf(s, "%d", chan->idle_kick);
+  else if (CHECK("limit"))         simple_sprintf(s, "%d", chan->limitraise);
   else if (CHECK("stop-net-hack")) simple_sprintf(s, "%d", chan->stopnethack_mode);
   else if (CHECK("revenge-mode"))  simple_sprintf(s, "%d", chan->revenge_mode);
-  else if (CHECK("flood-pub"))     simple_sprintf(s, "%d %d", chan->flood_pub_thr, chan->flood_pub_time);
+  else if (CHECK("flood-chan"))    simple_sprintf(s, "%d %d", chan->flood_pub_thr, chan->flood_pub_time);
   else if (CHECK("flood-ctcp"))    simple_sprintf(s, "%d %d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
   else if (CHECK("flood-join"))    simple_sprintf(s, "%d %d", chan->flood_join_thr, chan->flood_join_time);
   else if (CHECK("flood-kick"))    simple_sprintf(s, "%d %d", chan->flood_kick_thr, chan->flood_kick_time);
   else if (CHECK("flood-deop"))    simple_sprintf(s, "%d %d", chan->flood_deop_thr, chan->flood_deop_time);
   else if (CHECK("flood-nick"))    simple_sprintf(s, "%d %d", chan->flood_nick_thr, chan->flood_nick_time);
-  else if (CHECK("aop-delay"))     simple_sprintf(s, "%d %d", chan->aop_min, chan->aop_max);
-
+  else if (CHECK("ban-time"))  	   simple_sprintf(s, "%d", chan->ban_time);
+#ifdef S_IRCNET
+  else if (CHECK("exempt-time"))   simple_sprintf(s, "%d", chan->exempt_time);
+  else if (CHECK("invite-time"))   simple_sprintf(s, "%d", chan->invite_time);
+#endif
   else if CHKFLAG_POS(CHAN_ENFORCEBANS,    "enforcebans",    chan->status)
   else if CHKFLAG_POS(CHAN_DYNAMICBANS,    "dynamicbans",    chan->status)
   else if CHKFLAG_NEG(CHAN_NOUSERBANS,     "userbans",       chan->status)
-  else if CHKFLAG_POS(CHAN_OPONJOIN,       "autoop",         chan->status)
-  else if CHKFLAG_POS(CHAN_AUTOHALFOP,     "autohalfop",     chan->status)
   else if CHKFLAG_POS(CHAN_BITCH,          "bitch",          chan->status)
-  else if CHKFLAG_POS(CHAN_GREET,          "greet",          chan->status)
   else if CHKFLAG_POS(CHAN_PROTECTOPS,     "protectops",     chan->status)
-  else if CHKFLAG_POS(CHAN_PROTECTHALFOPS, "protecthalfops", chan->status)
   else if CHKFLAG_POS(CHAN_PROTECTFRIENDS, "protectfriends", chan->status)
   else if CHKFLAG_POS(CHAN_DONTKICKOPS,    "dontkickops",    chan->status)
   else if CHKFLAG_POS(CHAN_INACTIVE,       "inactive",       chan->status)
-  else if CHKFLAG_POS(CHAN_LOGSTATUS,      "statuslog",      chan->status)
   else if CHKFLAG_POS(CHAN_REVENGE,        "revenge",        chan->status)
   else if CHKFLAG_POS(CHAN_REVENGEBOT,     "revengebot",     chan->status)
   else if CHKFLAG_POS(CHAN_SECRET,         "secret",         chan->status)
-  else if CHKFLAG_POS(CHAN_SHARED,         "shared",         chan->status)
-  else if CHKFLAG_POS(CHAN_AUTOVOICE,      "autovoice",      chan->status)
   else if CHKFLAG_POS(CHAN_CYCLE,          "cycle",          chan->status)
-  else if CHKFLAG_POS(CHAN_SEEN,           "seen",           chan->status)
   else if CHKFLAG_POS(CHAN_NODESYNCH,      "nodesynch",      chan->status)
-
+#ifdef S_IRCNET
   else if CHKFLAG_POS(CHAN_DYNAMICEXEMPTS, "dynamicexempts", chan->ircnet_status)
   else if CHKFLAG_NEG(CHAN_NOUSEREXEMPTS,  "userexempts",    chan->ircnet_status)
   else if CHKFLAG_POS(CHAN_DYNAMICINVITES, "dynamicinvites", chan->ircnet_status)
   else if CHKFLAG_NEG(CHAN_NOUSERINVITES,  "userinvites",    chan->ircnet_status)
+#endif
+  else if CHKFLAG_POS(CHAN_CLOSED,          "closed",          chan->status)
+  else if CHKFLAG_POS(CHAN_TAKE,          "take",          chan->status)
+  else if CHKFLAG_POS(CHAN_NOMOP,          "nomop",          chan->status)
+  else if CHKFLAG_POS(CHAN_MANOP,          "manop",          chan->status)
+  else if CHKFLAG_POS(CHAN_VOICE,          "voice",          chan->status)
+  else if CHKFLAG_POS(CHAN_FASTOP,          "fastop",          chan->status)
+  else if CHKFLAG_POS(CHAN_PRIVATE,          "private",          chan->status)
 
   else {
     /* Hopefully it's a user-defined flag. */
@@ -945,12 +973,20 @@ static int tcl_channel_get(Tcl_Interp * irp, struct chanset_t *chan, char *setti
 static int tcl_channel STDVAR
 {
   struct chanset_t *chan;
-
+  char buf2[1024];
   BADARGS(2, 999, " command ?options?");
   if (!strcmp(argv[1], "add")) {
     BADARGS(3, 4, " add channel-name ?options-list?");
-    if (argc == 3)
+    if (argc == 3) {
+      
+      sprintf(buf2, "cjoin %s", argv[2]);
+      if (!loading)
+        botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
       return tcl_channel_add(irp, argv[2], "");
+    }
+    sprintf(buf2, "cjoin %s %s", argv[2], argv[3]);
+    if (!loading)
+      botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
     return tcl_channel_add(irp, argv[2], argv[3]);
   }
   if (!strcmp(argv[1], "set")) {
@@ -964,6 +1000,8 @@ static int tcl_channel STDVAR
       Tcl_AppendResult(irp, "no such channel record", NULL);
       return TCL_ERROR;
     }
+    sprintf(buf2, "cset %s %s", chan->dname, argv[3]);
+    botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
     return tcl_channel_modify(irp, chan, argc - 3, &argv[3]);
   }
   if (!strcmp(argv[1], "get")) {
@@ -987,10 +1025,13 @@ static int tcl_channel STDVAR
   if (!strcmp(argv[1], "remove")) {
     BADARGS(3, 3, " remove channel-name");
     chan = findchan_by_dname(argv[2]);
+
     if (chan == NULL) {
       Tcl_AppendResult(irp, "no such channel record", NULL);
       return TCL_ERROR;
     }
+    sprintf(buf2, "cpart %s", argv[2]);
+    botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
     remove_channel(chan);
     return TCL_OK;
   }
@@ -1004,13 +1045,17 @@ static int tcl_channel STDVAR
 static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 			      int items, char **item)
 {
-  int i, x = 0, found,
-      old_status = chan->status,
+  int i, x = 0, found;
+#ifdef LEAF
+  int old_status = chan->status,
       old_mode_mns_prot = chan->mode_mns_prot,
       old_mode_pls_prot = chan->mode_pls_prot;
+#endif
   struct udef_struct *ul = udef;
+  char s[121];
+#ifdef LEAF
   module_entry *me;
-
+#endif
   for (i = 0; i < items; i++) {
     if (!strcmp(item[i], "need-op")) {
       i++;
@@ -1064,9 +1109,9 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 	  Tcl_AppendResult(irp, "channel chanmode needs argument", NULL);
 	return TCL_ERROR;
       }
-      if (strlen(item[i]) > 120)
-	item[i][120] = 0;
-      set_mode_protect(chan, item[i]);
+      strncpy(s, item[i], 120);
+      s[120] = 0;
+      set_mode_protect(chan, s);
     } else if (!strcmp(item[i], "idle-kick")) {
       i++;
       if (i >= items) {
@@ -1075,6 +1120,15 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 	return TCL_ERROR;
       }
       chan->idle_kick = atoi(item[i]);
+    } else if (!strcmp(item[i], "limit")) {
+      i++;
+      if (i >= items) {
+        if (irp)
+          Tcl_AppendResult(irp, "channel limit needs argument", NULL);
+        return TCL_ERROR;
+      }
+      chan->limitraise = atoi(item[i]);
+      chan->limit_prot = 0;
     } else if (!strcmp(item[i], "dont-idle-kick"))
       chan->idle_kick = 0;
     else if (!strcmp(item[i], "stopnethack-mode")) {
@@ -1093,6 +1147,41 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
         return TCL_ERROR;
       }
       chan->revenge_mode = atoi(item[i]);
+    } else if (!strcmp(item[i], "ban-time")) {
+      i++;
+      if (i >= items) {
+        if (irp)
+          Tcl_AppendResult(irp, "channel ban-time needs argument", NULL);
+        return TCL_ERROR;
+      }
+      chan->ban_time = atoi(item[i]);
+#ifdef S_IRCNET
+    } else if (!strcmp(item[i], "exempt-time")) {
+      i++;
+      if (i >= items) {
+        if (irp)
+          Tcl_AppendResult(irp, "channel exempt-time needs argument", NULL);
+        return TCL_ERROR;
+      }
+      chan->exempt_time = atoi(item[i]);
+    } else if (!strcmp(item[i], "invite-time")) {
+      i++;
+      if (i >= items) {
+        if (irp)
+          Tcl_AppendResult(irp, "channel invite-time needs argument", NULL);
+        return TCL_ERROR;
+      }
+      chan->invite_time = atoi(item[i]);
+#endif
+    } else if (!strcmp(item[i], "topic")) {
+      i++;
+      if (i >= items) {
+	if (irp)
+	  Tcl_AppendResult(irp, "channel topic needs argument", NULL);
+	return TCL_ERROR;
+      }
+      strncpyz(chan->topic_prot, item[i], sizeof(chan->topic_prot));
+      check_topic(chan);
     }
     else if (!strcmp(item[i], "+enforcebans"))
       chan->status |= CHAN_ENFORCEBANS;
@@ -1106,14 +1195,6 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
       chan->status |= CHAN_NOUSERBANS;
     else if (!strcmp(item[i], "+userbans"))
       chan->status &= ~CHAN_NOUSERBANS;
-    else if (!strcmp(item[i], "+autoop"))
-      chan->status |= CHAN_OPONJOIN;
-    else if (!strcmp(item[i], "-autoop"))
-      chan->status &= ~CHAN_OPONJOIN;
-    else if (!strcmp(item[i], "+autohalfop"))
-      chan->status |= CHAN_AUTOHALFOP;
-    else if (!strcmp(item[i], "-autohalfop"))
-      chan->status &= ~CHAN_AUTOHALFOP;
     else if (!strcmp(item[i], "+bitch"))
       chan->status |= CHAN_BITCH;
     else if (!strcmp(item[i], "-bitch"))
@@ -1122,18 +1203,10 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
       chan->status |= CHAN_NODESYNCH;
     else if (!strcmp(item[i], "-nodesynch"))
       chan->status &= ~CHAN_NODESYNCH;
-    else if (!strcmp(item[i], "+greet"))
-      chan->status |= CHAN_GREET;
-    else if (!strcmp(item[i], "-greet"))
-      chan->status &= ~CHAN_GREET;
     else if (!strcmp(item[i], "+protectops"))
       chan->status |= CHAN_PROTECTOPS;
     else if (!strcmp(item[i], "-protectops"))
       chan->status &= ~CHAN_PROTECTOPS;
-    else if (!strcmp(item[i], "+protecthalfops"))
-      chan->status |= CHAN_PROTECTHALFOPS;
-    else if (!strcmp(item[i], "-protecthalfops"))
-      chan->status &= ~CHAN_PROTECTHALFOPS;
     else if (!strcmp(item[i], "+protectfriends"))
       chan->status |= CHAN_PROTECTFRIENDS;
     else if (!strcmp(item[i], "-protectfriends"))
@@ -1146,10 +1219,6 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
       chan->status |= CHAN_INACTIVE;
     else if (!strcmp(item[i], "-inactive"))
       chan->status&= ~CHAN_INACTIVE;
-    else if (!strcmp(item[i], "+statuslog"))
-      chan->status |= CHAN_LOGSTATUS;
-    else if (!strcmp(item[i], "-statuslog"))
-      chan->status &= ~CHAN_LOGSTATUS;
     else if (!strcmp(item[i], "+revenge"))
       chan->status |= CHAN_REVENGE;
     else if (!strcmp(item[i], "-revenge"))
@@ -1162,22 +1231,11 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
       chan->status |= CHAN_SECRET;
     else if (!strcmp(item[i], "-secret"))
       chan->status &= ~CHAN_SECRET;
-    else if (!strcmp(item[i], "+shared"))
-      chan->status |= CHAN_SHARED;
-    else if (!strcmp(item[i], "-shared"))
-      chan->status &= ~CHAN_SHARED;
-    else if (!strcmp(item[i], "+autovoice"))
-      chan->status |= CHAN_AUTOVOICE;
-    else if (!strcmp(item[i], "-autovoice"))
-      chan->status &= ~CHAN_AUTOVOICE;
     else if (!strcmp(item[i], "+cycle"))
       chan->status |= CHAN_CYCLE;
     else if (!strcmp(item[i], "-cycle"))
       chan->status &= ~CHAN_CYCLE;
-    else if (!strcmp(item[i], "+seen"))
-      chan->status |= CHAN_SEEN;
-    else if (!strcmp(item[i], "-seen"))
-      chan->status &= ~CHAN_SEEN;
+#ifdef S_IRCNET
     else if (!strcmp(item[i], "+dynamicexempts"))
       chan->ircnet_status|= CHAN_DYNAMICEXEMPTS;
     else if (!strcmp(item[i], "-dynamicexempts"))
@@ -1194,9 +1252,51 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
       chan->ircnet_status|= CHAN_NOUSERINVITES;
     else if (!strcmp(item[i], "+userinvites"))
       chan->ircnet_status&= ~CHAN_NOUSERINVITES;
+#endif
+    else if (!strcmp(item[i], "+closed"))
+      chan->status |= CHAN_CLOSED;
+    else if (!strcmp(item[i], "-closed"))
+      chan->status &= ~CHAN_CLOSED;
+    else if (!strcmp(item[i], "+take"))
+      chan->status |= CHAN_TAKE;
+    else if (!strcmp(item[i], "-take"))
+      chan->status &= ~CHAN_TAKE;
+    else if (!strcmp(item[i], "+nomop"))
+      chan->status |= CHAN_NOMOP;
+    else if (!strcmp(item[i], "-nomop"))
+      chan->status &= ~CHAN_NOMOP;
+    else if (!strcmp(item[i], "+manop"))
+      chan->status |= CHAN_MANOP;
+    else if (!strcmp(item[i], "-manop"))
+      chan->status &= ~CHAN_MANOP;
+    else if (!strcmp(item[i], "+voice"))
+      chan->status |= CHAN_VOICE;
+    else if (!strcmp(item[i], "-voice"))
+      chan->status &= ~CHAN_VOICE;
+    else if (!strcmp(item[i], "+fastop")) {
+      chan->status |= CHAN_FASTOP;
+    }
+    else if (!strcmp(item[i], "-fastop"))
+      chan->status &= ~(CHAN_FASTOP | CHAN_PROTECTFRIENDS | CHAN_PROTECTOPS | CHAN_DONTKICKOPS);
+    else if (!strcmp(item[i], "+private")) {
+      chan->status |= CHAN_PRIVATE;
+    }
+    else if (!strcmp(item[i], "-private"))
+      chan->status &= ~CHAN_PRIVATE;
+
     /* ignore wasoptest, stopnethack and clearbans in chanfile, remove
        this later */
-    else if (!strcmp(item[i], "-stopnethack"))  ;
+    else if (!strcmp(item[i], "+nomdop"))  ;
+    else if (!strcmp(item[i], "-nomdop"))  ;
+    else if (!strcmp(item[i], "+nomop"))  ;
+    else if (!strcmp(item[i], "-nomop"))  ;
+    else if (!strcmp(item[i], "+punish"))  ;
+    else if (!strcmp(item[i], "-punish"))  ;
+    else if (!strcmp(item[i], "+seen"))  ;
+    else if (!strcmp(item[i], "-seen"))  ;
+    else if (!strcmp(item[i], "+secret"))  ;
+    else if (!strcmp(item[i], "-secret"))  ;
+      else if (!strcmp(item[i], "-stopnethack"))  ;
     else if (!strcmp(item[i], "+stopnethack"))  ;
     else if (!strcmp(item[i], "-wasoptest"))  ;
     else if (!strcmp(item[i], "+wasoptest"))  ;  /* Eule 01.2000 */
@@ -1245,23 +1345,6 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 	*pthr = atoi(item[i]);
 	*ptime = 1;
       }
-    } else if (!strncmp(item[i], "aop-delay", 9)) {
-      char *p;
-      i++;
-      if (i >= items) {
-	if (irp)
-	  Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
-	return TCL_ERROR;
-      }
-      p = strchr(item[i], ':');
-      if (p) {
-	p++;
-	chan->aop_min = atoi(item[i]);
-	chan->aop_max = atoi(p);
-      } else {
-	chan->aop_min = atoi(item[i]);
-	chan->aop_max = chan->aop_min;
-      }
     } else {
       if (!strncmp(item[i] + 1, "udef-flag-", 10))
         initudef(UDEF_FLAG, item[i] + 11, 0);
@@ -1311,6 +1394,7 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
    * (note: it may cause problems if there is no chanfile!)
    * <drummer/1999/10/21>
    */
+#ifdef LEAF
   if (protect_readonly || chan_hack) {
     if (((old_status ^ chan->status) & CHAN_INACTIVE) &&
 	module_find("irc", 0, 0)) {
@@ -1324,15 +1408,18 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 					   chan->channel.key[0] ?
 					   chan->channel.key : chan->key_prot);
     }
-    if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS | CHAN_OPONJOIN |
-	CHAN_BITCH | CHAN_AUTOVOICE | CHAN_AUTOHALFOP)) {
+Context;
+    if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS |
+	CHAN_BITCH)) {
       if ((me = module_find("irc", 0, 0)))
         (me->funcs[IRC_RECHECK_CHANNEL])(chan, 1);
     } else if (old_mode_pls_prot != chan->mode_pls_prot ||
 	       old_mode_mns_prot != chan->mode_mns_prot)
-    if ((me = module_find("irc", 1, 2)))
+    if ((me = module_find("irc", 0, 0)))
       (me->funcs[IRC_RECHECK_CHANNEL_MODES])(chan);
   }
+Context;
+#endif
   if (x > 0)
     return TCL_ERROR;
   return TCL_OK;
@@ -1341,7 +1428,7 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 static int tcl_do_masklist(maskrec *m, Tcl_Interp *irp)
 {
   char ts[21], ts1[21], ts2[21], *p;
-#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
   CONST char *list[6];
 #else
   char *list[6];
@@ -1423,7 +1510,8 @@ static int tcl_channels STDVAR
     Tcl_AppendElement(irp, chan->dname);
   return TCL_OK;
 }
-
+#ifdef HUB
+/* obsolete
 static int tcl_savechannels STDVAR
 {
   BADARGS(1, 1, "");
@@ -1431,10 +1519,9 @@ static int tcl_savechannels STDVAR
     Tcl_AppendResult(irp, "no channel file");
     return TCL_ERROR;
   }
-  write_channels();
+ //obsolete old .chan write_channels();
   return TCL_OK;
 }
-
 static int tcl_loadchannels STDVAR
 {
   BADARGS(1, 1, "");
@@ -1446,7 +1533,8 @@ static int tcl_loadchannels STDVAR
   read_channels(1);
   return TCL_OK;
 }
-
+*/
+#endif
 static int tcl_validchan STDVAR
 {
   struct chanset_t *chan;
@@ -1680,7 +1768,7 @@ static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options)
   int ret = TCL_OK;
   int join = 0;
   char buf[2048], buf2[256];
-#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
   CONST char **item;
 #else
   char **item;
@@ -1732,8 +1820,10 @@ static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options)
     chan->stopnethack_mode = global_stopnethack_mode;
     chan->revenge_mode = global_revenge_mode;
     chan->idle_kick = global_idle_kick;
-    chan->aop_min = global_aop_min;
-    chan->aop_max = global_aop_max;
+    chan->limitraise = 20;
+    chan->ban_time = global_ban_time;
+    chan->exempt_time = global_exempt_time;
+    chan->invite_time = global_invite_time;
 
     /* We _only_ put the dname (display name) in here so as not to confuse
      * any code later on. chan->name gets updated with the channel name as
@@ -1755,12 +1845,18 @@ static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options)
    * if a user goes back to an eggdrop that no-longer supports certain
    * (channel) options.
    */
+#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
+  if ((tcl_channel_modify(irp, chan, items, (char **)item) != TCL_OK) && !chan_hack) {
+#else
   if ((tcl_channel_modify(irp, chan, items, item) != TCL_OK) && !chan_hack) {
+#endif
     ret = TCL_ERROR;
   }
   Tcl_Free((char *) item);
+#ifdef LEAF
   if (join && !channel_inactive(chan) && module_find("irc", 0, 0))
     dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, chan->key_prot);
+#endif
   return ret;
 }
 
@@ -1884,8 +1980,12 @@ static tcl_cmds channels_cmds[] =
   {"exemptlist",	tcl_exemptlist},
   {"invitelist",	tcl_invitelist},
   {"banlist",		tcl_banlist},
+#ifdef HUB
+/* obsolete
   {"savechannels",	tcl_savechannels},
   {"loadchannels",	tcl_loadchannels},
+*/
+#endif
   {"validchan",		tcl_validchan},
   {"isdynamic",		tcl_isdynamic},
   {"getchaninfo",	tcl_getchaninfo},

+ 0 - 18
src/mod/channels.mod/udefchan.c

@@ -2,24 +2,6 @@
  * udefchan.c -- part of channels.mod
  *   user definable channel flags/settings
  *
- * $Id: udefchan.c,v 1.7 2002/01/02 03:46:37 guppy Exp $
- */
-/*
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 static int expmem_udef(struct udef_struct *ul)

+ 249 - 50
src/mod/channels.mod/userchan.c

@@ -1,27 +1,12 @@
 /*
  * userchan.c -- part of channels.mod
  *
- * $Id: userchan.c,v 1.28 2002/02/24 07:17:58 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+#ifdef S_DCCPASS
+extern struct cmd_pass *cmdpass;
+#endif
+
 struct chanuserrec *get_chanrec(struct userrec *u, char *chname)
 {
   struct chanuserrec *ch;
@@ -235,12 +220,13 @@ static int u_delban(struct chanset_t *c, char *who, int doit)
   int j, i = 0;
   maskrec *t;
   maskrec **u = (c) ? &c->bans : &global_bans;
+  char temp[256];
 
   if (!strchr(who, '!') && (j = atoi(who))) {
     j--;
     for (; (*u) && j; u = &((*u)->next), j--);
     if (*u) {
-      strcpy(who, (*u)->mask);
+      strncpyz(temp, (*u)->mask, sizeof temp);
       i = 1;
     } else
       return -j - 1;
@@ -248,6 +234,7 @@ static int u_delban(struct chanset_t *c, char *who, int doit)
     /* Find matching host, if there is one */
     for (; *u && !i; u = &((*u)->next))
       if (!rfc_casecmp((*u)->mask, who)) {
+        strncpyz(temp, who, sizeof temp);
 	i = 1;
 	break;
       }
@@ -256,7 +243,7 @@ static int u_delban(struct chanset_t *c, char *who, int doit)
   }
   if (i && doit) {
     if (!noshare) {
-      char *mask = str_escape(who, ':', '\\');
+      char *mask = str_escape(temp, ':', '\\');
 
       if (mask) {
 	/* Distribute chan bans differently */
@@ -267,6 +254,10 @@ static int u_delban(struct chanset_t *c, char *who, int doit)
 	nfree(mask);
       }
     }
+    if (lastdeletedmask)
+      nfree(lastdeletedmask);
+    lastdeletedmask = nmalloc(strlen((*u)->mask) + 1);
+    strcpy(lastdeletedmask, (*u)->mask);
     nfree((*u)->mask);
     if ((*u)->desc)
       nfree((*u)->desc);
@@ -1055,6 +1046,53 @@ static void tell_invites(int idx, int show_inact, char *match)
     dprintf(idx, "%s.\n", INVITES_USEINVITESALL);
 }
 
+static int write_config(FILE *f, int idx)
+{
+  int i = 0;
+#ifdef S_DCCPASS
+  struct cmd_pass *cp;
+#endif
+  putlog(LOG_DEBUG, "@", "Writing config entries...");
+  if (lfprintf(f, CONFIG_NAME " - -\n") == EOF) /* Daemus */
+      return 0;
+  for (i = 0; i < cfg_count; i++)
+    if ((cfg[i]->flags & CFGF_GLOBAL) && (cfg[i]->gdata)) {
+      if (lfprintf(f, "@ %s %s\n", cfg[i]->name, cfg[i]->gdata ? cfg[i]->gdata : "") == EOF)
+        return 0;
+    }
+
+/* old tcl shit..
+  int total = 0, i = 0;
+
+//fix proc config to accept NUM 0 for total, num for specific entry.
+  if (Tcl_Eval(interp, "config_start") == TCL_OK) { //make the tcl copy over vital vars first.
+   if (Tcl_Eval(interp, "array size a") == TCL_OK) { //get total config entries
+    total = atoi(interp->result);
+    for (i = 0; i < total; i++) { //loop each entry
+     buf[0] = '\0';
+     sprintf(buf, "config %i", i); //call proc config with i, returns + set...
+     if (Tcl_Eval(interp, buf) == TCL_OK) {
+       if (lfprintf(f, "%s\n", interp->result) == EOF) //write each config %i entry on a line alone.
+        return 0;
+     } else
+       return 0;
+    }
+//    if (lfprintf(f, "+ config_end\n") == EOF) //write config_end to userfile
+//      return 0;
+   } else 
+     return 0;
+  } else
+    return 0;
+*/
+
+#ifdef S_DCCPASS
+  for (cp = cmdpass; cp; cp = cp->next)
+    if (lfprintf(f, "- %s %s\n", cp->name, cp->pass) == EOF)
+      return 0;
+#endif
+
+  return 1;
+}
 /* Write the ban lists and the ignore list to a file.
  */
 static int write_bans(FILE *f, int idx)
@@ -1065,12 +1103,12 @@ static int write_bans(FILE *f, int idx)
   char	*mask;
 
   if (global_ign)
-    if (fprintf(f, IGNORE_NAME " - -\n") == EOF)	/* Daemus */
+    if (lfprintf(f, IGNORE_NAME " - -\n") == EOF)	/* Daemus */
       return 0;
   for (i = global_ign; i; i = i->next) {
     mask = str_escape(i->igmask, ':', '\\');
     if (!mask ||
-	fprintf(f, "- %s:%s%lu:%s:%lu:%s\n", mask,
+	lfprintf(f, "- %s:%s%lu:%s:%lu:%s\n", mask,
 		(i->flags & IGREC_PERM) ? "+" : "", i->expire,
 		i->user ? i->user : botnetnick, i->added,
 		i->msg ? i->msg : "") == EOF) {
@@ -1081,12 +1119,12 @@ static int write_bans(FILE *f, int idx)
     nfree(mask);
   }
   if (global_bans)
-    if (fprintf(f, BAN_NAME " - -\n") == EOF)	/* Daemus */
+    if (lfprintf(f, BAN_NAME " - -\n") == EOF)	/* Daemus */
       return 0;
   for (b = global_bans; b; b = b->next) {
     mask = str_escape(b->mask, ':', '\\');
     if (!mask ||
-	fprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
+	lfprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
 		(b->flags & MASKREC_PERM) ? "+" : "", b->expire,
 		(b->flags & MASKREC_STICKY) ? "*" : "", b->added,
 		b->lastactive, b->user ? b->user : botnetnick,
@@ -1098,20 +1136,21 @@ static int write_bans(FILE *f, int idx)
     nfree(mask);
   }
   for (chan = chanset; chan; chan = chan->next)
-    if ((idx < 0) || (chan->status & CHAN_SHARED)) {
+    if ((idx < 0)  || 1) {
       struct flag_record fr = {FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0};
 
       if (idx >= 0)
 	get_user_flagrec(dcc[idx].user, &fr, chan->dname);
       else
 	fr.chan = BOT_SHARE;
-      if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
-	if (fprintf(f, "::%s bans\n", chan->dname) == EOF)
+
+      //if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
+	if (lfprintf(f, "::%s bans\n", chan->dname) == EOF)
 	  return 0;
 	for (b = chan->bans; b; b = b->next) {
 	  mask = str_escape(b->mask, ':', '\\');
 	  if (!mask ||
-	      fprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
+	      lfprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
 		      (b->flags & MASKREC_PERM) ? "+" : "", b->expire,
 		      (b->flags & MASKREC_STICKY) ? "*" : "", b->added,
 		      b->lastactive, b->user ? b->user : botnetnick,
@@ -1122,11 +1161,11 @@ static int write_bans(FILE *f, int idx)
 	  }
 	  nfree(mask);
 	}
-      }
+      //}
     }
   return 1;
 }
-
+#ifdef S_IRCNET
 /* Write the exemptlists to a file.
  */
 static int write_exempts(FILE *f, int idx)
@@ -1136,12 +1175,12 @@ static int write_exempts(FILE *f, int idx)
   char	*mask;
 
   if (global_exempts)
-    if (fprintf(f, EXEMPT_NAME " - -\n") == EOF) /* Daemus */
+    if (lfprintf(f, EXEMPT_NAME " - -\n") == EOF) /* Daemus */
       return 0;
   for (e = global_exempts; e; e = e->next) {
     mask = str_escape(e->mask, ':', '\\');
     if (!mask ||
-	fprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", e->mask,
+	lfprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", e->mask,
 		(e->flags & MASKREC_PERM) ? "+" : "", e->expire,
 		(e->flags & MASKREC_STICKY) ? "*" : "", e->added,
 		e->lastactive, e->user ? e->user : botnetnick,
@@ -1153,20 +1192,20 @@ static int write_exempts(FILE *f, int idx)
     nfree(mask);
   }
   for (chan = chanset;chan;chan=chan->next)
-    if ((idx < 0) || (chan->status & CHAN_SHARED)) {
+    if ((idx < 0) || 1) {
       struct flag_record fr = {FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0};
 
       if (idx >= 0)
 	get_user_flagrec(dcc[idx].user,&fr,chan->dname);
       else
 	fr.chan = BOT_SHARE;
-      if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
-	if (fprintf(f, "&&%s exempts\n", chan->dname) == EOF)
+//      if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
+	if (lfprintf(f, "&&%s exempts\n", chan->dname) == EOF)
 	  return 0;
 	for (e = chan->exempts; e; e = e->next) {
 	  mask = str_escape(e->mask, ':', '\\');
 	  if (!mask ||
-	      fprintf(f,"%s %s:%s%lu%s:+%lu:%lu:%s:%s\n","%",e->mask,
+	      lfprintf(f,"%s %s:%s%lu%s:+%lu:%lu:%s:%s\n","%",e->mask,
 		      (e->flags & MASKREC_PERM) ? "+" : "", e->expire,
 		      (e->flags & MASKREC_STICKY) ? "*" : "", e->added,
 		      e->lastactive, e->user ? e->user : botnetnick,
@@ -1177,7 +1216,7 @@ static int write_exempts(FILE *f, int idx)
 	  }
 	  nfree(mask);
 	}
-      }
+      //}
     }
   return 1;
 }
@@ -1191,12 +1230,12 @@ static int write_invites(FILE *f, int idx)
   char	*mask;
 
   if (global_invites)
-    if (fprintf(f, INVITE_NAME " - -\n") == EOF) /* Daemus */
+    if (lfprintf(f, INVITE_NAME " - -\n") == EOF) /* Daemus */
       return 0;
   for (ir = global_invites; ir; ir = ir->next)  {
     mask = str_escape(ir->mask, ':', '\\');
     if (!mask ||
-	fprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
+	lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
 		(ir->flags & MASKREC_PERM) ? "+" : "", ir->expire,
 		(ir->flags & MASKREC_STICKY) ? "*" : "", ir->added,
 		ir->lastactive, ir->user ? ir->user : botnetnick,
@@ -1208,20 +1247,20 @@ static int write_invites(FILE *f, int idx)
     nfree(mask);
   }
   for (chan = chanset; chan; chan = chan->next)
-    if ((idx < 0) || (chan->status & CHAN_SHARED)) {
+    if ((idx < 0) || (1)) {
       struct flag_record fr = {FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0};
 
       if (idx >= 0)
 	get_user_flagrec(dcc[idx].user,&fr,chan->dname);
       else
 	fr.chan = BOT_SHARE;
-      if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
-	if (fprintf(f, "$$%s invites\n", chan->dname) == EOF)
+//      if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
+	if (lfprintf(f, "$$%s invites\n", chan->dname) == EOF)
 	  return 0;
 	for (ir = chan->invites; ir; ir = ir->next) {
 	  mask = str_escape(ir->mask, ':', '\\');
 	  if (!mask ||
-	      fprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
+	      lfprintf(f,"@ %s:%s%lu%s:+%lu:%lu:%s:%s\n",ir->mask,
 		      (ir->flags & MASKREC_PERM) ? "+" : "", ir->expire,
 		      (ir->flags & MASKREC_STICKY) ? "*" : "", ir->added,
 		      ir->lastactive, ir->user ? ir->user : botnetnick,
@@ -1232,28 +1271,157 @@ static int write_invites(FILE *f, int idx)
 	  }
 	  nfree(mask);
 	}
-      }
+      //}
     }
   return 1;
 }
+#endif
+/* Write the channels to the userfile
+ */
+static int write_chans(FILE *f, int idx)
+{
+
+  char w[1024], w2[1024], name[163];
+  char topic[1002], udefs[2048] = "", sadd[5], buf[2048];
+  struct chanset_t *chan;
+  struct udef_struct *ul;
+
+  putlog(LOG_DEBUG, "*", "Writing channels..");
+
+  if (lfprintf(f, CHANS_NAME " - -\n") == EOF) /* Daemus */
+    return 0;
+
+  for (chan = chanset; chan; chan = chan->next) {
+
+
+    if ((idx < 0) || (1)) {
+      struct flag_record fr = {FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0};
+      if (idx >= 0)
+        get_user_flagrec(dcc[idx].user,&fr,chan->dname);
+      else
+        fr.chan = BOT_SHARE;
+
+//    if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
+
+     putlog(LOG_DEBUG, "*", "writing channel %s to userfile..", chan->dname);
+
+     memset(udefs,'\0',2048);
+     convert_element(chan->dname, name);
+     get_mode_protect(chan, w);
+     convert_element(w, w2);
+     convert_element(chan->topic_prot, topic);
+     for (ul = udef; ul; ul = ul->next) { //put the udefs into one string
+       memset(buf,'\0',2048);
+       if (ul->defined && ul->name) { 
+	if (ul->type == UDEF_FLAG)
+	 sprintf(buf, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-', "udef-flag-", ul->name);
+	else if (ul->type == UDEF_INT)
+	  sprintf(buf, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values, chan->dname));
+	else
+	  debug1("UDEF-ERROR: unknown type %d", ul->type);
+        strcat(udefs,buf);
+       }
+     }
+   //insert the ending character into a string
+     sprintf(sadd, "%s\n", channel_static(chan) ? "" : "}");
+
+     if (lfprintf(f, "+ channel %s %s%schanmode %s topic %s idle-kick %d limit %d stopnethack-mode %d \
+revenge-mode %d \
+flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
+flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
+ban-time %d \
+exempt-time %d invite-time %d \
+%cenforcebans %cdynamicbans %cuserbans %cbitch \
+%cprotectops %cprotectfriends %cdontkickops \
+%crevenge %crevengebot %cprivate \
+%ccycle %cinactive \
+%cdynamicexempts %cuserexempts %cdynamicinvites %cuserinvites \
+%cnodesynch \
+%cclosed %ctake %cmanop %cvoice %cfastop %s %s",
+	channel_static(chan) ? "set" : "add",
+	name,
+	channel_static(chan) ? " " : " { ",
+	w2,
+        topic,
+	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (lcode)*/
+        chan->limitraise,
+	chan->stopnethack_mode,
+        chan->revenge_mode,
+	chan->flood_pub_thr, chan->flood_pub_time,
+        chan->flood_ctcp_thr, chan->flood_ctcp_time,
+        chan->flood_join_thr, chan->flood_join_time,
+        chan->flood_kick_thr, chan->flood_kick_time,
+        chan->flood_deop_thr, chan->flood_deop_time,
+	chan->flood_nick_thr, chan->flood_nick_time,
+        chan->ban_time,
+#ifdef S_IRCNET
+        chan->exempt_time,
+        chan->invite_time,
+#endif
+ 	PLSMNS(channel_enforcebans(chan)),
+	PLSMNS(channel_dynamicbans(chan)),
+	PLSMNS(!channel_nouserbans(chan)),
+	PLSMNS(channel_bitch(chan)),
+	PLSMNS(channel_protectops(chan)),
+	PLSMNS(channel_protectfriends(chan)),
+	PLSMNS(channel_dontkickops(chan)),
+	PLSMNS(channel_revenge(chan)),
+	PLSMNS(channel_revengebot(chan)),
+	PLSMNS(channel_private(chan)),
+	PLSMNS(channel_cycle(chan)),
+	PLSMNS(channel_inactive(chan)),
+#ifdef S_IRCNET
+	PLSMNS(channel_dynamicexempts(chan)),
+	PLSMNS(!channel_nouserexempts(chan)),
+ 	PLSMNS(channel_dynamicinvites(chan)),
+	PLSMNS(!channel_nouserinvites(chan)),
+#endif
+	PLSMNS(channel_nodesynch(chan)),
+	PLSMNS(channel_closed(chan)),
+	PLSMNS(channel_take(chan)),
+	PLSMNS(channel_manop(chan)),
+	PLSMNS(channel_voice(chan)),
+	PLSMNS(channel_fastop(chan)),
+        udefs,
+        sadd) == EOF)
+          return 0;
+//     } 
+    } 
+
+  }
+  return 1;
+
+}
+
 
 static void channels_writeuserfile(void)
 {
+#ifdef HUB
   char	 s[1024];
   FILE	*f;
   int	 ret = 0;
-
+  putlog(LOG_DEBUG, "@", "Writing channel/ban/exempt/invite entries.");
   simple_sprintf(s, "%s~new", userfile);
   f = fopen(s, "a");
   if (f) {
-    ret = write_bans(f, -1);
+//write channels to the userfile
+    ret  = write_chans(f, -1);
+    ret += write_config(f, -1);
+    ret += write_bans(f, -1);
+#ifdef S_IRCNET
     ret += write_exempts(f, -1);
     ret += write_invites(f, -1);
+#endif
     fclose(f);
   }
+#ifdef S_IRCNET
+  if (ret < 5)
+#else
   if (ret < 3)
+#endif
     putlog(LOG_MISC, "*", USERF_ERRWRITE);
-  write_channels();
+  //old .chan write_channels();
+#endif
 }
 
 /* Expire mask originally set by `who' on `chan'?
@@ -1310,9 +1478,39 @@ static int expired_mask(struct chanset_t *chan, char *who)
   else
     return 1;
 }
-
+// cheap hack.
+static void switch_static(void)
+{
+ if (setstatic)
+  setstatic = 0;
+ else
+  setstatic = 1;
+}
+#ifdef LEAF
+int checklimit = 1;
+void check_limitraise() {
+  int i=0;
+  struct chanset_t * chan;
+  struct userrec *u;
+  u=get_user_by_handle(userlist, botnetnick);
+  for (chan=chanset;chan;chan=chan->next,i++) {
+    if (i % 2 == checklimit) {
+      if (chan->limitraise) {
+        get_user_flagrec(u, &user, chan->dname);
+        if (glob_dolimit(user) || (chan_dolimit(user)))
+          raise_limit(chan);
+      }
+    }
+  }
+  if (checklimit)
+    checklimit=0;
+  else
+    checklimit=1;
+}
+#endif
 /* Check for expired timed-bans.
  */
+
 static void check_expired_bans(void)
 {
   maskrec *u, *u2;
@@ -1352,7 +1550,7 @@ static void check_expired_bans(void)
     }
   }
 }
-
+#ifdef S_IRCNET
 /* Check for expired timed-exemptions
  */
 static void check_expired_exempts(void)
@@ -1473,3 +1671,4 @@ static void check_expired_invites(void)
     }
   }
 }
+#endif

+ 1 - 2
src/mod/compress.mod/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile.in for src/mod/compress.mod/
-# $Id: Makefile.in,v 1.7 2000/09/12 15:26:52 fabian Exp $
 
 ZLIB = @ZLIB@
 srcdir = .
@@ -22,7 +21,7 @@ modules: ../../../compress.$(MOD_EXT)
 	mv compress.o ../
 
 ../../../compress.$(MOD_EXT): ../compress.o
-	$(LD) -o ../../../compress.$(MOD_EXT) ../compress.o $(ZLIB) $(XLIBS)
+	$(LD) -static -o ../../../compress.$(MOD_EXT) ../compress.o $(ZLIB) $(XLIBS)
 	$(STRIP) ../../../compress.$(MOD_EXT)
 
 depend:

+ 3 - 9
src/mod/compress.mod/compress.c

@@ -6,7 +6,6 @@
  * Written by Fabian Knittel <fknittel@gmx.de>. Based on zlib examples
  * by Jean-loup Gailly and Miguel Albrecht.
  *
- * $Id: compress.c,v 1.14 2002/06/06 18:52:22 wcc Exp $
  */
 /*
  * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
@@ -46,14 +45,15 @@
 
 #define BUFLEN	512
 
+#undef HAVE_MMAP
 
 static Function *global = NULL,
 		*share_funcs = NULL;
 
 static unsigned int compressed_files;	/* Number of files compressed.      */
 static unsigned int uncompressed_files;	/* Number of files uncompressed.    */
-static unsigned int share_compressed;	/* Compress userfiles when sharing? */
-static unsigned int compress_level;	/* Default compression used.	    */
+static unsigned int share_compressed = 1;	/* Compress userfiles when sharing? */
+static unsigned int compress_level = 9;	/* Default compression used.	    */
 
 
 static int uncompress_to_file(char *f_src, char *f_target);
@@ -390,7 +390,6 @@ static int compress_report(int idx, int details)
 
 static char *compress_close()
 {
-  rem_help_reference("compress.help");
   rem_tcl_commands(my_tcl_cmds);
   rem_tcl_ints(my_tcl_ints);
   uff_deltable(compress_uff_table);
@@ -426,10 +425,6 @@ char *compress_start(Function *global_funcs)
   compress_level	= 9;
 
   module_register(MODULE_NAME, compress_table, 1, 1);
-  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
-    module_undepend(MODULE_NAME);
-    return "This module requires Eggdrop 1.6.0 or later.";
-  }
   share_funcs = module_depend(MODULE_NAME, "share", 2, 3);
   if (!share_funcs) {
     module_undepend(MODULE_NAME);
@@ -439,6 +434,5 @@ char *compress_start(Function *global_funcs)
   uff_addtable(compress_uff_table);
   add_tcl_ints(my_tcl_ints);
   add_tcl_commands(my_tcl_cmds);
-  add_help_reference("compress.help");
   return NULL;
 }

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

@@ -2,7 +2,6 @@
  * compress.h -- part of src/mod/compress.mod
  *   header file for the zlib compression module
  *
- * $Id: compress.h,v 1.5 2002/01/02 03:46:38 guppy Exp $
  */
 /*
  * Copyright (C) 2000, 2001, 2002 Eggheads Development Team

+ 0 - 1
src/mod/compress.mod/compress_config.h.in

@@ -1,6 +1,5 @@
 dnl Eggdrop compile-time configuration file for src/mod/compress.mod
 dnl
-dnl $Id: configure.in,v 1.3 2001/06/28 19:04:28 guppy Exp $
 
 dnl This file is based on the autoconf m4 macros. Special eggdrop
 dnl macros are used to optimise the size of the resulting configure

+ 0 - 1
src/mod/compress.mod/tclcompress.c

@@ -4,7 +4,6 @@
  *
  * Written by Fabian Knittel <fknittel@gmx.de>
  *
- * $Id: tclcompress.c,v 1.5 2002/01/02 03:46:38 guppy Exp $
  */
 /*
  * Copyright (C) 2000, 2001, 2002 Eggheads Development Team

+ 1 - 0
src/mod/confdefs.h

@@ -0,0 +1 @@
+

+ 0 - 0
src/mod/config.cache


+ 3 - 0
src/mod/config.log

@@ -0,0 +1,3 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+

+ 1 - 2
src/mod/console.mod/Makefile

@@ -1,5 +1,4 @@
 # Makefile for src/mod/console.mod/
-# $Id: Makefile,v 1.14 2000/09/27 19:47:16 fabian Exp $
 
 srcdir = .
 
@@ -20,7 +19,7 @@ modules: ../../../console.$(MOD_EXT)
 	mv console.o ../
 
 ../../../console.$(MOD_EXT): ../console.o
-	$(LD) -o ../../../console.$(MOD_EXT) ../console.o $(XLIBS)
+	$(LD) -static -o ../../../console.$(MOD_EXT) ../console.o $(XLIBS)
 	$(STRIP) ../../../console.$(MOD_EXT)
 
 depend:

+ 68 - 43
src/mod/console.mod/console.c

@@ -3,24 +3,6 @@
  *   saved console settings based on console.tcl
  *   by cmwagner/billyjoe/D. Senso
  *
- * $Id: console.c,v 1.25 2002/06/06 18:52:23 wcc Exp $
- */
-/*
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #define MODULE_NAME "console"
@@ -30,7 +12,7 @@
 #include "console.h"
 
 static Function *global = NULL;
-static int console_autosave = 0;
+static int console_autosave = 1;
 static int force_channel = 0;
 static int info_party = 0;
 
@@ -41,6 +23,7 @@ struct console_info {
   int echoflags;
   int page;
   int conchan;
+  int color;
 };
 
 static struct user_entry_type USERENTRY_CONSOLE;
@@ -65,6 +48,8 @@ static int console_unpack(struct userrec *u, struct user_entry *e)
   ci->page = atoi(arg);
   arg = newsplit(&par);
   ci->conchan = atoi(arg);
+  arg = newsplit(&par);
+  ci->color = atoi(arg);
   list_type_kill(e->u.list);
   e->u.extra = ci;
   return 1;
@@ -78,10 +63,10 @@ static int console_pack(struct userrec *u, struct user_entry *e)
 
   ci = (struct console_info *) e->u.extra;
 
-  l = simple_sprintf(work, "%s %s %s %d %d %d",
+  l = simple_sprintf(work, "%s %s %s %d %d %d %d",
 		     ci->channel, masktype(ci->conflags),
 		     stripmasktype(ci->stripflags), ci->echoflags,
-		     ci->page, ci->conchan);
+		     ci->page, ci->conchan, ci->color);
 
   e->u.list = user_malloc(sizeof(struct list_type));
   e->u.list->next = NULL;
@@ -108,14 +93,13 @@ static int console_write_userfile(FILE *f, struct userrec *u,
 {
   struct console_info *i = e->u.extra;
 
-  if (fprintf(f, "--CONSOLE %s %s %s %d %d %d\n",
+  if (lfprintf(f, "--CONSOLE %s %s %s %d %d %d %d\n",
 	      i->channel, masktype(i->conflags),
 	      stripmasktype(i->stripflags), i->echoflags,
-	      i->page, i->conchan) == EOF)
+	      i->page, i->conchan, i->color) == EOF)
     return 0;
   return 1;
 }
-
 static int console_set(struct userrec *u, struct user_entry *e, void *buf)
 {
   struct console_info *ci = (struct console_info *) e->u.extra;
@@ -141,10 +125,10 @@ static int console_tcl_get(Tcl_Interp *irp, struct userrec *u,
   char work[1024];
   struct console_info *i = e->u.extra;
 
-  simple_sprintf(work, "%s %s %s %d %d %d",
+  simple_sprintf(work, "%s %s %s %d %d %d %d",
 		 i->channel, masktype(i->conflags),
 		 stripmasktype(i->stripflags), i->echoflags,
-		 i->page, i->conchan);
+		 i->page, i->conchan, i->color);
   Tcl_AppendResult(irp, work, NULL);
   return TCL_OK;
 }
@@ -176,8 +160,11 @@ static int console_tcl_set(Tcl_Interp *irp, struct userrec *u,
 	i->echoflags = (argv[6][0] == '1') ? 1 : 0;
 	if (argc > 7) {
 	  i->page = atoi(argv[7]);
-	  if (argc > 8)
+	  if (argc > 8) {
 	    i->conchan = atoi(argv[8]);
+            if (argc > 9)
+              i->color = atoi(argv[9]);
+          }  
 	}
       }
     }
@@ -193,7 +180,7 @@ static int console_expmem(struct user_entry *e)
   return sizeof(struct console_info) + strlen(i->channel) + 1;
 }
 
-static void console_display(int idx, struct user_entry *e)
+static void console_display(int idx, struct user_entry *e, struct userrec *u)
 {
   struct console_info *i = e->u.extra;
 
@@ -207,6 +194,13 @@ static void console_display(int idx, struct user_entry *e)
     dprintf(idx, "    %s %d, %s %s%d\n", CONSOLE_PAGE_SETTING, i->page,
             CONSOLE_CHANNEL2, (i->conchan < GLOBAL_CHANS) ? "" : "*",
             i->conchan % GLOBAL_CHANS);
+    dprintf(idx, "    Color:");
+    if (i->color == 1)
+     dprintf(idx, " mIRC\n");
+    else if (i->color == 2)
+     dprintf(idx, " ANSI\n");
+    else
+     dprintf(idx, " off\n");      
   }
 }
 
@@ -254,16 +248,37 @@ static int console_chon(char *handle, int idx)
       if (i->echoflags)
 	dcc[idx].status |= STAT_ECHO;
       else
-	dcc[idx].status &= ~STAT_ECHO;
+        	dcc[idx].status &= ~STAT_ECHO;
       if (i->page) {
 	dcc[idx].status |= STAT_PAGE;
 	dcc[idx].u.chat->max_line = i->page;
 	if (!dcc[idx].u.chat->line_count)
 	  dcc[idx].u.chat->current_lines = 0;
       }
-      dcc[idx].u.chat->channel = i->conchan;
-    } else if (force_channel > -1)
-      dcc[idx].u.chat->channel = force_channel;
+//putlog(LOG_MISC, "*", "UH: %s color: %d", handle, i->color);
+//      dcc[idx].status &= ~(STAT_COLOR | STAT_COLORA | STAT_COLORM);
+      if (i->color) {
+        if (i->color == 1) {
+         dcc[idx].status &= ~STAT_COLORA;
+         dcc[idx].status |= (STAT_COLOR | STAT_COLORM);
+        } else if (i->color == 2) {
+         dcc[idx].status &= ~STAT_COLORM;
+         dcc[idx].status |= (STAT_COLOR | STAT_COLORA);
+        }
+      } else
+         dcc[idx].status &= ~(STAT_COLOR | STAT_COLORA | STAT_COLORM);
+/* lame.
+      if (!(dcc[idx].user->flags & USER_PARTY))
+        dcc[idx].u.chat->channel = i->conchan;
+      else
+        dcc[idx].u.chat->channel = (-1);
+    } else if (force_channel > -1) {
+      if (!(dcc[idx].user->flags & USER_PARTY))
+        dcc[idx].u.chat->channel = force_channel;
+      else
+        dcc[idx].u.chat->channel = (-1);
+*/
+    }
     if ((dcc[idx].u.chat->channel >= 0) &&
 	(dcc[idx].u.chat->channel < GLOBAL_CHANS)) {
       botnet_send_join_idx(idx, -1);
@@ -308,6 +323,13 @@ static int console_store(struct userrec *u, int idx, char *par)
     i->page = dcc[idx].u.chat->max_line;
   else
     i->page = 0;
+  if (dcc[idx].status & STAT_COLOR) {
+    if (dcc[idx].status & STAT_COLORM)
+      i->color = 1;
+    else if (dcc[idx].status & STAT_COLORA)
+      i->color = 2;
+  } else
+   i->color = 0;
   i->conchan = dcc[idx].u.chat->channel;
   if (par) {
     dprintf(idx, "%s\n", CONSOLE_SAVED_SETTINGS2);
@@ -318,6 +340,13 @@ static int console_store(struct userrec *u, int idx, char *par)
 	    i->echoflags ? CONSOLE_YES : CONSOLE_NO);
     dprintf(idx, "  %s %d, %s %d\n", CONSOLE_PAGE_SETTING, i->page,
             CONSOLE_CHANNEL2, i->conchan);
+    dprintf(idx, "    Color:");
+    if (i->color == 1)
+     dprintf(idx, " mIRC\n");
+    else if (i->color == 2)
+     dprintf(idx, " ANSI\n");
+    else
+     dprintf(idx, " off\n");
   }
   set_user(&USERENTRY_CONSOLE, u, i);
   return 0;
@@ -345,18 +374,18 @@ static cmd_t mychon[] =
   {NULL,	NULL,	NULL,			NULL}
 };
 
-static cmd_t mydcc[] =
+static dcc_cmd_t mydcc[] =
 {
-  {"store",	"",	console_store,		NULL},
-  {NULL,	NULL,	NULL,			NULL}
+  {"store",	"",	console_store,		NULL,        NULL},
+  {NULL,	NULL,	NULL,			NULL,        NULL}
 };
 
 static char *console_close()
 {
   rem_builtins(H_chon, mychon);
-  rem_builtins(H_dcc, mydcc);
+  rem_builtins_dcc(H_dcc, mydcc);
   rem_tcl_ints(myints);
-  rem_help_reference("console.help");
+  //rem_help_reference("console.help");
   del_entry_type(&USERENTRY_CONSOLE);
   del_lang_section("console");
   module_undepend(MODULE_NAME);
@@ -379,14 +408,10 @@ char *console_start(Function * global_funcs)
   global = global_funcs;
 
   module_register(MODULE_NAME, console_table, 1, 1);
-  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
-    module_undepend(MODULE_NAME);
-    return "This module requires Eggdrop 1.6.0 or later.";
-  }
   add_builtins(H_chon, mychon);
-  add_builtins(H_dcc, mydcc);
+  add_builtins_dcc(H_dcc, mydcc);
   add_tcl_ints(myints);
-  add_help_reference("console.help");
+  //add_help_reference("console.help");
   USERENTRY_CONSOLE.get = def_get;
   add_entry_type(&USERENTRY_CONSOLE);
   add_lang_section("console");

+ 11 - 28
src/mod/console.mod/console.h

@@ -1,38 +1,21 @@
 /*
  * console.h -- part of console.mod
  *
- * $Id: console.h,v 1.3 2002/01/02 03:46:38 guppy Exp $
- */
-/*
- * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MOD_CONSOLE_CONSOLE_H
 #define _EGG_MOD_CONSOLE_CONSOLE_H
 
-#define CONSOLE_SAVED_SETTINGS	get_language(0xb040)
-#define CONSOLE_SAVED_SETTINGS2	get_language(0xb041)
-#define CONSOLE_CHANNEL		get_language(0xb042)
-#define CONSOLE_FLAGS		get_language(0xb043)
-#define CONSOLE_STRIPFLAGS	get_language(0xb044)
-#define CONSOLE_ECHO		get_language(0xb045)
-#define CONSOLE_PAGE_SETTING	get_language(0xb046)
-#define CONSOLE_CHANNEL2	get_language(0xb047)
-#define CONSOLE_YES		get_language(0xb048)
-#define CONSOLE_NO		get_language(0xb049)
+#define CONSOLE_SAVED_SETTINGS  "Saved Console Settings:"
+#define CONSOLE_SAVED_SETTINGS2	"Saved your Console Settings:"
+#define CONSOLE_CHANNEL		"Channel:"
+#define CONSOLE_FLAGS		"Console flags:"
+#define CONSOLE_STRIPFLAGS	"Strip flags:"
+#define CONSOLE_ECHO		"Echo:"
+#define CONSOLE_PAGE_SETTING	"Page setting:"
+#define CONSOLE_CHANNEL2	"Console channel:"
+#define CONSOLE_YES		"yes"
+#define CONSOLE_NO		"no"
+#define CONSOLE_COLOR		"Color:"
 
 #endif				/* _EGG_MOD_CONSOLE_CONSOLE_H */

+ 1 - 2
src/mod/ctcp.mod/Makefile

@@ -1,5 +1,4 @@
 # Makefile for src/mod/ctcp.mod/
-# $Id: Makefile,v 1.11 2000/09/12 15:26:52 fabian Exp $
 
 srcdir = .
 
@@ -20,7 +19,7 @@ modules: ../../../ctcp.$(MOD_EXT)
 	mv ctcp.o ../
 
 ../../../ctcp.$(MOD_EXT): ../ctcp.o
-	$(LD) -o ../../../ctcp.$(MOD_EXT) ../ctcp.o
+	$(LD) -static -o ../../../ctcp.$(MOD_EXT) ../ctcp.o
 	$(STRIP) ../../../ctcp.$(MOD_EXT)
 
 depend:

+ 734 - 150
src/mod/ctcp.mod/ctcp.c

@@ -2,151 +2,678 @@
  * ctcp.c -- part of ctcp.mod
  *   all the ctcp handling (except DCC, it's special ;)
  *
- * $Id: ctcp.c,v 1.18 2002/06/06 18:52:23 wcc Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #define MODULE_NAME "ctcp"
 #define MAKING_CTCP
 #include "ctcp.h"
 #include "src/mod/module.h"
+
+#ifdef LEAF
 #include "server.mod/server.h"
 #include <netinet/in.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;
+#else
+static Function *global = NULL;
+#endif
+
+#define CLOAK_COUNT             10 /* The number of scripts currently existing */
+#define CLOAK_PLAIN             1 /* This is your plain bitchx client behaviour */
+#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 /* Now with full theme and customization support */
+#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;
+}
+
+/* HAH
+char *underscoredots(char *s) // amazingly silly function...
+{
+  int size = strlen(s) + 1;
+  char *p, *p2;
+
+Context;
+  p = nmalloc(size);
+  p2 = nmalloc(size);
+  strcpy(p, s);
+  while (p && *p) {
+    if (!strncmp(p, ".", 1)) {
+      size += 2;
+Context;
+      p2 = nrealloc(p2, size);
+      strcat(p2, STR("\037.\037"));
+    } else
+      strncat(p2, p, 1);
+    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:
+  {
+    char mircver[4];
+
+    switch (random() % 5) {
+      case 0:
+        strcpy(mircver, "6.01");
+        break;
+      case 1:
+        strcpy(mircver, "6.02");
+        break;
+      case 2:
+        strcpy(mircver, "6.03");
+        break;
+      case 3:
+        strcpy(mircver, "6.1");
+        break;
+      case 4:
+        strcpy(mircver, "5.91");
+        break;
+      default:
+        strcpy(mircver, "");
+    }
+    sprintf(ctcpversion, STR("mIRC v%s Khaled Mardam-Bey"), mircver);
+    strcpy(ctcpuserinfo, botrealname);
+    strcpy(autoaway, STR("auto-away after 10 minutes"));
+    strcpy(kickprefix, "");
+    strcpy(bankickprefix, "");
+    break;
+  }
+  case CLOAK_CYPRESS:
+  {
+    char theme[30];
+
+    switch (random() % 25) { /* 0-19 = script, 20-24 = plain */
+    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:
+//      p = underscoredots(cloak_osver);
+//      sprintf(tmp, STR("%s %s"), cloak_os, p);
+//      nfree(p);
+      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:
+//      p = underscoredots(cloak_osver);
+//      sprintf(tmp, STR("%s %s"), cloak_os, p);
+//      nfree(p);
+      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:
+//      p = underscoredots(cloak_osver);
+//      sprintf(tmp, STR("%s %s"), cloak_os, p);
+//      nfree(p);
+      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 ctcp_minutely()
+{
+  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) {
+    for (i = 0; i < dcc_total; i++) {
+      if ((dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)"))) {
+        putlog(LOG_DEBUG, "*", "Closing listening port %d", dcc[i].port);
+
+        killsock(dcc[i].sock);
+        lostdcc(i);
+        break;
+      }
+    }
+  } else
+    listen_time--;
+}
+
+static int ctcp_FINGER(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+{
+  char *p;
+  int idletime;
+  struct passwd *pwd;
 
-static char ctcp_version[121];
-static char ctcp_finger[121];
-static char ctcp_userinfo[121];
-static int ctcp_mode = 0;
+  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;
+}
 
+static int ctcp_ECHO(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+{
+  char reply[60];
 
-static int ctcp_FINGER(char *nick, char *uhost, char *handle,
-		       char *object, char *keyword, char *text)
+  strncpy0(reply, text, sizeof(reply));
+  dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, reply);
+  return 1;
+}
+static int ctcp_PING(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
 {
-  if (ctcp_mode != 1 && ctcp_finger[0])
-    simple_sprintf(ctcp_reply, "%s\001FINGER %s\001", ctcp_reply, ctcp_finger);
+
+  if (strlen(text) <= 80)       /* bitchx ignores > 80 */
+    dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, text);
   return 1;
 }
 
-static int ctcp_ECHOERR(char *nick, char *uhost, char *handle,
-			char *object, char *keyword, char *text)
+static int ctcp_VERSION(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 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);
+//if mirc send second reply here..
+
   return 1;
 }
 
-static int ctcp_PING(char *nick, char *uhost, char *handle,
-		     char *object, char *keyword, char *text)
+static int ctcp_WHOAMI(char *nick, char *uhost, char *handle, char *object, char *keyword, 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);
+  dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: Access Denied\n"), nick);
   return 1;
 }
 
-static int ctcp_VERSION(char *nick, char *uhost, char *handle,
-			char *object, char *keyword, char *text)
+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)
 {
-  if (ctcp_mode != 1 && ctcp_version[0])
-    simple_sprintf(ctcp_reply, "%s\001VERSION %s\001", ctcp_reply,
-		   ctcp_version);
+  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;
 }
 
-static int ctcp_USERINFO(char *nick, char *uhost, char *handle,
-			 char *object, char *keyword, char *text)
+static int ctcp_USERINFO(char *nick, char *uhost, char *handle, char *object, 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;
 }
 
-static int ctcp_CLIENTINFO(char *nick, char *uhosr, char *handle,
-			   char *object, char *keyword, char *msg)
+static int ctcp_CLIENTINFO(char *nick, char *uhost, char *handle, char *object, char *keyword, char *msg)
 {
-  char *p = NULL;
+  char text[256];
 
-  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);
-  } else
-    simple_sprintf(ctcp_reply, "%s\001CLIENTINFO %s\001", ctcp_reply, p);
+  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 {
+    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;
 }
 
-static int ctcp_TIME(char *nick, char *uhost, char *handle, char *object,
-		     char *keyword, char *text)
+static int ctcp_TIME(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
 {
-  char tms[25];
+  char tms[81];
 
-  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);
+  strncpy0(tms, ctime(&now), sizeof(tms));
+  dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, tms);
   return 1;
 }
 
-static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object,
-		     char *keyword, char *text)
+
+static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
 {
+
   struct userrec *u = get_user_by_handle(userlist, handle);
-  int atr = u ? u->flags : 0, i;
+  int i, ix = (-1);
 
-  if ((atr & (USER_PARTY | USER_XFER)) ||
-      ((atr & USER_OP) && !require_p)) {
+  if (!ischanhub() && !issechub())
+    return 0;
 
     if (u_pass_match(u, "-")) {
       simple_sprintf(ctcp_reply, "%s\001ERROR no password set\001", ctcp_reply);
@@ -154,58 +681,81 @@ static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object,
     }
 
     for (i = 0; i < dcc_total; i++) {
-      if ((dcc[i].type->flags & DCT_LISTEN) &&
-	  (!strcmp(dcc[i].nick, "(telnet)") ||
-	   !strcmp(dcc[i].nick, "(users)"))) {
-        /* Do me a favour and don't change this back to a CTCP reply,
-         * CTCP replies are NOTICE's this has to be a PRIVMSG
-         * -poptix 5/1/1997 */
-	dprintf(DP_SERVER, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n",
-		nick,
-		iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip()),
-		dcc[i].port);
-        return 1;
-      }
+      if ((dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)")))
+        ix = i;
     }
-    simple_sprintf(ctcp_reply, "%s\001ERROR no telnet port\001", ctcp_reply);
-  }
-  return 1;
+    if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0)) < 0))
+      simple_sprintf(ctcp_reply, "%s\001ERROR no telnet port\001", ctcp_reply);
+    else {
+      if (listen_time <= 2)
+        listen_time++;
+      /* do me a favour and don't change this back to a CTCP reply,
+       * CTCP replies are NOTICE's this has to be a PRIVMSG
+       * -poptix 5/1/1997 */
+      dprintf(DP_HELP, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n", nick, iptolong(getmyip(0)), dcc[ix].port);
+    }
+
+
+
+    return 1;
 }
 
 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},
+  {"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 /* LEAF */
 
-static tcl_strings mystrings[] =
+void cloak_describe(struct cfg_entry *cfgent, int idx)
 {
-  {"ctcp-version",	ctcp_version,	120,	0},
-  {"ctcp-finger",	ctcp_finger,	120,	0},
-  {"ctcp-userinfo",	ctcp_userinfo,	120,	0},
-  {NULL,		NULL,		0,	0}
-};
+  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"));
+}
 
-static tcl_ints myints[] =
+void cloak_changed(struct cfg_entry *cfgent, char *oldval, int *valid)
 {
-  {"ctcp-mode",		&ctcp_mode},
-  {NULL,		NULL}
+  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 *ctcp_close()
 {
-  rem_tcl_strings(mystrings);
-  rem_tcl_ints(myints);
+#ifdef LEAF
   rem_builtins(H_ctcp, myctcp);
-  rem_help_reference("ctcp.help");
+#endif
   module_undepend(MODULE_NAME);
   return NULL;
 }
@@ -222,32 +772,66 @@ static Function ctcp_table[] =
 
 char *ctcp_start(Function * global_funcs)
 {
+#ifdef LEAF
+  char *p;
+#ifdef HAVE_UNAME
+  struct utsname un;
+#endif
+#endif
   global = global_funcs;
 
   module_register(MODULE_NAME, ctcp_table, 1, 0);
-  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
-    module_undepend(MODULE_NAME);
-    return "This module requires Eggdrop 1.6.0 or later.";
-  }
+#ifdef LEAF
   if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) {
     module_undepend(MODULE_NAME);
     return "This module requires server module 1.0 or later.";
   }
-  add_tcl_strings(mystrings);
-  add_tcl_ints(myints);
-  add_builtins(H_ctcp, myctcp);
-  add_help_reference("ctcp.help");
-  if (!ctcp_version[0]) {
-    strncpy(ctcp_version, ver, 120);
-    ctcp_version[120] = 0;
-  }
-  if (!ctcp_finger[0]) {
-    strncpy(ctcp_finger, ver, 120);
-    ctcp_finger[120] = 0;
+#ifdef HAVE_UNAME
+  egg_bzero(&un, sizeof(un));
+  if (!uname(&un)) {
+    strncpy0(cloak_os, un.sysname, sizeof(cloak_os));
+    strncpy0(cloak_osver, un.release, sizeof(cloak_osver));
+    strncpy0(cloak_host, un.nodename, sizeof(cloak_host));
+  } else {
+#endif /* HAVE_UNAME */
+/* shit, we have to come up with something ourselves.. */
+    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]) {
-    strncpy(ctcp_userinfo, ver, 120);
-    ctcp_userinfo[120] = 0;
+#endif /* HAVE_UNAME */
+  if ((p = strchr(cloak_host, '.')))
+    *p = 0;
+
+  switch (random() % 4) {
+  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;
 }
+

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

@@ -2,25 +2,6 @@
  * ctcp.h -- part of ctcp.mod
  *   all the defines for ctcp.c
  *
- * $Id: ctcp.h,v 1.5 2002/01/02 03:46:38 guppy Exp $
- */
-/*
- * Copyright (C) 1997 Robey Pointer
- * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
- *
- * 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 2
- * of the License, 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _EGG_MOD_CTCP_CTCP_H

+ 1 - 2
src/mod/dns.mod/Makefile.in

@@ -1,5 +1,4 @@
 # Makefile for src/mod/dns.mod/
-# $Id: Makefile.in,v 1.8 2001/07/24 15:08:22 guppy Exp $
 
 RESLIB = @RESLIB@
 RESINCLUDE = @RESINCLUDE@
@@ -23,7 +22,7 @@ modules: ../../../dns.$(MOD_EXT)
 	mv dns.o ../
 
 ../../../dns.$(MOD_EXT): ../dns.o
-	$(LD) -o ../../../dns.$(MOD_EXT) ../dns.o $(RESLIB)
+	$(LD) -static -o ../../../dns.$(MOD_EXT) ../dns.o $(RESLIB)
 	$(STRIP) ../../../dns.$(MOD_EXT)
 
 depend:

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů