--- /dev/null
+config.log
+config.cache
+config.status
+autom4te.cache
+Makefile
+lint.out
+rsa_respond.tar.gz
+.depend
--- /dev/null
+/* $Id: .indent.pro 238 2005-09-21 05:26:03Z nenolod $ */
+
+/* copy this file to the source dir then run indent file.c */
+
+--gnu-style
+
+/* This is the indent before the brace not inside the block. */
+--brace-indent0
+
+/* Indent case: by 2 and braces inside case by 0(then by 0)... */
+--case-brace-indentation0
+--case-indentation2
+
+--indent-level8
+
+/* Put while() on the brace from do... */
+--cuddle-do-while
+
+/* Disable an annoying format... */
+--no-space-after-function-call-names
+
+/* Disable an annoying format... */
+--dont-break-procedure-type
+
+/* Disable an annoying format... */
+--no-space-after-casts
+
+--line-length200
+
+/* typedefs */
+-T boolean_t
+-T node_t
+-T list_t
+-T tld_t
+-T kline_t
+-T EVH
+-T sra_t
+-T server_t
+-T user_t
+-T channel_t
+-T chanuser_t
+-T myuser_t
+-T mychan_t
+-T chanacs_t
+-T CONFIGENTRY
+-T CONFIGFILE
+-T Block
+-T MemBlock
+-T BlockHeap
--- /dev/null
+ Known Bugs worthy of a mention:
+--------------------------------------------------------------------------------
+
+1. /MODUNLOAD causes cores:
+ - If a module is modified before being unloaded, /MODUNLOAD (and
+ therefore /MODRELOAD) may cause a core.
+
+ This problem is caused by the behaviour of the OS, which treats
+ shared libraries differently to executables (modifying the ircd
+ binary whilst it is running would also cause a core, but is denied
+ by the OS).
+
+ A workaround to avoid coring is possible however. To install new
+ modules, first remove or rename the old module, then copy/move the
+ new file into place. install or make install is also safe.
+ /MODUNLOAD will then work successfully.
+
+ We will likely have a workaround implemented in the next version.
+
+BUG REPORTS: If you run this code and encounter problems, you must report
+ the bug via IRC, irc.atheme.net #athemenet-dev.
+
+ Please include a gdb backtrace and keep your binaries, modules and core file
+ in case the developers need more information.
+
+--------------------------------------------------------------------------------
+$Id: BUGS 1634 2006-06-04 13:26:04Z jilles $
--- /dev/null
+$Id: CREDITS 3133 2007-01-21 15:38:16Z jilles $
+
+Charybdis started as an evolution from ircd-ratbox-2.1.5+datadrain. Its
+development is led by a team of dedicated developers who have put a lot
+of time into the project.
+
+The charybdis core team is listed in nick-alphabetical order:
+
+gxti, Michael Tharp <gxti -at- partiallystapled.com>
+jilles, Jilles Tjoelker <jilles -at- stack.nl>
+nenolod, William Pitcock <nenolod -at- nenolod.net>
+twincest, River Tarnell <river -at- attenuate.org>
+
+The following people have made contributions to the Charybdis release,
+in nick-alphabetical order:
+
+AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
+anfl, Lee Hardy <lee -at- leeh.co.uk>
+beu, Elfyn McBratney <elfyn.mcbratney -at- gmail.com>
+Entrope, Michael Poole <mdpoole -at- trolius.org>
+ThaPrince, Jon Christopherson <jon -at- vile.com>
+w00t, Robin Burchell <surreal.w00t -at- gmail.com>
+
+Visit the Charybdis website at: http://www.ircd-charybdis.org
--- /dev/null
+jilles 2007/01/23 23:48:50 UTC (20070123-3139)
+ Log:
+ Merged revisions 3135,3137 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r3135 | jilles | 2007-01-23 22:19:14 +0100 (Tue, 23 Jan 2007) | 3 lines
+
+ - Expand TRACE description
+ - Mention expiry time in TESTLINE
+ ........
+ r3137 | jilles | 2007-01-23 22:20:30 +0100 (Tue, 23 Jan 2007) | 2 lines
+
+ Update copyright year for sgml docs to 2007.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -1 branches/release-2.1/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ +77 -3 branches/release-2.1/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2007/01/21 15:38:16 UTC (20070121-3133)
+ Log:
+ Merged revisions 1999 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+ Add river to CREDITS
+
+ ........
+ r1999 | river | 2006-09-02 05:15:18 +0200 (Sat, 02 Sep 2006) | 2 lines
+
+ vanity
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -0 branches/release-2.1/CREDITS (File Modified)
+
+
+jilles 2007/01/21 15:36:31 UTC (20070121-3131)
+ Log:
+ Merged revisions 1995,1997,2019-2020,2023-2028,2031-2032,2055-2058,2061,2063 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r1995 | river | 2006-09-02 05:06:52 +0200 (Sat, 02 Sep 2006) | 3 lines
+
+ add "use_forward" option from +malfunc, lets admins disable chanmode +QFf
+ ........
+ r1997 | river | 2006-09-02 05:09:57 +0200 (Sat, 02 Sep 2006) | 3 lines
+
+ - add use_forward to /info
+ ........
+ r2061 | jilles | 2006-09-23 13:51:11 +0200 (Sat, 23 Sep 2006) | 5 lines
+
+ Call channel_modes() with &me instead of source_p when
+ sending out a JOIN and SJOIN for a local user. This
+ saves checking whether they are on the channel they
+ have just joined.
+ ........
+ r2063 | jilles | 2006-09-23 14:17:00 +0200 (Sat, 23 Sep 2006) | 6 lines
+
+ If use_forward is disabled:
+ - hide +fFQ in 005
+ - hide +f in /mode #channel (/mode #channel f still shows it)
+ - do not send any mode changes adding +f to local clients
+ (-f ones are still sent)
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -0 branches/release-2.1/doc/example.conf (File Modified)
+ +5 -0 branches/release-2.1/doc/reference.conf (File Modified)
+ +1 -0 branches/release-2.1/include/s_conf.h (File Modified)
+ +4 -3 branches/release-2.1/modules/core/m_join.c (File Modified)
+ +1 -1 branches/release-2.1/modules/core/m_sjoin.c (File Modified)
+ +6 -0 branches/release-2.1/modules/m_info.c (File Modified)
+ +1 -1 branches/release-2.1/src/channel.c (File Modified)
+ +11 -1 branches/release-2.1/src/chmode.c (File Modified)
+ +1 -0 branches/release-2.1/src/newconf.c (File Modified)
+ +1 -0 branches/release-2.1/src/s_conf.c (File Modified)
+ +5 -0 branches/release-2.1/src/s_user.c (File Modified)
+ +4 -2 branches/release-2.1/src/supported.c (File Modified)
+
+
+jilles 2007/01/02 13:23:04 UTC (20070102-3121)
+ Log:
+ OPME/OMODE/OJOIN: Use get_oper_name() in log message.
+
+
+ Changes: Modified:
+ +3 -2 branches/release-2.1/extensions/m_ojoin.c (File Modified)
+ +2 -2 branches/release-2.1/extensions/m_omode.c (File Modified)
+ +3 -2 branches/release-2.1/extensions/m_opme.c (File Modified)
+
+
+jilles 2007/01/02 13:11:04 UTC (20070102-3117)
+ Log:
+ Add accountability (wallops, log) to OKICK.
+
+
+ Changes: Modified:
+ +14 -0 branches/release-2.1/extensions/m_okick.c (File Modified)
+
+
+jilles 2006/12/27 00:47:45 UTC (20061227-3063)
+ Log:
+ Allow kline ipv6:address, unkline some.host and unkline ipv6:address without *@.
+ Similar to branches/release-2.2 r3061.
+
+
+ Changes: Modified:
+ +2 -2 branches/release-2.1/modules/m_kline.c (File Modified)
+
+
+jilles 2006/12/27 00:36:54 UTC (20061227-3059)
+ Log:
+ - Write xline to file after instead of before notifying opers and source
+ - Also notify source of failure to add xline
+ Similar to branches/release-2.2 r3057.
+
+
+ Changes: Modified:
+ +4 -2 branches/release-2.1/modules/m_xline.c (File Modified)
+
+
+jilles 2006/12/27 00:25:50 UTC (20061227-3055)
+ Log:
+ If a dline/kline/resv cannot be added to the file, send
+ the regular notices to local opers and source anyway,
+ and also warn the source (local opers were already warned).
+ Similar to branches/release-2.2 r3053.
+
+
+ Changes: Modified:
+ +44 -42 branches/release-2.1/src/s_conf.c (File Modified)
+
+
+jilles 2006/12/27 00:02:32 UTC (20061227-3051)
+ Log:
+ Port over fixes from unkline/unxline/unresv to undline.
+ Similar to branches/release-2.2 r3049.
+
+
+ Changes: Modified:
+ +7 -2 branches/release-2.1/modules/m_dline.c (File Modified)
+
+
+jilles 2006/12/26 23:18:05 UTC (20061226-3047)
+ Log:
+ Merged revisions 2915 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2915 | jilles | 2006-12-17 01:40:54 +0100 (Sun, 17 Dec 2006) | 3 lines
+
+ In usage message, show kline.conf and xline.conf instead
+ of klines.conf and xlines.conf.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -2 branches/release-2.1/src/ircd.c (File Modified)
+
+
+jilles 2006/12/26 23:16:57 UTC (20061226-3045)
+ Log:
+ Merged revisions 2831,2833,2853 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2831 | jilles | 2006-12-14 00:19:51 +0100 (Thu, 14 Dec 2006) | 5 lines
+
+ unkline/unxline/unresv:
+ - if fclose on the output returns an error, treat this as a
+ write error too
+ - check if the rename from the temp file to the ban conf failed
+ ........
+ r2833 | jilles | 2006-12-14 00:39:25 +0100 (Thu, 14 Dec 2006) | 3 lines
+
+ When adding a permanent dline/kline/xline/resv, check
+ the return value of fclose().
+ ........
+ r2853 | jilles | 2006-12-16 00:24:32 +0100 (Sat, 16 Dec 2006) | 3 lines
+
+ Do not free xline aconf if it could not be written out.
+ It will be added to the list in memory anyway.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +7 -2 branches/release-2.1/modules/m_kline.c (File Modified)
+ +7 -2 branches/release-2.1/modules/m_resv.c (File Modified)
+ +12 -5 branches/release-2.1/modules/m_xline.c (File Modified)
+ +5 -1 branches/release-2.1/src/s_conf.c (File Modified)
+
+
+jilles 2006/12/05 13:24:19 UTC (20061205-2813)
+ Log:
+ NEWS: Clarify effects of ip_cloaking changes a little.
+
+
+ Changes: Modified:
+ +2 -0 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/12/05 13:18:39 UTC (20061205-2811)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +9 -9 branches/release-2.1/configure (File Modified)
+
+
+jilles 2006/12/05 13:18:19 UTC (20061205-2809)
+ Log:
+ Version bump on 2.1 branch to 2.1.2.
+
+
+ Changes: Modified:
+ +1 -1 branches/release-2.1/configure.ac (File Modified)
+
+
+jilles 2006/12/05 12:47:23 UTC (20061205-2807)
+ Log:
+ Mention r2801/r2805.
+
+
+ Changes: Modified:
+ +1 -0 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/12/05 12:45:43 UTC (20061205-2805)
+ Log:
+ Merged revisions 2801 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2801 | jilles | 2006-12-03 20:18:59 +0100 (Sun, 03 Dec 2006) | 3 lines
+
+ ip_cloaking: try to avoid truncation by removing more
+ components of the hostname (except the TLD).
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +14 -2 branches/release-2.1/extensions/ip_cloaking.c (File Modified)
+
+
+jilles 2006/12/02 20:40:54 UTC (20061202-2793)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +8 -1 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/12/02 20:32:39 UTC (20061202-2791)
+ Log:
+ Merged revisions 2781 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2781 | jilles | 2006-12-02 01:50:29 +0100 (Sat, 02 Dec 2006) | 5 lines
+
+ Fix stupid bug: checked a hostmask against the found
+ ban instead of all exceptions, causing all host mangled
+ clients to be exempted if there was a single ban
+ exception in many cases.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -2 branches/release-2.1/src/channel.c (File Modified)
+
+
+jilles 2006/12/02 20:00:18 UTC (20061202-2789)
+ Log:
+ Merged revisions 2773 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2773 | jilles | 2006-11-24 20:45:29 +0100 (Fri, 24 Nov 2006) | 3 lines
+
+ user@host must be *@* for a shared{} block with flags=locops
+ (server should not be *).
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +3 -1 branches/release-2.1/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/11/27 11:45:31 UTC (20061127-2775)
+ Log:
+ Tweak \s code a little.
+
+
+ Changes: Modified:
+ +1 -1 branches/release-2.1/modules/m_etrace.c (File Modified)
+ +1 -1 branches/release-2.1/modules/m_testmask.c (File Modified)
+ +1 -1 branches/release-2.1/modules/m_xline.c (File Modified)
+
+
+jilles 2006/11/12 14:21:16 UTC (20061112-2765)
+ Log:
+ Merged revisions 2761 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2761 | jilles | 2006-11-12 15:02:47 +0100 (Sun, 12 Nov 2006) | 2 lines
+
+ The testline/no_tilde fixes are in 2.1.1.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -1 branches/release-2.1/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/11/10 23:02:43 UTC (20061110-2759)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +4 -1 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/11/10 22:58:15 UTC (20061110-2757)
+ Log:
+ Merged revisions 2125,2182-2183,2190-2195,2204-2205,2208-2209,2238-2239,2286-2287,2296-2297,2440-2441,2542-2547,2681-2682,2687-2690,2697,2703,2705,2707-2711 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+ no_tilde fixes
+
+ ........
+ r2125 | jilles | 2006-09-26 00:59:18 +0200 (Tue, 26 Sep 2006) | 5 lines
+
+ If the auth{} block has no_tilde and is not kline exempt,
+ check the username without tilde against klines too.
+ This is consistent with the way klines work on spoofs
+ (klines checked on both raw and appearing-on-IRC version).
+ ........
+ r2697 | jilles | 2006-11-06 11:37:00 +0100 (Mon, 06 Nov 2006) | 4 lines
+
+ Rework the fix for klines with no_tilde.
+ Add an extra argument to find_address_conf() for the
+ username without tilde, as that may contain one character more.
+ ........
+ r2703 | jilles | 2006-11-06 16:49:44 +0100 (Mon, 06 Nov 2006) | 3 lines
+
+ Unbreak compile (because of r2697).
+ testline with ~ could be improved some more perhaps, but this should work.
+ ........
+ r2705 | jilles | 2006-11-06 17:42:21 +0100 (Mon, 06 Nov 2006) | 2 lines
+
+ testline: take no_tilde and username truncation into account
+ ........
+ r2711 | jilles | 2006-11-08 14:05:14 +0100 (Wed, 08 Nov 2006) | 2 lines
+
+ Add some information on /testline with no_tilde and username truncation.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +5 -0 branches/release-2.1/doc/sgml/oper-guide/commands.sgml (File Modified)
+ +1 -0 branches/release-2.1/extensions/m_webirc.c (File Modified)
+ +2 -1 branches/release-2.1/include/hostmask.h (File Modified)
+ +12 -1 branches/release-2.1/modules/m_testline.c (File Modified)
+ +16 -2 branches/release-2.1/src/hostmask.c (File Modified)
+ +2 -2 branches/release-2.1/src/s_conf.c (File Modified)
+
+
+jilles 2006/11/10 19:08:03 UTC (20061110-2755)
+ Log:
+ Merged revisions 2149,2151 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2149 | jilles | 2006-09-27 17:32:42 +0200 (Wed, 27 Sep 2006) | 3 lines
+
+ Move kills from services from +s to +k snomask.
+ Kills from non-service opers remain on +s.
+ ........
+ r2151 | jilles | 2006-09-27 17:41:39 +0200 (Wed, 27 Sep 2006) | 2 lines
+
+ Update description of +s and +k snomasks.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -1 branches/release-2.1/doc/sgml/oper-guide/umodes.sgml (File Modified)
+ +1 -1 branches/release-2.1/help/opers/snomask (File Modified)
+ +1 -1 branches/release-2.1/modules/core/m_kill.c (File Modified)
+
+
+jilles 2006/11/10 19:05:25 UTC (20061110-2753)
+ Log:
+ Merged revisions 2685 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2685 | jilles | 2006-11-01 18:44:01 +0100 (Wed, 01 Nov 2006) | 2 lines
+
+ Mention that exempt{} blocks do not exempt from DNSBL (for completeness).
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -1 branches/release-2.1/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/11/10 15:15:00 UTC (20061110-2743)
+ Log:
+ Merged revisions 2693 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2693 | jilles | 2006-11-06 02:35:21 +0100 (Mon, 06 Nov 2006) | 6 lines
+
+ Fix truncation (by one) of unidented usernames
+ if user registration is done because of DNSBL
+ completion (which is the usual case if a valid
+ NICK and USER are sent quickly and any DNSBLs
+ are enabled).
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -2 branches/release-2.1/src/blacklist.c (File Modified)
+
+
+jilles 2006/11/10 01:26:27 UTC (20061110-2739)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +10 -0 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/11/10 00:21:56 UTC (20061110-2737)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +9 -9 branches/release-2.1/configure (File Modified)
+
+
+jilles 2006/11/10 00:15:54 UTC (20061110-2735)
+ Log:
+ Version bump to 2.1.1.
+
+
+ Changes: Modified:
+ +1 -1 branches/release-2.1/configure.ac (File Modified)
+
+
+jilles 2006/11/10 00:04:08 UTC (20061110-2733)
+ Log:
+ Merged revisions 2186,2188,2190-2196,2204-2205,2208-2209,2224,2238-2239,2286-2287,2296-2297,2440-2441,2542-2547,2681-2682,2687-2690,2699,2701 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2186 | nenolod | 2006-09-28 04:24:41 +0200 (Thu, 28 Sep 2006) | 2 lines
+
+ - fix a server notice on SID collision where the server name is mentioned twice
+ ........
+ r2188 | nenolod | 2006-09-28 04:30:37 +0200 (Thu, 28 Sep 2006) | 2 lines
+
+ - get_server_name() is stupid
+ ........
+ r2196 | nenolod | 2006-09-28 05:03:07 +0200 (Thu, 28 Sep 2006) | 2 lines
+
+ - fix an oops
+ ........
+ r2224 | jilles | 2006-09-28 18:23:53 +0200 (Thu, 28 Sep 2006) | 4 lines
+
+ Do the Attempt to re-introduce SID server notice somewhat
+ differently, showing a real host again if !HIDE_SERVERS_IPS
+ and still showing the server name exactly once.
+ ........
+ r2699 | jilles | 2006-11-06 11:54:35 +0100 (Mon, 06 Nov 2006) | 2 lines
+
+ Fix log message for Attempt to re-introduce SID (server notice was ok).
+ ........
+ r2701 | jilles | 2006-11-06 12:05:23 +0100 (Mon, 06 Nov 2006) | 4 lines
+
+ - replace "No N line" with "no connect block" in a
+ serverlog message
+ - show attempted server name in a few serverlog messages
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +13 -6 branches/release-2.1/modules/core/m_server.c (File Modified)
+
+
+jilles 2006/11/09 23:53:43 UTC (20061109-2731)
+ Log:
+ Merged revisions 2218 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2218 | jilles | 2006-09-28 16:06:06 +0200 (Thu, 28 Sep 2006) | 2 lines
+
+ Fix garbage in /stats y output on 64-bit archs.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -1 branches/release-2.1/src/messages.tab (File Modified)
+
+
+jilles 2006/11/09 23:52:06 UTC (20061109-2729)
+ Log:
+ Merged revisions 2438 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2438 | jilles | 2006-10-06 23:51:04 +0200 (Fri, 06 Oct 2006) | 2 lines
+
+ Enable Revision keyword in addition to Id.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ + - branches/release-2.1/extensions/m_identify.c (Property Modified)
+
+
+jilles 2006/11/09 23:48:45 UTC (20061109-2727)
+ Log:
+ Merged revisions 2679 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2679 | jilles | 2006-10-29 14:24:28 +0100 (Sun, 29 Oct 2006) | 4 lines
+
+ Port over ratbox 2.2 r23253 (anfl):
+ - remove the cached storage of how many +beI there are, thereby fixing a
+ case where it can get desynced from reality
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +0 -1 branches/release-2.1/include/channel.h (File Modified)
+ +1 -8 branches/release-2.1/src/chmode.c (File Modified)
+
+
+jilles 2006/11/09 23:43:35 UTC (20061109-2725)
+ Log:
+ Merged revisions 2093,2095 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2093 | nenolod | 2006-09-25 08:01:01 +0200 (Mon, 25 Sep 2006) | 2 lines
+
+ - change DNSBL licensing to BSD.
+ ........
+ r2095 | nenolod | 2006-09-25 08:04:37 +0200 (Mon, 25 Sep 2006) | 2 lines
+
+ - change x86-assembly FNV implementation to BSD license
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +27 -16 branches/release-2.1/src/blacklist.c (File Modified)
+ +27 -16 branches/release-2.1/src/fnvhash.s (File Modified)
+
+
+jilles 2006/11/09 23:35:48 UTC (20061109-2723)
+ Log:
+ Merged revisions 2073,2075 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2073 | jilles | 2006-09-24 20:23:35 +0200 (Sun, 24 Sep 2006) | 3 lines
+
+ Put full information in the squit reason when exiting
+ a server due to a servlink (ziplinks) error.
+ ........
+ r2075 | jilles | 2006-09-24 20:33:12 +0200 (Sun, 24 Sep 2006) | 3 lines
+
+ Put full information in the squit reason when exiting
+ a server due to not enough arguments for a command.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +7 -5 branches/release-2.1/src/parse.c (File Modified)
+ +4 -1 branches/release-2.1/src/s_serv.c (File Modified)
+
+
+jilles 2006/11/09 23:30:38 UTC (20061109-2721)
+ Log:
+ Merged revisions 2071 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2071 | jilles | 2006-09-24 20:21:57 +0200 (Sun, 24 Sep 2006) | 4 lines
+
+ Don't redirect users from an existing domain to an
+ existing server in reference.conf.
+ Idea from ratbox.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +2 -2 branches/release-2.1/doc/reference.conf (File Modified)
+
+
+jilles 2006/09/27 17:19:03 UTC (20060927-2182)
+ Log:
+ Merged revisions 2053 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2053 | jilles | 2006-09-09 17:30:38 +0200 (Sat, 09 Sep 2006) | 5 lines
+
+ Make find_channel_membership() choose the shortest list
+ (channel's list or user's list) to search, avoiding excessive
+ CPU usage with services which are in lots of channels.
+ From ratbox 2.2 (anfl/jilles)
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +21 -4 branches/release-2.1/src/channel.c (File Modified)
+
+
+jilles 2006/09/14 22:01:16 UTC (20060914-2057)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +9 -9 branches/release-2.1/configure (File Modified)
+
+
+jilles 2006/09/14 22:00:30 UTC (20060914-2055)
+ Log:
+ Version change 2.1.0rc1 -> 2.1.0 (release).
+
+
+ Changes: Modified:
+ +1 -1 branches/release-2.1/configure.ac (File Modified)
+
+
+jilles 2006/09/02 23:57:18 UTC (20060902-2031)
+ Log:
+ Merged revisions 2029 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2029 | jilles | 2006-09-03 01:56:06 +0200 (Sun, 03 Sep 2006) | 2 lines
+
+ NEWS: mention m_webirc.c module
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +1 -0 branches/release-2.1/NEWS (File Modified)
+
+
+jilles 2006/09/02 23:50:03 UTC (20060902-2027)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +9 -9 branches/release-2.1/configure (File Modified)
+
+
+jilles 2006/09/02 23:49:29 UTC (20060902-2025)
+ Log:
+ Change version to 2.1.0rc1.
+
+
+ Changes: Modified:
+ +1 -1 branches/release-2.1/configure.ac (File Modified)
+
+
+jilles 2006/09/02 23:47:27 UTC (20060902-2023)
+ Log:
+ Merged revisions 2021 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2021 | jilles | 2006-09-03 01:24:17 +0200 (Sun, 03 Sep 2006) | 4 lines
+
+ Get rid of delete_resolver_queries_f(), dnsbl_hits and
+ related flaky looking things, and instead keep a list
+ of BlacklistClients in PreClient.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +4 -1 branches/release-2.1/include/blacklist.h (File Modified)
+ +1 -1 branches/release-2.1/include/client.h (File Modified)
+ +0 -1 branches/release-2.1/include/res.h (File Modified)
+ +17 -32 branches/release-2.1/src/blacklist.c (File Modified)
+ +0 -24 branches/release-2.1/src/res.c (File Modified)
+ +1 -1 branches/release-2.1/src/s_user.c (File Modified)
+
+
+jilles 2006/09/02 19:25:05 UTC (20060902-2019)
+ Log:
+ Merged revisions 2015,2017 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r2015 | jilles | 2006-09-02 20:11:23 +0200 (Sat, 02 Sep 2006) | 4 lines
+
+ Check if the name in the question section of the
+ DNS reply matches what we queried, to guard against
+ late replies to a previous query with the same id.
+ ........
+ r2017 | jilles | 2006-09-02 20:24:34 +0200 (Sat, 02 Sep 2006) | 2 lines
+
+ res.c: add a comment summarizing our changes
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +53 -18 branches/release-2.1/src/res.c (File Modified)
+
+
+jilles 2006/09/01 19:43:30 UTC (20060901-1985)
+ Log:
+ Merged revisions 1981 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r1981 | jilles | 2006-09-01 03:21:02 +0200 (Fri, 01 Sep 2006) | 2 lines
+
+ Alphabetize extensions and tweak the descriptions a little.
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +5 -5 branches/release-2.1/doc/example.conf (File Modified)
+ +13 -13 branches/release-2.1/doc/reference.conf (File Modified)
+
+
+jilles 2006/09/01 19:42:07 UTC (20060901-1983)
+ Log:
+ Merged revisions 1975 via svnmerge from
+ http://svn.atheme.org/charybdis/trunk
+
+ ........
+ r1975 | jilles | 2006-09-01 01:56:25 +0200 (Fri, 01 Sep 2006) | 4 lines
+
+ Fix bug in WEBIRC to deal with hosts being longer than HOSTLEN.
+ We should use the IP and not truncate the hostname.
+ From ratbox 2.2 (androsyn)
+ ........
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+ +7 -1 branches/release-2.1/extensions/m_webirc.c (File Modified)
+
+
+jilles 2006/09/01 00:01:23 UTC (20060901-1977)
+ Log:
+ Initialized merge tracking via "svnmerge" with revisions "1-1918" from
+ http://svn.atheme.org/charybdis/trunk
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (Property Modified)
+
+
+nenolod 2006/08/31 10:32:46 UTC (20060831-1919)
+ Log:
+ - branch 2.1 release family
+
+
+ Changes: Modified:
+ + - branches/release-2.1/ (File Added)
+
+
+jilles 2006/08/30 16:20:52 UTC (20060830-1917)
+ Log:
+ Describe new handling of host mangling in channel bans in SGML.
+
+
+ Changes: Modified:
+ +7 -1 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+nenolod 2006/08/29 20:24:08 UTC (20060829-1915)
+ Log:
+ - ok, 2.1 operline brought to you by marvin the melancholy robot
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/messages.tab (File Modified)
+
+
+nenolod 2006/08/29 19:48:43 UTC (20060829-1913)
+ Log:
+ - change RPL_YOUREOPER to "Be sure to duck the rotten tomatoes."
+ If anybody comes up with anything better, then please let us know
+ and we will change this before 2.1 is branched.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/messages.tab (File Modified)
+
+
+jilles 2006/08/29 19:34:39 UTC (20060829-1911)
+ Log:
+ Add EUID to capab.txt.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/technical/capab.txt (File Modified)
+
+
+jilles 2006/08/29 19:32:44 UTC (20060829-1909)
+ Log:
+ Update NEWS file.
+
+
+ Changes: Modified:
+ +3 -0 trunk/NEWS (File Modified)
+
+
+jilles 2006/08/29 19:18:15 UTC (20060829-1907)
+ Log:
+ Allow service{} servers to manipulate the nick delay table
+ (for "nickserv enforcement").
+ Syntax: :<server> ENCAP * NICKDELAY <duration> <nick>
+ If duration is 0, the nickdelay entry is removed, otherwise
+ it is added with the duration in seconds (maximum 24 hours).
+ It is suggested that this is used if the EUID capab is present.
+
+
+ Changes: Modified:
+ +42 -1 trunk/modules/m_services.c (File Modified)
+
+
+jilles 2006/08/29 14:51:31 UTC (20060829-1905)
+ Log:
+ HURT: strip off *@ from the start of the mask
+ reject anything else containing '@' or '!'
+
+
+ Changes: Modified:
+ +11 -0 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/08/29 14:46:33 UTC (20060829-1903)
+ Log:
+ ircd.c: need supported.h here
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/08/29 14:45:53 UTC (20060829-1901)
+ Log:
+ HURT: less ambiguity here
+ ips/hosts to be hurt must contain a '.' or ':' otherwise
+ they are interpreted as nicks
+
+
+ Changes: Modified:
+ +14 -9 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/08/29 14:40:11 UTC (20060829-1899)
+ Log:
+ - we're now ircd-charybdis.org.
+ - properly alphabetize credits
+
+
+ Changes: Modified:
+ +4 -5 trunk/CREDITS (File Modified) (Property Modified)
+
+
+nenolod 2006/08/29 14:35:53 UTC (20060829-1897)
+ Log:
+ - add additional modules to the configs
+
+
+ Changes: Modified:
+ +6 -0 trunk/doc/example.conf (File Modified)
+ +12 -0 trunk/doc/reference.conf (File Modified)
+
+
+nenolod 2006/08/29 14:26:40 UTC (20060829-1895)
+ Log:
+ - remove hurt.h, it is pointless and confusing
+
+
+ Changes: Modified:
+ +27 -62 trunk/extensions/hurt.c (File Modified)
+ + - trunk/extensions/hurt.h (File Deleted)
+
+
+nenolod 2006/08/29 14:24:37 UTC (20060829-1893)
+ Log:
+ - add code to suggest a local HURT by nickname.
+ - clean up this code (use libcharybdis runtime for memory management, not system libc)
+
+
+ Changes: Modified:
+ +40 -10 trunk/extensions/hurt.c (File Modified)
+ +1 -0 trunk/extensions/hurt.h (File Modified)
+
+
+nenolod 2006/08/29 14:13:06 UTC (20060829-1891)
+ Log:
+ - update NEWS file
+
+
+ Changes: Modified:
+ +2 -1 trunk/NEWS (File Modified)
+
+
+jilles 2006/08/29 13:49:29 UTC (20060829-1889)
+ Log:
+ MASKTRACE/TESTMASK: check orighost as well
+
+
+ Changes: Modified:
+ +4 -2 trunk/modules/m_etrace.c (File Modified)
+ +3 -1 trunk/modules/m_testmask.c (File Modified)
+
+
+jilles 2006/08/29 13:42:56 UTC (20060829-1887)
+ Log:
+ Make RPL_ISUPPORT (005) numeric modularizable.
+ Currently it will reassemble the numeric every time
+ it needs to be sent, using a few dozen callbacks;
+ if this is too slow some caching scheme should be
+ implemented.
+
+
+ Changes: Modified:
+ +0 -1 trunk/include/s_user.h (File Modified)
+ +36 -114 trunk/include/supported.h (File Modified)
+ +1 -1 trunk/modules/m_version.c (File Modified)
+ +1 -0 trunk/src/Makefile.in (File Modified)
+ +1 -0 trunk/src/ircd.c (File Modified)
+ +300 -25 trunk/src/s_user.c (File Modified)
+ + - trunk/src/supported.c (File Added)
+
+
+jilles 2006/08/28 10:09:50 UTC (20060828-1885)
+ Log:
+ EUID orighost could differ from host only in case,
+ do not mark as dynamic spoof then
+
+
+ Changes: Modified:
+ +2 -1 trunk/modules/core/m_nick.c (File Modified)
+
+
+jilles 2006/08/28 09:52:57 UTC (20060828-1883)
+ Log:
+ kline help file: clarify a bit and remove some obsolete stuff
+ partly suggested by Olin
+
+
+ Changes: Modified:
+ +8 -8 trunk/help/opers/kline (File Modified)
+
+
+jilles 2006/08/28 09:51:56 UTC (20060828-1881)
+ Log:
+ Update NEWS file.
+
+
+ Changes: Modified:
+ +20 -0 trunk/NEWS (File Modified)
+
+
+jilles 2006/08/27 21:18:43 UTC (20060827-1879)
+ Log:
+ Show real host/IP to nonopers whoising themselves.
+ The IP is not shown for auth{} spoofs, otherwise it is,
+ as it looked rather weird to me to show an auth{} spoofed
+ IP like this. (/userhost on self still shows the IP.)
+
+
+ Changes: Modified:
+ +13 -2 trunk/modules/m_whois.c (File Modified)
+
+
+jilles 2006/08/27 18:30:04 UTC (20060827-1877)
+ Log:
+ Document nick_delay stuff and move it around a bit.
+
+
+ Changes: Modified:
+ +1 -2 trunk/doc/example.conf (File Modified)
+ +8 -2 trunk/doc/reference.conf (File Modified)
+
+
+nenolod 2006/08/27 18:22:55 UTC (20060827-1875)
+ Log:
+ - disable nickdelay by default. Needs to be documented in reference.conf.
+
+
+ Changes: Modified:
+ +2 -0 trunk/doc/example.conf (File Modified)
+ +2 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/08/27 18:05:50 UTC (20060827-1873)
+ Log:
+ Fix RPL_WHOISLOGGEDIN (330) not being sent in TS6 form.
+
+
+ Changes: Modified:
+ +2 -1 trunk/modules/m_services.c (File Modified)
+
+
+jilles 2006/08/27 15:36:00 UTC (20060827-1871)
+ Log:
+ ip_cloaking: somewhat hackish but we need to send the
+ 396 (RPL_HOSTHIDDEN) on connect if +h is in default
+ umodes
+
+
+ Changes: Modified:
+ +3 -0 trunk/extensions/ip_cloaking.c (File Modified)
+
+
+jilles 2006/08/27 14:24:25 UTC (20060827-1869)
+ Log:
+ If EUID is used, show realhost in far connect notice
+ (but not in far disconnect notice).
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/sno_farconnect.c (File Modified)
+
+
+jilles 2006/08/27 14:21:45 UTC (20060827-1867)
+ Log:
+ ip_cloaking:
+ - use non-ENCAP CHGHOST if possible
+ - really introduce new users with their mangled and real
+ host if +h is in default umodes
+
+
+ Changes: Modified:
+ +15 -3 trunk/extensions/ip_cloaking.c (File Modified)
+
+
+jilles 2006/08/27 14:02:57 UTC (20060827-1865)
+ Log:
+ Add non-ENCAP CHGHOST.
+
+
+ Changes: Modified:
+ +49 -11 trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2006/08/27 13:40:37 UTC (20060827-1863)
+ Log:
+ Initial addition of EUID (puts realhost/account in same
+ command as user introduction).
+ See doc/technical/euid.txt for more information.
+ At this time, EUID requires TS6, and new CHGHOST is not done yet.
+
+
+ Changes: Modified:
+ + - trunk/doc/technical/euid.txt (File Added)
+ +2 -1 trunk/include/s_serv.h (File Modified)
+ +1 -1 trunk/include/s_user.h (File Modified)
+ +127 -4 trunk/modules/core/m_nick.c (File Modified)
+ +1 -34 trunk/modules/m_chghost.c (File Modified)
+ +0 -28 trunk/modules/m_services.c (File Modified)
+ +30 -1 trunk/src/s_serv.c (File Modified)
+ +30 -3 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/08/26 23:21:42 UTC (20060826-1861)
+ Log:
+ Store the mangled host in localClient and use it for
+ ban matching (also match real host for mangled users,
+ also match mangled host for uncloaked users).
+ Improve interaction of +h with auth{} and services
+ spoofs.
+ Note that all of this only applies to clients who
+ connect after the mangling module is loaded
+ (other clients cannot even set +h).
+ The sorcerynet cloaking module has not been updated
+ for these changes.
+
+
+ Changes: Modified:
+ +31 -13 trunk/extensions/ip_cloaking.c (File Modified)
+ +3 -0 trunk/include/client.h (File Modified)
+ +64 -5 trunk/src/channel.c (File Modified)
+ +1 -0 trunk/src/client.c (File Modified)
+ +2 -2 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/08/25 20:20:42 UTC (20060825-1859)
+ Log:
+ Document /stats U letters in sgml.
+
+
+ Changes: Modified:
+ +27 -21 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/08/25 14:33:51 UTC (20060825-1857)
+ Log:
+ Better description of hub_mask and leaf_mask.
+
+
+ Changes: Modified:
+ +13 -2 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/08/25 14:24:14 UTC (20060825-1855)
+ Log:
+ Add operspy_dont_care_user_info to sgml docs.
+
+
+ Changes: Modified:
+ +6 -0 trunk/doc/sgml/oper-guide/oprivs.sgml (File Modified)
+
+
+jilles 2006/08/24 18:30:52 UTC (20060824-1853)
+ Log:
+ Add general::operspy_dont_care_user_info.
+ This makes /who mask equivalent to /who !mask for opers
+ with the operspy flag, and removes the operspy log/notice
+ on /who mask, /masktrace and /scan.
+ The necessary privilege (operspy flag) is unchanged.
+ Behaviour for the other operspy commands (channel
+ related ones) is also unchanged.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +6 -0 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +10 -8 trunk/modules/m_etrace.c (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +8 -5 trunk/modules/m_scan.c (File Modified)
+ +1 -1 trunk/modules/m_version.c (File Modified)
+ +6 -1 trunk/modules/m_who.c (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/08/24 17:16:53 UTC (20060824-1851)
+ Log:
+ Show 'S' in /version if sno_farconnect.so has ever been loaded.
+ This letter will also be used for showing operspy with
+ limited accountability (show non channel related info
+ without '!' or notice).
+
+
+ Changes: Modified:
+ +2 -0 trunk/doc/server-version-info (File Modified)
+ +3 -0 trunk/extensions/sno_farconnect.c (File Modified)
+ +2 -0 trunk/include/ircd.h (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +2 -0 trunk/modules/m_version.c (File Modified)
+ +1 -0 trunk/src/ircd_state.c (File Modified)
+
+
+jilles 2006/08/23 12:40:21 UTC (20060823-1849)
+ Log:
+ Add m_webirc module, allows showing real host of CGI:IRC users.
+ Differences to the version available on my web page for a while:
+ instructions on how to set it up.
+
+
+ Changes: Modified:
+ +137 -0 trunk/extensions/Makefile.in (File Modified)
+ + - trunk/extensions/m_webirc.c (File Added)
+
+
+nenolod 2006/08/23 10:21:57 UTC (20060823-1847)
+ Log:
+ - make I/O ports code compile on solaris 10 (tested on SunOS 5.10 sun4u sparc64)
+
+
+ Changes: Modified:
+ +5 -50 trunk/libcharybdis/ports.c (File Modified)
+
+
+nenolod 2006/08/22 23:57:10 UTC (20060822-1845)
+ Log:
+ - move beu from core to contributors
+ - adjust captialisation on gxti's nickname (he uses gxti now instead of GXTi).
+
+
+ Changes: Modified:
+ +2 -2 trunk/CREDITS (File Modified)
+
+
+jilles 2006/08/22 17:57:25 UTC (20060822-1843)
+ Log:
+ Mention that class blocks must be defined before the
+ auth or connect blocks referencing them.
+
+
+ Changes: Modified:
+ +4 -2 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/08/22 17:30:03 UTC (20060822-1841)
+ Log:
+ extb_canjoin:
+ - change from "can join" to "is banned", this reverses sense
+ and removes "weird" checks like for +i, +l, +j
+ - don't allow $j to same channel
+ - +s/+p restriction removed, anyone can /mode b anyway
+ - +k check removed
+
+
+ Changes: Modified:
+ +12 -8 trunk/extensions/extb_canjoin.c (File Modified)
+
+
+jilles 2006/08/22 15:25:37 UTC (20060822-1839)
+ Log:
+ Add a few important lines from reference.conf to example.conf.
+
+
+ Changes: Modified:
+ +8 -1 trunk/doc/example.conf (File Modified)
+
+
+nenolod 2006/08/22 14:05:58 UTC (20060822-1837)
+ Log:
+ - we don't support rtsigio anymore
+ - we definately don't support VMS nor Cygwin either.
+
+
+ Changes: Modified:
+ +2 -2 trunk/INSTALL (File Modified)
+ +0 -2 trunk/README.FIRST (File Modified)
+
+
+nenolod 2006/08/22 12:59:38 UTC (20060822-1835)
+ Log:
+ - if the channel is +k, pass the source channel's key to can_join() for the target channel.
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/extb_canjoin.c (File Modified)
+
+
+jilles 2006/08/22 12:55:22 UTC (20060822-1833)
+ Log:
+ extb_canjoin:
+ - return EXTBAN_NOMATCH for a valid ban that does not match
+ - consider a $j ban invalid if we were already processing a
+ can_join for a $j ban
+
+
+ Changes: Modified:
+ +7 -2 trunk/extensions/extb_canjoin.c (File Modified)
+
+
+jilles 2006/08/22 12:44:04 UTC (20060822-1831)
+ Log:
+ extb_extgecos: realhost -> orighost
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/extb_extgecos.c (File Modified)
+
+
+nenolod 2006/08/22 07:05:17 UTC (20060822-1829)
+ Log:
+ - add $j extban type, allows entry or non-entry to a channel based on whether or not you can join another channel.
+
+
+ Changes: Modified:
+ +59 -0 trunk/extensions/Makefile.in (File Modified)
+ + - trunk/extensions/extb_canjoin.c (File Added)
+
+
+nenolod 2006/08/22 05:06:34 UTC (20060822-1827)
+ Log:
+ - oh right, charybdis calls that 'orighost'.
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_who.c (File Modified)
+
+
+nenolod 2006/08/22 05:05:20 UTC (20060822-1825)
+ Log:
+ - allow *opers* to do a /who based on realhost. Perhaps this should require operspy? TBD.
+
+
+ Changes: Modified:
+ +2 -0 trunk/modules/m_who.c (File Modified)
+
+
+nenolod 2006/08/22 00:16:38 UTC (20060822-1823)
+ Log:
+ - also check $x against realhost
+
+
+ Changes: Modified:
+ +12 -1 trunk/extensions/extb_extgecos.c (File Modified)
+
+
+jilles 2006/08/20 17:16:37 UTC (20060820-1811)
+ Log:
+ Sorcerynet people want a debugging notice moved from +s to +d.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/08/20 16:59:27 UTC (20060820-1805)
+ Log:
+ Use source_p instead of client_p for free_pre_client().
+ client_p could be NULL or another client.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/client.c (File Modified)
+
+
+nenolod 2006/08/20 16:58:04 UTC (20060820-1803)
+ Log:
+ - revert this, I know how to fix it now
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2006/08/20 16:55:31 UTC (20060820-1801)
+ Log:
+ - pass an actual valid client_p to exit_client() when dealing with Overriden condition.
+ This fix is probably suboptimal, but it does indeed fix the problem.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2006/08/20 10:27:33 UTC (20060820-1799)
+ Log:
+ - add extb_extgecos extban option ($x:nick!user@host#gecos), from sorcery modules
+
+
+ Changes: Modified:
+ +49 -0 trunk/extensions/Makefile.in (File Modified)
+ + - trunk/extensions/extb_extgecos.c (File Added)
+
+
+jilles 2006/08/10 00:00:44 UTC (20060810-1797)
+ Log:
+ Remove undocumented and unused general::fallback_to_ip6_int config option.
+
+
+ Changes: Modified:
+ +0 -3 trunk/include/s_conf.h (File Modified)
+ +0 -3 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/08/04 20:12:47 UTC (20060804-1795)
+ Log:
+ SGML docs:
+ - document new TESTMASK
+ - mention that TESTMASK matching is the same as MASKTRACE matching
+ - mention that gecos in TESTMASK/MASKTRACE is optional (has always
+ been that way)
+
+
+ Changes: Modified:
+ +23 -6 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/08/04 19:56:03 UTC (20060804-1793)
+ Log:
+ New testmask from ratbox 2.2.
+ Allows matches on nick, ip and gecos in addition to user
+ and host, and is fully analogous to masktrace.
+ The numeric has changed from 724 to 727 and fields in it
+ have changed.
+
+
+ Changes: Modified:
+ +4 -3 trunk/help/opers/testmask (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +82 -9 trunk/modules/m_testmask.c (File Modified)
+ +2 -2 trunk/src/messages.tab (File Modified)
+
+
+jilles 2006/08/04 19:33:27 UTC (20060804-1791)
+ Log:
+ contrib -> extensions
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/08/03 22:12:00 UTC (20060803-1789)
+ Log:
+ CHGHOST: Check validity of new hostname.
+ If the command came from a local client (disabled by
+ default), send an error message and drop the command.
+ If the command came from a remote client or server,
+ send a notice to opers and the target user (if local).
+
+
+ Changes: Modified:
+ +42 -1 trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2006/07/31 15:54:57 UTC (20060731-1787)
+ Log:
+ Update NEWS file.
+
+
+ Changes: Modified:
+ +23 -1 trunk/NEWS (File Modified)
+
+
+jilles 2006/07/31 15:24:06 UTC (20060731-1785)
+ Log:
+ When an outgoing server connection succeeds, set
+ localClient->ip by simply copying the whole sockaddr
+ struct instead of copying certain parts only.
+
+
+ Changes: Modified:
+ +1 -19 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/07/31 15:17:19 UTC (20060731-1783)
+ Log:
+ Give a special error message and ignore the connect block
+ if trying to add a connect block for the server's own name.
+
+
+ Changes: Modified:
+ +7 -0 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/07/30 18:07:38 UTC (20060730-1781)
+ Log:
+ Provide stubs for BlockHeapUsage(), struct MemBlock and MemBlock
+ when --disable-balloc is used, so that it compiles.
+ Obviously the BlockHeapUsage() stub returns just zeroes so
+ /stats z will be less informative.
+
+
+ Changes: Modified:
+ +5 -0 trunk/libcharybdis/balloc.h (File Modified)
+
+
+jilles 2006/07/30 16:36:39 UTC (20060730-1779)
+ Log:
+ Free and zero dns_query in DNS callback for outgoing connect.
+ This avoids double free of reslist.
+
+
+ Changes: Modified:
+ +4 -0 trunk/libcharybdis/commio.c (File Modified)
+
+
+jilles 2006/07/30 16:10:50 UTC (20060730-1777)
+ Log:
+ From ratbox, log failed outgoing connections to serverlog.
+ Added: IP address.
+
+
+ Changes: Modified:
+ +13 -1 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/07/30 15:44:50 UTC (20060730-1775)
+ Log:
+ Change serverlog message when connecting to be more clear and show the port number.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/07/30 15:03:52 UTC (20060730-1773)
+ Log:
+ Remove gethost_byname(), this is meaningless
+ since the removal of AAAA -> A fallback (r1763).
+
+
+ Changes: Modified:
+ +0 -1 trunk/include/res.h (File Modified)
+ +0 -12 trunk/src/res.c (File Modified)
+
+
+jilles 2006/07/30 14:47:53 UTC (20060730-1771)
+ Log:
+ Remove ip6.int support and use only ip6.arpa.
+ The global ip6.int zone has disappeared on June 1
+ and a lot of other software has been removing ip6.int
+ support also.
+ This removes the second and last case where IPv6
+ support in charybdis causes extra lookups and slows
+ DNS down.
+
+
+ Changes: Modified:
+ +5 -27 trunk/src/res.c (File Modified)
+
+
+jilles 2006/07/30 14:30:48 UTC (20060730-1769)
+ Log:
+ Mention new default (r1767) for connect::aftype in sgml docs.
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/07/30 13:59:15 UTC (20060730-1767)
+ Log:
+ Use IPv6 if connect::host looks like an IPv6 address
+ (contains a colon). No need to aftype=ipv6 anymore.
+
+
+ Changes: Modified:
+ +2 -0 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/07/30 13:42:26 UTC (20060730-1765)
+ Log:
+ More information about connect::host.
+
+
+ Changes: Modified:
+ +7 -2 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/07/30 12:59:39 UTC (20060730-1763)
+ Log:
+ Remove fallback to A if AAAA cannot be found.
+ In case of a forward check of a reverse lookup, we
+ already know if it's ipv4 or ipv6, so it is not
+ useful and in case of a forward lookup of a hostname
+ in connect::host, connect::aftype already specifies
+ if it's ipv4 or ipv6.
+
+
+ Changes: Modified:
+ +4 -27 trunk/src/res.c (File Modified)
+
+
+jilles 2006/07/27 19:27:49 UTC (20060727-1761)
+ Log:
+ msg_channel():
+ - check if +c made the message text empty and refuse
+ to send it if so
+ - don't copy message text if it is not necessary
+ (channel is -c)
+
+
+ Changes: Modified:
+ +14 -4 trunk/modules/core/m_message.c (File Modified)
+
+
+jilles 2006/07/25 23:46:50 UTC (20060725-1759)
+ Log:
+ remove_conf_item(): do not free cf_name, this is generally a string constant
+
+
+ Changes: Modified:
+ +0 -1 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/07/25 23:34:45 UTC (20060725-1757)
+ Log:
+ Remove the old unused FDL_ constants.
+
+
+ Changes: Modified:
+ +0 -9 trunk/libcharybdis/commio.h (File Modified)
+
+
+jilles 2006/07/25 23:17:59 UTC (20060725-1755)
+ Log:
+ Remove an unused struct irc_sockaddr_storage from fde_t
+ (allocated for every possible file descriptor).
+
+
+ Changes: Modified:
+ +0 -2 trunk/libcharybdis/commio.h (File Modified)
+
+
+jilles 2006/07/25 22:48:38 UTC (20060725-1753)
+ Log:
+ If the DNS lookup for an outgoing connection is still
+ pending when it is closed, clean it up.
+
+
+ Changes: Modified:
+ +1 -0 trunk/libcharybdis/commio.c (File Modified)
+
+
+jilles 2006/07/25 22:40:33 UTC (20060725-1751)
+ Log:
+ If proc_answer() fails (for example if a lookup for an
+ A record returns a CNAME), fail the query immediately.
+ Previously the packet was just ignored, leaving the
+ query to time out.
+
+
+ Changes: Modified:
+ +4 -8 trunk/src/res.c (File Modified)
+
+
+jilles 2006/07/25 22:16:20 UTC (20060725-1749)
+ Log:
+ Correct sockhost field in an outgoing server connection.
+ First copy the host field from the server_conf, then
+ take the IP from to where the connection was attempted
+ when the connection callback is called.
+ (Before r1747 this used the IP from the server_conf.)
+
+
+ Changes: Modified:
+ +8 -2 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/07/25 21:22:45 UTC (20060725-1747)
+ Log:
+ Remove ipnum (keep aftype) and dns_query from server_conf.
+ We don't keep track of binary form address in connect{}
+ blocks anymore, DNS lookups of names in host= gone.
+ As before the DNS lookup is done on connect.
+ This should unbreak hostnames in host= somewhat.
+
+
+ Changes: Modified:
+ +1 -2 trunk/include/s_newconf.h (File Modified)
+ +2 -2 trunk/src/newconf.c (File Modified)
+ +1 -42 trunk/src/s_newconf.c (File Modified)
+ +12 -31 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/07/25 16:25:56 UTC (20060725-1745)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +1 -1 trunk/configure (File Modified)
+
+
+jilles 2006/07/25 16:25:12 UTC (20060725-1743)
+ Log:
+ Fix --disable-balloc help text (said --disable-small-net).
+
+
+ Changes: Modified:
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2006/07/23 18:58:52 UTC (20060723-1741)
+ Log:
+ Add general::servicestring, shown on RPL_WHOISOPERATOR for
+ services (+S). Unlike operstring and adminstring, this
+ is not changeable with /quote set but is updated on rehash.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +10 -2 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +3 -2 trunk/modules/m_whois.c (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/07/22 16:27:02 UTC (20060722-1739)
+ Log:
+ Fix handling of comma in whois: ignore the comma and
+ everything after it but do output the entire parameter
+ in RPL_ENDOFWHOIS.
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_whois.c (File Modified)
+
+
+beu 2006/07/21 22:36:46 UTC (20060721-1737)
+ Log:
+ New /stats letter 's' to list HURTs:
+ - opers get the full listing.
+ - users get any HURTs that match their sockhost/orighost if
+ "stats_k_oper_only" is set to 1.
+
+
+ Changes: Modified:
+ +50 -0 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/07/19 02:35:40 UTC (20060719-1735)
+ Log:
+ - make the newconf system available to modules.
+
+
+ Changes: Modified:
+ +4 -1 trunk/include/newconf.h (File Modified)
+ +4 -8 trunk/src/newconf.c (File Modified)
+
+
+beu 2006/07/18 22:39:16 UTC (20060718-1733)
+ Log:
+ Undo silly commit (tor.dnsbl.sectoor.de requirs record checking).
+
+ Changes: Modified:
+ +0 -3 trunk/doc/example.conf (File Modified)
+ +0 -3 trunk/doc/reference.conf (File Modified)
+
+
+beu 2006/07/18 22:34:36 UTC (20060718-1731)
+ Log:
+ Add more effective Tor DNSBL (more up-to-date, more NATed nodes, etc).
+
+
+ Changes: Modified:
+ +3 -0 trunk/doc/example.conf (File Modified)
+ +3 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/07/17 16:48:13 UTC (20060717-1729)
+ Log:
+ Fix too early truncation of JOIN channel list.
+
+
+ Changes: Modified:
+ +2 -3 trunk/modules/core/m_join.c (File Modified)
+
+
+jilles 2006/07/07 21:59:52 UTC (20060707-1727)
+ Log:
+ - From ratbox 2.2 (anfl), send server notices about read
+ errors from handshakes and servers to +s instead of +d.
+ - Send various server notices about failed server
+ connections which did not reach registered state network
+ wide if the connection was initiated by a remote oper.
+ This avoids annoying the whole net if there is a
+ broken autoconnect, but allows all opers to see why a
+ remote connect failed. Failed connections which did reach
+ server state already generate server notices everywhere.
+
+ Note: this is an exception to our general policy to not send
+ server notices about unregistered connections remotely.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/client.h (File Modified)
+ +20 -6 trunk/src/client.c (File Modified)
+ +6 -6 trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2006/07/07 14:41:39 UTC (20060707-1725)
+ Log:
+ - fix typoes
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/example.conf (File Modified)
+ +1 -1 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/07/06 15:23:58 UTC (20060706-1723)
+ Log:
+ Don't allow #channel +b $c:&channel (inconsistent target).
+
+
+ Changes: Modified:
+ +3 -0 trunk/extensions/extb_channel.c (File Modified)
+
+
+jilles 2006/07/05 14:37:18 UTC (20060705-1721)
+ Log:
+ Remove dns_query pointer from LocalClient, we store this in AuthQuery.
+
+
+ Changes: Modified:
+ +0 -2 trunk/include/client.h (File Modified)
+
+
+jilles 2006/07/05 13:28:40 UTC (20060705-1719)
+ Log:
+ Invalidate can_send ban cache when a TS6 SJOIN clears the ban list.
+
+
+ Changes: Modified:
+ +2 -0 trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2006/07/04 14:41:11 UTC (20060704-1717)
+ Log:
+ Store IP addresses in whowas. These are shown to opers.
+ Obtained from Eurus patches.
+ orighost tracking removed (not worth the memory IMHO),
+ numeric changed to RPL_WHOISACTUALLY, fixed to deal
+ with unknown IPs and to not violate auth{} spoof policy.
+
+
+ Changes: Modified:
+ +2 -0 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +1 -0 trunk/include/whowas.h (File Modified)
+ +10 -1 trunk/modules/m_whowas.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+ +4 -0 trunk/src/whowas.c (File Modified)
+
+
+jilles 2006/07/03 15:18:47 UTC (20060703-1715)
+ Log:
+ Describe hostmask parameter of masktrace better in sgml docs.
+
+
+ Changes: Modified:
+ +5 -0 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/07/03 14:03:05 UTC (20060703-1713)
+ Log:
+ masktrace help file: mention CIDR IP masks
+ From ratbox 2.2
+
+
+ Changes: Modified:
+ +2 -0 trunk/help/opers/masktrace (File Modified)
+
+
+jilles 2006/07/03 13:56:38 UTC (20060703-1711)
+ Log:
+ MASKTRACE: allow normal match() on IP address also
+ From ratbox 2.2
+
+
+ Changes: Modified:
+ +2 -3 trunk/modules/m_etrace.c (File Modified)
+
+
+jilles 2006/06/29 22:36:45 UTC (20060629-1709)
+ Log:
+ Allow +S clients (services) to send to channels and @/+ channels always.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_message.c (File Modified)
+ +1 -1 trunk/src/channel.c (File Modified)
+
+
+jilles 2006/06/29 22:25:46 UTC (20060629-1707)
+ Log:
+ Allow servers to send to @#chan and +#chan.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_message.c (File Modified)
+
+
+jilles 2006/06/29 21:51:59 UTC (20060629-1705)
+ Log:
+ Don't count opers on service{} servers in /lusers.
+
+
+ Changes: Modified:
+ +2 -2 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/06/29 21:19:38 UTC (20060629-1703)
+ Log:
+ Show opers the real host behind a dynamic spoof in WHOIS.
+ If the user is auth{} spoofed, this shows the auth{} spoof
+ otherwise it shows the DNS hostname and IP address.
+ The numeric used is 378 (RPL_WHOISHOST) taken from Unreal.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +12 -2 trunk/modules/m_whois.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+
+
+jilles 2006/06/27 16:25:52 UTC (20060627-1701)
+ Log:
+ Remove #define HIDE_SPOOF_IPS from config.h, should
+ have been done earlier.
+
+
+ Changes: Modified:
+ +0 -7 trunk/include/config.h (File Modified)
+
+
+jilles 2006/06/27 15:29:10 UTC (20060627-1699)
+ Log:
+ Bring back ERR_CANTKILLSERVER.
+
+
+ Changes: Modified:
+ +5 -7 trunk/modules/core/m_kill.c (File Modified)
+
+
+jilles 2006/06/27 15:18:57 UTC (20060627-1697)
+ Log:
+ ip_cloaking module:
+ - also send RPL_HOSTHIDDEN on -h
+ - don't allow +h for auth{} spoofed clients
+
+
+ Changes: Modified:
+ +8 -2 trunk/extensions/ip_cloaking.c (File Modified)
+
+
+jilles 2006/06/27 15:11:23 UTC (20060627-1695)
+ Log:
+ /etc/resolv.conf parsing:
+ - don't crash (sometimes) if there is a line without an argument
+ (e.g. 'search' by itself)
+ - fix handling of lines with leading whitespace
+
+
+ Changes: Modified:
+ +9 -8 trunk/src/reslib.c (File Modified)
+
+
+jilles 2006/06/20 14:26:16 UTC (20060620-1683)
+ Log:
+ Put back code that terminates DNS queries, which was
+ removed during the resolver changes.
+
+
+ Changes: Modified:
+ +4 -0 trunk/src/s_auth.c (File Modified)
+
+
+nenolod 2006/06/20 09:20:58 UTC (20060620-1681)
+ Log:
+ - oh hey, that was in the wrong place
+
+
+ Changes: Modified:
+ +13 -13 trunk/src/s_auth.c (File Modified)
+
+
+nenolod 2006/06/20 08:33:20 UTC (20060620-1679)
+ Log:
+ - handle a situation where a user can go away before DNS completes
+
+
+ Changes: Modified:
+ +13 -0 trunk/src/s_auth.c (File Modified)
+
+
+jilles 2006/06/16 14:43:33 UTC (20060616-1677)
+ Log:
+ More dnsbl stuff
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/blacklist.h (File Modified)
+ +1 -0 trunk/include/res.h (File Modified)
+ +33 -2 trunk/src/blacklist.c (File Modified)
+ +2 -0 trunk/src/client.c (File Modified)
+ +24 -0 trunk/src/res.c (File Modified)
+
+
+jilles 2006/06/15 22:32:23 UTC (20060615-1675)
+ Log:
+ Don't touch the returned sockaddr (mangle_mapped_sockaddr())
+ if comm_accept() failed.
+
+ Found with valgrind.
+
+
+ Changes: Modified:
+ +4 -4 trunk/src/listener.c (File Modified)
+
+
+nenolod 2006/06/15 18:13:04 UTC (20060615-1673)
+ Log:
+ - handle unavailable Client/preClient structs
+
+
+ Changes: Modified:
+ +9 -0 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/06/14 17:52:20 UTC (20060614-1671)
+ Log:
+ Add +lf to SGML docs.
+
+
+ Changes: Modified:
+ +3 -2 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+jilles 2006/06/14 17:48:41 UTC (20060614-1669)
+ Log:
+ Also do forwarding if the channel limit (+l) is exceeded.
+
+
+ Changes: Modified:
+ +1 -1 trunk/help/opers/cmode (File Modified)
+ +2 -2 trunk/modules/core/m_join.c (File Modified)
+
+
+beu 2006/06/07 11:53:21 UTC (20060607-1663)
+ Log:
+ Post-release lovin':
+ - Update version to 2.1.0.
+ - Regenerate configure.
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+beu 2006/06/07 11:42:54 UTC (20060607-1659)
+ Log:
+ Comment out example blacklist{} block.
+
+
+ Changes: Modified:
+ +7 -7 trunk/doc/example.conf (File Modified)
+ +7 -7 trunk/doc/reference.conf (File Modified)
+
+
+beu 2006/06/07 10:59:48 UTC (20060607-1653)
+ Log:
+ Add note regarding use of AHBL BLs.
+
+
+ Changes: Modified:
+ +4 -0 trunk/doc/example.conf (File Modified)
+ +4 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/06/05 15:43:45 UTC (20060605-1646)
+ Log:
+ Fix typos.
+
+
+ Changes: Modified:
+ +2 -2 trunk/CREDITS (File Modified)
+
+
+jilles 2006/06/05 15:28:22 UTC (20060605-1644)
+ Log:
+ Add beu to CREDITS.
+
+
+ Changes: Modified:
+ +1 -0 trunk/CREDITS (File Modified)
+
+
+jilles 2006/06/05 00:02:19 UTC (20060605-1640)
+ Log:
+ Put more recent ratbox CREDITS here.
+
+
+ Changes: Modified:
+ +3 -2 trunk/doc/Ratbox-team (File Modified)
+
+
+jilles 2006/06/04 19:19:02 UTC (20060604-1636)
+ Log:
+ Clarify a bit.
+
+
+ Changes: Modified:
+ +5 -4 trunk/NEWS (File Modified)
+
+
+jilles 2006/06/04 13:26:04 UTC (20060604-1634)
+ Log:
+ Mention that install or make install also avoids modunload crashes.
+
+
+ Changes: Modified:
+ +2 -1 trunk/BUGS (File Modified)
+
+
+nenolod 2006/06/04 07:01:42 UTC (20060604-1632)
+ Log:
+ - update NEWS a bit
+
+
+ Changes: Modified:
+ +3 -8 trunk/NEWS (File Modified)
+
+
+nenolod 2006/06/04 03:06:33 UTC (20060604-1630)
+ Log:
+ - further updates
+
+
+ Changes: Modified:
+ +3 -2 trunk/BUGS (File Modified)
+
+
+nenolod 2006/06/04 03:05:20 UTC (20060604-1628)
+ Log:
+ - add orighost check to hurt.c
+ - update BUGS info
+
+
+ Changes: Modified:
+ +1 -6 trunk/BUGS (File Modified)
+ +1 -1 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/04 03:03:46 UTC (20060604-1626)
+ Log:
+ Make kline_exempt exempt from HURT also.
+
+
+ Changes: Modified:
+ +2 -1 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/04 03:02:27 UTC (20060604-1624)
+ Log:
+ Fix mask HEAL propagation.
+
+
+ Changes: Modified:
+ +6 -3 trunk/extensions/hurt.c (File Modified)
+
+
+beu 2006/06/04 03:01:05 UTC (20060604-1622)
+ Log:
+ - Remove old cruft.
+ - Update.
+
+
+ Changes: Modified:
+ +18 -31 trunk/extensions/README (File Modified)
+
+
+jilles 2006/06/04 02:46:31 UTC (20060604-1620)
+ Log:
+ More target change hax.
+ Ick.
+
+
+ Changes: Modified:
+ +5 -0 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/04 02:44:47 UTC (20060604-1618)
+ Log:
+ Improvements to HURT propagation.
+
+
+ Changes: Modified:
+ +8 -6 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/06/04 02:33:31 UTC (20060604-1616)
+ Log:
+ - further simplification
+
+
+ Changes: Modified:
+ +25 -76 trunk/extensions/hurt.c (File Modified)
+ +0 -9 trunk/extensions/hurt.h (File Modified)
+
+
+nenolod 2006/06/04 02:22:52 UTC (20060604-1614)
+ Log:
+ - client_exit hook
+
+
+ Changes: Modified:
+ +13 -0 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/06/04 02:17:01 UTC (20060604-1612)
+ Log:
+ - cut off at 15 messages instead of 30
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/hurt.h (File Modified)
+
+
+jilles 2006/06/04 02:16:18 UTC (20060604-1610)
+ Log:
+ Squash a warning here.
+
+
+ Changes: Modified:
+ +1 -3 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/06/04 02:11:40 UTC (20060604-1608)
+ Log:
+ Don't show servers in /stats l to nonopers if flatten links is enabled.
+
+
+ Changes: Modified:
+ +3 -1 trunk/modules/m_stats.c (File Modified)
+
+
+nenolod 2006/06/04 02:05:50 UTC (20060604-1606)
+ Log:
+ - hurt expiry
+
+
+ Changes: Modified:
+ +20 -7 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/06/04 01:59:06 UTC (20060604-1603)
+ Log:
+ - remove inline stuff (yuck)
+ - sockaddr should have been sockhost
+
+
+ Changes: Modified:
+ +22 -31 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/06/04 01:56:14 UTC (20060604-1601)
+ Log:
+ - make hurt checking actually work
+
+
+ Changes: Modified:
+ +2 -7 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/04 01:55:34 UTC (20060604-1599)
+ Log:
+ Slight tweak to alias{}.
+
+
+ Changes: Modified:
+ +4 -0 trunk/src/parse.c (File Modified)
+
+
+nenolod 2006/06/04 01:54:42 UTC (20060604-1597)
+ Log:
+ - further simplification
+
+
+ Changes: Modified:
+ +59 -71 trunk/extensions/hurt.c (File Modified)
+ +0 -1 trunk/extensions/hurt.h (File Modified)
+
+
+nenolod 2006/06/04 01:40:14 UTC (20060604-1595)
+ Log:
+ - further cleanup (but, it does not compile right now because i've removed the patricia code (well, most of it)
+
+
+ Changes: Modified:
+ +10 -20 trunk/extensions/hurt.c (File Modified)
+ +0 -4 trunk/extensions/hurt.h (File Modified)
+
+
+nenolod 2006/06/04 01:25:26 UTC (20060604-1593)
+ Log:
+ - remove some unnecessary code here (hurt_initial_check_event()).
+
+
+ Changes: Modified:
+ +0 -23 trunk/extensions/hurt.c (File Modified)
+
+
+nenolod 2006/06/04 01:21:30 UTC (20060604-1591)
+ Log:
+ - if PRIVMSG has been crippled (localClient.target_last > CurrentTime), and the PM target is an operator, then allow it through
+
+
+ Changes: Modified:
+ +8 -0 trunk/modules/core/m_message.c (File Modified)
+
+
+nenolod 2006/06/04 01:09:52 UTC (20060604-1589)
+ Log:
+ - more sane tgchange hax
+
+
+ Changes: Modified:
+ +2 -1 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 23:28:39 UTC (20060603-1587)
+ Log:
+ Make HEAL <nick> work.
+
+
+ Changes: Modified:
+ +40 -43 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 23:04:33 UTC (20060603-1585)
+ Log:
+ Destroy hurt_clients list on unload.
+
+
+ Changes: Modified:
+ +7 -0 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 22:55:21 UTC (20060603-1583)
+ Log:
+ Coding style: no space between a function name and parenthesis.
+
+
+ Changes: Modified:
+ +43 -43 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 22:48:40 UTC (20060603-1581)
+ Log:
+ Now works and throws out hurt clients after 30 protocol messages
+ unless they identify.
+
+
+ Changes: Modified:
+ +28 -36 trunk/extensions/hurt.c (File Modified)
+ +1 -7 trunk/extensions/hurt.h (File Modified)
+
+
+jilles 2006/06/03 22:19:39 UTC (20060603-1579)
+ Log:
+ Working addition/lookup.
+
+
+ Changes: Modified:
+ +8 -0 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 22:00:31 UTC (20060603-1577)
+ Log:
+ Get rid of hyb6 style propagation (:server COMMAND source).
+
+
+ Changes: Modified:
+ +18 -22 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 21:53:47 UTC (20060603-1575)
+ Log:
+ add not-working hurt_add and hurt_find
+
+
+ Changes: Modified:
+ +13 -5 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 21:34:56 UTC (20060603-1573)
+ Log:
+ Comment out a lot of stuff so I can load and unload this without crashing.
+
+
+ Changes: Modified:
+ +17 -6 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 21:24:02 UTC (20060603-1571)
+ Log:
+ Fix svn:keywords and add a short comment at the top.
+
+
+ Changes: Modified:
+ +8 -0 trunk/extensions/hurt.c (File Modified) (Property Modified)
+
+
+jilles 2006/06/03 21:21:44 UTC (20060603-1569)
+ Log:
+ - Make hurt module compile
+ - Link it to the build
+ - Initial tweaks, use struct Message's min params, ERR_NOPRIVS shows
+ correct flag name, no CAP_TS6 use etc
+
+
+ Changes: Modified:
+ +1 -0 trunk/extensions/Makefile.in (File Modified)
+ +30 -32 trunk/extensions/hurt.c (File Modified)
+
+
+jilles 2006/06/03 21:06:46 UTC (20060603-1567)
+ Log:
+ Put beu's hurt module in trunk.
+
+
+ Changes: Modified:
+ + - trunk/extensions/hurt.c (File Added)
+ + - trunk/extensions/hurt.h (File Added)
+
+
+nenolod 2006/06/02 00:43:35 UTC (20060602-1563)
+ Log:
+ - _iprint(): use stderr instead of stdout
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_log.c (File Modified)
+
+
+jilles 2006/06/01 23:50:54 UTC (20060601-1561)
+ Log:
+ - Open fd 0, 1, 2 to /dev/null so we don't get kqueue there
+ and subsequently destroy our kqueue when we close 0, 1, 2
+ (broke /restart).
+ - After closing fd 0, 1, 2 reopen them to /dev/null again
+ so we don't send messages from malloc etc to a random
+ user's connection.
+ - Remove an obsolete comment.
+
+
+ Changes: Modified:
+ +13 -2 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/06/01 22:17:16 UTC (20060601-1559)
+ Log:
+ Update NEWS file.
+
+
+ Changes: Modified:
+ +29 -1 trunk/NEWS (File Modified)
+
+
+jilles 2006/06/01 20:18:31 UTC (20060601-1551)
+ Log:
+ Rerun autoconf.
+
+
+ Changes: Modified:
+ +1 -1 trunk/configure (File Modified)
+
+
+jilles 2006/06/01 20:17:21 UTC (20060601-1549)
+ Log:
+ Fix openssl version check to also accept versions newer than 0.9.6.
+
+
+ Changes: Modified:
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2006/06/01 18:18:28 UTC (20060601-1543)
+ Log:
+ Oops, need packet.h here.
+
+
+ Changes: Modified:
+ +1 -0 trunk/modules/m_cmessage.c (File Modified)
+
+
+jilles 2006/06/01 18:17:00 UTC (20060601-1541)
+ Log:
+ End the flood grace period in CPRIVMSG/CNOTICE.
+
+
+ Changes: Modified:
+ +3 -0 trunk/modules/m_cmessage.c (File Modified)
+
+
+nenolod 2006/06/01 17:51:07 UTC (20060601-1539)
+ Log:
+ - update class::connectfreq documentation
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/06/01 17:41:10 UTC (20060601-1537)
+ Log:
+ - get rid of the "minimum connection frequency delay" concept, as it is quite silly and does no good anyway
+
+
+ Changes: Modified:
+ +3 -6 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2006/06/01 15:27:18 UTC (20060601-1535)
+ Log:
+ New RPL_YOUREOPER, from ircd.digi.pl3d.5.2.1.jp3 (1995-1996).
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/messages.tab (File Modified)
+
+
+jilles 2006/06/01 13:06:23 UTC (20060601-1533)
+ Log:
+ Don't mention that /stats p shows idle times, as it doesn't.
+
+
+ Changes: Modified:
+ +1 -1 trunk/help/opers/stats (File Modified)
+ +1 -1 trunk/help/users/stats (File Modified)
+
+
+jilles 2006/06/01 12:59:03 UTC (20060601-1531)
+ Log:
+ /stats A shows DNS servers, it doesn't matter whether ircd
+ uses ADNS or something else.
+
+
+ Changes: Modified:
+ +1 -1 trunk/help/opers/stats (File Modified)
+
+
+jilles 2006/05/30 21:34:57 UTC (20060530-1529)
+ Log:
+ get_client_name() fix
+
+
+ Changes: Modified:
+ +4 -0 trunk/src/client.c (File Modified)
+
+
+jilles 2006/05/28 13:58:14 UTC (20060528-1527)
+ Log:
+ Add some comments.
+
+
+ Changes: Modified:
+ +6 -0 trunk/src/ircd.c (File Modified)
+
+
+beu 2006/05/28 09:22:09 UTC (20060528-1521)
+ Log:
+ Fix argument order for AC_SEARCH_LIBS (yeah, I fail...)
+
+ Changes: Modified:
+ +16 -17 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+beu 2006/05/28 09:10:43 UTC (20060528-1517)
+ Log:
+ Fix build for SunOS/Solaris [libnsl is required for inet_ntoa()].
+
+ Changes: Modified:
+ +135 -0 trunk/configure (File Modified)
+ +6 -0 trunk/configure.ac (File Modified)
+
+
+jilles 2006/05/28 03:28:53 UTC (20060528-1515)
+ Log:
+ Exit 0 on successful -conftest.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/05/28 03:19:47 UTC (20060528-1513)
+ Log:
+ Make the "keep the parent process around" thing work, by opening
+ a pipe to the child process. This pipe is on fd 0 in the child
+ process. After successful initialization, the child will write
+ a byte to this pipe, on fatal errors it will close it without
+ writing anything.
+
+ Somewhat hackish still but should work.
+
+
+ Changes: Modified:
+ +27 -30 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/05/28 02:37:26 UTC (20060528-1511)
+ Log:
+ - convert some error messages to ierror() over fprintf/ilog combination
+
+
+ Changes: Modified:
+ +3 -6 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/05/28 02:35:58 UTC (20060528-1509)
+ Log:
+ - inotice() for loadmodule when in foreground mode
+
+
+ Changes: Modified:
+ +3 -0 trunk/src/modules.c (File Modified)
+
+
+nenolod 2006/05/28 02:34:43 UTC (20060528-1507)
+ Log:
+ - remove inotice() on loading modules from the config
+
+
+ Changes: Modified:
+ +0 -3 trunk/src/modules.c (File Modified)
+
+
+nenolod 2006/05/28 00:11:14 UTC (20060528-1505)
+ Log:
+ - usleep for 50000usec in the parent process to allow for startup messages
+ to be cleanly printed before detaching to shell, this should be more than
+ enough time really
+
+
+ Changes: Modified:
+ +3 -0 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/05/28 00:07:11 UTC (20060528-1503)
+ Log:
+ - display more errors during normal startup as to try to help people find common problems
+
+
+ Changes: Modified:
+ +27 -10 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/05/27 23:36:23 UTC (20060527-1501)
+ Log:
+ - version bump in preparation of 2.0.0 release
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2006/05/27 20:39:47 UTC (20060527-1495)
+ Log:
+ Change example.conf operator block from "admin" to "god",
+ so as to show we encourage per-person operator blocks.
+
+
+ Changes: Modified:
+ +4 -2 trunk/doc/example.conf (File Modified)
+
+
+jilles 2006/05/27 20:33:58 UTC (20060527-1493)
+ Log:
+ Document alias{} block.
+
+
+ Changes: Modified:
+ +28 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/05/27 20:28:00 UTC (20060527-1491)
+ Log:
+ Document DNS blacklist stuff in sgml.
+
+
+ Changes: Modified:
+ +6 -0 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+ +39 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/05/27 20:13:30 UTC (20060527-1489)
+ Log:
+ Misc /stats clarifications.
+
+
+ Changes: Modified:
+ +9 -4 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/05/27 19:54:37 UTC (20060527-1487)
+ Log:
+ Move snomasks into umodes chapter.
+ Move oprivs chapter down.
+
+
+ Changes: Modified:
+ +1 -160 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ + - trunk/doc/sgml/oper-guide/snomasks.sgml (File Deleted)
+ +137 -0 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/05/27 19:09:19 UTC (20060527-1485)
+ Log:
+ Mention operator{} user@host change.
+
+
+ Changes: Modified:
+ +9 -3 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/05/27 18:58:12 UTC (20060527-1483)
+ Log:
+ operator{} block user@host matches against orighost now, not host.
+ This means that services/+h spoofs do not work in operator{} blocks;
+ auth{} spoofs still work.
+
+
+ Changes: Modified:
+ +4 -0 trunk/doc/example.conf (File Modified)
+ +1 -1 trunk/doc/reference.conf (File Modified)
+ +2 -2 trunk/modules/m_challenge.c (File Modified)
+ +1 -1 trunk/modules/m_oper.c (File Modified)
+
+
+nenolod 2006/05/27 17:24:05 UTC (20060527-1481)
+ Log:
+ - inotice/iwarn/ierror() stuff I was working on
+
+
+ Changes: Modified:
+ +3 -0 trunk/include/s_log.h (File Modified)
+ +15 -11 trunk/src/ircd.c (File Modified)
+ +3 -1 trunk/src/modules.c (File Modified)
+ +1 -1 trunk/src/newconf.c (File Modified)
+ +54 -0 trunk/src/s_log.c (File Modified)
+
+
+jilles 2006/05/26 22:54:29 UTC (20060526-1473)
+ Log:
+ Oops, don't add blacklists to the list twice on rehash.
+
+
+ Changes: Modified:
+ +3 -2 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/05/26 22:27:21 UTC (20060526-1471)
+ Log:
+ Remove notices to the client about progress of dnsbl lookups.
+
+
+ Changes: Modified:
+ +0 -4 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/05/26 22:18:23 UTC (20060526-1469)
+ Log:
+ Add auth{} flag dnsbl_exempt.
+
+
+ Changes: Modified:
+ +2 -1 trunk/doc/example.conf (File Modified)
+ +2 -1 trunk/doc/reference.conf (File Modified)
+ +2 -0 trunk/include/s_conf.h (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +8 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/05/26 22:07:49 UTC (20060526-1467)
+ Log:
+ Switch alias{} and blacklist{} around, for consistency with example.conf.
+
+
+ Changes: Modified:
+ +18 -18 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/05/26 21:58:29 UTC (20060526-1465)
+ Log:
+ Send a warning to the user if they are dnsbl listed but exempted.
+
+
+ Changes: Modified:
+ +17 -12 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/05/26 21:25:28 UTC (20060526-1463)
+ Log:
+ Move throwing out dnsbl listed clients to registration,
+ and make kline_exempt exempt from it.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/blacklist.h (File Modified)
+ +4 -0 trunk/include/client.h (File Modified)
+ +15 -16 trunk/src/blacklist.c (File Modified)
+ +6 -0 trunk/src/client.c (File Modified)
+ +17 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/05/26 21:20:56 UTC (20060526-1461)
+ Log:
+ Show refcount in /stats n.
+
+
+ Changes: Modified:
+ +3 -2 trunk/modules/m_stats.c (File Modified)
+
+
+jilles 2006/05/26 20:50:41 UTC (20060526-1459)
+ Log:
+ Don't look up dnsbls twice if they send USER twice.
+
+
+ Changes: Modified:
+ +5 -3 trunk/modules/m_user.c (File Modified)
+
+
+jilles 2006/05/26 20:42:48 UTC (20060526-1457)
+ Log:
+ Add /stats n to help files.
+
+
+ Changes: Modified:
+ +1 -0 trunk/help/opers/stats (File Modified)
+ +1 -0 trunk/help/users/stats (File Modified)
+
+
+jilles 2006/05/26 20:36:54 UTC (20060526-1455)
+ Log:
+ Only check dnsbls for A records, not AAAA.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/05/26 20:09:55 UTC (20060526-1453)
+ Log:
+ Don't remove non-illegal blacklists on completion of check.
+ Add debugging notices (not working).
+
+
+ Changes: Modified:
+ +5 -1 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/05/26 19:58:05 UTC (20060526-1451)
+ Log:
+ Don't call register_local_user() if they haven't sent a nick yet.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/blacklist.c (File Modified)
+
+
+jilles 2006/05/26 19:45:28 UTC (20060526-1449)
+ Log:
+ Add /stats n, shows dnsbls with counts (counts reset on rehash).
+
+
+ Changes: Modified:
+ +21 -0 trunk/modules/m_stats.c (File Modified)
+
+
+jilles 2006/05/26 18:57:36 UTC (20060526-1447)
+ Log:
+ More dnsbl rehash fixes, it was adding bogus entries.
+
+
+ Changes: Modified:
+ +2 -7 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/05/26 17:38:52 UTC (20060526-1445)
+ Log:
+ Need blacklist.h here.
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+nenolod 2006/05/26 17:33:33 UTC (20060526-1443)
+ Log:
+ - nuke iauth
+
+
+ Changes: Modified:
+ +1 -2 trunk/configure (File Modified)
+ +0 -48 trunk/configure.ac (File Modified)
+ + - trunk/doc/example-iauth.conf (File Deleted)
+ + - trunk/iauth/ (File Deleted)
+
+
+jilles 2006/05/26 17:20:01 UTC (20060526-1441)
+ Log:
+ Improve handling of rehashing with blacklists.
+ Also some coding style tweaks.
+
+
+ Changes: Modified:
+ +3 -2 trunk/include/blacklist.h (File Modified)
+ +35 -16 trunk/src/blacklist.c (File Modified)
+ +2 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/05/25 15:20:48 UTC (20060525-1439)
+ Log:
+ Clear can_send cache if a user logs in or out from services.
+
+
+ Changes: Modified:
+ +2 -0 trunk/modules/m_services.c (File Modified)
+
+
+jilles 2006/05/23 16:41:33 UTC (20060523-1425)
+ Log:
+ Add unsupported/ directory and move m_force.c and m_clearchan.c into it.
+ This directory is not entered by default.
+ More stuff needs to be moved into here.
+
+
+ Changes: Modified:
+ +2 -1 trunk/configure (File Modified)
+ +1 -0 trunk/configure.ac (File Modified)
+ +69 -458 trunk/extensions/Makefile.in (File Modified)
+ + - trunk/extensions/m_clearchan.c (File Deleted)
+ + - trunk/extensions/m_force.c (File Deleted)
+ + - trunk/unsupported/ (File Added)
+ + - trunk/unsupported/Makefile.in (File Added)
+ + - trunk/unsupported/m_clearchan.c (File Added)
+ + - trunk/unsupported/m_force.c (File Added)
+
+
+jilles 2006/05/23 16:32:11 UTC (20060523-1423)
+ Log:
+ Logging/wallops for forcejoin/forcepart, numeric fix.
+ This needs to be moved to the toys section.
+
+
+ Changes: Modified:
+ +22 -2 trunk/extensions/m_force.c (File Modified)
+
+
+jilles 2006/05/23 16:06:01 UTC (20060523-1421)
+ Log:
+ Fix comments at the top (including copyright).
+
+
+ Changes: Modified:
+ +3 -2 trunk/extensions/m_omode.c (File Modified)
+
+
+jilles 2006/05/23 16:01:22 UTC (20060523-1419)
+ Log:
+ Add OMODE command to extensions/ for oper mode hacking:
+ - requires admin privs
+ - does not work for opped opers
+ - sends wallops
+ - sends a ServerMode for opping the oper themselves,
+ otherwise a mode coming from the oper (not only
+ does this provide full accountability, it is also
+ easiest to implement while avoiding channels
+ messed up with bogus bans etc).
+
+
+ Changes: Modified:
+ +171 -0 trunk/extensions/Makefile.in (File Modified)
+ + - trunk/extensions/m_omode.c (File Added)
+
+
+gxti 2006/05/22 23:02:06 UTC (20060522-1417)
+ Log:
+ Metadata fix
+
+
+ Changes: Modified:
+ + - trunk/include/blacklist.h (Property Modified)
+ + - trunk/src/blacklist.c (Property Modified)
+
+
+nenolod 2006/05/22 19:25:09 UTC (20060522-1415)
+ Log:
+ - avoid loosing the username forever when calling register_local_user after the blacklist checking lock has been released
+
+
+ Changes: Modified:
+ +5 -1 trunk/src/blacklist.c (File Modified)
+
+
+nenolod 2006/05/22 17:13:15 UTC (20060522-1413)
+ Log:
+ Initial DNS blacklist support:
+ - see example.conf for how to use.
+ - because opm.blitzed.org is currently offline, we recommend ircbl.ahbl.org as a replacement
+ - tor.ahbl.org is also included because most networks will not want to allow tor
+ (and we're considering going KoS on tor users here anyway due to abuse)
+
+
+ Changes: Modified:
+ +18 -0 trunk/doc/example.conf (File Modified)
+ +66 -0 trunk/doc/reference.conf (File Modified)
+ + - trunk/include/blacklist.h (File Added)
+ +2 -0 trunk/include/client.h (File Modified)
+ +3 -0 trunk/modules/m_user.c (File Modified)
+ +152 -0 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/blacklist.c (File Added)
+ +34 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_auth.c (File Modified)
+ +4 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/05/21 17:38:31 UTC (20060521-1411)
+ Log:
+ Remove last bit of lzo stuff (comment in example.conf connect{}).
+
+
+ Changes: Modified:
+ +0 -4 trunk/doc/example.conf (File Modified)
+
+
+jilles 2006/05/21 14:46:17 UTC (20060521-1409)
+ Log:
+ Show sasl successes and failures in /stats t (like other
+ things in /stats t, about local clients only).
+
+
+ Changes: Modified:
+ +2 -0 trunk/include/s_stats.h (File Modified)
+ +3 -0 trunk/modules/m_sasl.c (File Modified)
+ +3 -0 trunk/src/s_stats.c (File Modified)
+
+
+jilles 2006/05/20 20:13:56 UTC (20060520-1405)
+ Log:
+ Allow messaging services by nickname without using
+ target change slots (this was already possible with
+ user@server notation or services shortcuts).
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/core/m_message.c (File Modified)
+
+
+jilles 2006/05/20 19:28:16 UTC (20060520-1393)
+ Log:
+ Abort a safelist if a new /list comes in while one is already in progress.
+
+
+ Changes: Modified:
+ +16 -0 trunk/modules/m_list_safelist.c (File Modified)
+
+
+jilles 2006/05/20 19:24:11 UTC (20060520-1391)
+ Log:
+ Change $![letter]:[mask] to $~[letter]:[mask]
+ so both ! and ~ invert an extban.
+
+
+ Changes: Modified:
+ +2 -0 trunk/src/chmode.c (File Modified)
+
+
+nenolod 2006/05/20 19:19:00 UTC (20060520-1389)
+ Log:
+ - revert due to technical issues
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/extban.c (File Modified)
+
+
+nenolod 2006/05/20 19:17:42 UTC (20060520-1387)
+ Log:
+ - allow $![letter]:[mask] to also invert an extban, like $~[letter]:[mask], since some people will likely believe that is the correct way of doing it
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/extban.c (File Modified)
+
+
+jilles 2006/05/20 18:32:45 UTC (20060520-1385)
+ Log:
+ Don't pace /list on a single channel.
+
+
+ Changes: Modified:
+ +10 -7 trunk/modules/m_list_safelist.c (File Modified)
+
+
+jilles 2006/05/20 18:15:46 UTC (20060520-1383)
+ Log:
+ Add EXTBAN=$:<letters> to 005 if any extban modules are loaded.
+
+
+ Changes: Modified:
+ +4 -2 trunk/include/supported.h (File Modified)
+
+
+jilles 2006/05/20 17:21:19 UTC (20060520-1381)
+ Log:
+ Extban types are case insensitive; force them to lowercase when added.
+
+
+ Changes: Modified:
+ +5 -5 trunk/doc/extban.txt (File Modified)
+ +4 -0 trunk/src/chmode.c (File Modified)
+ +3 -3 trunk/src/extban.c (File Modified)
+
+
+jilles 2006/05/20 14:11:07 UTC (20060520-1379)
+ Log:
+ sendto_wallops_flags():
+ - instead of checking IsOper on each client, walk the appropriate list
+ - instead of sending non-+z wallops from persons to nonopers, send only
+ +w wallops from persons
+
+
+ Changes: Modified:
+ +1 -5 trunk/src/send.c (File Modified)
+
+
+jilles 2006/05/20 13:48:37 UTC (20060520-1377)
+ Log:
+ Prefix oper wallops with "WALLOPS - " if they would
+ otherwise look like operwalls or locops, when sending
+ them to local users.
+
+
+ Changes: Modified:
+ +11 -1 trunk/modules/m_wallops.c (File Modified)
+
+
+jilles 2006/05/20 13:47:22 UTC (20060520-1375)
+ Log:
+ Make sure destination field in some sasl numerics
+ is the user's nick, not the sasl agent or server
+ name.
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_sasl.c (File Modified)
+
+
+beu 2006/05/19 19:24:44 UTC (20060519-1373)
+ Log:
+ Add `-I.' to INCLUDES (hurt module has it's own header file...)
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/Makefile.in (File Modified)
+
+
+jilles 2006/05/19 18:10:55 UTC (20060519-1369)
+ Log:
+ Invalidate can_send cache on CHGHOST/SIGNON (change_nick_user_host()).
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/s_user.c (File Modified)
+
+
+beu 2006/05/19 18:10:13 UTC (20060519-1367)
+ Log:
+ Fix build for when IPv6 is disabled.
+
+
+ Changes: Modified:
+ +12 -10 trunk/src/s_auth.c (File Modified)
+
+
+jilles 2006/05/18 18:38:04 UTC (20060518-1365)
+ Log:
+ Add information about adding extban types.
+
+
+ Changes: Modified:
+ +25 -0 trunk/doc/extban.txt (File Modified)
+
+
+jilles 2006/05/18 17:59:35 UTC (20060518-1363)
+ Log:
+ Better extban validation: try to match a new extban from
+ a local user against its setter to see if it is valid.
+ Unknown extban types from remotes are no longer hidden.
+
+
+ Changes: Modified:
+ +4 -3 trunk/doc/extban.txt (File Modified)
+ +1 -0 trunk/include/channel.h (File Modified)
+ +2 -6 trunk/src/chmode.c (File Modified)
+ +32 -0 trunk/src/extban.c (File Modified)
+
+
+jilles 2006/05/17 20:55:55 UTC (20060517-1359)
+ Log:
+ Make sure both .c.o: and .s.o: are followed by the necessary command.
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/Makefile.in (File Modified)
+
+
+jilles 2006/05/17 18:07:20 UTC (20060517-1357)
+ Log:
+ Add need_sasl auth{} flag to sgml documentation.
+
+
+ Changes: Modified:
+ +7 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/05/17 17:50:10 UTC (20060517-1353)
+ Log:
+ Document need_sasl auth{} flag in example confs.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +1 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/05/17 17:37:46 UTC (20060517-1349)
+ Log:
+ Don't allow TB to set an empty topic.
+ This would be possible if a server sent bad protocol
+ and could cause a crash.
+
+
+ Changes: Modified:
+ +4 -0 trunk/modules/m_tb.c (File Modified)
+
+
+nenolod 2006/05/17 14:49:13 UTC (20060517-1347)
+ Log:
+ - oops
+
+
+ Changes: Modified:
+ +1 -1 trunk/Makefile.in (File Modified)
+
+
+nenolod 2006/05/17 14:46:58 UTC (20060517-1345)
+ Log:
+ - typo fix
+
+
+ Changes: Modified:
+ +2 -2 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+nenolod 2006/05/17 14:45:52 UTC (20060517-1343)
+ Log:
+ - rebuild configure
+
+
+ Changes: Modified:
+ +2 -2 trunk/configure (File Modified)
+
+
+nenolod 2006/05/17 00:52:51 UTC (20060517-1341)
+ Log:
+ - makefile fix
+
+
+ Changes: Modified:
+ +1 -1 trunk/extensions/Makefile.in (File Modified)
+
+
+nenolod 2006/05/17 00:45:40 UTC (20060517-1339)
+ Log:
+ - rename contrib to extensions to bring some clarity to things
+
+
+ Changes: Modified:
+ +1 -1 trunk/Makefile.in (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+ +10 -10 trunk/doc/example.conf (File Modified)
+ +10 -10 trunk/doc/reference.conf (File Modified)
+ + - trunk/extensions/ (File Added)
+ + - trunk/extras/ (File Deleted)
+
+
+nenolod 2006/05/17 00:43:32 UTC (20060517-1337)
+ Log:
+ - temporary rename
+
+
+ Changes: Modified:
+ +1 -1 trunk/Makefile.in (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+ + - trunk/contrib/ (File Deleted)
+ + - trunk/extras/ (File Added)
+
+
+jilles 2006/05/14 13:47:33 UTC (20060514-1333)
+ Log:
+ Don't allow servers to QUIT (they should use SQUIT).
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_quit.c (File Modified)
+
+
+nenolod 2006/05/14 02:09:30 UTC (20060514-1329)
+ Log:
+ - keywords
+
+
+ Changes: Modified:
+ + - trunk/src/fnvhash.s (Property Modified)
+
+
+nenolod 2006/05/14 01:47:33 UTC (20060514-1327)
+ Log:
+ - reduced version of code
+
+
+ Changes: Modified:
+ +9 -61 trunk/src/fnvhash.s (File Modified)
+
+
+nenolod 2006/05/14 01:20:24 UTC (20060514-1325)
+ Log:
+ - ok, this only works on x86, because amd64 wants pushq/%rbp for stack manipulation
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/fnvhash.s (File Modified)
+
+
+jilles 2006/05/14 01:19:25 UTC (20060514-1323)
+ Log:
+ Fix orighost matching for klines, etc. Was hashing the visible
+ host, oops.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/hostmask.c (File Modified)
+
+
+nenolod 2006/05/13 23:49:14 UTC (20060513-1321)
+ Log:
+ - integrate fnvhash.s into buildsystem (--enable-ricer-hashing).
+
+
+ Changes: Modified:
+ +7 -1 trunk/configure (File Modified)
+ +5 -0 trunk/configure.ac (File Modified)
+ +5 -6 trunk/src/Makefile.in (File Modified)
+ +0 -4 trunk/src/fnvhash.s (File Modified)
+ +0 -2 trunk/src/hash.c (File Modified)
+
+
+nenolod 2006/05/13 23:35:31 UTC (20060513-1319)
+ Log:
+ - regenerate configure
+
+
+ Changes: Modified:
+ +18 -0 trunk/configure (File Modified)
+
+
+nenolod 2006/05/13 23:35:15 UTC (20060513-1317)
+ Log:
+ - --enable-ricer-hashing option.
+
+
+ Changes: Modified:
+ +9 -0 trunk/configure.ac (File Modified)
+ +3 -0 trunk/include/setup.h.in (File Modified)
+
+
+nenolod 2006/05/13 23:22:47 UTC (20060513-1315)
+ Log:
+ - Add assembly versions of the hashing code. They live in src/fnvhash.s, and require an x86 or x64 CPU.
+
+
+ Changes: Modified:
+ + - trunk/src/fnvhash.s (File Added)
+ +3 -0 trunk/src/hash.c (File Modified)
+
+
+jilles 2006/05/12 15:57:25 UTC (20060512-1309)
+ Log:
+ Fix syntax error in reference.conf.
+
+
+ Changes: Modified:
+ +0 -1 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/05/11 16:28:16 UTC (20060511-1307)
+ Log:
+ Expand blah.blah and blah:blah to *!*@... instead of ...!*@* for bans
+ (&& instead of ||...)
+ Allows stuff like /mode +b 127.0.0.1 to ban that IP.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/chmode.c (File Modified)
+
+
+jilles 2006/05/11 16:16:36 UTC (20060511-1303)
+ Log:
+ Documentation for extban.
+
+
+ Changes: Modified:
+ + - trunk/doc/extban.txt (File Added)
+
+
+jilles 2006/05/11 15:50:33 UTC (20060511-1301)
+ Log:
+ Add extban modules to example confs.
+
+
+ Changes: Modified:
+ +5 -0 trunk/doc/example.conf (File Modified)
+ +10 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/05/11 15:43:03 UTC (20060511-1299)
+ Log:
+ Initial addition of extended ban types (conditionals).
+ Allows custom +bqeI checks via modules.
+ Initial extra types are account (a[:mask]), oper (o),
+ channel (c:name), realname (r:mask), server (s:mask).
+
+
+ Changes: Modified:
+ +229 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/extb_account.c (File Added)
+ + - trunk/contrib/extb_channel.c (File Added)
+ + - trunk/contrib/extb_oper.c (File Added)
+ + - trunk/contrib/extb_realname.c (File Added)
+ + - trunk/contrib/extb_server.c (File Added)
+ +13 -0 trunk/include/channel.h (File Modified)
+ +1 -0 trunk/src/Makefile.in (File Modified)
+ +14 -5 trunk/src/channel.c (File Modified)
+ +91 -0 trunk/src/chmode.c (File Modified)
+ + - trunk/src/extban.c (File Added)
+
+
+jilles 2006/05/09 19:28:19 UTC (20060509-1297)
+ Log:
+ Do not force +bqeI modes starting with '$' in nick!user@host format.
+ * and ? characters in them are still assumed to be wildcards.
+
+
+ Changes: Modified:
+ +6 -0 trunk/src/chmode.c (File Modified)
+
+
+nenolod 2006/05/08 13:05:25 UTC (20060508-1295)
+ Log:
+ - memory leak fix, reported by Lee Hardy <lee@leeh.co.uk>
+
+
+ Changes: Modified:
+ +4 -0 trunk/modules/m_capab.c (File Modified)
+
+
+jilles 2006/05/05 19:00:19 UTC (20060505-1291)
+ Log:
+ Stop some mixing of client and server protocol.
+
+
+ Changes: Modified:
+ +6 -0 trunk/modules/core/m_nick.c (File Modified)
+ +4 -2 trunk/modules/m_pass.c (File Modified)
+ +6 -0 trunk/modules/m_sasl.c (File Modified)
+ +6 -0 trunk/modules/m_user.c (File Modified)
+
+
+nenolod 2006/05/05 15:06:00 UTC (20060505-1287)
+ Log:
+ - additional revert
+
+
+ Changes: Modified:
+ +0 -2 trunk/include/s_newconf.h (File Modified)
+ +0 -4 trunk/include/s_serv.h (File Modified)
+ +0 -1 trunk/src/newconf.c (File Modified)
+ +1 -13 trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2006/05/05 15:03:53 UTC (20060505-1285)
+ Log:
+ - revert LZOLink patch for now
+
+
+ Changes: Modified:
+ +0 -1 trunk/servlink/Makefile.in (File Modified)
+ +0 -16 trunk/servlink/README (File Modified)
+ +2 -36 trunk/servlink/control.c (File Modified)
+ +0 -3 trunk/servlink/control.h (File Modified)
+ +7 -5955 trunk/servlink/io.c (File Modified)
+ + - trunk/servlink/lzoconf.h (File Deleted)
+ + - trunk/servlink/lzodefs.h (File Deleted)
+ + - trunk/servlink/minilzo.c (File Deleted)
+ + - trunk/servlink/minilzo.h (File Deleted)
+ +0 -1 trunk/servlink/servlink.h (File Modified)
+
+
+nenolod 2006/05/05 13:37:26 UTC (20060505-1283)
+ Log:
+ - more stuff here
+
+
+ Changes: Modified:
+ +4 -2 trunk/servlink/control.c (File Modified)
+ +2 -1 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 04:21:59 UTC (20060505-1281)
+ Log:
+ - oops
+
+
+ Changes: Modified:
+ +2 -2 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 04:15:09 UTC (20060505-1279)
+ Log:
+ - paranoia, prevent segfaults
+
+
+ Changes: Modified:
+ +2 -2 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 03:49:15 UTC (20060505-1277)
+ Log:
+ - more optimal servlink code
+
+
+ Changes: Modified:
+ +21 -8 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 03:33:12 UTC (20060505-1275)
+ Log:
+ - more efficient read strategy
+
+
+ Changes: Modified:
+ +15 -3 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 03:23:07 UTC (20060505-1273)
+ Log:
+ - use lzo_uintp cast to make LZO happy
+
+
+ Changes: Modified:
+ +3 -3 trunk/servlink/io.c (File Modified)
+
+
+nenolod 2006/05/05 03:09:46 UTC (20060505-1271)
+ Log:
+ - lzolink patch. not highly tested yet, will need extensive testing before 2.0 release
+
+
+ Changes: Modified:
+ +4 -0 trunk/doc/example.conf (File Modified)
+ +2 -1 trunk/include/s_newconf.h (File Modified)
+ +4 -0 trunk/include/s_serv.h (File Modified)
+ +1 -0 trunk/servlink/Makefile.in (File Modified)
+ +16 -0 trunk/servlink/README (File Modified)
+ +34 -2 trunk/servlink/control.c (File Modified)
+ +3 -0 trunk/servlink/control.h (File Modified)
+ +5929 -7 trunk/servlink/io.c (File Modified)
+ + - trunk/servlink/lzoconf.h (File Added)
+ + - trunk/servlink/lzodefs.h (File Added)
+ + - trunk/servlink/minilzo.c (File Added)
+ + - trunk/servlink/minilzo.h (File Added)
+ +1 -0 trunk/servlink/servlink.h (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +14 -2 trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2006/04/30 16:51:11 UTC (20060430-1269)
+ Log:
+ - remove imalloc, it was a concept that probably wouldn't have worked properly
+
+
+ Changes: Modified:
+ +0 -977 trunk/libcharybdis/Makefile.in (File Modified)
+ + - trunk/libcharybdis/imalloc.c (File Deleted)
+ + - trunk/libcharybdis/imalloc.h (File Deleted)
+
+
+nenolod 2006/04/29 03:04:39 UTC (20060429-1267)
+ Log:
+ - disable imalloc for now
+
+
+ Changes: Modified:
+ +33 -7 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 02:47:22 UTC (20060429-1265)
+ Log:
+ - remove unneeded debug code
+
+
+ Changes: Modified:
+ +0 -6 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 02:46:00 UTC (20060429-1263)
+ Log:
+ - minimum allocation size is 32 bytes, not 16 due to dlink_list overhead
+
+
+ Changes: Modified:
+ +6 -4 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 02:40:23 UTC (20060429-1261)
+ Log:
+ - more stuff here, imalloc remains disabled for now
+
+
+ Changes: Modified:
+ +2 -3 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 02:27:03 UTC (20060429-1259)
+ Log:
+ - more progress
+
+
+ Changes: Modified:
+ +13 -4 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 02:21:48 UTC (20060429-1257)
+ Log:
+ - more tweaks
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/imalloc.c (File Modified)
+ +2 -0 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/04/29 02:13:05 UTC (20060429-1255)
+ Log:
+ - roll back libircd crap
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/Makefile.in (File Modified)
+ +4 -0 trunk/libcharybdis/imalloc.c (File Modified)
+ +29 -0 trunk/src/.depend (File Modified)
+ +6 -21 trunk/src/Makefile.in (File Modified)
+ +3 -218 trunk/src/ircd.c (File Modified)
+ + - trunk/src/ircd_linker.c (File Deleted)
+ + - trunk/src/main.c (File Deleted)
+
+
+nenolod 2006/04/29 01:57:30 UTC (20060429-1253)
+ Log:
+ - realloc(), free() implementation
+
+
+ Changes: Modified:
+ +141 -0 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 01:12:55 UTC (20060429-1251)
+ Log:
+ - malloc(), calloc() implementation
+
+
+ Changes: Modified:
+ +78 -3 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/29 00:41:14 UTC (20060429-1249)
+ Log:
+ - block_free(), block_find(), retune_heaps() implementation
+
+
+ Changes: Modified:
+ +146 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 21:43:10 UTC (20060428-1246)
+ Log:
+ - block_destroy code, block_allocate code.
+
+
+ Changes: Modified:
+ +81 -4 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 21:04:19 UTC (20060428-1244)
+ Log:
+ - block_new() code
+
+
+ Changes: Modified:
+ +57 -0 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 20:34:53 UTC (20060428-1242)
+ Log:
+ - disable imalloc again :P
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 20:34:31 UTC (20060428-1240)
+ Log:
+ - fix warning
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 20:34:03 UTC (20060428-1238)
+ Log:
+ - fix typo
+
+
+ Changes: Modified:
+ +2 -2 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 20:32:20 UTC (20060428-1236)
+ Log:
+ - constructor code for imalloc engine (malloc_init())
+
+
+ Changes: Modified:
+ +35 -2 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 20:22:37 UTC (20060428-1234)
+ Log:
+ - imalloc engine improvements
+
+
+ Changes: Modified:
+ +60 -6 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 19:51:10 UTC (20060428-1232)
+ Log:
+ - replace mmap() code with direct brk()/sbrk() calls.
+
+
+ Changes: Modified:
+ +32 -10 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 19:26:44 UTC (20060428-1230)
+ Log:
+ - remove outdated i_malloc() interfaces
+
+
+ Changes: Modified:
+ +1 -44 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 15:04:38 UTC (20060428-1228)
+ Log:
+ - redisable imalloc (sorry!)
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 15:03:12 UTC (20060428-1226)
+ Log:
+ - correct GET_PAGE_SLOT() macro
+
+
+ Changes: Modified:
+ +2 -2 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 15:01:53 UTC (20060428-1224)
+ Log:
+ - oops forgot to commit it with imalloc turned off
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/28 15:01:29 UTC (20060428-1222)
+ Log:
+ - cleanups
+
+
+ Changes: Modified:
+ +11 -11 trunk/libcharybdis/imalloc.c (File Modified)
+ +8 -2 trunk/libcharybdis/imalloc.h (File Modified)
+
+
+nenolod 2006/04/28 14:56:20 UTC (20060428-1220)
+ Log:
+ - lowlevel imalloc code
+
+
+ Changes: Modified:
+ +278 -16 trunk/libcharybdis/imalloc.c (File Modified)
+ + - trunk/libcharybdis/imalloc.h (File Added)
+
+
+nenolod 2006/04/26 14:53:05 UTC (20060426-1218)
+ Log:
+ - fix bindings
+
+
+ Changes: Modified:
+ +3 -3 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/26 14:51:53 UTC (20060426-1216)
+ Log:
+ remove #ifndef
+
+
+ Changes: Modified:
+ +0 -1 trunk/libcharybdis/imalloc.c (File Modified)
+
+
+nenolod 2006/04/26 14:50:01 UTC (20060426-1214)
+ Log:
+ - add imalloc engine, however the actual engine itself has not been written yet (just the bindings for if the imalloc option is unavailable, which are forcefully used at present)
+
+
+ Changes: Modified:
+ +115 -0 trunk/libcharybdis/Makefile.in (File Modified)
+ + - trunk/libcharybdis/imalloc.c (File Added)
+
+
+nenolod 2006/04/26 14:37:24 UTC (20060426-1212)
+ Log:
+ - increment configure Id
+
+
+ Changes: Modified:
+ +2208 -1 trunk/configure (File Modified)
+
+
+nenolod 2006/04/26 14:33:37 UTC (20060426-1210)
+ Log:
+ - bootstrap for imalloc code
+
+
+ Changes: Modified:
+ +54 -1 trunk/configure.ac (File Modified)
+ +27 -0 trunk/include/setup.h.in (File Modified)
+
+
+jilles 2006/04/25 14:52:37 UTC (20060425-1208)
+ Log:
+ Clarify interaction of spoofs and channel bans/operator{} blocks.
+
+
+ Changes: Modified:
+ +4 -1 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+ +6 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/04/24 13:42:18 UTC (20060424-1206)
+ Log:
+ - move rehash checking &c into a timed event (idea stolen from ratbox3)
+
+
+ Changes: Modified:
+ +30 -22 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/04/22 17:07:07 UTC (20060422-1204)
+ Log:
+ If shared{} blocks deny something, the command
+ is silently ignored.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/04/22 10:26:56 UTC (20060422-1202)
+ Log:
+ Move up IsService check so we don't store a non-service
+ in preClient->sasl_agent.
+
+
+ Changes: Modified:
+ +6 -6 trunk/modules/m_sasl.c (File Modified)
+
+
+gxti 2006/04/22 03:53:40 UTC (20060422-1198)
+ Log:
+ SASL ENCAP messages originate from the server, not the agent. Check the correct cptr for service status.
+ Add some more sanity checks on agent strings.
+
+
+ Changes: Modified:
+ +13 -11 trunk/modules/m_sasl.c (File Modified)
+
+
+jilles 2006/04/21 16:28:56 UTC (20060421-1194)
+ Log:
+ Unknown clients can have an ID too now so make sure to remove
+ them from the hash if they exit.
+
+
+ Changes: Modified:
+ +3 -0 trunk/src/client.c (File Modified)
+
+
+jilles 2006/04/21 16:21:02 UTC (20060421-1192)
+ Log:
+ Only accept sasl from servers in a service{} block.
+ Not tested but this must go in.
+
+
+ Changes: Modified:
+ +6 -0 trunk/modules/m_sasl.c (File Modified)
+ +3 -0 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/04/19 15:52:08 UTC (20060419-1190)
+ Log:
+ Only process SAVE messages targetting registered users,
+ not servers or unregistered connections. Could cause
+ a crash when bad protocol was received.
+
+
+ Changes: Modified:
+ +5 -1 trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2006/04/19 03:44:55 UTC (20060419-1186)
+ Log:
+ - fix QJM buffer overflow vulnerability (fucking GXTi)
+
+
+ Changes: Modified:
+ +3 -3 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/04/18 23:28:33 UTC (20060418-1184)
+ Log:
+ Mention /scan umodes under oper_spy privilege.
+
+
+ Changes: Modified:
+ +3 -2 trunk/doc/sgml/oper-guide/oprivs.sgml (File Modified)
+
+
+jilles 2006/04/18 23:05:05 UTC (20060418-1182)
+ Log:
+ Mention that overlapping cluster blocks are a bad thing.
+
+
+ Changes: Modified:
+ +5 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/04/18 22:57:47 UTC (20060418-1180)
+ Log:
+ - Document cluster{} and shared{} blocks.
+ - Mention that service{} does not allow wildcards.
+
+
+ Changes: Modified:
+ +222 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/04/18 22:22:36 UTC (20060418-1178)
+ Log:
+ Document exempt{} and service{} blocks, point to reference.conf for
+ general{}, channel{} and serverhide{}.
+
+
+ Changes: Modified:
+ +88 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/04/18 22:02:17 UTC (20060418-1176)
+ Log:
+ Document ~ in lists of values better.
+
+
+ Changes: Modified:
+ +7 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/04/18 21:51:18 UTC (20060418-1174)
+ Log:
+ More detailed CNOTICE, CPRIVMSG descriptions.
+
+
+ Changes: Modified:
+ +9 -0 trunk/doc/sgml/oper-guide/ucommands.sgml (File Modified)
+
+
+jilles 2006/04/18 13:49:18 UTC (20060418-1172)
+ Log:
+ Oops, need both Revision and Id on modules.
+
+
+ Changes: Modified:
+ + - trunk/modules/sno_routing.c (Property Modified)
+
+
+jilles 2006/04/17 22:26:12 UTC (20060417-1170)
+ Log:
+ Tweak header comment a bit (filename, Id).
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/sno_routing.c (File Modified) (Property Modified)
+
+
+jilles 2006/04/17 00:13:57 UTC (20060417-1166)
+ Log:
+ Add GLINE and UNGLINE.
+
+
+ Changes: Modified:
+ +40 -0 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/04/16 13:07:49 UTC (20060416-1156)
+ Log:
+ New configure with proper Id.
+
+
+ Changes: Modified:
+ +3 -1 trunk/configure (File Modified)
+
+
+jilles 2006/04/16 13:06:04 UTC (20060416-1154)
+ Log:
+ Change #include directives for in6addr_any, hopefully compiles better now.
+
+
+ Changes: Modified:
+ +3 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2006/04/09 20:20:32 UTC (20060409-1152)
+ Log:
+ Encourage putting actual administrative information
+ in the admin{} block.
+
+
+ Changes: Modified:
+ +3 -3 trunk/doc/example.conf (File Modified)
+
+
+gxti 2006/04/08 01:36:41 UTC (20060408-1150)
+ Log:
+ New auth{} flag need_sasl to reject connecting users who have not authenticated by the time they register.
+
+
+ Changes: Modified:
+ +9 -7 trunk/include/s_conf.h (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +10 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/04/07 22:52:35 UTC (20060407-1146)
+ Log:
+ - Change to glines = no in example confs
+ - Point to clustered/remote KLINE/UNKLINE in notices if glines
+ are disabled.
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/example.conf (File Modified)
+ +1 -1 trunk/doc/reference.conf (File Modified)
+ +2 -2 trunk/modules/m_gline.c (File Modified)
+
+
+nenolod 2006/04/06 13:35:20 UTC (20060406-1144)
+ Log:
+ - forward-port QJM fix from 1.1
+
+
+ Changes: Modified:
+ +2 -0 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/04/06 13:33:39 UTC (20060406-1142)
+ Log:
+ - add switch to configure to disable the block allocator
+
+
+ Changes: Modified:
+ +18 -0 trunk/configure (File Modified)
+ +9 -0 trunk/configure.ac (File Modified)
+ +0 -6 trunk/include/config.h (File Modified)
+ +3 -0 trunk/include/setup.h.in (File Modified)
+
+
+gxti 2006/04/02 08:30:17 UTC (20060402-1118)
+ Log:
+ Fix wierd error that would exit SASL users with "Overridden"
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/03/30 10:11:21 UTC (20060330-1116)
+ Log:
+ Remove obsolete XXX comment about lazylinks.
+
+
+ Changes: Modified:
+ +0 -3 trunk/contrib/m_ojoin.c (File Modified)
+
+
+jilles 2006/03/30 02:22:18 UTC (20060330-1114)
+ Log:
+ OJOIN: make sure to send the wallops remotely for #channels
+
+
+ Changes: Modified:
+ +5 -0 trunk/contrib/m_ojoin.c (File Modified)
+
+
+gxti 2006/03/30 02:14:42 UTC (20060330-1112)
+ Log:
+ Accountability for OJOIN (contrib module)
+
+ Changes: Modified:
+ +6 -0 trunk/contrib/m_ojoin.c (File Modified)
+
+
+nenolod 2006/03/29 22:55:25 UTC (20060329-1110)
+ Log:
+ - move more stuff over to ircd_state
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/linebuf.c (File Modified)
+ +1 -1 trunk/libcharybdis/tools.c (File Modified)
+ +9 -0 trunk/src/ircd_state.c (File Modified)
+ +3 -3 trunk/src/patricia.c (File Modified)
+
+
+nenolod 2006/03/29 22:49:53 UTC (20060329-1108)
+ Log:
+ - move more stuff out of libircd and into ircd_state.c
+
+
+ Changes: Modified:
+ +5 -5 trunk/src/channel.c (File Modified)
+ +4 -4 trunk/src/client.c (File Modified)
+ +12 -0 trunk/src/ircd_state.c (File Modified)
+
+
+nenolod 2006/03/29 22:46:12 UTC (20060329-1106)
+ Log:
+ - this is just barrels of fun
+
+
+ Changes: Modified:
+ + - trunk/include/ircd_state.h (File Added)
+ +1 -1 trunk/src/Makefile.in (File Modified)
+ +2 -1 trunk/src/channel.c (File Modified)
+ +3 -52 trunk/src/ircd.c (File Modified)
+ +100 -3 trunk/src/ircd_state.c (File Modified)
+
+
+jilles 2006/03/26 22:51:26 UTC (20060326-1100)
+ Log:
+ It's .include, not #include.
+
+
+ Changes: Modified:
+ +3 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/03/26 22:35:04 UTC (20060326-1098)
+ Log:
+ More consistent section titles.
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+ +8 -6 trunk/doc/sgml/oper-guide/snomasks.sgml (File Modified)
+ +5 -5 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/03/23 11:15:26 UTC (20060323-1096)
+ Log:
+ Mention possible exceeding of +j/+l due to propagation
+ delays between servers.
+
+
+ Changes: Modified:
+ +8 -0 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+jilles 2006/03/23 11:04:43 UTC (20060323-1094)
+ Log:
+ Formatting nits:
+ - "text" -> <quote>text</quote>
+ - <filename>
+ - a few more
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+ +19 -19 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+ +1 -1 trunk/doc/sgml/oper-guide/snomasks.sgml (File Modified)
+ +1 -1 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/03/23 01:23:57 UTC (20060323-1092)
+ Log:
+ Remove text about deprecation of glines.
+
+
+ Changes: Modified:
+ +0 -4 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/03/23 00:20:59 UTC (20060323-1090)
+ Log:
+ - Add description of umode +D, deaf.
+ - Mention CALLERID 005 token with umode +g.
+
+
+ Changes: Modified:
+ +24 -0 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/03/19 15:57:54 UTC (20060319-1088)
+ Log:
+ Strip off a leading colon in services shortcuts (aliases).
+
+
+ Changes: Modified:
+ +2 -0 trunk/src/parse.c (File Modified)
+
+
+jilles 2006/03/17 23:20:30 UTC (20060317-1086)
+ Log:
+ Add no_oper_invis contrib module, denies opers setting
+ themselves invisible (except hidden_oper's).
+
+
+ Changes: Modified:
+ +42 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/no_oper_invis.c (File Added)
+
+
+jilles 2006/03/17 21:02:06 UTC (20060317-1084)
+ Log:
+ Mention /stats E, make the other /stats descriptions more consistent.
+
+
+ Changes: Modified:
+ +13 -7 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/03/17 18:01:32 UTC (20060317-1082)
+ Log:
+ Mention that the KILL reason and oper will appear on channels.
+
+
+ Changes: Modified:
+ +3 -0 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/03/17 15:49:35 UTC (20060317-1080)
+ Log:
+ Mention /mode #channel f to query forward channel from outside.
+
+
+ Changes: Modified:
+ +4 -0 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+jilles 2006/03/17 15:13:00 UTC (20060317-1074)
+ Log:
+ Port over RATBOX_2_1 r20960 (anfl):
+ client connect notices to +C should be hiding the extra
+ fields for spoofed users
+
+
+ Changes: Modified:
+ +2 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/03/15 17:07:32 UTC (20060315-1072)
+ Log:
+ Add a chapter with our extra user commands:
+ ACCEPT, CNOTICE, CPRIVMSG, HELP, KNOCK, MONITOR.
+
+
+ Changes: Modified:
+ +181 -0 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ + - trunk/doc/sgml/oper-guide/ucommands.sgml (File Added)
+
+
+jilles 2006/03/15 14:31:14 UTC (20060315-1070)
+ Log:
+ Do not put by <server>: in SQUIT reasons to servers
+ other than the one being exited.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/client.c (File Modified)
+
+
+jilles 2006/03/14 19:16:18 UTC (20060314-1068)
+ Log:
+ Regenerate configure.
+
+
+ Changes: Modified:
+ +1162 -1159 trunk/configure (File Modified)
+
+
+jilles 2006/03/14 19:15:34 UTC (20060314-1066)
+ Log:
+ Move the warning flags down so they do not mess up
+ checks like for -Wl,-export-dynamic.
+
+
+ Changes: Modified:
+ +33 -30 trunk/configure.ac (File Modified)
+
+
+nenolod 2006/03/14 14:53:54 UTC (20060314-1064)
+ Log:
+ - more work here
+
+
+ Changes: Modified:
+ +2 -1 trunk/iauth/Makefile.in (File Modified)
+
+
+nenolod 2006/03/14 14:51:39 UTC (20060314-1062)
+ Log:
+ - build iauth makefile
+
+
+ Changes: Modified:
+ +3 -2 trunk/configure (File Modified)
+ +1 -0 trunk/configure.ac (File Modified)
+
+
+nenolod 2006/03/14 14:50:54 UTC (20060314-1060)
+ Log:
+ - Makefile
+
+
+ Changes: Modified:
+ + - trunk/iauth/Makefile.in (File Added)
+
+
+nenolod 2006/03/14 14:46:12 UTC (20060314-1058)
+ Log:
+ - add iauth.conf.example from irc2.11
+
+
+ Changes: Modified:
+ + - trunk/doc/example-iauth.conf (File Added)
+
+
+nenolod 2006/03/14 14:38:33 UTC (20060314-1056)
+ Log:
+ - wow, i found some docs on this thing
+
+
+ Changes: Modified:
+ + - trunk/doc/technical/iauth-internals.txt (File Added)
+
+
+nenolod 2006/03/14 14:36:46 UTC (20060314-1054)
+ Log:
+ - no longer applicable
+
+
+ Changes: Modified:
+ + - trunk/authdaemon/ (File Deleted)
+
+
+nenolod 2006/03/14 14:27:52 UTC (20060314-1052)
+ Log:
+ - remove libircd.so on make clean (oops)
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/Makefile.in (File Modified)
+
+
+nenolod 2006/03/14 14:25:50 UTC (20060314-1050)
+ Log:
+ - merge iauth source for experimentation
+
+
+ Changes: Modified:
+ + - trunk/iauth/ (File Added)
+ + - trunk/iauth/a_conf.c (File Added)
+ + - trunk/iauth/a_conf_def.h (File Added)
+ + - trunk/iauth/a_conf_ext.h (File Added)
+ + - trunk/iauth/a_defines.h (File Added)
+ + - trunk/iauth/a_externs.h (File Added)
+ + - trunk/iauth/a_io.c (File Added)
+ + - trunk/iauth/a_io_ext.h (File Added)
+ + - trunk/iauth/a_log.c (File Added)
+ + - trunk/iauth/a_log_def.h (File Added)
+ + - trunk/iauth/a_log_ext.h (File Added)
+ + - trunk/iauth/a_struct_def.h (File Added)
+ + - trunk/iauth/iauth.c (File Added)
+ + - trunk/iauth/mod_lhex.c (File Added)
+ + - trunk/iauth/mod_lhex_ext.h (File Added)
+ + - trunk/iauth/mod_pipe.c (File Added)
+ + - trunk/iauth/mod_pipe_ext.h (File Added)
+ + - trunk/iauth/mod_rfc931.c (File Added)
+ + - trunk/iauth/mod_rfc931_ext.h (File Added)
+ + - trunk/iauth/mod_socks.c (File Added)
+ + - trunk/iauth/mod_socks_ext.h (File Added)
+ + - trunk/iauth/mod_webproxy.c (File Added)
+ + - trunk/iauth/mod_webproxy_ext.h (File Added)
+
+
+jilles 2006/03/12 16:05:39 UTC (20060312-1044)
+ Log:
+ User /quote help index was not sorted properly.
+
+
+ Changes: Modified:
+ +2 -2 trunk/help/Makefile.in (File Modified)
+ +8 -8 trunk/help/users/index (File Modified)
+
+
+jilles 2006/03/12 15:57:27 UTC (20060312-1038)
+ Log:
+ Add SCAN help file.
+
+
+ Changes: Modified:
+ +25 -8 trunk/help/opers/index (File Modified)
+ + - trunk/help/opers/scan (File Added)
+
+
+jilles 2006/03/12 15:27:06 UTC (20060312-1032)
+ Log:
+ SGML docs:
+ - Document SCAN UMODES
+ - Add details about the IP address field in MASKTRACE/CHANTRACE/SCAN UMODES
+
+
+ Changes: Modified:
+ +41 -0 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/03/10 15:28:58 UTC (20060310-1028)
+ Log:
+ Add our copyright information to /info (part of release-1.1 r1026).
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/version.c.SH (File Modified)
+
+
+jilles 2006/03/10 00:16:30 UTC (20060310-1020)
+ Log:
+ Fix some compile warnings.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_join.c (File Modified)
+ +2 -2 trunk/modules/core/m_nick.c (File Modified)
+ +0 -1 trunk/modules/core/m_sjoin.c (File Modified)
+ +1 -1 trunk/modules/m_scan.c (File Modified)
+ +4 -4 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/03/09 15:54:20 UTC (20060309-1012)
+ Log:
+ RSFNC: OK, actually consider unknowns also for detecting a collide.
+ Otherwise we can get two clients with the same nick.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2006/03/09 15:32:14 UTC (20060309-1006)
+ Log:
+ - charybdis profiling stuff
+ - move all channel mode logic into src/chmode.c from modules/core/m_mode.c
+ - update .depend
+
+
+ Changes: Modified:
+ +0 -8 trunk/configure (File Modified)
+ +1 -8 trunk/configure.ac (File Modified)
+ +18 -0 trunk/include/channel.h (File Modified)
+ +0 -1322 trunk/modules/core/m_mode.c (File Modified)
+ +335 -260 trunk/src/.depend (File Modified)
+ +1569 -0 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/chmode.c (File Added)
+ +16 -1 trunk/src/ircd.c (File Modified)
+ +11 -0 trunk/src/main.c (File Modified)
+ +11 -0 trunk/src/modules.c (File Modified)
+
+
+jilles 2006/03/09 14:33:38 UTC (20060309-1004)
+ Log:
+ RSFNC: Do not send kills to servers for unknowns
+
+
+ Changes: Modified:
+ +4 -2 trunk/modules/m_services.c (File Modified)
+
+
+jilles 2006/03/09 14:25:01 UTC (20060309-1002)
+ Log:
+ Describe service{} blocks in reference.conf.
+
+
+ Changes: Modified:
+ +12 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/03/09 01:14:34 UTC (20060309-996)
+ Log:
+ Replace this list of modes with pointers to other documentation.
+
+
+ Changes: Modified:
+ +6 -50 trunk/doc/modes.txt (File Modified)
+
+
+jilles 2006/03/08 00:10:46 UTC (20060308-986)
+ Log:
+ Name the variable for the channel pointer 'chptr' instead of 'cptr',
+ looks too much like an old-ircd client pointer otherwise.
+
+
+ Changes: Modified:
+ +7 -7 trunk/contrib/m_findforwards.c (File Modified)
+
+
+jilles 2006/03/08 00:09:27 UTC (20060308-984)
+ Log:
+ findforwards:
+ - note truncation of the list (perhaps sending multiple
+ notices is better)
+ - clarify in a comment that /findforwards on a nonexistent
+ channel can be useful
+ - sendto_one_notice() requires that the text start with
+ a colon
+
+
+ Changes: Modified:
+ +9 -3 trunk/contrib/m_findforwards.c (File Modified)
+
+
+jilles 2006/03/07 23:33:48 UTC (20060307-982)
+ Log:
+ When we close a local server's link, always include the
+ name of the client causing the exit in the reason in the
+ SQUIT we send them (replacing them with us). This makes
+ sure server notices for stuff like "Not enough arguments
+ to server command" are different on the two sides.
+
+
+ Changes: Modified:
+ +7 -5 trunk/src/client.c (File Modified)
+
+
+gxti 2006/03/07 22:58:03 UTC (20060307-980)
+ Log:
+ New contrib module m_findforwards.c
+
+
+ Changes: Modified:
+ +112 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/m_findforwards.c (File Added)
+
+
+jilles 2006/03/07 22:21:29 UTC (20060307-968)
+ Log:
+ Whoops, don't show real host behind auth{} spoof in
+ spoof notices if hide_spoof_ips is enabled.
+
+ From ratbox (part of initial HIDE_SPOOF_IPS to conf patch)
+
+
+ Changes: Modified:
+ +3 -2 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/03/07 12:54:53 UTC (20060307-962)
+ Log:
+ Add dalnet-style /identify that sends to nickserv or chanserv.
+
+
+ Changes: Modified:
+ +102 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/m_identify.c (File Added)
+
+
+jilles 2006/03/07 12:26:20 UTC (20060307-958)
+ Log:
+ Document alias{} blocks a bit better.
+
+
+ Changes: Modified:
+ +9 -0 trunk/doc/reference.conf (File Modified)
+
+
+nenolod 2006/03/06 04:01:20 UTC (20060306-948)
+ Log:
+ - add aliases to /stats m (data usage is not counted though, sorry)
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +3 -0 trunk/src/newconf.c (File Modified)
+ +15 -0 trunk/src/parse.c (File Modified)
+
+
+nenolod 2006/03/06 03:43:02 UTC (20060306-946)
+ Log:
+ - remove m_sshortcut as it's no longer relevant
+
+
+ Changes: Modified:
+ +0 -145 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/m_sshortcut.c (File Deleted)
+
+
+nenolod 2006/03/06 03:41:31 UTC (20060306-944)
+ Log:
+ - support for aliases, needs some more work before it can be backported to the 1.2 branch (jilles changed this to use
+ targets instead of my original idea :P)
+
+
+ Changes: Modified:
+ +32 -0 trunk/doc/example.conf (File Modified)
+ +35 -0 trunk/doc/reference.conf (File Modified)
+ +4 -0 trunk/include/parse.h (File Modified)
+ +7 -0 trunk/include/s_conf.h (File Modified)
+ +82 -0 trunk/src/newconf.c (File Modified)
+ +78 -0 trunk/src/parse.c (File Modified)
+ +16 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/03/05 23:33:56 UTC (20060305-942)
+ Log:
+ Remove some spaces after tabs. ??
+
+
+ Changes: Modified:
+ +18 -18 trunk/src/newconf.c (File Modified)
+
+
+jilles 2006/03/05 23:15:38 UTC (20060305-940)
+ Log:
+ Global /who:
+ - make sure to clear all marks also if the who was aborted
+ because of too many matches
+ - give ERR_TOOMANYMATCHES if too many matches
+ - clarify comments
+
+ ratbox RATBOX_2_2 r22003 (jilles)
+
+
+ Changes: Modified:
+ +28 -26 trunk/modules/m_who.c (File Modified)
+
+
+nenolod 2006/03/05 09:45:50 UTC (20060305-936)
+ Log:
+ - devel is 2.0
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+nenolod 2006/03/05 03:39:14 UTC (20060305-932)
+ Log:
+ - add /rehash nickdelay to clear out the nickdelay tables (hack hack!)
+
+
+ Changes: Modified:
+ +2 -1 trunk/include/s_newconf.h (File Modified)
+ +20 -0 trunk/modules/m_rehash.c (File Modified)
+ +1 -1 trunk/src/s_newconf.c (File Modified)
+
+
+gxti 2006/03/05 03:38:33 UTC (20060305-930)
+ Log:
+ Pull quiet_on_ban from the config as only people who can't configure their ircd properly turn this off.
+
+
+ Changes: Modified:
+ +0 -1 trunk/doc/example.conf (File Modified)
+ +0 -3 trunk/doc/reference.conf (File Modified)
+ +0 -1 trunk/include/s_conf.h (File Modified)
+ +0 -6 trunk/modules/m_info.c (File Modified)
+ +1 -1 trunk/src/channel.c (File Modified)
+ +0 -1 trunk/src/newconf.c (File Modified)
+
+
+gxti 2006/03/05 00:48:56 UTC (20060305-928)
+ Log:
+ Missing header in m_chghost.c
+
+ Changes: Modified:
+ +1 -0 trunk/modules/m_chghost.c (File Modified)
+
+
+gxti 2006/02/28 19:53:33 UTC (20060228-926)
+ Log:
+ Relocate QJM code to a seperate function(change_nick_user_host)
+ Change CHGHOST to use change_nick_user_host instead of just setting it
+
+
+ Changes: Modified:
+ +3 -0 trunk/include/s_user.h (File Modified)
+ +1 -1 trunk/modules/m_chghost.c (File Modified)
+ +3 -78 trunk/modules/m_signon.c (File Modified)
+ +89 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/02/28 13:24:51 UTC (20060228-924)
+ Log:
+ Restore /stats a (dns servers, admin-only).
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/res.h (File Modified)
+ +5 -8 trunk/modules/m_stats.c (File Modified)
+ +16 -0 trunk/src/res.c (File Modified)
+
+
+nenolod 2006/02/23 18:29:24 UTC (20060223-920)
+ Log:
+ - Add CHARYBDIS_PROFILE if we are profiling.
+ - Remove -static from CFLAGS when profiling because this is really unnecessary.
+ - Remove duplicate --enable-epoll entry.
+
+
+ Changes: Modified:
+ +1595 -15 trunk/configure (File Modified)
+ +30 -11 trunk/configure.ac (File Modified)
+ +3 -0 trunk/include/setup.h.in (File Modified)
+
+
+nenolod 2006/02/23 18:17:21 UTC (20060223-918)
+ Log:
+ - Add CHARYBDIS_C_GCC_TRY_FLAGS. Guess where this is from. Just guess.
+
+
+ Changes: Modified:
+ +28 -0 trunk/aclocal.m4 (File Modified)
+
+
+jilles 2006/02/23 13:25:48 UTC (20060223-916)
+ Log:
+ Allow requesting forward channel and quiet list in same mode command.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_mode.c (File Modified)
+
+
+jilles 2006/02/22 00:06:41 UTC (20060222-912)
+ Log:
+ Add description of xline wildcards.
+
+
+ Changes: Modified:
+ +14 -3 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+gxti 2006/02/21 23:54:57 UTC (20060221-908)
+ Log:
+ Stop throwing out LOGIN from non-bursting servers as this interferes with SASL.
+
+
+ Changes: Modified:
+ +0 -4 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2006/02/21 02:25:43 UTC (20060221-906)
+ Log:
+ typo
+
+
+ Changes: Modified:
+ +1 -1 trunk/include/hook.h (File Modified)
+
+
+nenolod 2006/02/20 22:34:50 UTC (20060220-904)
+ Log:
+ call_hook, not hook_call
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2006/02/20 22:05:41 UTC (20060220-902)
+ Log:
+ Add h_channel_join, a hook that's fired (for modules) when a channel is joined.
+ Could be useful for a number of things.
+
+
+ Changes: Modified:
+ +9 -0 trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2006/02/20 21:35:40 UTC (20060220-900)
+ Log:
+ New type: hook_data_channel_activity, used primarily for joins and parts from a channel.
+
+
+ Changes: Modified:
+ +7 -0 trunk/include/hook.h (File Modified)
+
+
+gxti 2006/02/20 21:27:46 UTC (20060220-896)
+ Log:
+ Burst LOGIN on registration if the user was already identified (i.e. from SIGNON)
+
+
+ Changes: Modified:
+ +15 -0 trunk/modules/m_services.c (File Modified)
+
+
+jilles 2006/02/20 11:26:45 UTC (20060220-894)
+ Log:
+ Clarify snomask +f, +k, +u.
+
+
+ Changes: Modified:
+ +8 -4 trunk/doc/sgml/oper-guide/snomasks.sgml (File Modified)
+
+
+jilles 2006/02/20 11:26:22 UTC (20060220-892)
+ Log:
+ Cmode +p and +s may be set simultaneously.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+nenolod 2006/02/20 05:20:38 UTC (20060220-890)
+ Log:
+ actually, we should check the data version on each reload (oops)
+
+
+ Changes: Modified:
+ +6 -6 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/20 05:17:22 UTC (20060220-888)
+ Log:
+ more work on the loader
+
+
+ Changes: Modified:
+ +45 -21 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/20 04:04:42 UTC (20060220-886)
+ Log:
+ Add prototype ircd_state.c
+
+
+ Changes: Modified:
+ + - trunk/src/ircd_state.c (File Added)
+
+
+jilles 2006/02/19 00:41:15 UTC (20060219-882)
+ Log:
+ Smaller improvements.
+
+
+ Changes: Modified:
+ +18 -8 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/02/19 00:15:39 UTC (20060219-880)
+ Log:
+ Add a lot of stuff here.
+
+
+ Changes: Modified:
+ +210 -16 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/02/18 22:55:32 UTC (20060218-878)
+ Log:
+ Add +o, +t and +v cmodes and add a lot of information to other cmodes.
+
+
+ Changes: Modified:
+ +81 -10 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+jilles 2006/02/18 21:57:54 UTC (20060218-873)
+ Log:
+ Invex doesn't trump +r or (sic) +J.
+
+
+ Changes: Modified:
+ +0 -2 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+nenolod 2006/02/18 21:56:00 UTC (20060218-871)
+ Log:
+ Check to make sure a module is not loaded before loading it.
+
+
+ Changes: Modified:
+ +6 -1 trunk/src/ircd_parser.y (File Modified)
+
+
+nenolod 2006/02/16 18:54:16 UTC (20060216-869)
+ Log:
+ - Add a missing comma in the HeaderMessages array
+ - Only send "Your hostname is too long ..." if that really is the case
+
+
+ Changes: Modified:
+ +2 -2 trunk/src/s_auth.c (File Modified)
+
+
+nenolod 2006/02/16 14:25:09 UTC (20060216-867)
+ Log:
+ build_symtable() will have already bailed here, so no need to check
+ explicitly whether or not charybdis_main is NULL.
+
+
+ Changes: Modified:
+ +7 -16 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/16 14:05:37 UTC (20060216-865)
+ Log:
+ Data structure versioning, part 1.
+
+
+ Changes: Modified:
+ +10 -1 trunk/include/ircd_defs.h (File Modified)
+ +2 -0 trunk/src/ircd.c (File Modified)
+ +15 -3 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/16 06:51:59 UTC (20060216-863)
+ Log:
+ build a symbol table and use that instead of doing a raw dlsym on everything
+
+
+ Changes: Modified:
+ + - trunk/include/ircd_linker.h (File Added)
+ +71 -1 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/ircd_linker.c (File Added)
+ +16 -4 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/15 23:15:08 UTC (20060215-861)
+ Log:
+ The launcher now calls io_loop() instead of charybdis_main().
+ This is so that we do not have to reinitialize *everything* later.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/ircd.h (File Modified)
+ +6 -7 trunk/src/ircd.c (File Modified)
+ +13 -1 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/15 23:05:22 UTC (20060215-859)
+ Log:
+ Use global binding on libircd.so.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/main.c (File Modified)
+
+
+nenolod 2006/02/15 22:49:16 UTC (20060215-857)
+ Log:
+ - most of the IRCd is now a shared library, ircd is just a launcher that opens libircd.so and runs it now.
+ (it will do more later)
+
+
+ Changes: Modified:
+ +14 -12 trunk/include/config.h (File Modified)
+ +1 -1 trunk/libcharybdis/Makefile.in (File Modified)
+ +31 -5 trunk/src/Makefile.in (File Modified)
+ +78 -1 trunk/src/ircd.c (File Modified)
+ + - trunk/src/main.c (File Added)
+
+
+nenolod 2006/02/15 03:27:43 UTC (20060215-855)
+ Log:
+ Add whitespace here, oops.
+
+
+ Changes: Modified:
+ +1 -1 trunk/CREDITS (File Modified)
+
+
+nenolod 2006/02/15 01:34:19 UTC (20060215-851)
+ Log:
+ Properly copy over the IP address here instead of using a cheap hack.
+ Because the hack didn't work right except on IPv6. :|
+
+
+ Changes: Modified:
+ +12 -2 trunk/src/s_newconf.c (File Modified)
+
+
+jilles 2006/02/15 01:33:43 UTC (20060215-849)
+ Log:
+ Revert reject cache notice to ratbox's, which more
+ clearly suggests what's happening.
+
+
+ Changes: Modified:
+ +4 -1 trunk/src/reject.c (File Modified)
+
+
+nenolod 2006/02/15 01:30:41 UTC (20060215-847)
+ Log:
+ Fix the openssl status in the overview information.
+
+
+ Changes: Modified:
+ +1 -3 trunk/configure (File Modified)
+ +1 -3 trunk/configure.ac (File Modified)
+
+
+jilles 2006/02/15 00:53:32 UTC (20060215-843)
+ Log:
+ - Add simple exempt{} block (127.0.0.1) to example.conf.
+ - Remove mention of deny{}.
+
+
+ Changes: Modified:
+ +5 -0 trunk/doc/example.conf (File Modified)
+ +1 -1 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/15 00:37:34 UTC (20060215-839)
+ Log:
+ example.conf: add some comments at the start
+ reference.conf: some ircd-ratbox -> charybdis
+
+
+ Changes: Modified:
+ +11 -0 trunk/doc/example.conf (File Modified)
+ +6 -5 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/15 00:27:59 UTC (20060215-833)
+ Log:
+ Rename m_createauthonly module to createauthonly
+ as this is not a module providing an m_function
+ (command).
+
+
+ Changes: Modified:
+ +1 -38 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/createauthonly.c (File Added)
+ + - trunk/contrib/m_createauthonly.c (File Deleted)
+
+
+jilles 2006/02/15 00:22:08 UTC (20060215-831)
+ Log:
+ Add to example confs commented lines for:
+ createauthonly.so, ip_cloaking.so, sno_farconnect.so,
+ sno_globalkline.so, sno_globaloper.so.
+
+
+ Changes: Modified:
+ +5 -1 trunk/doc/example.conf (File Modified)
+ +9 -1 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/15 00:12:24 UTC (20060215-829)
+ Log:
+ - Unbreak connecting to connect{}s with hostnames
+ instead of IP addresses (broken with new resolver).
+ - Try to do A/AAAA query based on aftype in
+ connect{} (doesn't seem to work fully).
+
+
+ Changes: Modified:
+ +19 -2 trunk/libcharybdis/commio.c (File Modified)
+
+
+jilles 2006/02/14 22:54:37 UTC (20060214-827)
+ Log:
+ Unbreak /rehash dns.
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/res.c (File Modified)
+
+
+jilles 2006/02/14 22:40:55 UTC (20060214-825)
+ Log:
+ Preserve Hybrid Id and add one of our own.
+
+
+ Changes: Modified:
+ +2 -1 trunk/src/res.c (File Modified) (Property Modified)
+ +2 -1 trunk/src/reslib.c (File Modified) (Property Modified)
+
+
+jilles 2006/02/14 22:17:17 UTC (20060214-821)
+ Log:
+ Add anfl and Androsyn to CREDITS.
+ They wrote a lot of ratbox code we use, both before and after the fork.
+
+
+ Changes: Modified:
+ +2 -0 trunk/CREDITS (File Modified)
+
+
+nenolod 2006/02/14 21:39:42 UTC (20060214-819)
+ Log:
+ Hostname validity check.
+
+
+ Changes: Modified:
+ +42 -3 trunk/src/s_auth.c (File Modified)
+
+
+nenolod 2006/02/14 21:02:12 UTC (20060214-817)
+ Log:
+ Version bump to 1.2.0.
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+nenolod 2006/02/14 20:55:24 UTC (20060214-815)
+ Log:
+ - Missed a spot in the IPv6 code here. Should be usable now.
+
+
+ Changes: Modified:
+ +2 -2 trunk/src/res.c (File Modified)
+
+
+nenolod 2006/02/14 20:52:15 UTC (20060214-813)
+ Log:
+ Alright, so, this massive commit does the following:
+ - Removes adns
+ - Adds a resolver based on the undernet and hybrid one.
+ - Tries to clean up a giant mess in the header dependencies (encountered during the above)
+ - Makes a check in ./configure be posixly correct
+ - Simplifies the auth code and DNS callbacks
+
+ Needs testing. Especially under IPv6. I probably fucked something up there. I will test it later.
+
+
+ Changes: Modified:
+ +1 -1 trunk/Makefile.in (File Modified)
+ + - trunk/adns/ (File Deleted)
+ +148 -80 trunk/configure (File Modified)
+ +1 -2 trunk/configure.ac (File Modified)
+ +6 -0 trunk/include/client.h (File Modified)
+ +1 -0 trunk/include/packet.h (File Modified)
+ +153 -41 trunk/include/res.h (File Modified)
+ + - trunk/include/reslib.h (File Added)
+ +4 -33 trunk/libcharybdis/commio.c (File Modified)
+ +930 -1449 trunk/modules/.depend (File Modified)
+ +3 -0 trunk/modules/m_stats.c (File Modified)
+ +417 -621 trunk/src/.depend (File Modified)
+ +1 -1 trunk/src/.indent.pro (File Modified)
+ +2069 -289 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/adns.c (File Deleted)
+ + - trunk/src/res.c (File Added)
+ + - trunk/src/reslib.c (File Added)
+ +11 -50 trunk/src/s_auth.c (File Modified)
+ +4 -26 trunk/src/s_newconf.c (File Modified)
+
+
+nenolod 2006/02/13 20:14:51 UTC (20060213-811)
+ Log:
+ Document the NOBALLOC feature.
+
+
+ Changes: Modified:
+ +7 -1 trunk/include/config.h (File Modified)
+
+
+jilles 2006/02/12 20:50:51 UTC (20060212-806)
+ Log:
+ commands.sgml changes
+
+
+ Changes: Modified:
+ +126 -51 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2006/02/12 19:58:28 UTC (20060212-804)
+ Log:
+ connect{} changes.
+
+
+ Changes: Modified:
+ +11 -4 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 19:47:43 UTC (20060212-802)
+ Log:
+ Improve description of class{} block (in particular,
+ mention server classes as well as client classes).
+
+
+ Changes: Modified:
+ +41 -3 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 19:37:35 UTC (20060212-800)
+ Log:
+ In comment:
+ -/* sendq: servers need a higher sendq as they send more data */
+ +/* sendq: servers need a higher sendq as they are sent more data */
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/12 19:33:35 UTC (20060212-798)
+ Log:
+ Add modules{} block.
+
+
+ Changes: Modified:
+ +28 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 17:31:44 UTC (20060212-796)
+ Log:
+ Add general::oper_snomask, snomask on oper up for opers
+ that have umode +s set on oper up, but do not have
+ a specific snomask setting in their operator block.
+ If this is empty or not specified, +s is used as before.
+
+
+ Changes: Modified:
+ +4 -1 trunk/doc/example.conf (File Modified)
+ +7 -1 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/client.h (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +32 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+ +13 -3 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/02/12 07:27:54 UTC (20060212-794)
+ Log:
+ fix error
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+nenolod 2006/02/12 07:13:38 UTC (20060212-792)
+ Log:
+ Add MASKTRACE and CHANTRACE commands.
+
+
+ Changes: Modified:
+ +23 -5 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+nenolod 2006/02/12 06:39:51 UTC (20060212-790)
+ Log:
+ document loadmodule directive
+
+
+ Changes: Modified:
+ +12 -3 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 06:36:19 UTC (20060212-788)
+ Log:
+ finish this up
+
+
+ Changes: Modified:
+ +29 -3 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 06:29:55 UTC (20060212-786)
+ Log:
+ q:lines are no longer living in the ircd.conf either
+
+
+ Changes: Modified:
+ +0 -8 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 04:28:54 UTC (20060212-784)
+ Log:
+ remove k:line, d:line, x:line as they are their own files now
+
+
+ Changes: Modified:
+ +0 -29 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 03:55:38 UTC (20060212-782)
+ Log:
+ New place for operator::snomask.
+
+
+ Changes: Modified:
+ +9 -9 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:46:29 UTC (20060212-780)
+ Log:
+ Document connect {}.
+
+
+ Changes: Modified:
+ +101 -20 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 03:42:26 UTC (20060212-778)
+ Log:
+ example.conf: move operator::snomask to a more logical place,
+ more sensible default
+ reference.conf: add operator::snomask
+
+
+ Changes: Modified:
+ +3 -3 trunk/doc/example.conf (File Modified)
+ +3 -0 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/12 03:34:24 UTC (20060212-776)
+ Log:
+ Allow specifying +D (deaf), +Q (noforward) and +R (regonlymsg)
+ in those conf entries that take umodes like <name1>, <name2>, ...
+
+
+ Changes: Modified:
+ +3 -0 trunk/doc/reference.conf (File Modified)
+ +3 -0 trunk/src/newconf.c (File Modified)
+
+
+nenolod 2006/02/12 03:33:02 UTC (20060212-774)
+ Log:
+ Remove H:line
+
+
+ Changes: Modified:
+ +0 -7 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:30:32 UTC (20060212-772)
+ Log:
+ Aesthetic changes.
+
+
+ Changes: Modified:
+ +2 -0 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:28:34 UTC (20060212-770)
+ Log:
+ s/allow/auth
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:26:36 UTC (20060212-768)
+ Log:
+ fix
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:25:40 UTC (20060212-766)
+ Log:
+ Document operator {} blocks.
+
+
+ Changes: Modified:
+ +65 -17 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 03:18:31 UTC (20060212-764)
+ Log:
+ auth{}: clarify/add some details
+
+
+ Changes: Modified:
+ +14 -7 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:11:11 UTC (20060212-762)
+ Log:
+ auth{}: Move a paragraph.
+
+
+ Changes: Modified:
+ +3 -3 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+nenolod 2006/02/12 03:02:10 UTC (20060212-760)
+ Log:
+ Document auth{} blocks.
+
+
+ Changes: Modified:
+ +107 -43 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2006/02/12 02:23:21 UTC (20060212-758)
+ Log:
+ Add umode +R.
+
+
+ Changes: Modified:
+ +2 -1 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/02/12 02:19:41 UTC (20060212-756)
+ Log:
+ Add umode +R, prevents unidentified clients from
+ sending private messages or notices. /accept'ed
+ clients and opers are exempt.
+ Due to the /accept part, this is only checked
+ at the target's server, may want to change
+ this?
+
+
+ Changes: Modified:
+ +1 -0 trunk/help/opers/umode (File Modified)
+ +1 -0 trunk/help/users/umode (File Modified)
+ +2 -0 trunk/include/client.h (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +11 -1 trunk/modules/core/m_message.c (File Modified)
+ +9 -1 trunk/modules/m_cmessage.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/02/12 01:26:44 UTC (20060212-754)
+ Log:
+ Don't allow a nick change if banned or quieted (and not
+ voiced or opped) on a channel. This uses numeric 435
+ (bahamut's "cannot change to a banned nick") because
+ bahamut/ircu's 437 and hyperion's 438 already have
+ another meaning for us.
+
+
+ Changes: Modified:
+ +2 -0 trunk/include/channel.h (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +9 -0 trunk/modules/core/m_nick.c (File Modified)
+ +38 -0 trunk/src/channel.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+
+
+jilles 2006/02/11 20:55:03 UTC (20060211-752)
+ Log:
+ KNOCK:
+ - respect ban exceptions
+ - also deny a knock if quieted
+
+
+ Changes: Modified:
+ +2 -1 trunk/modules/m_knock.c (File Modified)
+
+
+jilles 2006/02/11 19:42:32 UTC (20060211-750)
+ Log:
+ Reverse bad substitution in comment.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/channel.c (File Modified)
+
+
+jilles 2006/02/11 19:04:47 UTC (20060211-748)
+ Log:
+ - set DynSpoof flag for clients spoofed at registration
+ - add orighost instead of host to the hostname hash
+
+
+ Changes: Modified:
+ +5 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/02/11 16:59:13 UTC (20060211-746)
+ Log:
+ sendto_common_channels_local_butone(): nicer way to skip the user themselves.
+
+
+ Changes: Modified:
+ +2 -3 trunk/src/send.c (File Modified)
+
+
+gxti 2006/02/10 02:44:34 UTC (20060210-744)
+ Log:
+ Change login field semantics in SVSLOGIN/SIGNON to allow both no-change and logout.
+
+
+ Changes: Modified:
+ +17 -7 trunk/modules/m_signon.c (File Modified)
+
+
+gxti 2006/02/09 02:44:48 UTC (20060209-742)
+ Log:
+ Correct minimum args on ENCAP SASL to avoid nasty core.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_sasl.c (File Modified)
+
+
+jilles 2006/02/09 01:14:21 UTC (20060209-740)
+ Log:
+ Style nits: sptr can't ever be NULL, don't compare truth
+ values with YES.
+
+
+ Changes: Modified:
+ +2 -3 trunk/modules/m_scan.c (File Modified)
+
+
+jilles 2006/02/09 01:04:56 UTC (20060209-738)
+ Log:
+ - Comment out scan_cmodes() prototype to suppress warning
+ - Correct minimum parameter count for mo_scan()
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_scan.c (File Modified)
+
+
+jilles 2006/02/09 00:56:16 UTC (20060209-736)
+ Log:
+ SCAN UMODES:
+ - Include full command in operspy notice
+ - Allow global scans (no-list used, mask not used) without operspy
+ - Use ERR_NOPRIVS numeric
+
+
+ Changes: Modified:
+ +21 -9 trunk/modules/m_scan.c (File Modified)
+
+
+jilles 2006/02/08 23:45:23 UTC (20060208-734)
+ Log:
+ Cancel out the >3 default if < is given; this way
+ any </> specification fully overrides the default.
+
+
+ Changes: Modified:
+ +3 -0 trunk/modules/m_list_safelist.c (File Modified)
+
+
+jilles 2006/02/08 23:13:44 UTC (20060208-732)
+ Log:
+ - Call mo_list() from m_list() to reduce code duplication
+ - Default to >3, rather arbitrarily (conf option?)
+ - Make < and > mean less than and greater than again
+
+
+ Changes: Modified:
+ +16 -47 trunk/modules/m_list_safelist.c (File Modified)
+
+
+jilles 2006/02/08 22:20:43 UTC (20060208-730)
+ Log:
+ When processing topic burst, hide connecting server
+ on netburst if flatten links is enabled.
+
+
+ Changes: Modified:
+ +9 -2 trunk/modules/m_tb.c (File Modified)
+
+
+nenolod 2006/02/08 22:03:57 UTC (20060208-728)
+ Log:
+ - remove PENALTY token
+
+
+ Changes: Modified:
+ +0 -1 trunk/include/supported.h (File Modified)
+
+
+nenolod 2006/02/08 22:00:03 UTC (20060208-726)
+ Log:
+ 005 fixups:
+ - Add PENALTY because we have a pace-wait system.
+ - Add FNC due to SAVE and RSFNC
+ - Add q to MAXLIST.
+
+
+ Changes: Modified:
+ +4 -2 trunk/include/supported.h (File Modified)
+
+
+nenolod 2006/02/08 21:55:57 UTC (20060208-724)
+ Log:
+ mkay, indent went nuts here
+
+
+ Changes: Modified:
+ +4 -6 trunk/modules/m_list_safelist.c (File Modified)
+
+
+nenolod 2006/02/08 21:51:28 UTC (20060208-722)
+ Log:
+ Implement SAFELIST. The old ratbox method is now called m_list_ratbox.c,
+ and can be used instead. The SAFELIST implementation is the one used by
+ default, as most users/networks will be used to it.
+
+
+ Changes: Modified:
+ +1 -0 trunk/NEWS (File Modified)
+ +14 -0 trunk/include/client.h (File Modified)
+ +5 -0 trunk/include/hash.h (File Modified)
+ +404 -272 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/m_list.c (File Deleted)
+ + - trunk/modules/m_list_ratbox.c (File Added)
+ + - trunk/modules/m_list_safelist.c (File Added)
+ +5 -5 trunk/src/hash.c (File Modified)
+
+
+jilles 2006/02/08 21:02:52 UTC (20060208-720)
+ Log:
+ Clear invites on a lowerTS JOIN or SJOIN.
+ This should complete kick_on_split_riding protection.
+
+
+ Changes: Modified:
+ +5 -0 trunk/modules/core/m_join.c (File Modified)
+ +5 -1 trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2006/02/08 20:26:58 UTC (20060208-718)
+ Log:
+ Like in ratbox, send and interpret timestamps on invites.
+
+
+ Changes: Modified:
+ +9 -2 trunk/modules/m_invite.c (File Modified)
+
+
+jilles 2006/02/07 12:48:28 UTC (20060207-716)
+ Log:
+ Add +S (network service) umode. Just for completeness, users or opers
+ cannot set this.
+
+
+ Changes: Modified:
+ +19 -0 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+nenolod 2006/02/06 20:04:23 UTC (20060206-714)
+ Log:
+ update NEWS a bit
+
+
+ Changes: Modified:
+ +35 -2 trunk/NEWS (File Modified)
+
+
+gxti 2006/02/06 04:42:14 UTC (20060206-712)
+ Log:
+ Split off a PreClient structure for data to be freed on registation (i.e. password).
+ New hook introduce_client for post-registration messages.
+ Fix b0rked SASL numerics.
+ Burst REALHOST post-introduction for spoofed-on-registration clients.
+ Rearrange SVSLOGIN arguments so that allowednicks is at the end; optional.
+ Pre-registration signon support.
+
+
+ Changes: Modified:
+ +10 -0 trunk/configure (File Modified)
+ +2 -0 trunk/configure.ac (File Modified)
+ +14 -4 trunk/include/client.h (File Modified)
+ +1 -0 trunk/include/hook.h (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +3 -0 trunk/include/setup.h.in (File Modified)
+ +16 -0 trunk/modules/m_chghost.c (File Modified)
+ +25 -21 trunk/modules/m_sasl.c (File Modified)
+ +63 -30 trunk/modules/m_signon.c (File Modified)
+ +18 -0 trunk/src/client.c (File Modified)
+ +2 -0 trunk/src/hook.c (File Modified)
+ +5 -5 trunk/src/messages.tab (File Modified)
+ +2 -0 trunk/src/s_serv.c (File Modified)
+ +28 -2 trunk/src/s_user.c (File Modified)
+
+
+gxti 2006/02/06 03:10:01 UTC (20060206-710)
+ Log:
+ Update hook documentation.
+
+
+ Changes: Modified:
+ +30 -0 trunk/doc/hooks.txt (File Modified)
+
+
+jilles 2006/02/05 22:44:03 UTC (20060205-708)
+ Log:
+ Improve @/# handling in match_esc().
+
+
+ Changes: Modified:
+ +21 -13 trunk/src/match.c (File Modified)
+
+
+nenolod 2006/02/05 21:09:04 UTC (20060205-706)
+ Log:
+ backtrack instead of bailing out when handling a mismatched escape
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/match.c (File Modified)
+
+
+nenolod 2006/02/05 20:33:39 UTC (20060205-704)
+ Log:
+ Denote Entrope as being a contributor, since we used his match() routines from ircu/srvx.
+
+ Changes: Modified:
+ +2 -1 trunk/CREDITS (File Modified)
+
+
+nenolod 2006/02/05 20:24:55 UTC (20060205-702)
+ Log:
+ Fix the escape brokenness and pick up a more efficient matching algorithm,
+ via ircu (Entrope, Runaway et al.). Where do we lose? Nowhere.
+ Patch sent upstream. They can do whatever they want with it, *shrug*.
+
+
+ Changes: Modified:
+ +147 -161 trunk/src/match.c (File Modified)
+
+
+jilles 2006/02/04 20:13:39 UTC (20060204-700)
+ Log:
+ If flatten links is enabled, fake the origins of some ServerModes
+ sent to clients so that the server sending the netburst is hidden.
+ Most mode hacks still show the true source.
+
+
+ Changes: Modified:
+ +17 -4 trunk/modules/core/m_mode.c (File Modified)
+ +20 -10 trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2006/02/04 18:26:55 UTC (20060204-698)
+ Log:
+ - When exiting a local server, send SQUIT <them> :<reason> (no matter
+ where the exit originated).
+ - When receiving an SQUIT for a server themselves
+ (IsMe(target_p) || target_p == client_p)
+ close their link and send a local server notice.
+
+
+ Changes: Modified:
+ +16 -9 trunk/modules/core/m_squit.c (File Modified)
+ +6 -3 trunk/src/client.c (File Modified)
+
+
+nenolod 2006/02/04 04:37:10 UTC (20060204-696)
+ Log:
+ Hooking into the wrong hook, whoops. :P
+
+
+ Changes: Modified:
+ +3 -5 trunk/contrib/m_createauthonly.c (File Modified)
+ +6 -10 trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2006/02/04 04:11:17 UTC (20060204-694)
+ Log:
+ this doesn't work right, right now :P
+
+
+ Changes: Modified:
+ +40 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/m_createauthonly.c (File Added)
+ +6 -0 trunk/include/hook.h (File Modified)
+ +26 -1 trunk/modules/core/m_join.c (File Modified)
+ +1 -1 trunk/src/ircd.c (File Modified)
+
+
+nenolod 2006/02/04 03:11:05 UTC (20060204-692)
+ Log:
+ Make can_join() hookable.
+
+
+ Changes: Modified:
+ +12 -1 trunk/src/channel.c (File Modified)
+
+
+nenolod 2006/02/04 03:04:20 UTC (20060204-690)
+ Log:
+ add 'int approved;' to the channel event hook
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/hook.h (File Modified)
+
+
+gxti 2006/02/04 02:50:03 UTC (20060204-688)
+ Log:
+ Use SIDs in SASL ENCAP origin.
+ Ignore responses from other agents once the first SASL response has been received for a client.
+
+
+ Changes: Modified:
+ +9 -5 trunk/modules/m_sasl.c (File Modified)
+
+
+gxti 2006/02/04 01:44:17 UTC (20060204-686)
+ Log:
+ Removed stray debug code.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_sasl.c (File Modified)
+
+
+jilles 2006/02/03 22:39:24 UTC (20060203-684)
+ Log:
+ Don't complain "unknown MODE flag" if a non-oper attempts
+ to unset an oper only umode they do not have.
+ This is to prevent unwanted error messages when users/bots
+ do things like MODE <nick> +i-sw.
+
+
+ Changes: Modified:
+ +4 -2 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/02/03 22:32:03 UTC (20060203-682)
+ Log:
+ Fix client_exit hook name and only call it for local exits that are not
+ IsAnyServer.
+
+
+ Changes: Modified:
+ +3 -2 trunk/modules/m_sasl.c (File Modified)
+
+
+gxti 2006/02/03 21:41:48 UTC (20060203-680)
+ Log:
+ Fix SASL logic to actually use stored agent UID.
+ Change instances of SASL code that use sendto_one_prefix for ENCAP.
+ Add abort code for exiting clients.
+
+
+ Changes: Modified:
+ +18 -9 trunk/modules/m_sasl.c (File Modified)
+
+
+jilles 2006/02/03 20:25:01 UTC (20060203-678)
+ Log:
+ Port over ratbox 2.2 /challenge. This is slightly more secure
+ (better crypto, longer keys, challenge timeout) and has better
+ client scripts.
+
+ The respond tool is no longer part of the ircd tree but a
+ separate package, currently available from
+ http://respond.ircd-ratbox.org (we should mirror/... this).
+
+
+ Changes: Modified:
+ +65 -310 trunk/doc/challenge.txt (File Modified)
+ +5 -5 trunk/include/client.h (File Modified)
+ +3 -0 trunk/include/irc_string.h (File Modified)
+ +3 -0 trunk/include/numeric.h (File Modified)
+ +94 -50 trunk/modules/m_challenge.c (File Modified)
+ +1 -2 trunk/src/client.c (File Modified)
+ +125 -0 trunk/src/irc_string.c (File Modified)
+ +2 -2 trunk/src/messages.tab (File Modified)
+ + - trunk/tools/rsa_respond/ (File Deleted)
+
+
+gxti 2006/02/03 20:05:09 UTC (20060203-676)
+ Log:
+ Preliminary SASL support.
+
+
+ Changes: Modified:
+ +7 -0 trunk/include/client.h (File Modified)
+ +6 -0 trunk/include/numeric.h (File Modified)
+ +1 -0 trunk/modules/Makefile.in (File Modified)
+ +1 -1 trunk/modules/core/m_nick.c (File Modified)
+ +175 -1 trunk/modules/m_cap.c (File Modified)
+ + - trunk/modules/m_sasl.c (File Added)
+ +2 -0 trunk/modules/m_user.c (File Modified)
+ +5 -5 trunk/src/messages.tab (File Modified)
+ +8 -2 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/02/03 18:13:03 UTC (20060203-674)
+ Log:
+ SIGNON: make logout also apply remotely.
+
+
+ Changes: Modified:
+ +7 -2 trunk/modules/m_signon.c (File Modified)
+
+
+gxti 2006/02/03 17:45:04 UTC (20060203-672)
+ Log:
+ Use an asterisk when sending empty logins in SIGNON.
+
+
+ Changes: Modified:
+ +5 -5 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/02/03 17:38:31 UTC (20060203-670)
+ Log:
+ SIGNON: Only add whowas entry (add_history()) and wipe
+ accepts (del_all_accepts()) if nick changed.
+
+
+ Changes: Modified:
+ +5 -3 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/02/03 17:26:52 UTC (20060203-668)
+ Log:
+ SIGNON: slight fixes to collision code:
+ - don't kill if target_p == source_p (nick unchanged or only changed case)
+ - add comment that SAVE support is missing
+ - use sendto_realops_snomask() instead of sendto_realops_flags()
+
+
+ Changes: Modified:
+ +9 -6 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/02/03 17:19:26 UTC (20060203-666)
+ Log:
+ Fix up kills for bad nick/user/host on SIGNON.
+
+
+ Changes: Modified:
+ +16 -6 trunk/modules/m_signon.c (File Modified)
+
+
+jilles 2006/02/03 16:50:56 UTC (20060203-664)
+ Log:
+ If changing to a nick with a digit, only allow the UID.
+
+
+ Changes: Modified:
+ +4 -0 trunk/modules/m_signon.c (File Modified)
+
+
+gxti 2006/02/03 04:20:31 UTC (20060203-661)
+ Log:
+ Cleaned up SIGNON patch for mainline with quit-join-mode support.
+ Strip leading digits from logins that are not purely numeric.
+
+
+ Changes: Modified:
+ +3 -0 trunk/include/numeric.h (File Modified)
+ +2 -0 trunk/include/send.h (File Modified)
+ +1 -0 trunk/modules/Makefile.in (File Modified)
+ +456 -3 trunk/modules/m_services.c (File Modified)
+ + - trunk/modules/m_signon.c (File Added)
+ +2 -2 trunk/src/messages.tab (File Modified)
+ +98 -0 trunk/src/send.c (File Modified)
+
+
+jilles 2006/02/02 14:10:16 UTC (20060202-659)
+ Log:
+ Remove old server notice umodes from example confs.
+
+
+ Changes: Modified:
+ +1 -2 trunk/doc/example.conf (File Modified)
+ +4 -17 trunk/doc/reference.conf (File Modified)
+
+
+jilles 2006/02/01 15:11:42 UTC (20060201-657)
+ Log:
+ Add snomask help file (forgot this earlier).
+
+
+ Changes: Modified:
+ + - trunk/help/opers/snomask (File Added)
+
+
+jilles 2006/01/31 12:50:36 UTC (20060131-655)
+ Log:
+ Add umode +l (receive locops).
+
+
+ Changes: Modified:
+ +11 -0 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/01/31 12:44:21 UTC (20060131-653)
+ Log:
+ We don't plan to implement cmode +R (quiet unidentified) and
+ umode +I (deny invite) for 1.1, so comment them out from the
+ docs.
+
+
+ Changes: Modified:
+ +2 -0 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+ +2 -0 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/01/31 12:40:38 UTC (20060131-651)
+ Log:
+ Improve snomask usage description.
+
+
+ Changes: Modified:
+ +9 -5 trunk/doc/sgml/oper-guide/snomasks.sgml (File Modified)
+
+
+jilles 2006/01/31 12:33:01 UTC (20060131-649)
+ Log:
+ Mention the word snomask with umode +s (needs to be a link really).
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/01/31 12:28:58 UTC (20060131-647)
+ Log:
+ Add snomask +Z (operspy notices).
+
+
+ Changes: Modified:
+ +10 -0 trunk/doc/sgml/oper-guide/snomasks.sgml (File Modified)
+
+
+jilles 2006/01/31 12:23:29 UTC (20060131-645)
+ Log:
+ Misc updates/clarifications.
+
+
+ Changes: Modified:
+ +8 -6 trunk/doc/sgml/oper-guide/oprivs.sgml (File Modified)
+
+
+jilles 2006/01/31 12:15:29 UTC (20060131-643)
+ Log:
+ Document snomasks.
+
+
+ Changes: Modified:
+ +139 -0 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ + - trunk/doc/sgml/oper-guide/snomasks.sgml (File Added)
+ +3 -85 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2006/01/30 01:07:43 UTC (20060130-641)
+ Log:
+ - Allow ENCAP REALHOST outside burst
+ - Fix comment describing race condition: this can only happen
+ on a local whois with use_whois_actually enabled
+
+
+ Changes: Modified:
+ +4 -6 trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2006/01/29 21:42:06 UTC (20060129-639)
+ Log:
+ Add sno_globaloper.c, remote oper up notices generated from user mode changes.
+
+
+ Changes: Modified:
+ +39 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/sno_globaloper.c (File Added)
+
+
+jilles 2006/01/29 21:26:53 UTC (20060129-637)
+ Log:
+ Pass along old umodes and snomask in umode_changed hook,
+ changing its parameter type from struct Client *
+ to hook_data_umode_changed *. (For a new client, both
+ are zero.)
+
+ The IP cloaking module now fully ignores umode changes
+ where +h didn't change.
+
+
+ Changes: Modified:
+ +7 -2 trunk/contrib/ip_cloaking.c (File Modified)
+ +7 -0 trunk/include/hook.h (File Modified)
+ +18 -4 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/01/29 20:41:26 UTC (20060129-635)
+ Log:
+ move libcharybdis-provided function initialisation into libcharybdis_init().
+
+
+ Changes: Modified:
+ +32 -11 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/01/29 20:40:55 UTC (20060129-633)
+ Log:
+ Make +f notices (local host, global host, global user@host, local class)
+ netwide. Exceeding /quote set max remains local.
+
+
+ Changes: Modified:
+ +4 -4 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/01/29 20:32:44 UTC (20060129-631)
+ Log:
+ Netwide notices about attempts to join juped channels.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_join.c (File Modified)
+
+
+jilles 2006/01/29 19:57:17 UTC (20060129-629)
+ Log:
+ Send server notices about failed oper attempts globally.
+ Successful remote oper attempt notices will be generated
+ from the mode changes.
+
+
+ Changes: Modified:
+ +3 -3 trunk/modules/m_challenge.c (File Modified)
+ +2 -2 trunk/modules/m_oper.c (File Modified)
+
+
+jilles 2006/01/29 19:56:11 UTC (20060129-627)
+ Log:
+ Rest of infrastructure for sending server notices globally.
+ Uses a new L_NETWIDE level on sendto_realops_snomask().
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/send.h (File Modified)
+ +31 -4 trunk/src/send.c (File Modified)
+
+
+jilles 2006/01/29 18:55:28 UTC (20060129-625)
+ Log:
+ Add general::global_snotices conf option to control
+ whether we send out SNOTEs. Does not do anything yet.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +6 -0 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/01/29 13:47:35 UTC (20060129-623)
+ Log:
+ Only accept SNOTE from servers.
+
+
+ Changes: Modified:
+ +2 -0 trunk/modules/m_snote.c (File Modified)
+
+
+jilles 2006/01/29 13:25:06 UTC (20060129-621)
+ Log:
+ Correct parv indices so this actually works.
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_snote.c (File Modified)
+
+
+jilles 2006/01/29 13:16:10 UTC (20060129-619)
+ Log:
+ s/scan/snote/g
+
+
+ Changes: Modified:
+ +3 -3 trunk/modules/m_snote.c (File Modified)
+
+
+nenolod 2006/01/29 04:51:26 UTC (20060129-617)
+ Log:
+ Add m_snote.c, SNOTE propagator.
+
+
+ Changes: Modified:
+ +86 -0 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/m_snote.c (File Added)
+
+
+nenolod 2006/01/29 03:25:01 UTC (20060129-615)
+ Log:
+ start seeding the 1.1 NEWS file
+
+
+ Changes: Modified:
+ +4 -0 trunk/NEWS (File Modified)
+
+
+nenolod 2006/01/29 03:03:02 UTC (20060129-613)
+ Log:
+ rename some modules to more descriptive names...
+
+
+ Changes: Modified:
+ +2 -131 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/globalconnexit.c (File Deleted)
+ + - trunk/contrib/globallineactive.c (File Deleted)
+ + - trunk/contrib/sno_farconnect.c (File Added)
+ + - trunk/contrib/sno_globalkline.c (File Added)
+ +1 -120 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/networknotice.c (File Deleted)
+ + - trunk/modules/sno_routing.c (File Added)
+
+
+jilles 2006/01/28 22:02:18 UTC (20060128-611)
+ Log:
+ Add networknotice (global netjoin/netsplit notices with counts/reasons).
+ Uses FLAGS2_FLOODDONE bit on servers.
+
+
+ Changes: Modified:
+ +3 -0 trunk/include/client.h (File Modified)
+ +121 -1 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/networknotice.c (File Added)
+
+
+jilles 2006/01/28 21:44:33 UTC (20060128-609)
+ Log:
+ Don't show servers in /trace to nonopers if flatten links is enabled.
+
+
+ Changes: Modified:
+ +8 -5 trunk/modules/m_trace.c (File Modified)
+
+
+jilles 2006/01/28 16:45:46 UTC (20060128-607)
+ Log:
+ CHGHOST:
+ - use RPL_HOSTHIDDEN numeric also when resetting hostname to original
+ - send back confirmation to source, if local client
+ - send a +s server notice if the source is neither a server nor a service (+S)
+
+
+ Changes: Modified:
+ +5 -1 trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2006/01/28 16:01:05 UTC (20060128-605)
+ Log:
+ Use sendto_realops_snomask_from() to make the
+ server notices appear to come from the affected
+ user's server.
+
+
+ Changes: Modified:
+ +5 -6 trunk/contrib/globalconnexit.c (File Modified)
+ +6 -6 trunk/contrib/globallineactive.c (File Modified)
+
+
+jilles 2006/01/28 16:00:14 UTC (20060128-603)
+ Log:
+ Add sendto_realops_snomask_from(), allows
+ specification of apparent source server.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/send.h (File Modified)
+ +41 -1 trunk/src/send.c (File Modified)
+
+
+jilles 2006/01/28 15:30:20 UTC (20060128-601)
+ Log:
+ Revert r579. Keep host, not orighost in oper up notice.
+ It would be inconsistent to have orighost there, and we
+ don't want to mess up all server notices by putting both
+ host and orighost.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/28 15:27:10 UTC (20060128-599)
+ Log:
+ Include the IP address in operlog/foperlog.
+
+
+ Changes: Modified:
+ +10 -8 trunk/modules/m_challenge.c (File Modified)
+ +8 -6 trunk/modules/m_oper.c (File Modified)
+
+
+jilles 2006/01/28 15:17:01 UTC (20060128-597)
+ Log:
+ Call umode_changed hook on oper up.
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/28 15:13:27 UTC (20060128-595)
+ Log:
+ Add globalconnexit contrib module, shows remote client connects/exits
+ except netsplits/netjoin on snomask +F.
+ Notice formatting will probably change somewhat still.
+
+
+ Changes: Modified:
+ +80 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/globalconnexit.c (File Added)
+
+
+jilles 2006/01/28 14:54:44 UTC (20060128-593)
+ Log:
+ Declare snomask_modes[] so modules can provide snomasks.
+
+
+ Changes: Modified:
+ +2 -0 trunk/include/snomask.h (File Modified)
+
+
+jilles 2006/01/28 14:40:10 UTC (20060128-591)
+ Log:
+ Replace user_signon hook with two new hooks: new_local_user
+ and new_remote_user.
+ These are called right before the user is introduced to the
+ rest of the network.
+
+
+ Changes: Modified:
+ +2 -1 trunk/include/hook.h (File Modified)
+ +2 -0 trunk/modules/core/m_nick.c (File Modified)
+ +4 -2 trunk/src/hook.c (File Modified)
+ +2 -3 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/01/28 01:51:45 UTC (20060128-589)
+ Log:
+ Change requirements from L_ADMIN to L_OPER for SCAN UMODES.
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_scan.c (File Modified)
+
+
+jilles 2006/01/27 19:45:11 UTC (20060127-587)
+ Log:
+ Update doc/technical/send.txt.
+
+
+ Changes: Modified:
+ +91 -131 trunk/doc/technical/send.txt (File Modified)
+
+
+jilles 2006/01/27 14:44:19 UTC (20060127-585)
+ Log:
+ Add chantrace and masktrace to help files.
+
+
+ Changes: Modified:
+ + - trunk/help/opers/chantrace (File Added)
+ +27 -20 trunk/help/opers/index (File Modified)
+ + - trunk/help/opers/masktrace (File Added)
+ +2 -0 trunk/help/opers/operspy (File Modified)
+
+
+jilles 2006/01/27 14:41:47 UTC (20060127-583)
+ Log:
+ Port over chantrace from ratbox 2.2 (anfl/androsyn)
+ Shows etrace-like output for all users in a channel,
+ in particular IP addresses.
+
+
+ Changes: Modified:
+ +75 -2 trunk/modules/m_etrace.c (File Modified)
+
+
+jilles 2006/01/27 13:49:21 UTC (20060127-581)
+ Log:
+ Port over ratbox 2.2 r21727 (anfl):
+ add some logging when we drop servers in places where we only notify opers
+
+
+ Changes: Modified:
+ +31 -0 trunk/modules/core/m_server.c (File Modified)
+
+
+nenolod 2006/01/27 01:00:48 UTC (20060127-579)
+ Log:
+ display orighost in operup message
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/26 17:13:21 UTC (20060126-577)
+ Log:
+ Add globallineactive contrib module, a hack which can often
+ show k/d/g/x line active for remote clients.
+
+
+ Changes: Modified:
+ +52 -0 trunk/contrib/Makefile.in (File Modified)
+ + - trunk/contrib/globallineactive.c (File Added)
+
+
+jilles 2006/01/26 16:34:00 UTC (20060126-575)
+ Log:
+ Show IP field in the same way as MASKTRACE:
+ "255.255.255.255" if it's unknown (remote TS5 client)
+ and "0" if we or the remote server are purposely
+ hiding it.
+
+
+ Changes: Modified:
+ +12 -1 trunk/modules/m_scan.c (File Modified)
+
+
+jilles 2006/01/26 16:25:22 UTC (20060126-573)
+ Log:
+ scan umodes:
+ - don't show servers in a global scan
+ - don't show ip if it's spoofed and hide_spoof_ips is enabled
+
+
+ Changes: Modified:
+ +4 -1 trunk/modules/m_scan.c (File Modified)
+
+
+nenolod 2006/01/26 16:06:57 UTC (20060126-571)
+ Log:
+ Implement SCAN UMODES.
+
+
+ Changes: Modified:
+ +3 -0 trunk/include/numeric.h (File Modified)
+ +128 -2 trunk/modules/m_scan.c (File Modified)
+ +2 -2 trunk/src/messages.tab (File Modified)
+
+
+nenolod 2006/01/26 15:06:43 UTC (20060126-569)
+ Log:
+ more oops
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_scan.c (File Modified)
+
+
+nenolod 2006/01/26 15:06:03 UTC (20060126-567)
+ Log:
+ parv[0] should be parv[1].
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_scan.c (File Modified)
+
+
+nenolod 2006/01/26 15:05:04 UTC (20060126-565)
+ Log:
+ another oops
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_scan.c (File Modified)
+
+
+nenolod 2006/01/26 15:00:41 UTC (20060126-563)
+ Log:
+ fix mistake here
+
+
+ Changes: Modified:
+ +2 -2 trunk/modules/m_scan.c (File Modified)
+
+
+nenolod 2006/01/26 14:58:36 UTC (20060126-561)
+ Log:
+ framework for scan command
+
+
+ Changes: Modified:
+ +113 -0 trunk/modules/Makefile.in (File Modified)
+ + - trunk/modules/m_scan.c (File Added)
+
+
+nenolod 2006/01/26 14:12:14 UTC (20060126-559)
+ Log:
+ Add TRACEMASK from ratbox 3.0 (r21780 -- androsyn).
+
+
+ Changes: Modified:
+ +2 -0 trunk/include/irc_string.h (File Modified)
+ +157 -1 trunk/modules/m_etrace.c (File Modified)
+ +129 -90 trunk/src/match.c (File Modified)
+
+
+nenolod 2006/01/23 15:57:12 UTC (20060123-557)
+ Log:
+ orighost may live in a different hash bucket (likely the case), lets check it standalone
+
+
+ Changes: Modified:
+ +39 -3 trunk/src/hostmask.c (File Modified)
+
+
+nenolod 2006/01/23 15:11:11 UTC (20060123-555)
+ Log:
+ SVN didn't check modules/ somehow, hrmm.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_kline.c (File Modified)
+ +6 -6 trunk/modules/m_stats.c (File Modified)
+
+
+nenolod 2006/01/23 15:01:41 UTC (20060123-553)
+ Log:
+ Track hostmask entries for client_p->orighost, if available.
+ Not throughly tested, but seems to work fine.
+
+
+ Changes: Modified:
+ +8 -4 trunk/include/hostmask.h (File Modified)
+ +14 -10 trunk/src/hostmask.c (File Modified)
+
+
+jilles 2006/01/22 19:14:11 UTC (20060122-549)
+ Log:
+ Pass on SQUIT reasons more.
+
+
+ Changes: Modified:
+ +17 -19 trunk/src/client.c (File Modified)
+
+
+jilles 2006/01/21 17:25:27 UTC (20060121-543)
+ Log:
+ Use IsOperAdmin() instead of IsAdmin() for admin-only server notices.
+ This way, hidden admins also get them.
+
+
+ Changes: Modified:
+ +4 -4 trunk/src/send.c (File Modified)
+
+
+jilles 2006/01/20 22:26:17 UTC (20060120-541)
+ Log:
+ From ircd-ratbox 2.2 (r21339 anfl):
+ ms_kill() should be using find_person(), not find_client()
+ otherwise it can generate a core.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/core/m_kill.c (File Modified)
+
+
+jilles 2006/01/18 22:56:51 UTC (20060118-539)
+ Log:
+ Add m_error to core_module_table, so it is loaded by default.
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/modules.c (File Modified)
+
+
+jilles 2006/01/18 00:28:30 UTC (20060118-536)
+ Log:
+ comment is a const char *, not char *.
+
+
+ Changes: Modified:
+ +1 -1 trunk/include/hook.h (File Modified)
+
+
+jilles 2006/01/18 00:10:02 UTC (20060118-534)
+ Log:
+ Fix a long standing hybrid 7 bug: when getting a read error
+ on a server, report_error() is called with a %d instead of
+ a %s in the format string ("Lost connection" in +d).
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/client.c (File Modified)
+
+
+jilles 2006/01/16 17:21:11 UTC (20060116-532)
+ Log:
+ Clarifications.
+
+
+ Changes: Modified:
+ +12 -7 trunk/doc/technical/capab.txt (File Modified)
+
+
+nenolod 2006/01/16 04:46:11 UTC (20060116-530)
+ Log:
+ Add document describing capabilities and what they mean.
+
+
+ Changes: Modified:
+ + - trunk/doc/technical/capab.txt (File Added)
+
+
+jilles 2006/01/16 01:19:24 UTC (20060116-528)
+ Log:
+ Change client_exit hook to pass all exit_client() parameters.
+
+
+ Changes: Modified:
+ +8 -0 trunk/include/hook.h (File Modified)
+ +6 -1 trunk/src/client.c (File Modified)
+
+
+jilles 2006/01/15 21:51:42 UTC (20060115-526)
+ Log:
+ Add client_exit hook, called in exit_client() for all
+ clients of all types, except clients exiting because
+ of netsplits (QS). The only thing done before it is
+ marking the client as "closing" (to prevent
+ recursion).
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/hook.h (File Modified)
+ +2 -0 trunk/src/client.c (File Modified)
+ +2 -0 trunk/src/hook.c (File Modified)
+
+
+jilles 2006/01/15 21:06:36 UTC (20060115-524)
+ Log:
+ Improve the code that calculates the nnnS nnnC counts
+ in RPL_TRACESERVER.
+
+ From ircd-ratbox RATBOX_2_2 r21650 and r21678 (anfl/jilles).
+
+
+ Changes: Modified:
+ +43 -36 trunk/modules/m_trace.c (File Modified)
+
+
+jilles 2006/01/15 20:55:27 UTC (20060115-522)
+ Log:
+ Add server_eob hook.
+ Planning to use this for netsplit/join notices.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/hook.h (File Modified)
+ +2 -0 trunk/modules/m_pong.c (File Modified)
+ +2 -0 trunk/src/hook.c (File Modified)
+
+
+jilles 2006/01/15 20:01:51 UTC (20060115-520)
+ Log:
+ Default motd: ircd-ratbox -> charybdis
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/ircd.motd (File Modified)
+
+
+jilles 2006/01/15 19:35:03 UTC (20060115-518)
+ Log:
+ Shouldn't use the UMODE_ALL alias here; instead UMODE_SERVNOTICE.
+
+
+ Changes: Modified:
+ +4 -4 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 19:12:28 UTC (20060115-516)
+ Log:
+ - Remove obsolete EOB help file
+ - Document snomask in the help files
+ - Update indexes
+
+
+ Changes: Modified:
+ + - trunk/help/opers/eob (File Deleted)
+ +13 -12 trunk/help/opers/index (File Modified)
+ +1 -13 trunk/help/opers/umode (File Modified)
+ +7 -7 trunk/help/users/index (File Modified)
+
+
+nenolod 2006/01/15 17:50:43 UTC (20060115-514)
+ Log:
+ Bail if snomask to parse is not given. Pointy hat to myself.
+
+
+ Changes: Modified:
+ +3 -0 trunk/src/snomask.c (File Modified)
+
+
+gxti 2006/01/15 17:48:44 UTC (20060115-512)
+ Log:
+ Remove m_flags from autoconf
+
+
+ Changes: Modified:
+ +0 -1 trunk/contrib/Makefile.in (File Modified)
+
+
+nenolod 2006/01/15 17:44:55 UTC (20060115-510)
+ Log:
+ remove m_flags
+
+
+ Changes: Modified:
+ + - trunk/contrib/m_flags.c (File Deleted)
+
+
+jilles 2006/01/15 17:22:19 UTC (20060115-508)
+ Log:
+ If +s is in oper_only_umodes, clear snomask on deoper.
+
+
+ Changes: Modified:
+ +5 -0 trunk/src/s_user.c (File Modified)
+
+
+gxti 2006/01/15 17:16:50 UTC (20060115-506)
+ Log:
+ Fix incorrect default settings for nicklen and topiclen in ./configure help entries.
+
+
+ Changes: Modified:
+ +2 -2 trunk/configure (File Modified)
+ +2 -2 trunk/configure.ac (File Modified)
+
+
+jilles 2006/01/15 17:15:56 UTC (20060115-504)
+ Log:
+ Remove the old server notice umodes.
+ Default oper only umodes is now +s.
+ Please make sure all remaining umodes still work.
+
+
+ Changes: Modified:
+ +3 -21 trunk/include/client.h (File Modified)
+ +0 -12 trunk/src/newconf.c (File Modified)
+ +1 -1 trunk/src/s_conf.c (File Modified)
+ +12 -12 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 17:00:27 UTC (20060115-502)
+ Log:
+ operator::flags nick_changes now controls +n snomask instead of +n umode.
+
+
+ Changes: Modified:
+ +8 -8 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 16:53:16 UTC (20060115-500)
+ Log:
+ Move down h_umode_changed hook call after umode allowed checks
+ (so it will not see +a if someone tries to set it but is not
+ allowed to).
+
+
+ Changes: Modified:
+ +2 -3 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 16:40:33 UTC (20060115-498)
+ Log:
+ Move over non-+s server notices (hopefully, all of them).
+
+
+ Changes: Modified:
+ +1 -1 trunk/contrib/spy_admin_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_info_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_links_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_motd_notice.c (File Modified)
+ +3 -3 trunk/contrib/spy_stats_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_stats_p_notice.c (File Modified)
+ +2 -2 trunk/contrib/spy_trace_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_whois_notice.c (File Modified)
+ +1 -1 trunk/contrib/spy_whois_notice_global.c (File Modified)
+ +2 -2 trunk/libcharybdis/event.c (File Modified)
+ +2 -2 trunk/modules/core/m_join.c (File Modified)
+ +1 -1 trunk/modules/core/m_kill.c (File Modified)
+ +3 -3 trunk/modules/core/m_message.c (File Modified)
+ +11 -11 trunk/modules/core/m_nick.c (File Modified)
+ +2 -2 trunk/modules/core/m_server.c (File Modified)
+ +1 -1 trunk/modules/core/m_sjoin.c (File Modified)
+ +1 -1 trunk/modules/m_post.c (File Modified)
+ +1 -1 trunk/modules/m_services.c (File Modified)
+ +2 -2 trunk/src/channel.c (File Modified)
+ +3 -3 trunk/src/client.c (File Modified)
+ +1 -1 trunk/src/hash.c (File Modified)
+ +5 -5 trunk/src/s_conf.c (File Modified)
+ +2 -2 trunk/src/s_log.c (File Modified)
+ +4 -4 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 16:18:59 UTC (20060115-496)
+ Log:
+ Rename SNO_SPAMBOT to SNO_BOTS and add SNO_OPERSPY.
+
+
+ Changes: Modified:
+ +2 -1 trunk/include/snomask.h (File Modified)
+ +2 -2 trunk/src/snomask.c (File Modified)
+
+
+jilles 2006/01/15 16:08:28 UTC (20060115-494)
+ Log:
+ s/sendto_realops_flags(UMODE_ALL,/sendto_realops_snomask(SNO_GENERAL,/
+
+
+ Changes: Modified:
+ +1 -1 trunk/contrib/example_module.c (File Modified)
+ +2 -2 trunk/include/ircd_defs.h (File Modified)
+ +6 -6 trunk/modules/core/m_error.c (File Modified)
+ +1 -1 trunk/modules/core/m_join.c (File Modified)
+ +2 -2 trunk/modules/core/m_kill.c (File Modified)
+ +1 -1 trunk/modules/core/m_message.c (File Modified)
+ +1 -1 trunk/modules/core/m_mode.c (File Modified)
+ +14 -14 trunk/modules/core/m_nick.c (File Modified)
+ +18 -18 trunk/modules/core/m_server.c (File Modified)
+ +1 -1 trunk/modules/core/m_sjoin.c (File Modified)
+ +1 -1 trunk/modules/core/m_squit.c (File Modified)
+ +4 -4 trunk/modules/m_challenge.c (File Modified)
+ +4 -4 trunk/modules/m_dline.c (File Modified)
+ +13 -13 trunk/modules/m_gline.c (File Modified)
+ +5 -5 trunk/modules/m_kline.c (File Modified)
+ +2 -2 trunk/modules/m_oper.c (File Modified)
+ +1 -1 trunk/modules/m_pong.c (File Modified)
+ +13 -13 trunk/modules/m_rehash.c (File Modified)
+ +4 -4 trunk/modules/m_resv.c (File Modified)
+ +16 -16 trunk/modules/m_set.c (File Modified)
+ +3 -3 trunk/modules/m_svinfo.c (File Modified)
+ +6 -6 trunk/modules/m_xline.c (File Modified)
+ +1 -1 trunk/src/adns.c (File Modified)
+ +2 -2 trunk/src/channel.c (File Modified)
+ +1 -1 trunk/src/listener.c (File Modified)
+ +1 -1 trunk/src/s_auth.c (File Modified)
+ +15 -15 trunk/src/s_conf.c (File Modified)
+ +3 -3 trunk/src/s_user.c (File Modified)
+ +7 -7 trunk/src/send.c (File Modified)
+
+
+jilles 2006/01/15 15:34:12 UTC (20060115-492)
+ Log:
+ On oper up:
+ - set +s snomask if +s umode set but no snomasks
+ - put numerics in more logical order
+
+
+ Changes: Modified:
+ +3 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/15 15:12:39 UTC (20060115-490)
+ Log:
+ parse_snobuf_to_mask(): default to + at start
+ allows stuff like /mode jilles +s C
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/snomask.c (File Modified)
+
+
+jilles 2006/01/15 15:04:34 UTC (20060115-488)
+ Log:
+ Changes to user_mode() snomask handling.
+ - show snomask (if not 0) on /mode <nick>
+ - show snomask once at the end if +s/-s used
+ - only parse 1 parameter for umode changes
+ - don't crash on /mode <nick> +s
+ - /mode <nick> -s clears snomask, doesn't use parameter
+ - set umode +s iff snomask is not 0
+ - snomask is not propagated, but umode +s is
+
+
+ Changes: Modified:
+ +97 -72 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/01/15 10:36:32 UTC (20060115-486)
+ Log:
+ Convert some messages over to snomask.
+
+
+ Changes: Modified:
+ +29 -29 trunk/src/client.c (File Modified)
+ +2 -2 trunk/src/ircd.c (File Modified)
+ +13 -13 trunk/src/modules.c (File Modified)
+ +1 -1 trunk/src/newconf.c (File Modified)
+ +5 -5 trunk/src/parse.c (File Modified)
+ +1 -1 trunk/src/restart.c (File Modified)
+ +4 -4 trunk/src/s_newconf.c (File Modified)
+ +11 -11 trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2006/01/15 10:28:42 UTC (20060115-484)
+ Log:
+ include snomask.h from client.h
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/client.h (File Modified)
+
+
+nenolod 2006/01/15 10:28:18 UTC (20060115-482)
+ Log:
+ make the snomask parser display snomasks properly, and make sure snomasks are applied to o:lines properly
+
+
+ Changes: Modified:
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +2 -1 trunk/src/snomask.c (File Modified)
+
+
+nenolod 2006/01/15 10:17:52 UTC (20060115-480)
+ Log:
+ should start with +, not \0. Whoops. :)
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/snomask.c (File Modified)
+
+
+nenolod 2006/01/15 10:14:17 UTC (20060115-478)
+ Log:
+ core snomask support.
+
+
+ Changes: Modified:
+ +3 -0 trunk/doc/example.conf (File Modified)
+ +2 -0 trunk/include/client.h (File Modified)
+ +2 -0 trunk/include/numeric.h (File Modified)
+ +2 -0 trunk/include/s_newconf.h (File Modified)
+ +63 -0 trunk/include/send.h (File Modified)
+ + - trunk/include/snomask.h (File Added)
+ +1 -0 trunk/src/Makefile.in (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+ +8 -0 trunk/src/newconf.c (File Modified)
+ +12 -0 trunk/src/s_user.c (File Modified)
+ +235 -0 trunk/src/send.c (File Modified)
+ + - trunk/src/snomask.c (File Added)
+
+
+nenolod 2006/01/15 05:32:44 UTC (20060115-474)
+ Log:
+ add a blank line after the license info.
+
+
+ Changes: Modified:
+ +1 -1 trunk/CREDITS (File Modified)
+
+
+jilles 2006/01/14 19:59:18 UTC (20060114-472)
+ Log:
+ Extend copyright to 2006.
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+
+
+jilles 2006/01/14 19:56:24 UTC (20060114-470)
+ Log:
+ - Fix up book id.
+ - Give some credit to dancer-ircd/hyperion, Andrew Suffield.
+
+
+ Changes: Modified:
+ +1 -1 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ +5 -0 trunk/doc/sgml/oper-guide/intro.sgml (File Modified)
+
+
+jilles 2006/01/14 19:52:16 UTC (20060114-468)
+ Log:
+ Add oper privileges document.
+
+
+ Changes: Modified:
+ +162 -0 trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Modified)
+ + - trunk/doc/sgml/oper-guide/oprivs.sgml (File Added)
+
+
+jilles 2006/01/14 18:45:57 UTC (20060114-466)
+ Log:
+ Capitalize message names in services shortcuts (for consistency).
+
+
+ Changes: Modified:
+ +6 -6 trunk/modules/m_sshortcut.c (File Modified)
+
+
+jilles 2006/01/13 16:53:35 UTC (20060113-464)
+ Log:
+ Remove C++ comment.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/patricia.c (File Modified)
+
+
+jilles 2006/01/13 13:45:56 UTC (20060113-462)
+ Log:
+ Remove obsolete 'nextconnect' variable.
+
+
+ Changes: Modified:
+ +0 -1 trunk/include/ircd.h (File Modified)
+ +0 -2 trunk/src/client.c (File Modified)
+ +0 -1 trunk/src/ircd.c (File Modified)
+
+
+jilles 2006/01/13 13:02:54 UTC (20060113-460)
+ Log:
+ Remove this remnant of the hybrid 6 ziplinks implementation.
+
+
+ Changes: Modified:
+ + - trunk/include/s_zip.h (File Deleted)
+
+
+jilles 2006/01/09 16:05:47 UTC (20060109-458)
+ Log:
+ Make clone limiting work on orighost, not host (so it
+ looks through services cloaks). Lightly tested, please
+ test/review.
+
+
+ Changes: Modified:
+ +2 -0 trunk/modules/m_chghost.c (File Modified)
+ +1 -1 trunk/src/client.c (File Modified)
+ +1 -1 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/01/09 15:51:02 UTC (20060109-456)
+ Log:
+ Don't forget to link me_realhost() into the command hash.
+
+ Pointy hat to: myself
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2006/01/09 14:46:59 UTC (20060109-454)
+ Log:
+ It's call_hook, not hook_call.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/09 14:45:36 UTC (20060109-452)
+ Log:
+ Add unreject help file.
+
+
+ Changes: Modified:
+ + - trunk/help/opers/unreject (File Added)
+
+
+jilles 2006/01/09 14:41:41 UTC (20060109-450)
+ Log:
+ Link the all-important 42 module to the build :P
+
+
+ Changes: Modified:
+ +1 -0 trunk/contrib/Makefile.in (File Modified)
+
+
+jilles 2006/01/08 19:12:10 UTC (20060108-448)
+ Log:
+ Mention /rehash help.
+
+
+ Changes: Modified:
+ +1 -0 trunk/help/opers/rehash (File Modified)
+
+
+nenolod 2006/01/06 14:56:49 UTC (20060106-446)
+ Log:
+ Add h_user_signon hook.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/hook.h (File Modified)
+ +2 -0 trunk/src/hook.c (File Modified)
+ +4 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/06 02:30:23 UTC (20060106-444)
+ Log:
+ Oops, forgot to set orighost for remote client introductions.
+
+
+ Changes: Modified:
+ +1 -0 trunk/modules/core/m_nick.c (File Modified)
+
+
+jilles 2006/01/06 01:40:44 UTC (20060106-442)
+ Log:
+ Use TS6 forms in services shortcuts, if possible.
+
+
+ Changes: Modified:
+ +3 -3 trunk/modules/m_sshortcut.c (File Modified)
+
+
+jilles 2006/01/06 01:31:19 UTC (20060106-440)
+ Log:
+ - Start out default_umodes conf entry from the empty set instead of +i.
+ - Move oper_only_umodes check to where default_umodes is used, as
+ oper_only_umodes may not be set yet while we're reading the conf.
+
+
+ Changes: Modified:
+ +6 -7 trunk/src/newconf.c (File Modified)
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/06 01:00:44 UTC (20060106-438)
+ Log:
+ Move #define HIDE_SPOOF_IPS to general::hide_spoof_ips conf option.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +7 -0 trunk/doc/reference.conf (File Modified)
+ +0 -7 trunk/include/config.h.dist (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +9 -18 trunk/src/client.c (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+jilles 2006/01/06 00:14:18 UTC (20060106-436)
+ Log:
+ - Allow NULL target_ip in show_ip() (indicates message is being
+ sent to local opers)
+ - Add show_ip_conf(), like show_ip() but for a CONF_CLIENT
+ confitem
+ - Using these, remove all uses of #define HIDE_SPOOF_IPS except
+ those in src/client.c
+
+ From ratbox 2.2 svn (anfl)
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/client.h (File Modified)
+ +21 -2 trunk/src/client.c (File Modified)
+ +2 -4 trunk/src/hostmask.c (File Modified)
+ +1 -5 trunk/src/s_conf.c (File Modified)
+ +4 -8 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/01/06 00:01:30 UTC (20060106-434)
+ Log:
+ Fire off events properly.
+
+
+ Changes: Modified:
+ +7 -3 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2006/01/05 23:42:13 UTC (20060105-432)
+ Log:
+ make sure modules which depend on umode information get the message upon connection (oops)
+
+
+ Changes: Modified:
+ +3 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/05 23:33:33 UTC (20060105-430)
+ Log:
+ Replace usage of HIDE_SPOOF_IPS with show_ip() in etrace.
+ From ratbox 2.2 svn.
+
+
+ Changes: Modified:
+ +3 -7 trunk/modules/m_etrace.c (File Modified)
+
+
+nenolod 2006/01/05 23:27:27 UTC (20060105-428)
+ Log:
+ Replace silly `default_invisible' option with more versatile default_umodes.
+
+
+ Changes: Modified:
+ +2 -2 trunk/Makefile.in (File Modified)
+ +12 -1 trunk/doc/example.conf (File Modified)
+ +14 -7 trunk/doc/reference.conf (File Modified)
+ +2 -4 trunk/include/s_conf.h (File Modified)
+ +0 -6 trunk/modules/m_info.c (File Modified)
+ +4 -0 trunk/src/modules.c (File Modified)
+ +41 -1 trunk/src/newconf.c (File Modified)
+ +2 -2 trunk/src/s_conf.c (File Modified)
+ +3 -4 trunk/src/s_user.c (File Modified)
+
+
+jilles 2006/01/02 14:30:45 UTC (20060102-426)
+ Log:
+ Add temporary nick resvs with the proper duration,
+ not 60 times too long.
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_resv.c (File Modified)
+
+
+jilles 2006/01/02 14:21:31 UTC (20060102-424)
+ Log:
+ Add kick on split riding. See reference.conf for more details.
+
+
+ Changes: Modified:
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +16 -0 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +56 -0 trunk/modules/core/m_sjoin.c (File Modified)
+ +6 -0 trunk/modules/m_info.c (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+
+
+nenolod 2005/12/27 06:07:24 UTC (20051227-422)
+ Log:
+ New credits, denoting GXTi as being on the core team.
+
+
+ Changes: Modified:
+ +16 -5 trunk/CREDITS (File Modified)
+
+
+nenolod 2005/12/24 05:50:12 UTC (20051224-420)
+ Log:
+ better cloaking algorithm
+
+
+ Changes: Modified:
+ +14 -7 trunk/contrib/ip_cloaking.c (File Modified)
+
+
+nenolod 2005/12/23 21:43:09 UTC (20051223-418)
+ Log:
+ don't do redundant bitshifting.
+
+
+ Changes: Modified:
+ +2 -2 trunk/contrib/ip_cloaking.c (File Modified)
+
+
+jilles 2005/12/23 21:15:41 UTC (20051223-416)
+ Log:
+ Add ip_cloaking.so.
+
+
+ Changes: Modified:
+ +1 -0 trunk/contrib/Makefile.in (File Modified)
+
+
+jilles 2005/12/23 21:15:25 UTC (20051223-414)
+ Log:
+ Set the DynSpoof flag properly.
+
+
+ Changes: Modified:
+ +4 -0 trunk/contrib/ip_cloaking.c (File Modified)
+
+
+nenolod 2005/12/23 08:11:04 UTC (20051223-412)
+ Log:
+ first go at an ip_cloaking implementation for charybdis.
+
+
+ Changes: Modified:
+ + - trunk/contrib/ip_cloaking.c (File Added)
+
+
+nenolod 2005/12/23 07:25:47 UTC (20051223-410)
+ Log:
+ Add libcharybdis to contrib/ includes.
+
+
+ Changes: Modified:
+ +1 -1 trunk/contrib/Makefile.in (File Modified)
+
+
+nenolod 2005/12/23 02:40:07 UTC (20051223-408)
+ Log:
+ add h_umode_changed hook for modules that provide usermodes.
+
+
+ Changes: Modified:
+ +1 -0 trunk/include/hook.h (File Modified)
+ +2 -1 trunk/src/hook.c (File Modified)
+ +3 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/12/19 16:52:45 UTC (20051219-406)
+ Log:
+ Show quiets in /stats z.
+
+
+ Changes: Modified:
+ +15 -10 trunk/src/s_stats.c (File Modified)
+
+
+nenolod 2005/12/19 15:33:16 UTC (20051219-404)
+ Log:
+ remove old ratbox-services stuff from configure. pointed out with a pointy stick via
+
+
+ Changes: Modified:
+ +0 -12 trunk/configure (File Modified)
+ +0 -9 trunk/configure.ac (File Modified)
+ +0 -3 trunk/include/setup.h.in (File Modified)
+
+
+nenolod 2005/12/19 15:30:32 UTC (20051219-402)
+ Log:
+ change various buffer sizes to = topiclen.
+
+
+ Changes: Modified:
+ +3 -4 trunk/include/ircd_defs.h (File Modified)
+
+
+jon 2005/12/12 19:32:18 UTC (20051212-400)
+ Log:
+ - Partial commit test, partial ego strokage ;)
+
+
+ Changes: Modified:
+ +2 -1 trunk/CREDITS (File Modified)
+
+
+nenolod 2005/12/12 18:12:46 UTC (20051212-398)
+ Log:
+ More kqueue corrections.
+
+ Changes: Modified:
+ +8 -2 trunk/libcharybdis/kqueue.c (File Modified)
+
+
+nenolod 2005/12/12 06:27:59 UTC (20051212-396)
+ Log:
+ We want to use EV_ENABLE to enable tracking, as per the kqueue manpage.
+ Not sure why this wasn't this way to begin with.
+
+
+ Changes: Modified:
+ +3 -3 trunk/libcharybdis/kqueue.c (File Modified)
+
+
+jilles 2005/12/11 16:39:52 UTC (20051211-394)
+ Log:
+ example.conf tweaks:
+ Comment out serverinfo::vhost, serverinfo::vhost6 and listen::host,
+ most people do not need this.
+ Enable serverinfo::hub.
+
+
+ Changes: Modified:
+ +14 -11 trunk/doc/example.conf (File Modified)
+
+
+nenolod 2005/12/10 04:37:54 UTC (20051210-392)
+ Log:
+ Match properly, was backwards before, making connect "*.mask" { } blocks not work properly.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2005/12/07 18:46:56 UTC (20051207-390)
+ Log:
+ header include changes
+
+
+ Changes: Modified:
+ +1 -20 trunk/libcharybdis/devpoll.c (File Modified)
+ +1 -21 trunk/libcharybdis/epoll.c (File Modified)
+ +1 -19 trunk/libcharybdis/kqueue.c (File Modified)
+ +1 -18 trunk/libcharybdis/poll.c (File Modified)
+ +2 -3 trunk/libcharybdis/ports.c (File Modified)
+ +1 -21 trunk/libcharybdis/select.c (File Modified)
+
+
+nenolod 2005/12/07 16:34:40 UTC (20051207-388)
+ Log:
+ s/ilog/libcharybdis_{die,log,restart}/g
+
+
+ Changes: Modified:
+ +7 -9 trunk/libcharybdis/balloc.c (File Modified)
+ +4 -29 trunk/libcharybdis/commio.c (File Modified)
+ +5 -8 trunk/libcharybdis/devpoll.c (File Modified)
+ +4 -4 trunk/libcharybdis/epoll.c (File Modified)
+ +2 -2 trunk/libcharybdis/kqueue.c (File Modified)
+ +3 -0 trunk/libcharybdis/libcharybdis.h (File Modified)
+ +3 -14 trunk/libcharybdis/memory.c (File Modified)
+ +3 -3 trunk/libcharybdis/ports.c (File Modified)
+
+
+nenolod 2005/12/07 16:21:24 UTC (20051207-386)
+ Log:
+ Use the right callbacks in the function code.
+
+ Changes: Modified:
+ +2 -2 trunk/libcharybdis/libcharybdis.c (File Modified)
+
+
+nenolod 2005/12/07 16:18:43 UTC (20051207-384)
+ Log:
+ More work, it builds again!
+
+
+ Changes: Modified:
+ +1 -0 trunk/libcharybdis/Makefile.in (File Modified)
+ +138 -4 trunk/libcharybdis/commio.c (File Modified)
+ + - trunk/libcharybdis/libcharybdis.c (File Added)
+ + - trunk/libcharybdis/libcharybdis.h (File Added)
+
+
+nenolod 2005/12/07 15:15:59 UTC (20051207-382)
+ Log:
+ Move some stuff around.
+
+
+ Changes: Modified:
+ + - trunk/include/memory.h (File Deleted)
+ + - trunk/include/tools.h (File Deleted)
+ +8 -1 trunk/libcharybdis/Makefile.in (File Modified)
+ + - trunk/libcharybdis/memory.c (File Added)
+ + - trunk/libcharybdis/memory.h (File Added)
+ + - trunk/libcharybdis/snprintf.c (File Added)
+ + - trunk/libcharybdis/tools.c (File Added)
+ + - trunk/libcharybdis/tools.h (File Added)
+ +1000 -1062 trunk/modules/.depend (File Modified)
+ +421 -455 trunk/src/.depend (File Modified)
+ +0 -1191 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/memory.c (File Deleted)
+ + - trunk/src/snprintf.c (File Deleted)
+ + - trunk/src/tools.c (File Deleted)
+
+
+nenolod 2005/12/07 15:08:37 UTC (20051207-380)
+ Log:
+ move more headers into libcharybdis
+
+ Changes: Modified:
+ + - trunk/include/balloc.h (File Deleted)
+ + - trunk/include/event.h (File Deleted)
+ + - trunk/libcharybdis/balloc.h (File Added)
+ + - trunk/libcharybdis/event.h (File Added)
+ +924 -1020 trunk/modules/.depend (File Modified)
+ +327 -406 trunk/src/.depend (File Modified)
+
+
+nenolod 2005/12/07 15:06:15 UTC (20051207-378)
+ Log:
+ balloc, events -> libcharybdis
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/Makefile.in (File Modified)
+ + - trunk/libcharybdis/balloc.c (File Added)
+ + - trunk/libcharybdis/event.c (File Added)
+ +0 -1008 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/balloc.c (File Deleted)
+ + - trunk/src/event.c (File Deleted)
+
+
+nenolod 2005/12/07 15:00:41 UTC (20051207-376)
+ Log:
+ More fun
+
+ Changes: Modified:
+ + - trunk/include/commio.h (File Deleted)
+ + - trunk/include/linebuf.h (File Deleted)
+ + - trunk/libcharybdis/commio.h (File Added)
+ + - trunk/libcharybdis/linebuf.h (File Added)
+ +1644 -530 trunk/modules/.depend (File Modified)
+ +1 -1 trunk/modules/Makefile.in (File Modified)
+ +720 -284 trunk/src/.depend (File Modified)
+
+
+nenolod 2005/12/07 14:54:12 UTC (20051207-374)
+ Log:
+ Makefile reworking -- moving libcharybdis headers into proper location.
+
+ Changes: Modified:
+ +1 -1 trunk/adns/Makefile.in (File Modified)
+ +1 -1 trunk/src/Makefile.in (File Modified)
+
+
+nenolod 2005/12/07 14:47:30 UTC (20051207-372)
+ Log:
+ Document proposed authdaemon protocol.
+
+ Changes: Modified:
+ + - trunk/authdaemon/protocol.txt (File Added)
+
+
+nenolod 2005/12/07 14:42:23 UTC (20051207-370)
+ Log:
+ Makefile oops
+
+ Changes: Modified:
+ +2 -2 trunk/libcharybdis/Makefile.in (File Modified)
+
+
+nenolod 2005/12/07 14:38:33 UTC (20051207-368)
+ Log:
+ Remove dead makefile from generation
+
+ Changes: Modified:
+ +1 -2 trunk/configure (File Modified)
+ +0 -1 trunk/configure.ac (File Modified)
+
+
+nenolod 2005/12/07 14:36:56 UTC (20051207-366)
+ Log:
+ libcharybdisIO -> libcharybdis
+
+ Changes: Modified:
+ +1 -1 trunk/src/Makefile.in (File Modified)
+
+
+nenolod 2005/12/07 14:35:50 UTC (20051207-364)
+ Log:
+ More restructuring.
+
+ Changes: Modified:
+ + - trunk/libcharybdis/Makefile.in (File Added)
+ + - trunk/libcharybdis/commio.c (File Added)
+ + - trunk/libcharybdis/devpoll.c (File Added)
+ + - trunk/libcharybdis/epoll.c (File Added)
+ + - trunk/libcharybdis/io/ (File Deleted)
+ + - trunk/libcharybdis/kqueue.c (File Added)
+ + - trunk/libcharybdis/linebuf.c (File Added)
+ + - trunk/libcharybdis/log/ (File Deleted)
+ + - trunk/libcharybdis/poll.c (File Added)
+ + - trunk/libcharybdis/ports.c (File Added)
+ + - trunk/libcharybdis/select.c (File Added)
+
+
+nenolod 2005/12/07 14:33:31 UTC (20051207-362)
+ Log:
+ Blah kill makefile
+
+ Changes: Modified:
+ + - trunk/libcharybdis/Makefile.in (File Deleted)
+
+
+nenolod 2005/12/07 14:33:10 UTC (20051207-360)
+ Log:
+ Blah kill makefile
+
+ Changes: Modified:
+ +2 -4 trunk/libcharybdis/io/Makefile.in (File Modified)
+
+
+nenolod 2005/12/06 19:52:25 UTC (20051206-358)
+ Log:
+ add authdaemon dir for later hacking
+
+
+ Changes: Modified:
+ + - trunk/authdaemon/ (File Added)
+
+
+nenolod 2005/12/06 19:49:25 UTC (20051206-356)
+ Log:
+ linebuf -> libcharybdisIO
+
+
+ Changes: Modified:
+ +1 -1 trunk/libcharybdis/io/Makefile.in (File Modified)
+ + - trunk/libcharybdis/io/linebuf.c (File Added)
+ + - trunk/libcharybdis/log/ (File Added)
+ + - trunk/libcharybdis/log/Makefile.in (File Added)
+ +0 -687 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/linebuf.c (File Deleted)
+
+
+nenolod 2005/12/06 19:47:43 UTC (20051206-354)
+ Log:
+ Solaris 10 I/O ports support
+
+ Changes: Modified:
+ + - trunk/libcharybdis/io/ports.c (File Added)
+
+
+nenolod 2005/12/06 19:15:13 UTC (20051206-352)
+ Log:
+ libcharybdis stuff
+
+
+ Changes: Modified:
+ +1 -1 trunk/Makefile.in (File Modified)
+ +3 -1 trunk/configure (File Modified)
+ +133 -10 trunk/configure.ac (File Modified)
+ + - trunk/libcharybdis/ (File Added)
+ + - trunk/libcharybdis/Makefile.in (File Added)
+ + - trunk/libcharybdis/io/ (File Added)
+ +4 -2 trunk/libcharybdis/io/Makefile.in (File Modified)
+ +2 -3 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/io/ (File Deleted)
+
+
+nenolod 2005/12/06 18:57:28 UTC (20051206-350)
+ Log:
+ split IO stuff into libcharybdisIO.
+
+
+ Changes: Modified:
+ + - trunk/src/commio.c (File Deleted)
+ + - trunk/src/devpoll.c (File Deleted)
+ + - trunk/src/epoll.c (File Deleted)
+ + - trunk/src/io/ (File Added)
+ + - trunk/src/io/Makefile.in (File Added)
+ + - trunk/src/io/commio.c (File Added)
+ + - trunk/src/io/devpoll.c (File Added)
+ + - trunk/src/io/epoll.c (File Added)
+ + - trunk/src/io/kqueue.c (File Added)
+ + - trunk/src/io/poll.c (File Added)
+ + - trunk/src/io/select.c (File Added)
+ + - trunk/src/kqueue.c (File Deleted)
+ + - trunk/src/poll.c (File Deleted)
+ + - trunk/src/select.c (File Deleted)
+
+
+nenolod 2005/12/06 18:51:20 UTC (20051206-348)
+ Log:
+ Version bump: 1.1.0
+
+
+ Changes: Modified:
+ +86 -155 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2005/12/04 01:56:31 UTC (20051204-346)
+ Log:
+ Remove mentions of mkkeypair/cryptlinks.
+
+
+ Changes: Modified:
+ +1 -3 trunk/doc/challenge.txt (File Modified)
+
+
+jilles 2005/12/02 17:57:29 UTC (20051202-344)
+ Log:
+ Clarify serverinfo{} description.
+
+
+ Changes: Modified:
+ +13 -5 trunk/doc/sgml/oper-guide/config.sgml (File Modified)
+
+
+jilles 2005/12/02 17:41:44 UTC (20051202-342)
+ Log:
+ Some hyperion1->charybdis changes, and fixes in charybdis descriptions.
+
+
+ Changes: Modified:
+ +14 -41 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2005/12/02 17:38:53 UTC (20051202-340)
+ Log:
+ Improvements also applicable to hyperion 1.x.
+
+
+ Changes: Modified:
+ +4 -5 trunk/doc/sgml/oper-guide/commands.sgml (File Modified)
+
+
+jilles 2005/12/02 17:08:45 UTC (20051202-338)
+ Log:
+ - Add +F description
+ - General improvements and changes to charybdis
+
+
+ Changes: Modified:
+ +27 -14 trunk/doc/sgml/oper-guide/cmodes.sgml (File Modified)
+
+
+jilles 2005/12/02 16:43:45 UTC (20051202-336)
+ Log:
+ The server notice umodes only have an effect
+ for opers. ("sendto_realops_flags", so having
+ the umode is not enough, they must also be
+ opered)
+
+
+ Changes: Modified:
+ +13 -14 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+jilles 2005/12/02 16:39:40 UTC (20051202-334)
+ Log:
+ Updates to umodes docs.
+
+
+ Changes: Modified:
+ +25 -27 trunk/doc/sgml/oper-guide/umodes.sgml (File Modified)
+
+
+nenolod 2005/11/25 19:37:36 UTC (20051125-332)
+ Log:
+ Add SGML documentation.
+
+ Changes: Modified:
+ + - trunk/doc/sgml/ (File Added)
+ + - trunk/doc/sgml/oper-guide/ (File Added)
+ + - trunk/doc/sgml/oper-guide/charybdis-oper-guide.sgml (File Added)
+ + - trunk/doc/sgml/oper-guide/cmodes.sgml (File Added)
+ + - trunk/doc/sgml/oper-guide/commands.sgml (File Added)
+ + - trunk/doc/sgml/oper-guide/config.sgml (File Added)
+ + - trunk/doc/sgml/oper-guide/intro.sgml (File Added)
+ + - trunk/doc/sgml/oper-guide/stylesheet.dsl (File Added)
+ + - trunk/doc/sgml/oper-guide/umodes.sgml (File Added)
+
+
+jilles 2005/11/21 11:04:33 UTC (20051121-330)
+ Log:
+ Make operwall flag restrict setting umode +z.
+ This repairs this flag broken in charybdis-1.0.
+
+
+ Changes: Modified:
+ +41 -0 trunk/contrib/m_flags.c (File Modified)
+ +9 -0 trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/11/21 10:29:37 UTC (20051121-328)
+ Log:
+ Don't complain/reset remote clients +n. I'm still not
+ convinced propagating all umodes is the way to go, oh
+ well.
+
+
+ Changes: Modified:
+ +1 -1 trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/11/21 10:21:42 UTC (20051121-326)
+ Log:
+ - Require admin flag for oper /chghost (if it's enabled
+ which is not default)
+ - Give error message on nonexistant nick
+
+
+ Changes: Modified:
+ +12 -0 trunk/modules/m_chghost.c (File Modified)
+
+
+nenolod 2005/11/20 21:10:14 UTC (20051120-324)
+ Log:
+ Incorporated jilles' dynspoof patch with a few minor changes.
+
+ Changes: Modified:
+ +5 -2 trunk/include/client.h (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +75 -4 trunk/modules/m_chghost.c (File Modified)
+ +2 -21 trunk/modules/m_stats.c (File Modified)
+ +2 -8 trunk/modules/m_trace.c (File Modified)
+ +2 -0 trunk/src/client.c (File Modified)
+ +3 -0 trunk/src/s_user.c (File Modified)
+
+
+nenolod 2005/11/20 21:02:01 UTC (20051120-322)
+ Log:
+ Update NEWS.
+
+ Changes: Modified:
+ +5 -0 trunk/NEWS (File Modified)
+
+
+jilles 2005/11/17 22:38:52 UTC (20051117-320)
+ Log:
+ Make show_ip() far less braindead.
+
+ Obtained from: ratbox 2.2 SVN
+
+
+ Changes: Modified:
+ +14 -85 trunk/src/client.c (File Modified)
+
+
+jilles 2005/11/15 16:33:26 UTC (20051115-318)
+ Log:
+ Instead of not showing channels at all for whoising services,
+ only show channels the requester is also on. If operspying
+ services, show all the channels.
+
+
+ Changes: Modified:
+ +37 -40 trunk/modules/m_whois.c (File Modified)
+
+
+jilles 2005/11/15 15:59:00 UTC (20051115-316)
+ Log:
+ - Show real errno if we fail to connect to a server
+ - Don't show server IPs on IRC if a server goes dead
+ during handshake
+
+
+ Changes: Modified:
+ +2 -5 trunk/src/s_serv.c (File Modified)
+
+
+jilles 2005/11/15 15:28:18 UTC (20051115-314)
+ Log:
+ Revert hybrid 7.2 aline code. It causes too many problems.
+
+
+ Changes: Modified:
+ +1 -47 trunk/NEWS (File Modified)
+ + - trunk/include/aline.h (File Deleted)
+ +53 -6 trunk/modules/m_dline.c (File Modified)
+ +212 -16 trunk/modules/m_kline.c (File Modified)
+ +37 -8 trunk/modules/m_resv.c (File Modified)
+ +45 -24 trunk/modules/m_xline.c (File Modified)
+ +0 -485 trunk/src/Makefile.in (File Modified)
+ + - trunk/src/aline.c (File Deleted)
+
+
+jilles 2005/11/07 10:47:33 UTC (20051107-312)
+ Log:
+ Incorporate recent ratbox monitor bugfixes (could crash).
+
+
+ Changes: Modified:
+ +16 -0 trunk/modules/m_monitor.c (File Modified)
+ +4 -3 trunk/src/monitor.c (File Modified)
+
+
+jilles 2005/10/24 23:10:06 UTC (20051024-310)
+ Log:
+ Fix /invite UID leak.
+
+ Found by logiclrd@EFnet.
+
+
+ Changes: Modified:
+ +3 -2 trunk/modules/m_invite.c (File Modified)
+
+
+nenolod 2005/10/23 05:28:02 UTC (20051023-308)
+ Log:
+ Don't show what channels a service is in.
+
+ Changes: Modified:
+ +1 -0 trunk/NEWS (File Modified)
+ +40 -35 trunk/modules/m_whois.c (File Modified)
+
+
+nenolod 2005/10/23 05:21:13 UTC (20051023-306)
+ Log:
+ Update version to 1.0.3.
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2005/10/22 17:12:51 UTC (20051022-304)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +7 -1 trunk/NEWS (File Modified)
+
+
+jilles 2005/10/22 17:11:32 UTC (20051022-302)
+ Log:
+ Make sure we don't return alloca() (LOCAL_COPY) ed space.
+ More static buffers :(
+
+
+ Changes: Modified:
+ +12 -4 trunk/src/aline.c (File Modified)
+
+
+jilles 2005/10/18 21:52:35 UTC (20051018-300)
+ Log:
+ Make operspy mode (/mode !#channel showing parameters
+ even if not on channel) work again.
+
+
+ Changes: Modified:
+ +4 -4 trunk/src/channel.c (File Modified)
+
+
+jilles 2005/10/16 22:04:15 UTC (20051016-298)
+ Log:
+ Call server_introduced hook on TS6 remote server
+ introduction (ms_sid()).
+
+
+ Changes: Modified:
+ +6 -0 trunk/modules/core/m_server.c (File Modified)
+
+
+nenolod 2005/10/16 08:29:57 UTC (20051016-296)
+ Log:
+ Cyrix boxes are wierd.
+
+ Changes: Modified:
+ +2 -1 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2005/10/16 08:23:39 UTC (20051016-294)
+ Log:
+ More paranoia.
+
+ Changes: Modified:
+ +1 -1 trunk/include/client.h (File Modified)
+ +3 -1 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2005/10/16 08:07:40 UTC (20051016-292)
+ Log:
+ heh
+
+ Changes: Modified:
+ +1 -6 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2005/10/16 08:00:24 UTC (20051016-290)
+ Log:
+ Disable a check that doesn't always seem to work right for some reason.
+
+ Changes: Modified:
+ +2 -0 trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2005/10/15 04:58:18 UTC (20051015-288)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +4 -1 trunk/NEWS (File Modified)
+
+
+nenolod 2005/10/15 04:53:12 UTC (20051015-286)
+ Log:
+ 1.0.2
+
+
+ Changes: Modified:
+ +9 -9 trunk/configure (File Modified)
+ +1 -1 trunk/configure.ac (File Modified)
+
+
+jilles 2005/10/08 22:30:18 UTC (20051008-284)
+ Log:
+ Apply http://www.ircd-ratbox.org/download/ratbox-trace.diff.
+
+
+ Changes: Modified:
+ +3 -13 trunk/modules/m_trace.c (File Modified)
+
+
+jilles 2005/10/06 11:00:22 UTC (20051006-282)
+ Log:
+ Don't send empty RPL_WHOISCHANNELS on remote whois.
+
+ Pointy hat to: jilles
+
+
+ Changes: Modified:
+ +1 -1 trunk/modules/m_whois.c (File Modified)
+
+
+nenolod 2005/10/02 21:30:55 UTC (20051002-280)
+ Log:
+ Update NEWS.
+
+
+ Changes: Modified:
+ +3 -0 trunk/NEWS (File Modified)
+
+
+nenolod 2005/10/02 21:28:23 UTC (20051002-278)
+ Log:
+ Modular umode support.
+
+
+ Changes: Modified:
+ +0 -9 trunk/include/client.h (File Modified)
+ +2 -1 trunk/include/s_user.h (File Modified)
+ +1 -1 trunk/include/tools.h (File Modified)
+ +2 -2 trunk/modules/core/m_nick.c (File Modified)
+ +3 -0 trunk/src/ircd.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+ +2 -2 trunk/src/s_serv.c (File Modified)
+ +37 -59 trunk/src/s_user.c (File Modified)
+ +21 -0 trunk/src/tools.c (File Modified)
+
+
+jilles 2005/10/02 20:23:15 UTC (20051002-276)
+ Log:
+ Optionally do forced nick change to the UID instead of kill
+ on nick collisions, see doc/collision_fnc.txt for more
+ details.
+
+
+ Changes: Modified:
+ + - trunk/doc/collision_fnc.txt (File Added)
+ +1 -0 trunk/doc/example.conf (File Modified)
+ +8 -0 trunk/doc/reference.conf (File Modified)
+ +1 -0 trunk/include/numeric.h (File Modified)
+ +1 -0 trunk/include/s_conf.h (File Modified)
+ +2 -1 trunk/include/s_serv.h (File Modified)
+ +1 -0 trunk/include/s_stats.h (File Modified)
+ +275 -95 trunk/modules/core/m_nick.c (File Modified)
+ +1 -1 trunk/src/messages.tab (File Modified)
+ +1 -0 trunk/src/newconf.c (File Modified)
+ +1 -0 trunk/src/s_conf.c (File Modified)
+ +1 -0 trunk/src/s_serv.c (File Modified)
+ +2 -2 trunk/src/s_stats.c (File Modified)
+
+
+nenolod 2005/10/02 19:50:18 UTC (20051002-274)
+ Log:
+ Update NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+
+
+jilles 2005/09/28 15:45:31 UTC (20050928-272)
+ Log:
+ Don't allow lookups by uid in /monitor + and /monitor s.
+
+
+ Modified:
+ trunk/modules/m_monitor.c (File Modified)
+
+
+jilles 2005/09/28 13:05:01 UTC (20050928-270)
+ Log:
+ Stop garbage +j being set in cases like +j aaa:bbb by
+ initializing the variables properly.
+
+ Reported by kyle.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2005/09/25 15:51:54 UTC (20050925-268)
+ Log:
+ Apply flags to the proper server in me_gcap().
+
+
+ Modified:
+ trunk/modules/m_capab.c (File Modified)
+
+
+jilles 2005/09/22 23:13:46 UTC (20050922-266)
+ Log:
+ Use find_named_client() instead of find_client() to check
+ for nick collisions.
+
+
+ Modified:
+ trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2005/09/22 05:55:25 UTC (20050922-264)
+ Log:
+ - Replace old 381 numeric with a new, more positive one!
+
+
+ Modified:
+ trunk/src/messages.tab (File Modified)
+
+
+jilles 2005/09/22 00:38:45 UTC (20050922-262)
+ Log:
+ Make it compile again.
+
+
+ Modified:
+ trunk/src/channel.c (File Modified)
+ trunk/src/client.c (File Modified)
+ trunk/src/ircd.c (File Modified)
+ trunk/src/packet.c (File Modified)
+
+
+nenolod 2005/09/22 00:02:59 UTC (20050922-260)
+ Log:
+ - Prevent UID disclosure in cmode setting.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/21 23:57:17 UTC (20050921-258)
+ Log:
+ A different check which prevents UID disclosure.
+
+
+ Modified:
+ trunk/modules/core/m_kick.c (File Modified)
+
+
+nenolod 2005/09/21 23:46:04 UTC (20050921-256)
+ Log:
+ - Eliminate a potential UID leak in m_kick. (As seen on EFnet.)
+
+
+ Modified:
+ trunk/modules/core/m_kick.c (File Modified)
+
+
+nenolod 2005/09/21 23:35:12 UTC (20050921-254)
+ Log:
+ - Revert atheme coding style changes. We don't really need berkeley prototypes, that's overkill.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/modules/m_accept.c (File Modified)
+ trunk/modules/m_admin.c (File Modified)
+ trunk/modules/m_away.c (File Modified)
+ trunk/modules/m_cap.c (File Modified)
+ trunk/modules/m_capab.c (File Modified)
+ trunk/modules/m_challenge.c (File Modified)
+ trunk/modules/m_chghost.c (File Modified)
+ trunk/modules/m_close.c (File Modified)
+ trunk/modules/m_cmessage.c (File Modified)
+ trunk/modules/m_connect.c (File Modified)
+ trunk/modules/m_dline.c (File Modified)
+ trunk/modules/m_encap.c (File Modified)
+ trunk/modules/m_etrace.c (File Modified)
+ trunk/modules/m_gline.c (File Modified)
+ trunk/modules/m_help.c (File Modified)
+ trunk/modules/m_info.c (File Modified)
+ trunk/modules/m_invite.c (File Modified)
+ trunk/modules/m_ison.c (File Modified)
+ trunk/modules/m_kline.c (File Modified)
+ trunk/modules/m_knock.c (File Modified)
+ trunk/modules/m_links.c (File Modified)
+ trunk/modules/m_list.c (File Modified)
+ trunk/modules/m_locops.c (File Modified)
+ trunk/modules/m_lusers.c (File Modified)
+ trunk/modules/m_map.c (File Modified)
+ trunk/modules/m_monitor.c (File Modified)
+ trunk/modules/m_motd.c (File Modified)
+ trunk/modules/m_names.c (File Modified)
+ trunk/modules/m_oper.c (File Modified)
+ trunk/modules/m_operspy.c (File Modified)
+ trunk/modules/m_pass.c (File Modified)
+ trunk/modules/m_ping.c (File Modified)
+ trunk/modules/m_pong.c (File Modified)
+ trunk/modules/m_post.c (File Modified)
+ trunk/modules/m_rehash.c (File Modified)
+ trunk/modules/m_restart.c (File Modified)
+ trunk/modules/m_resv.c (File Modified)
+ trunk/modules/m_services.c (File Modified)
+ trunk/modules/m_set.c (File Modified)
+ trunk/modules/m_sshortcut.c (File Modified)
+ trunk/modules/m_stats.c (File Modified)
+ trunk/modules/m_svinfo.c (File Modified)
+ trunk/modules/m_tb.c (File Modified)
+ trunk/modules/m_testline.c (File Modified)
+ trunk/modules/m_testmask.c (File Modified)
+ trunk/modules/m_time.c (File Modified)
+ trunk/modules/m_topic.c (File Modified)
+ trunk/modules/m_trace.c (File Modified)
+ trunk/modules/m_unreject.c (File Modified)
+ trunk/modules/m_user.c (File Modified)
+ trunk/modules/m_userhost.c (File Modified)
+ trunk/modules/m_users.c (File Modified)
+ trunk/modules/m_version.c (File Modified)
+ trunk/modules/m_wallops.c (File Modified)
+ trunk/modules/m_who.c (File Modified)
+ trunk/modules/m_whois.c (File Modified)
+ trunk/modules/m_whowas.c (File Modified)
+ trunk/modules/m_xline.c (File Modified)
+ trunk/src/adns.c (File Modified)
+ trunk/src/aline.c (File Modified)
+ trunk/src/cache.c (File Modified)
+ trunk/src/channel.c (File Modified)
+ trunk/src/class.c (File Modified)
+ trunk/src/client.c (File Modified)
+ trunk/src/commio.c (File Modified)
+ trunk/src/event.c (File Modified)
+ trunk/src/hash.c (File Modified)
+ trunk/src/hostmask.c (File Modified)
+ trunk/src/ircd.c (File Modified)
+ trunk/src/kdparse.c (File Modified)
+ trunk/src/linebuf.c (File Modified)
+ trunk/src/listener.c (File Modified)
+ trunk/src/modules.c (File Modified)
+ trunk/src/monitor.c (File Modified)
+ trunk/src/newconf.c (File Modified)
+ trunk/src/packet.c (File Modified)
+ trunk/src/parse.c (File Modified)
+ trunk/src/reject.c (File Modified)
+ trunk/src/s_auth.c (File Modified)
+ trunk/src/s_conf.c (File Modified)
+ trunk/src/s_gline.c (File Modified)
+ trunk/src/s_log.c (File Modified)
+ trunk/src/s_newconf.c (File Modified)
+ trunk/src/s_serv.c (File Modified)
+ trunk/src/s_stats.c (File Modified)
+ trunk/src/s_user.c (File Modified)
+ trunk/src/send.c (File Modified)
+ trunk/src/whowas.c (File Modified)
+
+
+nenolod 2005/09/21 23:24:34 UTC (20050921-252)
+ Log:
+ - More coding style niceities. Pretty much got client.h squared away.
+
+
+ Modified:
+ trunk/modules/m_dline.c (File Modified)
+ trunk/modules/m_gline.c (File Modified)
+ trunk/modules/m_kline.c (File Modified)
+ trunk/modules/m_rehash.c (File Modified)
+ trunk/modules/m_resv.c (File Modified)
+ trunk/modules/m_stats.c (File Modified)
+ trunk/modules/m_testline.c (File Modified)
+ trunk/modules/m_user.c (File Modified)
+ trunk/modules/m_xline.c (File Modified)
+
+
+jilles 2005/09/21 22:37:13 UTC (20050921-250)
+ Log:
+ - Propagate quiets (+q) on netjoins
+ - Clear +q list too on lowerTS sjoin from TS6 source
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/s_serv.c (File Modified)
+
+
+jilles 2005/09/21 15:49:43 UTC (20050921-248)
+ Log:
+ Second argument to whois is always a nick, never a uid.
+ This prevents /whois other.server uid to get information
+ about that uid.
+
+
+ Modified:
+ trunk/modules/m_whois.c (File Modified)
+
+
+jilles 2005/09/21 15:43:45 UTC (20050921-246)
+ Log:
+ Don't allow local users to use uids in user mode.
+
+
+ Modified:
+ trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/09/21 15:42:56 UTC (20050921-244)
+ Log:
+ Make it compile again.
+
+
+ Modified:
+ trunk/src/s_stats.c (File Modified)
+
+
+jilles 2005/09/21 15:09:11 UTC (20050921-242)
+ Log:
+ Fix propagation of empty SJOIN.
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+nenolod 2005/09/21 06:13:45 UTC (20050921-240)
+ Log:
+ Some atheme-style niceties here.
+
+
+ Modified:
+ trunk/modules/m_accept.c (File Modified)
+ trunk/modules/m_admin.c (File Modified)
+ trunk/modules/m_away.c (File Modified)
+ trunk/modules/m_cap.c (File Modified)
+ trunk/modules/m_capab.c (File Modified)
+ trunk/modules/m_challenge.c (File Modified)
+ trunk/modules/m_chghost.c (File Modified)
+ trunk/modules/m_close.c (File Modified)
+ trunk/modules/m_cmessage.c (File Modified)
+ trunk/modules/m_connect.c (File Modified)
+ trunk/modules/m_dline.c (File Modified)
+ trunk/modules/m_encap.c (File Modified)
+ trunk/modules/m_etrace.c (File Modified)
+ trunk/modules/m_gline.c (File Modified)
+ trunk/modules/m_help.c (File Modified)
+ trunk/modules/m_info.c (File Modified)
+ trunk/modules/m_invite.c (File Modified)
+ trunk/modules/m_ison.c (File Modified)
+ trunk/modules/m_kline.c (File Modified)
+ trunk/modules/m_knock.c (File Modified)
+ trunk/modules/m_links.c (File Modified)
+ trunk/modules/m_list.c (File Modified)
+ trunk/modules/m_locops.c (File Modified)
+ trunk/modules/m_lusers.c (File Modified)
+ trunk/modules/m_map.c (File Modified)
+ trunk/modules/m_monitor.c (File Modified)
+ trunk/modules/m_motd.c (File Modified)
+ trunk/modules/m_names.c (File Modified)
+ trunk/modules/m_oper.c (File Modified)
+ trunk/modules/m_operspy.c (File Modified)
+ trunk/modules/m_pass.c (File Modified)
+ trunk/modules/m_ping.c (File Modified)
+ trunk/modules/m_pong.c (File Modified)
+ trunk/modules/m_post.c (File Modified)
+ trunk/modules/m_rehash.c (File Modified)
+ trunk/modules/m_restart.c (File Modified)
+ trunk/modules/m_resv.c (File Modified)
+ trunk/modules/m_services.c (File Modified)
+ trunk/modules/m_set.c (File Modified)
+ trunk/modules/m_sshortcut.c (File Modified)
+ trunk/modules/m_stats.c (File Modified)
+ trunk/modules/m_svinfo.c (File Modified)
+ trunk/modules/m_tb.c (File Modified)
+ trunk/modules/m_testline.c (File Modified)
+ trunk/modules/m_testmask.c (File Modified)
+ trunk/modules/m_time.c (File Modified)
+ trunk/modules/m_topic.c (File Modified)
+ trunk/modules/m_trace.c (File Modified)
+ trunk/modules/m_unreject.c (File Modified)
+ trunk/modules/m_user.c (File Modified)
+ trunk/modules/m_userhost.c (File Modified)
+ trunk/modules/m_users.c (File Modified)
+ trunk/modules/m_version.c (File Modified)
+ trunk/modules/m_wallops.c (File Modified)
+ trunk/modules/m_who.c (File Modified)
+ trunk/modules/m_whois.c (File Modified)
+ trunk/modules/m_whowas.c (File Modified)
+ trunk/modules/m_xline.c (File Modified)
+
+
+nenolod 2005/09/21 05:26:03 UTC (20050921-238)
+ Log:
+ Some initial tweaks to make it somewhat meet our coding standards, nowhere near done yet.
+
+
+ Modified:
+ trunk/.indent.pro (File Modified)
+ trunk/include/charybdis.h (File Added)
+ trunk/include/client.h (File Modified)
+ trunk/modules/.indent.pro (File Modified)
+ trunk/src/.indent.pro (File Modified)
+ trunk/src/adns.c (File Modified)
+ trunk/src/aline.c (File Modified)
+ trunk/src/cache.c (File Modified)
+ trunk/src/channel.c (File Modified)
+ trunk/src/class.c (File Modified)
+ trunk/src/client.c (File Modified)
+ trunk/src/commio.c (File Modified)
+ trunk/src/event.c (File Modified)
+ trunk/src/hash.c (File Modified)
+ trunk/src/hostmask.c (File Modified)
+ trunk/src/ircd.c (File Modified)
+ trunk/src/kdparse.c (File Modified)
+ trunk/src/linebuf.c (File Modified)
+ trunk/src/listener.c (File Modified)
+ trunk/src/modules.c (File Modified)
+ trunk/src/monitor.c (File Modified)
+ trunk/src/newconf.c (File Modified)
+ trunk/src/packet.c (File Modified)
+ trunk/src/parse.c (File Modified)
+ trunk/src/reject.c (File Modified)
+ trunk/src/s_auth.c (File Modified)
+ trunk/src/s_conf.c (File Modified)
+ trunk/src/s_gline.c (File Modified)
+ trunk/src/s_log.c (File Modified)
+ trunk/src/s_newconf.c (File Modified)
+ trunk/src/s_serv.c (File Modified)
+ trunk/src/s_stats.c (File Modified)
+ trunk/src/s_user.c (File Modified)
+ trunk/src/send.c (File Modified)
+ trunk/src/whowas.c (File Modified)
+
+
+nenolod 2005/09/21 04:31:10 UTC (20050921-236)
+ Log:
+ - Add parse_aline() via ircd-hybrid-7.2. This stuff lives in src/aline.c.
+ - Convert a few modules towards using this code.
+ - Make a note about this change in NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/include/aline.h (File Added)
+ trunk/modules/m_dline.c (File Modified)
+ trunk/modules/m_kline.c (File Modified)
+ trunk/modules/m_resv.c (File Modified)
+ trunk/modules/m_xline.c (File Modified)
+ trunk/src/Makefile.in (File Modified)
+ trunk/src/aline.c (File Added)
+
+
+nenolod 2005/09/21 00:20:28 UTC (20050921-234)
+ Log:
+ - Update NEWS document.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+
+
+jilles 2005/09/20 18:27:19 UTC (20050920-232)
+ Log:
+ Use find_named_person() instead of find_person() in services shortcuts.
+
+
+ Modified:
+ trunk/modules/m_sshortcut.c (File Modified)
+
+
+jilles 2005/09/18 22:18:59 UTC (20050918-230)
+ Log:
+ Fix propagation of empty channels (+P).
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/s_serv.c (File Modified)
+
+
+jilles 2005/09/18 22:18:04 UTC (20050918-228)
+ Log:
+ Use same comparison for +f.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+
+
+jilles 2005/09/18 18:48:13 UTC (20050918-226)
+ Log:
+ Retire server-server non-encap CHGHOST, and clean it up a bit.
+
+
+ Modified:
+ trunk/modules/m_chghost.c (File Modified)
+
+
+jilles 2005/09/18 14:26:20 UTC (20050918-224)
+ Log:
+ Use TS6 form for SQUIT wallops.
+
+
+ Modified:
+ trunk/modules/core/m_squit.c (File Modified)
+
+
+jilles 2005/09/18 14:25:54 UTC (20050918-222)
+ Log:
+ Propagate nick changes for remote clients in TS6 form if possible;
+ simplify the code a bit.
+
+
+ Modified:
+ trunk/modules/core/m_nick.c (File Modified)
+
+
+jilles 2005/09/18 14:16:43 UTC (20050918-220)
+ Log:
+ Only clear oper_only_umodes on deoper for local clients.
+
+
+ Modified:
+ trunk/src/s_user.c (File Modified)
+
+
+nenolod 2005/09/18 06:14:39 UTC (20050918-218)
+ Log:
+ - Don't enable use_whois_actually in the default config, makes cloaking
+ only useful for vanity.
+
+
+ Modified:
+ trunk/doc/example.conf (File Modified)
+
+
+jilles 2005/09/18 00:00:12 UTC (20050918-216)
+ Log:
+ Fix linebuf raw code to not truncate lines longer than
+ 510 characters. This stops ziplinks corruption at
+ the initial burst if the other side sends a lot.
+
+
+ Modified:
+ trunk/src/linebuf.c (File Modified)
+
+
+nenolod 2005/09/13 03:26:36 UTC (20050913-214)
+ Log:
+ - Add +r to channel_modes().
+
+
+ Modified:
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/13 00:11:52 UTC (20050913-212)
+ Log:
+ Update NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+
+
+nenolod 2005/09/12 23:49:25 UTC (20050912-210)
+ Log:
+ err, nvm. wrong project :-P
+
+
+ Modified:
+ trunk/src/match.c (File Modified)
+
+
+nenolod 2005/09/12 23:49:00 UTC (20050912-208)
+ Log:
+ make sure we don't crash on match(NULL, test)
+
+
+ Modified:
+ trunk/src/match.c (File Modified)
+
+
+jilles 2005/09/12 23:40:03 UTC (20050912-206)
+ Log:
+ Add remote rehash, /rehash <server> and /rehash <option> <server>,
+ flags = rehash in shared{}.
+ Uses :<source> ENCAP <target> REHASH [option].
+
+
+ Modified:
+ trunk/doc/example.conf (File Modified)
+ trunk/doc/reference.conf (File Modified)
+ trunk/help/opers/rehash (File Modified)
+ trunk/include/s_newconf.h (File Modified)
+ trunk/modules/m_rehash.c (File Modified)
+ trunk/modules/m_stats.c (File Modified)
+ trunk/src/newconf.c (File Modified)
+
+
+jilles 2005/09/12 22:48:44 UTC (20050912-204)
+ Log:
+ Initialize flags to 0 in conf_set_shared_flags() and
+ conf_set_cluster_flags().
+
+
+ Modified:
+ trunk/src/newconf.c (File Modified)
+
+
+jilles 2005/09/12 22:14:16 UTC (20050912-202)
+ Log:
+ Don't allow a forward from a #channel to an &channel.
+ Error message is Illegal channel name.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/12 21:56:51 UTC (20050912-200)
+ Log:
+ - change version to 1.0.1
+
+
+ Modified:
+ trunk/configure (File Modified)
+ trunk/configure.ac (File Modified)
+
+
+nenolod 2005/09/12 21:56:28 UTC (20050912-198)
+ Log:
+ Update NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+
+
+jilles 2005/09/12 21:55:58 UTC (20050912-196)
+ Log:
+ Services shortcuts changes:
+ - Require umode +S on target
+ - Use ERR_SERVICESDOWN (440) for error message
+ - Fix check for empty string
+
+
+ Modified:
+ trunk/include/numeric.h (File Modified)
+ trunk/modules/m_sshortcut.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/12 21:24:30 UTC (20050912-194)
+ Log:
+ s/IsChanService/IsService/g;
+
+
+ Modified:
+ trunk/modules/m_sshortcut.c (File Modified)
+
+
+nenolod 2005/09/12 21:23:42 UTC (20050912-192)
+ Log:
+ Add check for service validity in shortcut routines.
+
+
+ Modified:
+ trunk/modules/m_sshortcut.c (File Modified)
+
+
+jilles 2005/09/12 15:30:26 UTC (20050912-190)
+ Log:
+ Don't allow forwarding to a -F channel the setter is not on.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+jilles 2005/09/12 13:55:56 UTC (20050912-188)
+ Log:
+ Describe identify_service and identify_command in
+ reference.conf.
+
+
+ Modified:
+ trunk/doc/reference.conf (File Modified)
+
+
+jilles 2005/09/12 13:37:11 UTC (20050912-186)
+ Log:
+ More helpfile updates.
+
+
+ Modified:
+ trunk/help/Makefile.in (File Modified)
+ trunk/help/opers/die (File Modified)
+ trunk/help/opers/join (File Modified)
+ trunk/help/opers/links (File Modified)
+ trunk/help/opers/lusers (File Modified)
+ trunk/help/opers/map (File Added)
+ trunk/help/opers/motd (File Modified)
+ trunk/help/opers/names (File Modified)
+ trunk/help/opers/notice (File Modified)
+ trunk/help/opers/operspy (File Modified)
+ trunk/help/opers/part (File Modified)
+ trunk/help/opers/privmsg (File Modified)
+ trunk/help/opers/restart (File Modified)
+ trunk/help/opers/set (File Modified)
+ trunk/help/opers/stats (File Modified)
+ trunk/help/opers/trace (File Modified)
+ trunk/help/opers/version (File Modified)
+ trunk/help/users/notice (File Modified)
+ trunk/help/users/privmsg (File Modified)
+ trunk/help/users/stats (File Modified)
+
+
+jilles 2005/09/12 11:18:40 UTC (20050912-184)
+ Log:
+ Update help files.
+
+
+ Modified:
+ trunk/help/opers/cmode (File Modified)
+ trunk/help/opers/umode (File Modified)
+ trunk/help/opers/wallops (File Modified)
+ trunk/help/opers/who (File Modified)
+ trunk/help/users/umode (File Modified)
+
+
+jilles 2005/09/12 11:11:18 UTC (20050912-182)
+ Log:
+ Include cmode +r in 004 and 005.
+
+
+ Modified:
+ trunk/include/supported.h (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+jilles 2005/09/12 10:53:35 UTC (20050912-180)
+ Log:
+ No need to clear all 3 buffers in channel_modes().
+
+
+ Modified:
+ trunk/src/channel.c (File Modified)
+
+
+jilles 2005/09/12 10:31:54 UTC (20050912-178)
+ Log:
+ - Fix multiple +f modes per line
+ - -f shouldn't take a parameter
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+jilles 2005/09/12 10:04:27 UTC (20050912-176)
+ Log:
+ Channel mode +Q now prevents forwarding to or through
+ a channel, just like in hyperion, not from a channel.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+
+
+jilles 2005/09/12 09:36:21 UTC (20050912-174)
+ Log:
+ Complete +F/+Q propagation.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/12 06:10:29 UTC (20050912-172)
+ Log:
+ - A few minor fixes.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/m_services.c (File Modified)
+
+
+nenolod 2005/09/12 04:15:44 UTC (20050912-170)
+ Log:
+ - Fix netsplit obfuscation.
+
+
+ Modified:
+ trunk/src/client.c (File Modified)
+
+
+nenolod 2005/09/12 04:07:36 UTC (20050912-168)
+ Log:
+ - Fix another /stats p related bug.
+
+
+ Modified:
+ trunk/src/client.c (File Modified)
+
+
+nenolod 2005/09/12 03:57:13 UTC (20050912-166)
+ Log:
+ - Update example.conf.
+
+
+ Modified:
+ trunk/doc/example.conf (File Modified)
+
+
+nenolod 2005/09/12 03:52:56 UTC (20050912-164)
+ Log:
+ - Fix a minor bug here, and re-release 1.0.
+
+
+ Modified:
+ trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2005/09/12 03:19:51 UTC (20050912-162)
+ Log:
+ - Add bursted clients to /stats p list.
+
+
+ Modified:
+ trunk/modules/core/m_nick.c (File Modified)
+
+
+nenolod 2005/09/12 03:15:28 UTC (20050912-160)
+ Log:
+ - Add identify_service, identify_command options to the example.conf,
+ newconf parser.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/doc/example.conf (File Modified)
+ trunk/src/newconf.c (File Modified)
+
+
+nenolod 2005/09/12 03:00:04 UTC (20050912-158)
+ Log:
+ - Add services shortcuts.
+
+
+ Modified:
+ trunk/modules/Makefile.in (File Modified)
+ trunk/modules/m_sshortcut.c (File Added)
+
+
+nenolod 2005/09/12 02:46:00 UTC (20050912-156)
+ Log:
+ - put back checks i removed by mistake
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2005/09/12 02:42:09 UTC (20050912-154)
+ Log:
+ - Implement channel mode +Q, which disables forwarding.
+ - Make forwarding usable by everyone.
+ - Implement channel mode +F which bypasses authority checks on a target
+ set with this mode
+ - Update NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/include/channel.h (File Modified)
+ trunk/include/supported.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/12 02:13:26 UTC (20050912-152)
+ Log:
+ - Fix account handling brokenness.
+
+
+ Modified:
+ trunk/modules/m_services.c (File Modified)
+
+
+jilles 2005/09/12 02:04:09 UTC (20050912-150)
+ Log:
+ Identify to services via server password hack. Still
+ needs config file parts, like
+ identifyservice = "nickserv@services.int";
+ identifycommand = "IDENTIFY";
+
+
+ Modified:
+ trunk/include/s_conf.h (File Modified)
+ trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/09/12 01:59:46 UTC (20050912-148)
+ Log:
+ Make send.c compile.
+
+
+ Modified:
+ trunk/src/send.c (File Modified)
+
+
+nenolod 2005/09/12 01:18:24 UTC (20050912-146)
+ Log:
+ - Handle this better.
+
+
+ Modified:
+ trunk/src/send.c (File Modified)
+
+
+nenolod 2005/09/12 01:16:34 UTC (20050912-144)
+ Log:
+ If the source is not a client, don't send to normal users.
+
+
+ Modified:
+ trunk/src/send.c (File Modified)
+
+
+nenolod 2005/09/12 01:07:01 UTC (20050912-142)
+ Log:
+ - Make /wallops behave as wallops in other ircds.
+
+
+ Modified:
+ trunk/modules/m_wallops.c (File Modified)
+ trunk/src/send.c (File Modified)
+
+
+nenolod 2005/09/12 00:53:16 UTC (20050912-140)
+ Log:
+ - charybdis-1.0
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/configure (File Modified)
+ trunk/configure.ac (File Modified)
+
+
+nenolod 2005/09/12 00:48:18 UTC (20050912-138)
+ Log:
+ - Remove efnet configuration.
+ - Rename example.conf as reference.conf, and replace the default
+ example.conf with one suitable for AthemeNET.
+ - Update makefile to reflect these changes.
+
+
+ Modified:
+ trunk/doc/Makefile.in (File Modified)
+ trunk/doc/example.conf (File Modified)
+ trunk/doc/example.efnet.conf (File Deleted)
+ trunk/doc/reference.conf (File Added)
+
+
+nenolod 2005/09/12 00:30:48 UTC (20050912-136)
+ Log:
+ - Don't display opers who are /away.
+
+
+ Modified:
+ trunk/modules/m_stats.c (File Modified)
+
+
+jilles 2005/09/12 00:21:20 UTC (20050912-134)
+ Log:
+ Put cmode +f in 004 and 005.
+
+
+ Modified:
+ trunk/include/supported.h (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+jilles 2005/09/12 00:15:13 UTC (20050912-132)
+ Log:
+ Add user umode +Q which prevents a user from
+ being forwarded.
+
+
+ Modified:
+ trunk/include/client.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+ trunk/src/s_user.c (File Modified)
+
+
+jilles 2005/09/11 23:47:02 UTC (20050911-130)
+ Log:
+ Implement channel forwarding in m_join(). As in
+ hyperion, failing to join because of +i, +r or +j
+ can cause you to be forwarded, potentially
+ recursively. Unlike hyperion, a single numeric
+ is sent in case of a successful forward, otherwise
+ the ircd acts if there were no forward.
+
+
+ Modified:
+ trunk/include/numeric.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+jilles 2005/09/11 22:57:53 UTC (20050911-128)
+ Log:
+ Allow servers to set oper-only cmodes as well.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+jilles 2005/09/11 22:48:37 UTC (20050911-126)
+ Log:
+ Add cmode +f which takes a channel name, settable
+ only by opers for now. Does not do anything yet.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+jilles 2005/09/11 20:48:09 UTC (20050911-124)
+ Log:
+ Fully initialize 'mode' in ms_join() and ms_sjoin()
+ to avoid old +j garbage from being used.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2005/09/11 19:41:53 UTC (20050911-122)
+ Log:
+ - only touch join_count/join_delta if join throttling
+ is enabled on the channel
+ - reset join_count/join_delta to 0 if -j is set
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2005/09/11 18:57:20 UTC (20050911-120)
+ Log:
+ Also start a new "period" for join throttling for remote joins,
+ if necessary. Make the code slightly clearer.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+jilles 2005/09/11 18:12:20 UTC (20050911-118)
+ Log:
+ Some +j improvements, still broken.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2005/09/11 16:44:36 UTC (20050911-116)
+ Log:
+ Only do +z processing for +m channels the sender is on,
+ as bans/quiets are currently only checked locally.
+
+
+ Modified:
+ trunk/modules/core/m_message.c (File Modified)
+
+
+jilles 2005/09/11 16:01:02 UTC (20050911-114)
+ Log:
+ - Add max_bans_large configuration option, defaulting to 500, to
+ limit the number of bans in a +L channel
+ - Change b/e/I to b/e/I/q in texts
+
+
+ Modified:
+ trunk/doc/example.conf (File Modified)
+ trunk/include/s_conf.h (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/m_info.c (File Modified)
+ trunk/src/newconf.c (File Modified)
+ trunk/src/s_conf.c (File Modified)
+
+
+jilles 2005/09/11 15:20:38 UTC (20050911-112)
+ Log:
+ Store invite for +gi channels.
+ Note that +gi is significantly weaker access control than +i.
+
+
+ Modified:
+ trunk/modules/m_invite.c (File Modified)
+
+
+jilles 2005/09/11 14:38:35 UTC (20050911-110)
+ Log:
+ Nonops are allowed to see +q lists.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+jilles 2005/09/11 14:27:59 UTC (20050911-108)
+ Log:
+ Invalidate can_send() cache on -q.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/11 07:01:01 UTC (20050911-106)
+ Log:
+ - Make sure sjoin doesnt crash the ircd if it's blank. :X
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+nenolod 2005/09/11 06:28:20 UTC (20050911-104)
+ Log:
+ - Allow blank SJOINs -- for permanant channels.
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+nenolod 2005/09/11 06:12:40 UTC (20050911-102)
+ Log:
+ - Burst permanant channels.
+
+
+ Modified:
+ trunk/src/s_serv.c (File Modified)
+
+
+nenolod 2005/09/11 06:08:42 UTC (20050911-100)
+ Log:
+ - Fix handling of permanant channels.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2005/09/11 03:37:47 UTC (20050911-98)
+ Log:
+ - Run indent on core modules.
+ - Add propagation of join throttle settings.
+
+
+ Modified:
+ trunk/modules/core/m_die.c (File Modified)
+ trunk/modules/core/m_error.c (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_kick.c (File Modified)
+ trunk/modules/core/m_kill.c (File Modified)
+ trunk/modules/core/m_message.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_nick.c (File Modified)
+ trunk/modules/core/m_part.c (File Modified)
+ trunk/modules/core/m_quit.c (File Modified)
+ trunk/modules/core/m_server.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/modules/core/m_squit.c (File Modified)
+
+
+nenolod 2005/09/11 00:31:11 UTC (20050911-96)
+ Log:
+ - Fix mistake in commit message.
+
+
+ Modified:
+ trunk/ChangeLog (File Modified)
+
+
+nenolod 2005/09/11 00:30:36 UTC (20050911-94)
+ Log:
+ - Channel throttling.
+
+
+ Modified:
+ trunk/NEWS (File Modified)
+ trunk/include/supported.h (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 23:56:31 UTC (20050910-92)
+ Log:
+ - Channel throttle logic fixes.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+
+
+nenolod 2005/09/10 23:55:45 UTC (20050910-90)
+ Log:
+ - Add the throttle logic.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/include/numeric.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/src/channel.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 20:10:09 UTC (20050910-88)
+ Log:
+ - Cosmetic fixes to CREDITS.
+
+
+ Modified:
+ trunk/CREDITS (File Modified)
+
+
+nenolod 2005/09/10 19:54:51 UTC (20050910-86)
+ Log:
+ - Better channel_modes() from ShadowIRCd 4.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/10 19:01:56 UTC (20050910-84)
+ Log:
+ - Strip colour codes from parts.
+
+
+ Modified:
+ trunk/modules/core/m_part.c (File Modified)
+
+
+nenolod 2005/09/10 19:01:00 UTC (20050910-82)
+ Log:
+ - Strip colour codes from quits.
+
+
+ Modified:
+ trunk/modules/core/m_quit.c (File Modified)
+
+
+nenolod 2005/09/10 18:59:00 UTC (20050910-80)
+ Log:
+ - add +c/+g/+z to channel_modes().
+
+
+ Modified:
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/10 18:56:03 UTC (20050910-78)
+ Log:
+ - Add +g to 004/005 numerics.
+
+
+ Modified:
+ trunk/include/supported.h (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 18:54:51 UTC (20050910-76)
+ Log:
+ - Add +cgz to set_final_mode() in both join/sjoin.
+ - Implement channel mode +g: Free invite.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_join.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/modules/m_invite.c (File Modified)
+
+
+nenolod 2005/09/10 18:16:51 UTC (20050910-74)
+ Log:
+ - Make sure /stats p uses the right list.
+
+
+ Modified:
+ trunk/modules/m_stats.c (File Modified)
+
+
+nenolod 2005/09/10 18:16:27 UTC (20050910-72)
+ Log:
+ - local oper list becomes local_oper_list.
+ - all opers are stored on oper_list for /stats p.
+
+
+ Modified:
+ trunk/include/ircd.h (File Modified)
+ trunk/modules/m_stats.c (File Modified)
+ trunk/modules/m_trace.c (File Modified)
+ trunk/src/client.c (File Modified)
+ trunk/src/ircd.c (File Modified)
+ trunk/src/s_user.c (File Modified)
+ trunk/src/send.c (File Modified)
+
+
+nenolod 2005/09/10 07:03:09 UTC (20050910-70)
+ Log:
+ - Remove ENABLE_SERVICES legacy define.
+
+
+ Modified:
+ trunk/configure (File Modified)
+ trunk/configure.ac (File Modified)
+ trunk/include/client.h (File Modified)
+ trunk/include/m_info.h (File Modified)
+ trunk/include/s_conf.h (File Modified)
+ trunk/modules/Makefile.in (File Modified)
+ trunk/modules/core/m_kick.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_nick.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/modules/m_services.c (File Modified)
+ trunk/src/channel.c (File Modified)
+ trunk/src/newconf.c (File Modified)
+ trunk/src/s_conf.c (File Modified)
+ trunk/src/s_serv.c (File Modified)
+ trunk/src/s_user.c (File Modified)
+
+
+nenolod 2005/09/10 06:47:19 UTC (20050910-68)
+ Log:
+ - New reject message, ala ircu.
+
+
+ Modified:
+ trunk/src/reject.c (File Modified)
+
+
+nenolod 2005/09/10 06:27:05 UTC (20050910-66)
+ Log:
+ - Reduce 'broadcast storm' effect in m_chghost.
+
+
+ Modified:
+ trunk/modules/m_chghost.c (File Modified)
+
+
+nenolod 2005/09/10 06:22:38 UTC (20050910-64)
+ Log:
+ - Add +z to RPL_ISUPPORT, RPL_MYINFO.
+
+
+ Modified:
+ trunk/include/supported.h (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 06:21:43 UTC (20050910-62)
+ Log:
+ - Implement +z.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_message.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/10 06:03:27 UTC (20050910-60)
+ Log:
+ - use sendto_one_numeric() in some places.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/10 05:40:25 UTC (20050910-58)
+ Log:
+ - Implement channel mode +c -- colour stripping.
+
+
+ Modified:
+ trunk/include/irc_string.h (File Modified)
+ trunk/include/supported.h (File Modified)
+ trunk/modules/core/m_message.c (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/src/irc_string.c (File Modified)
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 05:29:17 UTC (20050910-56)
+ Log:
+ - Add +qLP to CHANMODES 005 numeric.
+
+
+ Modified:
+ trunk/include/supported.h (File Modified)
+
+
+nenolod 2005/09/10 05:12:55 UTC (20050910-54)
+ Log:
+ Move credits files to doc/.
+
+
+ Modified:
+ trunk/Hybrid-team (File Deleted)
+ trunk/Ratbox-team (File Deleted)
+ trunk/doc/Hybrid-team (File Added)
+ trunk/doc/Ratbox-team (File Added)
+
+
+nenolod 2005/09/10 05:11:15 UTC (20050910-52)
+ Log:
+ - Rename Ratbox credits as Ratbox-team.
+ - Add in our own CREDITS.
+
+
+ Modified:
+ trunk/CREDITS (File Deleted)
+ trunk/CREDITS (File Added)
+ trunk/Ratbox-team (File Added)
+
+
+nenolod 2005/09/10 05:03:03 UTC (20050910-50)
+ Log:
+ - Quietcache fixes.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/10 04:43:41 UTC (20050910-48)
+ Log:
+ - Rebuild configure.
+
+
+ Modified:
+ trunk/autom4te.cache/ (File Deleted)
+ trunk/configure (File Modified)
+
+
+nenolod 2005/09/10 03:25:41 UTC (20050910-46)
+ Log:
+ Add +q to messages.tab.
+
+
+ Modified:
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 03:17:39 UTC (20050910-44)
+ Log:
+ - port m_sjoin stuff to TS6 JOIN syntax.
+
+
+ Modified:
+ trunk/modules/core/m_join.c (File Modified)
+
+
+nenolod 2005/09/10 03:15:50 UTC (20050910-42)
+ Log:
+ - Implement channel mode +q (quiet)
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+jilles 2005/09/10 03:03:05 UTC (20050910-40)
+ Log:
+ Add +L/+P for set_final_mode().
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+
+
+jilles 2005/09/10 02:59:22 UTC (20050910-38)
+ Log:
+ Add +L/+P in channel_modes().
+
+
+ Modified:
+ trunk/src/channel.c (File Modified)
+
+
+jilles 2005/09/10 02:55:10 UTC (20050910-36)
+ Log:
+ - Use MODE_PERMANENT, not MODE_PERMANANT
+ - Actually use chm_staff()
+
+ It compiles but is not otherwise tested.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/10 02:53:04 UTC (20050910-34)
+ Log:
+ - Ok, patchlevel.h is fixed now.
+
+
+ Modified:
+ trunk/include/patchlevel.h (File Modified)
+
+
+nenolod 2005/09/10 02:45:47 UTC (20050910-32)
+ Log:
+ - *sigh*
+
+
+ Modified:
+ trunk/include/patchlevel.h (File Modified)
+ trunk/src/version.c.SH (File Modified)
+
+
+nenolod 2005/09/10 02:43:00 UTC (20050910-30)
+ Log:
+ - Fix compilation issue with version.c.
+
+
+ Modified:
+ trunk/src/version.c.SH (File Modified)
+
+
+nenolod 2005/09/10 02:33:47 UTC (20050910-28)
+ Log:
+ - Server hostmasking fixed in +datadrain ala hybrid 7.2, so we remove
+ this from the BUGS file.
+
+
+ Modified:
+ trunk/BUGS (File Modified)
+
+
+jilles 2005/09/10 02:30:22 UTC (20050910-26)
+ Log:
+ Mangle all netsplit messages if flatten links is enabled.
+
+
+ Modified:
+ trunk/src/client.c (File Modified)
+
+
+nenolod 2005/09/10 02:26:22 UTC (20050910-24)
+ Log:
+ - jilles pointed out that /stats p needed severe changes -- implement
+ them
+
+
+ Modified:
+ trunk/modules/m_stats.c (File Modified)
+
+
+nenolod 2005/09/10 02:24:18 UTC (20050910-22)
+ Log:
+ Rename RELNOTES to NEWS.
+
+
+ Modified:
+ trunk/NEWS (File Added)
+ trunk/RELNOTES (File Deleted)
+
+
+nenolod 2005/09/10 02:24:03 UTC (20050910-20)
+ Log:
+ Update RELNOTES.
+
+
+ Modified:
+ trunk/RELNOTES (File Modified)
+
+
+nenolod 2005/09/10 02:22:34 UTC (20050910-18)
+ Log:
+ - Make /stats p work globally.
+ - Change 'OPER(s)' to 'staff members'
+
+
+ Modified:
+ trunk/modules/m_stats.c (File Modified)
+
+
+nenolod 2005/09/10 02:19:01 UTC (20050910-16)
+ Log:
+ - add modes, +LP to RPL_MYINFO.
+
+
+ Modified:
+ trunk/src/messages.tab (File Modified)
+
+
+nenolod 2005/09/10 02:16:42 UTC (20050910-14)
+ Log:
+ More stuff to RELNOTES.
+
+
+ Modified:
+ trunk/RELNOTES (File Modified)
+
+
+nenolod 2005/09/10 01:32:27 UTC (20050910-12)
+ Log:
+ - Implement +P.
+
+
+ Modified:
+ trunk/modules/core/m_sjoin.c (File Modified)
+ trunk/src/channel.c (File Modified)
+
+
+nenolod 2005/09/10 01:28:47 UTC (20050910-10)
+ Log:
+ - Implement list limit exceed modes -- +L.
+
+
+ Modified:
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/10 01:26:55 UTC (20050910-8)
+ Log:
+ - Add handlers for modes +L, +P.
+
+
+ Modified:
+ trunk/include/channel.h (File Modified)
+ trunk/modules/core/m_mode.c (File Modified)
+
+
+nenolod 2005/09/10 01:02:21 UTC (20050910-6)
+ Log:
+ Update properties on *everything*.
+
+
+ Modified:
+ trunk/.cvsignore (Property Modified)
+ trunk/.indent.pro (Property Modified)
+ trunk/BUGS (File Modified) (Property Modified)
+ trunk/CREDITS (File Modified) (Property Modified)
+ trunk/ChangeLog (Property Modified)
+ trunk/Hybrid-team (File Modified) (Property Modified)
+ trunk/INSTALL (File Modified) (Property Modified)
+ trunk/LICENSE (File Modified) (Property Modified)
+ trunk/Makefile.in (File Modified) (Property Modified)
+ trunk/README.FIRST (File Modified) (Property Modified)
+ trunk/RELNOTES (File Modified) (Property Modified)
+ trunk/SVN-Access (Property Modified)
+ trunk/aclocal.m4 (File Modified) (Property Modified)
+ trunk/adns/.cvsignore (Property Modified)
+ trunk/adns/COPYING (Property Modified)
+ trunk/adns/GPL-vs-LGPL (Property Modified)
+ trunk/adns/Makefile.in (File Modified) (Property Modified)
+ trunk/adns/README (Property Modified)
+ trunk/adns/README.ircd (Property Modified)
+ trunk/adns/adns.h (File Modified) (Property Modified)
+ trunk/adns/check.c (File Modified) (Property Modified)
+ trunk/adns/dlist.h (File Modified) (Property Modified)
+ trunk/adns/event.c (File Modified) (Property Modified)
+ trunk/adns/general.c (File Modified) (Property Modified)
+ trunk/adns/internal.h (File Modified) (Property Modified)
+ trunk/adns/parse.c (File Modified) (Property Modified)
+ trunk/adns/query.c (File Modified) (Property Modified)
+ trunk/adns/reply.c (File Modified) (Property Modified)
+ trunk/adns/setup.c (File Modified) (Property Modified)
+ trunk/adns/transmit.c (File Modified) (Property Modified)
+ trunk/adns/tvarith.h (File Modified) (Property Modified)
+ trunk/adns/types.c (File Modified) (Property Modified)
+ trunk/configure (File Modified) (Property Modified)
+ trunk/configure.ac (File Modified) (Property Modified)
+ trunk/contrib/.cvsignore (Property Modified)
+ trunk/contrib/.indent.pro (Property Modified)
+ trunk/contrib/Makefile.in (File Modified) (Property Modified)
+ trunk/contrib/README (File Modified) (Property Modified)
+ trunk/contrib/example_module.c (File Modified) (Property Modified)
+ trunk/contrib/m_42.c (File Modified) (Property Modified)
+ trunk/contrib/m_clearchan.c (File Modified) (Property Modified)
+ trunk/contrib/m_flags.c (File Modified) (Property Modified)
+ trunk/contrib/m_force.c (File Modified) (Property Modified)
+ trunk/contrib/m_mkpasswd.c (File Modified) (Property Modified)
+ trunk/contrib/m_ojoin.c (File Modified) (Property Modified)
+ trunk/contrib/m_okick.c (File Modified) (Property Modified)
+ trunk/contrib/m_olist.c (File Modified) (Property Modified)
+ trunk/contrib/m_opme.c (File Modified) (Property Modified)
+ trunk/contrib/spy_admin_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_info_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_links_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_motd_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_stats_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_stats_p_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_trace_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_whois_notice.c (File Modified) (Property Modified)
+ trunk/contrib/spy_whois_notice_global.c (File Modified) (Property Modified)
+ trunk/doc/.cvsignore (Property Modified)
+ trunk/doc/CIDR.txt (File Modified) (Property Modified)
+ trunk/doc/Makefile.in (File Modified) (Property Modified)
+ trunk/doc/README.cidr_bans (File Modified) (Property Modified)
+ trunk/doc/Tao-of-IRC.940110 (Property Modified)
+ trunk/doc/challenge.txt (File Modified) (Property Modified)
+ trunk/doc/example.conf (File Modified) (Property Modified)
+ trunk/doc/example.efnet.conf (File Modified) (Property Modified)
+ trunk/doc/hooks.txt (File Modified) (Property Modified)
+ trunk/doc/index.txt (File Modified) (Property Modified)
+ trunk/doc/ircd.8 (File Modified) (Property Modified)
+ trunk/doc/ircd.motd (Property Modified)
+ trunk/doc/logfiles.txt (File Modified) (Property Modified)
+ trunk/doc/modeg.txt (File Modified) (Property Modified)
+ trunk/doc/modes.txt (File Modified) (Property Modified)
+ trunk/doc/monitor.txt (File Modified) (Property Modified)
+ trunk/doc/old/Authors (Property Modified)
+ trunk/doc/operguide.txt (File Modified) (Property Modified)
+ trunk/doc/opermyth.txt (Property Modified)
+ trunk/doc/server-version-info (File Modified) (Property Modified)
+ trunk/doc/services.txt (File Modified) (Property Modified)
+ trunk/doc/technical/README.TSora (Property Modified)
+ trunk/doc/technical/cluster.txt (File Modified) (Property Modified)
+ trunk/doc/technical/event.txt (File Modified) (Property Modified)
+ trunk/doc/technical/fd-management.txt (File Modified) (Property Modified)
+ trunk/doc/technical/file-management.txt (File Modified) (Property Modified)
+ trunk/doc/technical/hostmask.txt (File Modified) (Property Modified)
+ trunk/doc/technical/index.txt (File Modified) (Property Modified)
+ trunk/doc/technical/linebuf.txt (File Modified) (Property Modified)
+ trunk/doc/technical/network.txt (File Modified) (Property Modified)
+ trunk/doc/technical/rfc1459.txt (Property Modified)
+ trunk/doc/technical/send.txt (File Modified) (Property Modified)
+ trunk/doc/technical/ts5.txt (File Modified) (Property Modified)
+ trunk/doc/technical/ts6.txt (File Modified) (Property Modified)
+ trunk/doc/tgchange.txt (File Modified) (Property Modified)
+ trunk/doc/whats-new-2.0.txt (File Modified) (Property Modified)
+ trunk/doc/whats-new-2.1.txt (File Modified) (Property Modified)
+ trunk/help/Makefile.in (File Modified) (Property Modified)
+ trunk/help/opers/accept (Property Modified)
+ trunk/help/opers/admin (Property Modified)
+ trunk/help/opers/away (Property Modified)
+ trunk/help/opers/capab (Property Modified)
+ trunk/help/opers/challenge (Property Modified)
+ trunk/help/opers/close (Property Modified)
+ trunk/help/opers/cmode (Property Modified)
+ trunk/help/opers/cnotice (Property Modified)
+ trunk/help/opers/connect (Property Modified)
+ trunk/help/opers/cprivmsg (Property Modified)
+ trunk/help/opers/credits (Property Modified)
+ trunk/help/opers/die (Property Modified)
+ trunk/help/opers/dline (Property Modified)
+ trunk/help/opers/eob (Property Modified)
+ trunk/help/opers/error (Property Modified)
+ trunk/help/opers/etrace (Property Modified)
+ trunk/help/opers/gline (Property Modified)
+ trunk/help/opers/help (Property Modified)
+ trunk/help/opers/index (Property Modified)
+ trunk/help/opers/info (Property Modified)
+ trunk/help/opers/invite (Property Modified)
+ trunk/help/opers/ison (Property Modified)
+ trunk/help/opers/join (Property Modified)
+ trunk/help/opers/kick (Property Modified)
+ trunk/help/opers/kill (Property Modified)
+ trunk/help/opers/kline (Property Modified)
+ trunk/help/opers/knock (Property Modified)
+ trunk/help/opers/links (Property Modified)
+ trunk/help/opers/list (Property Modified)
+ trunk/help/opers/locops (Property Modified)
+ trunk/help/opers/lusers (Property Modified)
+ trunk/help/opers/modlist (Property Modified)
+ trunk/help/opers/modload (Property Modified)
+ trunk/help/opers/modrestart (Property Modified)
+ trunk/help/opers/modunload (Property Modified)
+ trunk/help/opers/motd (Property Modified)
+ trunk/help/opers/names (Property Modified)
+ trunk/help/opers/nick (Property Modified)
+ trunk/help/opers/notice (Property Modified)
+ trunk/help/opers/oper (Property Modified)
+ trunk/help/opers/operspy (Property Modified)
+ trunk/help/opers/operwall (Property Modified)
+ trunk/help/opers/part (Property Modified)
+ trunk/help/opers/pass (Property Modified)
+ trunk/help/opers/ping (Property Modified)
+ trunk/help/opers/pong (Property Modified)
+ trunk/help/opers/post (Property Modified)
+ trunk/help/opers/privmsg (Property Modified)
+ trunk/help/opers/quit (Property Modified)
+ trunk/help/opers/rehash (Property Modified)
+ trunk/help/opers/restart (Property Modified)
+ trunk/help/opers/resv (Property Modified)
+ trunk/help/opers/server (Property Modified)
+ trunk/help/opers/set (Property Modified)
+ trunk/help/opers/sjoin (Property Modified)
+ trunk/help/opers/squit (Property Modified)
+ trunk/help/opers/stats (Property Modified)
+ trunk/help/opers/svinfo (Property Modified)
+ trunk/help/opers/testgecos (Property Modified)
+ trunk/help/opers/testline (Property Modified)
+ trunk/help/opers/testmask (Property Modified)
+ trunk/help/opers/time (Property Modified)
+ trunk/help/opers/topic (Property Modified)
+ trunk/help/opers/trace (Property Modified)
+ trunk/help/opers/uhelp (Property Modified)
+ trunk/help/opers/umode (Property Modified)
+ trunk/help/opers/undline (Property Modified)
+ trunk/help/opers/ungline (Property Modified)
+ trunk/help/opers/unkline (Property Modified)
+ trunk/help/opers/unresv (Property Modified)
+ trunk/help/opers/unxline (Property Modified)
+ trunk/help/opers/user (Property Modified)
+ trunk/help/opers/userhost (Property Modified)
+ trunk/help/opers/users (Property Modified)
+ trunk/help/opers/version (Property Modified)
+ trunk/help/opers/wallops (Property Modified)
+ trunk/help/opers/who (Property Modified)
+ trunk/help/opers/whois (Property Modified)
+ trunk/help/opers/whowas (Property Modified)
+ trunk/help/opers/xline (Property Modified)
+ trunk/help/users/index (Property Modified)
+ trunk/help/users/info (Property Modified)
+ trunk/help/users/notice (Property Modified)
+ trunk/help/users/privmsg (Property Modified)
+ trunk/help/users/stats (Property Modified)
+ trunk/help/users/umode (Property Modified)
+ trunk/include/.cvsignore (Property Modified)
+ trunk/include/.indent.pro (Property Modified)
+ trunk/include/balloc.h (File Modified) (Property Modified)
+ trunk/include/cache.h (File Modified) (Property Modified)
+ trunk/include/channel.h (File Modified) (Property Modified)
+ trunk/include/class.h (File Modified) (Property Modified)
+ trunk/include/client.h (File Modified) (Property Modified)
+ trunk/include/commio.h (File Modified) (Property Modified)
+ trunk/include/common.h (File Modified) (Property Modified)
+ trunk/include/config.h (File Modified) (Property Modified)
+ trunk/include/config.h.dist (File Modified) (Property Modified)
+ trunk/include/defaults.h (File Modified) (Property Modified)
+ trunk/include/event.h (File Modified) (Property Modified)
+ trunk/include/hash.h (File Modified) (Property Modified)
+ trunk/include/hook.h (File Modified) (Property Modified)
+ trunk/include/hostmask.h (File Modified) (Property Modified)
+ trunk/include/irc_string.h (File Modified) (Property Modified)
+ trunk/include/ircd.h (File Modified) (Property Modified)
+ trunk/include/ircd_defs.h (File Modified) (Property Modified)
+ trunk/include/ircd_getopt.h (File Modified) (Property Modified)
+ trunk/include/ircd_signal.h (File Modified) (Property Modified)
+ trunk/include/linebuf.h (File Modified) (Property Modified)
+ trunk/include/listener.h (File Modified) (Property Modified)
+ trunk/include/m_info.h (File Modified) (Property Modified)
+ trunk/include/memory.h (File Modified) (Property Modified)
+ trunk/include/modules.h (File Modified) (Property Modified)
+ trunk/include/monitor.h (File Modified) (Property Modified)
+ trunk/include/msg.h (File Modified) (Property Modified)
+ trunk/include/newconf.h (File Modified) (Property Modified)
+ trunk/include/numeric.h (File Modified) (Property Modified)
+ trunk/include/packet.h (File Modified) (Property Modified)
+ trunk/include/parse.h (File Modified) (Property Modified)
+ trunk/include/patchlevel.h (File Modified) (Property Modified)
+ trunk/include/patricia.h (File Modified) (Property Modified)
+ trunk/include/reject.h (File Modified) (Property Modified)
+ trunk/include/res.h (File Modified) (Property Modified)
+ trunk/include/restart.h (File Modified) (Property Modified)
+ trunk/include/s_auth.h (File Modified) (Property Modified)
+ trunk/include/s_conf.h (File Modified) (Property Modified)
+ trunk/include/s_gline.h (File Modified) (Property Modified)
+ trunk/include/s_log.h (File Modified) (Property Modified)
+ trunk/include/s_newconf.h (File Modified) (Property Modified)
+ trunk/include/s_serv.h (File Modified) (Property Modified)
+ trunk/include/s_stats.h (File Modified) (Property Modified)
+ trunk/include/s_user.h (File Modified) (Property Modified)
+ trunk/include/s_zip.h (File Modified) (Property Modified)
+ trunk/include/scache.h (File Modified) (Property Modified)
+ trunk/include/send.h (File Modified) (Property Modified)
+ trunk/include/serno.h (Property Modified)
+ trunk/include/setup.h.in (Property Modified)
+ trunk/include/sprintf_irc.h (File Modified) (Property Modified)
+ trunk/include/stdinc.h (File Modified) (Property Modified)
+ trunk/include/supported.h (File Modified) (Property Modified)
+ trunk/include/tools.h (File Modified) (Property Modified)
+ trunk/include/whowas.h (File Modified) (Property Modified)
+ trunk/install-sh (File Modified) (Property Modified)
+ trunk/modules/.cvsignore (Property Modified)
+ trunk/modules/.depend (Property Modified)
+ trunk/modules/.indent.pro (Property Modified)
+ trunk/modules/Makefile.in (File Modified) (Property Modified)
+ trunk/modules/core/m_die.c (File Modified) (Property Modified)
+ trunk/modules/core/m_error.c (File Modified) (Property Modified)
+ trunk/modules/core/m_join.c (File Modified) (Property Modified)
+ trunk/modules/core/m_kick.c (File Modified) (Property Modified)
+ trunk/modules/core/m_kill.c (File Modified) (Property Modified)
+ trunk/modules/core/m_message.c (File Modified) (Property Modified)
+ trunk/modules/core/m_mode.c (File Modified) (Property Modified)
+ trunk/modules/core/m_nick.c (File Modified) (Property Modified)
+ trunk/modules/core/m_part.c (File Modified) (Property Modified)
+ trunk/modules/core/m_quit.c (File Modified) (Property Modified)
+ trunk/modules/core/m_server.c (File Modified) (Property Modified)
+ trunk/modules/core/m_sjoin.c (File Modified) (Property Modified)
+ trunk/modules/core/m_squit.c (File Modified) (Property Modified)
+ trunk/modules/m_accept.c (File Modified) (Property Modified)
+ trunk/modules/m_admin.c (File Modified) (Property Modified)
+ trunk/modules/m_away.c (File Modified) (Property Modified)
+ trunk/modules/m_cap.c (File Modified) (Property Modified)
+ trunk/modules/m_capab.c (File Modified) (Property Modified)
+ trunk/modules/m_challenge.c (File Modified) (Property Modified)
+ trunk/modules/m_chghost.c (File Modified) (Property Modified)
+ trunk/modules/m_close.c (File Modified) (Property Modified)
+ trunk/modules/m_cmessage.c (File Modified) (Property Modified)
+ trunk/modules/m_connect.c (File Modified) (Property Modified)
+ trunk/modules/m_dline.c (File Modified) (Property Modified)
+ trunk/modules/m_encap.c (File Modified) (Property Modified)
+ trunk/modules/m_etrace.c (File Modified) (Property Modified)
+ trunk/modules/m_gline.c (File Modified) (Property Modified)
+ trunk/modules/m_help.c (File Modified) (Property Modified)
+ trunk/modules/m_info.c (File Modified) (Property Modified)
+ trunk/modules/m_invite.c (File Modified) (Property Modified)
+ trunk/modules/m_ison.c (File Modified) (Property Modified)
+ trunk/modules/m_kline.c (File Modified) (Property Modified)
+ trunk/modules/m_knock.c (File Modified) (Property Modified)
+ trunk/modules/m_links.c (File Modified) (Property Modified)
+ trunk/modules/m_list.c (File Modified) (Property Modified)
+ trunk/modules/m_locops.c (File Modified) (Property Modified)
+ trunk/modules/m_lusers.c (File Modified) (Property Modified)
+ trunk/modules/m_map.c (File Modified) (Property Modified)
+ trunk/modules/m_monitor.c (File Modified) (Property Modified)
+ trunk/modules/m_motd.c (File Modified) (Property Modified)
+ trunk/modules/m_names.c (File Modified) (Property Modified)
+ trunk/modules/m_oper.c (File Modified) (Property Modified)
+ trunk/modules/m_operspy.c (File Modified) (Property Modified)
+ trunk/modules/m_pass.c (File Modified) (Property Modified)
+ trunk/modules/m_ping.c (File Modified) (Property Modified)
+ trunk/modules/m_pong.c (File Modified) (Property Modified)
+ trunk/modules/m_post.c (File Modified) (Property Modified)
+ trunk/modules/m_rehash.c (File Modified) (Property Modified)
+ trunk/modules/m_restart.c (File Modified) (Property Modified)
+ trunk/modules/m_resv.c (File Modified) (Property Modified)
+ trunk/modules/m_services.c (File Modified) (Property Modified)
+ trunk/modules/m_set.c (File Modified) (Property Modified)
+ trunk/modules/m_stats.c (File Modified) (Property Modified)
+ trunk/modules/m_svinfo.c (File Modified) (Property Modified)
+ trunk/modules/m_tb.c (File Modified) (Property Modified)
+ trunk/modules/m_testline.c (File Modified) (Property Modified)
+ trunk/modules/m_testmask.c (File Modified) (Property Modified)
+ trunk/modules/m_time.c (File Modified) (Property Modified)
+ trunk/modules/m_topic.c (File Modified) (Property Modified)
+ trunk/modules/m_trace.c (File Modified) (Property Modified)
+ trunk/modules/m_unreject.c (File Modified) (Property Modified)
+ trunk/modules/m_user.c (File Modified) (Property Modified)
+ trunk/modules/m_userhost.c (File Modified) (Property Modified)
+ trunk/modules/m_users.c (File Modified) (Property Modified)
+ trunk/modules/m_version.c (File Modified) (Property Modified)
+ trunk/modules/m_wallops.c (File Modified) (Property Modified)
+ trunk/modules/m_who.c (File Modified) (Property Modified)
+ trunk/modules/m_whois.c (File Modified) (Property Modified)
+ trunk/modules/m_whowas.c (File Modified) (Property Modified)
+ trunk/modules/m_xline.c (File Modified) (Property Modified)
+ trunk/modules/static_modules.c.SH (File Modified) (Property Modified)
+ trunk/servlink/.cvsignore (Property Modified)
+ trunk/servlink/.indent.pro (Property Modified)
+ trunk/servlink/Makefile.in (File Modified) (Property Modified)
+ trunk/servlink/README (File Modified) (Property Modified)
+ trunk/servlink/TODO (File Modified) (Property Modified)
+ trunk/servlink/control.c (File Modified) (Property Modified)
+ trunk/servlink/control.h (File Modified) (Property Modified)
+ trunk/servlink/io.c (File Modified) (Property Modified)
+ trunk/servlink/io.h (File Modified) (Property Modified)
+ trunk/servlink/servlink.c (File Modified) (Property Modified)
+ trunk/servlink/servlink.h (File Modified) (Property Modified)
+ trunk/src/.cvsignore (Property Modified)
+ trunk/src/.depend (Property Modified)
+ trunk/src/.indent.pro (Property Modified)
+ trunk/src/Makefile.in (File Modified) (Property Modified)
+ trunk/src/adns.c (File Modified) (Property Modified)
+ trunk/src/balloc.c (File Modified) (Property Modified)
+ trunk/src/cache.c (File Modified) (Property Modified)
+ trunk/src/channel.c (File Modified) (Property Modified)
+ trunk/src/class.c (File Modified) (Property Modified)
+ trunk/src/client.c (File Modified) (Property Modified)
+ trunk/src/commio.c (File Modified) (Property Modified)
+ trunk/src/devpoll.c (File Modified) (Property Modified)
+ trunk/src/epoll.c (File Modified) (Property Modified)
+ trunk/src/event.c (File Modified) (Property Modified)
+ trunk/src/getopt.c (File Modified) (Property Modified)
+ trunk/src/hash.c (File Modified) (Property Modified)
+ trunk/src/hook.c (File Modified) (Property Modified)
+ trunk/src/hostmask.c (File Modified) (Property Modified)
+ trunk/src/irc_string.c (File Modified) (Property Modified)
+ trunk/src/ircd.c (File Modified) (Property Modified)
+ trunk/src/ircd_lexer.l (File Modified) (Property Modified)
+ trunk/src/ircd_parser.y (File Modified) (Property Modified)
+ trunk/src/ircd_signal.c (File Modified) (Property Modified)
+ trunk/src/kdparse.c (File Modified) (Property Modified)
+ trunk/src/kqueue.c (File Modified) (Property Modified)
+ trunk/src/linebuf.c (File Modified) (Property Modified)
+ trunk/src/listener.c (File Modified) (Property Modified)
+ trunk/src/match.c (File Modified) (Property Modified)
+ trunk/src/memory.c (File Modified) (Property Modified)
+ trunk/src/messages.tab (File Modified) (Property Modified)
+ trunk/src/modules.c (File Modified) (Property Modified)
+ trunk/src/monitor.c (File Modified) (Property Modified)
+ trunk/src/newconf.c (File Modified) (Property Modified)
+ trunk/src/numeric.c (File Modified) (Property Modified)
+ trunk/src/packet.c (File Modified) (Property Modified)
+ trunk/src/parse.c (File Modified) (Property Modified)
+ trunk/src/patricia.c (File Modified) (Property Modified)
+ trunk/src/poll.c (File Modified) (Property Modified)
+ trunk/src/reject.c (File Modified) (Property Modified)
+ trunk/src/restart.c (File Modified) (Property Modified)
+ trunk/src/s_auth.c (File Modified) (Property Modified)
+ trunk/src/s_conf.c (File Modified) (Property Modified)
+ trunk/src/s_gline.c (File Modified) (Property Modified)
+ trunk/src/s_log.c (File Modified) (Property Modified)
+ trunk/src/s_newconf.c (File Modified) (Property Modified)
+ trunk/src/s_serv.c (File Modified) (Property Modified)
+ trunk/src/s_stats.c (File Modified) (Property Modified)
+ trunk/src/s_user.c (File Modified) (Property Modified)
+ trunk/src/scache.c (File Modified) (Property Modified)
+ trunk/src/select.c (File Modified) (Property Modified)
+ trunk/src/send.c (File Modified) (Property Modified)
+ trunk/src/snprintf.c (File Modified) (Property Modified)
+ trunk/src/tools.c (File Modified) (Property Modified)
+ trunk/src/version.c.SH (File Modified) (Property Modified)
+ trunk/src/whowas.c (File Modified) (Property Modified)
+ trunk/tools/.cvsignore (Property Modified)
+ trunk/tools/Makefile.in (File Modified) (Property Modified)
+ trunk/tools/README (File Modified) (Property Modified)
+ trunk/tools/README.mkpasswd (File Modified) (Property Modified)
+ trunk/tools/convertilines.c (File Modified) (Property Modified)
+ trunk/tools/convertklines.c (File Modified) (Property Modified)
+ trunk/tools/mkkeypair (Property Modified)
+ trunk/tools/mkpasswd.c (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/.cvsignore (Property Modified)
+ trunk/tools/rsa_respond/Makefile (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/README (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/challenge.irc (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/challenge.pl (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/respond.c (File Modified) (Property Modified)
+ trunk/tools/rsa_respond/rsa_respond-insecure.diff (File Modified) (Property Modified)
+ trunk/tools/untabify (File Modified) (Property Modified)
+ trunk/tools/viconf.c (File Modified) (Property Modified)
+
+
+nenolod 2005/09/10 00:57:52 UTC (20050910-4)
+ Log:
+ - Update RELNOTES.
+
+
+ Modified:
+ trunk/RELNOTES (File Modified)
+
+
+nenolod 2005/09/10 00:50:51 UTC (20050910-2)
+ Log:
+ - Make version.c use our serial, not ratbox's.
+
+
+ Modified:
+ trunk/src/version.c.SH (File Modified)
+
+
+leeh 2005/09/06 15:59:08 UTC (20050906_2-20748)
+ Log:
+ - update RELNOTES
+ - revved patchlevel to 2.1.5
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/RELNOTES (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/patchlevel.h (File Modified)
+
+
+leeh 2005/09/06 15:58:31 UTC (20050906_1-20746)
+ Log:
+ - fix buffer overflow and unterminated buffer when removing TS6 bans
+ - fix rebuilding of SJOIN
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_sjoin.c (File Modified)
+
+
+androsyn 2005/09/06 02:31:24 UTC (20050906_0-20728)
+ Log:
+ have servlink report if it gets an uncompressed error message when it gets inflate failures
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/servlink/io.c (File Modified)
+
+
+leeh 2005/08/31 20:59:02 UTC (20050831_0-20702)
+ Log:
+ - extend our copyrights to 2005.
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_die.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_error.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_join.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_kick.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_kill.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_message.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_mode.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_nick.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_part.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_quit.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_server.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_sjoin.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_squit.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_accept.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_admin.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_away.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_capab.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_challenge.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_close.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_connect.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_dline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_encap.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_etrace.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_gline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_help.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_info.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_invite.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_ison.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_kline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_knock.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_links.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_list.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_locops.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_lusers.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_motd.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_names.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_oper.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_operspy.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_pass.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_ping.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_pong.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_post.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_rehash.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_restart.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_resv.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_set.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_stats.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_svinfo.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_tb.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_testline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_topic.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_trace.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_unreject.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_user.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_userhost.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_users.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_version.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_wallops.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_who.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_whois.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_whowas.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_xline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/static_modules.c.SH (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/adns.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/balloc.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/cache.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/channel.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/class.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/client.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/commio.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/devpoll.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/epoll.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/event.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/getopt.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/hash.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/hostmask.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/irc_string.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/ircd.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/kdparse.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/kqueue.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/linebuf.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/listener.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/memory.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/modules.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/numeric.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/packet.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/parse.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/poll.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/reject.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/restart.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_auth.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_conf.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_gline.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_log.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_newconf.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_serv.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_stats.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_user.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/scache.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/select.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/send.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/tools.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/version.c.SH (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/whowas.c (File Modified)
+
+
+leeh 2005/08/26 13:07:25 UTC (20050826_1-20692)
+ Log:
+ - update RELNOTES
+ - revved patchlevel to 2.1.4
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/RELNOTES (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/patchlevel.h (File Modified)
+
+
+leeh 2005/08/26 12:22:52 UTC (20050826_0-20690)
+ Log:
+ - add TARGMAX to 005
+ - remove the +1 from ->uid in struct Client
+ - fix checking of accept entries in m_accept.c
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/include/client.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/supported.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_accept.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/s_user.c (File Modified)
+
+
+leeh 2005/08/23 19:28:33 UTC (20050823_0-20664)
+ Log:
+ - via jilles, fix possibility of RPL_WHOISCHANNELS being cut when we
+ send it over TS6
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_whois.c (File Modified)
+
+
+leeh 2005/08/22 20:13:32 UTC (20050822_1-20640)
+ Log:
+ - remove an unused variable
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/src/channel.c (File Modified)
+
+
+androsyn 2005/08/22 10:38:59 UTC (20050822_0-20638)
+ Log:
+ don't burst a TS5 name in burst_TS6. -via jillies
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/src/s_serv.c (File Modified)
+
+
+leeh 2005/08/21 12:17:12 UTC (20050821_1-20626)
+ Log:
+ - via jilles, make nickchanges invalidate any cached bans for
+ quiet_on_ban
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/include/channel.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_nick.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_services.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/channel.c (File Modified)
+
+
+leeh 2005/08/21 11:25:46 UTC (20050821_0-20624)
+ Log:
+ - fix some char vs byte usage to make adns compile cleanly with gcc4
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/adns/event.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/general.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/internal.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/parse.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/query.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/reply.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/transmit.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/adns/types.c (File Modified)
+
+
+androsyn 2005/07/31 05:12:43 UTC (20050731_0-20607)
+ Log:
+ userhost should allow 5 userhost checks, not 4
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_userhost.c (File Modified)
+
+
+leeh 2005/07/17 20:10:30 UTC (20050717_2-20587)
+ Log:
+ - another darwin fix
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/src/monitor.c (File Modified)
+
+
+leeh 2005/07/17 18:55:27 UTC (20050717_1-20583)
+ Log:
+ - darwin fixes
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/adns/Makefile.in (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/ircd_defs.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/newconf.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/include/s_conf.h (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/Makefile.in (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_challenge.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/hash.c (File Modified)
+ ircd-ratbox/branches/RATBOX_2_1/src/whowas.c (File Modified)
+
+
+leeh 2005/07/17 17:00:02 UTC (20050717_0-20575)
+ Log:
+ - remove bogus extern of abort_list
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/include/ircd.h (File Modified)
+
+
+androsyn 2005/07/08 00:37:30 UTC (20050708_0-20553)
+ Log:
+ svn repo access stuff
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/SVN-Access (File Added)
+
+
+androsyn 2005/07/07 21:01:50 UTC (20050707_1-20547)
+ Log:
+ test commit
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/RELNOTES (File Modified)
+
+
+androsyn 2005/07/07 21:01:50 UTC (20050707_0-20547)
+ Log:
+ test commit
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/RELNOTES (File Modified)
+
+
+androsyn 2005/07/05 14:01:52 UTC (20050705_2-19423)
+ Log:
+ revert omotd..i thought it was a good idea..oh well
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_motd.c (File Modified)
+
+
+androsyn 2005/07/05 04:55:42 UTC (20050705_1-19411)
+ Log:
+ Commas are bad things in channel keys
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/core/m_mode.c (File Modified)
+
+
+androsyn 2005/07/05 04:16:51 UTC (20050705_0-19405)
+ Log:
+ Add OMOTD command to display oper motd
+
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/modules/m_motd.c (File Modified)
+
+
+androsyn 2005/07/04 08:27:58 UTC (20050704_0-19391)
+ Log:
+ set m->prev = NULL in dlinkAdd, as it could possibly cause issues
+
+ Modified:
+ ircd-ratbox/branches/RATBOX_2_1/include/tools.h (File Modified)
+
+
+leeh 2005/06/22 22:10:50 UTC (20050622_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_whois.c
+ Log:
+ - stop testing whois for protocol violations, as they can be caused in
+ ircds going all the way back to the original ircd2.8
+
+ Revision Changes Path
+ 1.147.4.1 +20 -2 ircd-ratbox/modules/m_whois.c
+
+
+
+leeh 2005/06/16 23:10:21 UTC (20050616_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_time.c
+ Log:
+ - remove some 2.2 code
+
+ Revision Changes Path
+ 1.45.8.2 +5 -4 ircd-ratbox/modules/m_time.c
+
+
+
+androsyn 2005/06/15 18:55:24 UTC (20050615_2)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_time.c
+ Log:
+ backport of the silly december 31st bug
+
+ Revision Changes Path
+ 1.45.8.1 +6 -7 ircd-ratbox/modules/m_time.c
+
+
+
+leeh 2005/06/15 13:51:57 UTC (20050615_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . RELNOTES
+ include patchlevel.h
+ Log:
+ - revved patchlevel to 2.1.3
+
+ Revision Changes Path
+ 1.114.2.3 +18 -0 ircd-ratbox/RELNOTES
+ 7.73.2.3 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/06/15 01:54:00 UTC (20050615_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include client.h
+ modules m_accept.c
+ modules/core m_nick.c
+ src client.c
+ Log:
+ - stop removing a clients own list of accepted clients when they do a
+ nickchange
+ - clean up the accept code so its less retarded
+
+ Revision Changes Path
+ 7.266.4.3 +2 -2 ircd-ratbox/include/client.h
+ 1.161.4.5 +16 -2 ircd-ratbox/modules/core/m_nick.c
+ 1.59.4.1 +3 -2 ircd-ratbox/modules/m_accept.c
+ 7.492.4.1 +9 -63 ircd-ratbox/src/client.c
+
+
+
+leeh 2005/06/14 12:44:47 UTC (20050614_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include event.h
+ modules m_links.c
+ src event.c ircd.c newconf.c
+ Log:
+ - remove a defn of links_cache_list in m_links.c which was causing
+ the flattened links update to be ignored
+ - add eventUpdate(), and make links_delay update on rehash
+
+ Revision Changes Path
+ 1.19.8.1 +2 -0 ircd-ratbox/include/event.h
+ 1.70.4.1 +1 -2 ircd-ratbox/modules/m_links.c
+ 7.47.4.1 +25 -0 ircd-ratbox/src/event.c
+ 7.374.4.1 +1 -1 ircd-ratbox/src/ircd.c
+ 7.202.4.5 +2 -0 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/06/12 02:23:01 UTC (20050612_2)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc services.txt
+ src newconf.c
+ Log:
+ - make the conf parser apply service {}; on rehash
+
+ Revision Changes Path
+ 7.2.4.2 +8 -2 ircd-ratbox/doc/services.txt
+ 7.202.4.4 +24 -4 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/06/12 02:10:30 UTC (20050612_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include m_info.h
+ Log:
+ - show ENABLE_SERVICES define in info
+
+ Revision Changes Path
+ 7.56.4.2 +6 -0 ircd-ratbox/include/m_info.h
+
+
+
+leeh 2005/06/12 01:44:37 UTC (20050612_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c m_stats.c
+ Log:
+ - via jilles, make m_services.c hook into stats U and display service
+ blocks
+
+ Revision Changes Path
+ 1.6.4.7 +20 -1 ircd-ratbox/modules/m_services.c
+ 1.243.4.3 +4 -4 ircd-ratbox/modules/m_stats.c
+
+
+
+leeh 2005/06/11 20:33:12 UTC (20050611_3)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . configure configure.ac
+ Log:
+ - default build to -O2
+
+ Revision Changes Path
+ 7.249.2.2 +4 -4 ircd-ratbox/configure
+ 7.63.2.2 +4 -4 ircd-ratbox/configure.ac
+
+
+
+leeh 2005/06/11 20:26:02 UTC (20050611_2)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc example.conf example.efnet.conf
+ include client.h s_conf.h s_newconf.h
+ modules m_info.c
+ modules/core m_join.c m_nick.c
+ src channel.c newconf.c s_conf.c s_user.c
+ Log:
+ - remove no_oper_resvs from general {};
+ - add resv_exempt to auth {}; flags, exempts a user from nick/channel resvs
+
+ Revision Changes Path
+ 7.261.4.3 +1 -3 ircd-ratbox/doc/example.conf
+ 7.89.4.3 +3 -3 ircd-ratbox/doc/example.efnet.conf
+ 7.266.4.2 +3 -0 ircd-ratbox/include/client.h
+ 7.315.4.1 +3 -2 ircd-ratbox/include/s_conf.h
+ 7.46.4.1 +2 -3 ircd-ratbox/include/s_newconf.h
+ 1.164.4.1 +4 -4 ircd-ratbox/modules/core/m_join.c
+ 1.161.4.4 +2 -2 ircd-ratbox/modules/core/m_nick.c
+ 1.122.4.1 +1 -7 ircd-ratbox/modules/m_info.c
+ 7.436.4.1 +1 -1 ircd-ratbox/src/channel.c
+ 7.202.4.3 +1 -1 ircd-ratbox/src/newconf.c
+ 7.511.4.2 +0 -1 ircd-ratbox/src/s_conf.c
+ 7.342.4.1 +8 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/06/11 20:06:22 UTC (20050611_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules/core m_mode.c m_nick.c
+ src s_newconf.c
+ Log:
+ - 2.0 sync:
+ - raise max temptime to a year
+ - tidy up BMASK
+ - require 9 parameters in ms_nick(), 10 in ms_uid()
+
+ Revision Changes Path
+ 1.121.4.2 +23 -9 ircd-ratbox/modules/core/m_mode.c
+ 1.161.4.3 +23 -3 ircd-ratbox/modules/core/m_nick.c
+ 7.67.4.1 +2 -2 ircd-ratbox/src/s_newconf.c
+
+
+
+leeh 2005/06/11 16:35:25 UTC (20050611_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c
+ Log:
+ - only show services logged in info when its a local client
+
+ Revision Changes Path
+ 1.6.4.6 +4 -1 ircd-ratbox/modules/m_services.c
+
+
+
+androsyn 2005/06/03 19:12:17 UTC (20050603_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src match.c
+ Log:
+ passing a pointer to a pointer is not what was intended, oops
+
+ Revision Changes Path
+ 7.42.4.1 +3 -3 ircd-ratbox/src/match.c
+
+
+
+leeh 2005/06/03 11:18:11 UTC (20050603_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc services.txt
+ Log:
+ - update services.txt with FNC
+
+ Revision Changes Path
+ 7.2.4.1 +7 -0 ircd-ratbox/doc/services.txt
+
+
+
+androsyn 2005/05/30 16:47:27 UTC (20050530_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_resv.c
+ Log:
+ use target_server and not parv[3] to check if the target server is us. thanks to jilles for the patch
+
+ Revision Changes Path
+ 1.74.4.3 +2 -2 ircd-ratbox/modules/m_resv.c
+
+
+
+leeh 2005/05/19 12:44:47 UTC (20050519_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src s_auth.c
+ Log:
+ - add some uniqueness into auth process for bopm
+
+ Revision Changes Path
+ 7.192.4.3 +5 -0 ircd-ratbox/src/s_auth.c
+
+
+
+leeh 2005/05/19 08:50:26 UTC (20050519_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ contrib m_mkpasswd.c m_ojoin.c m_olist.c m_opme.c
+ Log:
+ - make contrib/ compile
+
+ Revision Changes Path
+ 1.12.8.1 +2 -1 ircd-ratbox/contrib/m_mkpasswd.c
+ 1.24.6.1 +2 -1 ircd-ratbox/contrib/m_ojoin.c
+ 1.14.6.1 +2 -1 ircd-ratbox/contrib/m_olist.c
+ 1.44.6.1 +2 -1 ircd-ratbox/contrib/m_opme.c
+
+
+
+androsyn 2005/05/18 22:01:55 UTC (20050518_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_monitor.c
+ Log:
+ Don't allow MONITOR from an unregistered client
+
+ Revision Changes Path
+ 1.3.4.1 +2 -2 ircd-ratbox/modules/m_monitor.c
+
+
+
+leeh 2005/05/17 13:16:11 UTC (20050517_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc example.conf example.efnet.conf
+ include class.h
+ src class.c messages.tab newconf.c
+ Log:
+ - remove sendq_eob, its become more of a hindrance than a benefit.
+ - sync example.efnet.conf cluster {}; with example.conf
+
+ Revision Changes Path
+ 7.261.4.2 +0 -3 ircd-ratbox/doc/example.conf
+ 7.89.4.2 +17 -12 ircd-ratbox/doc/example.efnet.conf
+ 7.25.4.1 +0 -3 ircd-ratbox/include/class.h
+ 7.68.4.1 +2 -8 ircd-ratbox/src/class.c
+ 7.126.4.1 +1 -1 ircd-ratbox/src/messages.tab
+ 7.202.4.2 +0 -7 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/05/11 22:39:00 UTC (20050511_5)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . RELNOTES
+ include patchlevel.h
+ Log:
+ - update RELNOTES
+ - revved patchlevel to 2.1.2
+
+ Revision Changes Path
+ 1.114.2.2 +17 -0 ircd-ratbox/RELNOTES
+ 7.73.2.2 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/05/11 22:29:18 UTC (20050511_4)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . configure configure.ac
+ Log:
+ - raise default topiclen to 160.
+
+ Revision Changes Path
+ 7.249.2.1 +3 -3 ircd-ratbox/configure
+ 7.63.2.1 +3 -3 ircd-ratbox/configure.ac
+
+
+
+leeh 2005/05/11 22:22:13 UTC (20050511_3)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c
+ Log:
+ - add a current tsinfo param to RSFNC, only accept the fnc if the clients
+ tsinfo matches this
+
+ Revision Changes Path
+ 1.6.4.5 +23 -7 ircd-ratbox/modules/m_services.c
+
+
+
+leeh 2005/05/11 21:58:41 UTC (20050511_2)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c
+ Log:
+ - monitor_signoff() the client we're nickchanging
+
+ Revision Changes Path
+ 1.6.4.4 +3 -1 ircd-ratbox/modules/m_services.c
+
+
+
+leeh 2005/05/11 21:52:51 UTC (20050511_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_trace.c
+ Log:
+ - fix various UID problems with trace
+
+ Revision Changes Path
+ 1.107.4.1 +16 -9 ircd-ratbox/modules/m_trace.c
+
+
+
+leeh 2005/05/11 21:22:02 UTC (20050511_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ help/opers dline kline
+ modules m_resv.c m_stats.c
+ modules/core m_mode.c
+ Log:
+ - sync with 2.0
+ - tidy up kline/dline help to note they dont accept nick as target
+ - disallow bans beginning with ':' over bmask
+ - disallow bans with a space in chm_ban
+ - stop counting hidden opers in stats p
+ - match() parameters in remote unresv were inverted, causing it to fail
+ - fix possibility of clients setting blank keys
+
+ Revision Changes Path
+ 1.2.18.1 +1 -4 ircd-ratbox/help/opers/dline
+ 1.2.24.1 +1 -1 ircd-ratbox/help/opers/kline
+ 1.121.4.1 +15 -5 ircd-ratbox/modules/core/m_mode.c
+ 1.74.4.2 +2 -2 ircd-ratbox/modules/m_resv.c
+ 1.243.4.2 +5 -3 ircd-ratbox/modules/m_stats.c
+
+
+
+leeh 2005/05/08 22:37:18 UTC (20050508_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src send.c
+ Log:
+ - fix problems with amd64 and the way we do va_list
+
+ Revision Changes Path
+ 7.286.4.1 +35 -21 ircd-ratbox/src/send.c
+
+
+
+leeh 2005/05/07 13:35:57 UTC (20050507_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c
+ Log:
+ - tidy up the kill notifications for RSFNC
+
+ Revision Changes Path
+ 1.6.4.3 +9 -2 ircd-ratbox/modules/m_services.c
+
+
+
+leeh 2005/05/07 10:35:54 UTC (20050507_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include s_serv.h
+ modules m_services.c
+ src s_serv.c
+ Log:
+ - some more rserv stuff:
+ - add RSFNC capability
+ - fix up RSFNC, kill existing clients if they exist.
+
+ Revision Changes Path
+ 7.97.4.1 +3 -1 ircd-ratbox/include/s_serv.h
+ 1.6.4.2 +24 -13 ircd-ratbox/modules/m_services.c
+ 7.426.4.1 +1 -0 ircd-ratbox/src/s_serv.c
+
+
+
+leeh 2005/05/06 23:50:29 UTC (20050506_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_services.c
+ Log:
+ - first stab at a FNC implementation for rserv
+
+ Revision Changes Path
+ 1.6.4.1 +86 -2 ircd-ratbox/modules/m_services.c
+
+
+
+leeh 2005/05/03 09:30:51 UTC (20050503_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ help/opers umode
+ Log:
+ - remove a tab
+
+ Revision Changes Path
+ 1.5.4.2 +1 -1 ircd-ratbox/help/opers/umode
+
+
+
+leeh 2005/05/02 22:46:52 UTC (20050502_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src newconf.c
+ Log:
+ - add links_delay back
+
+ Revision Changes Path
+ 7.202.4.1 +15 -0 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/04/27 21:50:30 UTC (20050427_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ help/opers umode
+ help/users umode
+ Log:
+ - swap tabs for spaces
+
+ Revision Changes Path
+ 1.5.4.1 +1 -1 ircd-ratbox/help/opers/umode
+ 1.2.4.1 +1 -1 ircd-ratbox/help/users/umode
+
+
+
+leeh 2005/04/27 21:38:20 UTC (20050427_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include m_info.h
+ Log:
+ - remove the CLIENT_FLOOD define from m_info.h, as the informations already
+ contained in the client_flood conf option
+ - remove a couple of unused defines from info
+
+ Revision Changes Path
+ 7.56.4.1 +0 -20 ircd-ratbox/include/m_info.h
+
+
+
+androsyn 2005/04/26 16:04:29 UTC (20050426_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src s_conf.c
+ Log:
+ use the correct field and swap to host byte order when displaying the Unauthorised connection message
+
+ Revision Changes Path
+ 7.511.4.1 +2 -2 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/04/17 13:31:34 UTC (20050417_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc example.conf example.efnet.conf
+ Log:
+ - fix missing closing comment tag
+
+ Revision Changes Path
+ 7.261.4.1 +1 -1 ircd-ratbox/doc/example.conf
+ 7.89.4.1 +1 -1 ircd-ratbox/doc/example.efnet.conf
+
+
+
+leeh 2005/04/12 18:44:21 UTC (20050412_2)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . RELNOTES
+ include patchlevel.h
+ Log:
+ - revved patchlevel to 2.1.1
+
+ Revision Changes Path
+ 1.114.2.1 +11 -0 ircd-ratbox/RELNOTES
+ 7.73.2.1 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/04/12 18:36:31 UTC (20050412_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_kline.c
+ Log:
+ - sync up remote kline reasons, so theyre consistent with what happens
+ when we add local klines - notably the "Temporary K-line x min" and
+ date added to reason.
+
+ Revision Changes Path
+ 1.200.4.1 +14 -5 ircd-ratbox/modules/m_kline.c
+
+
+
+leeh 2005/04/12 01:52:06 UTC (20050412_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc monitor.txt
+ Log:
+ - force the monitor spec to state RPL_MONONLINE must give n!u@h
+
+ Revision Changes Path
+ 1.3.4.2 +1 -4 ircd-ratbox/doc/monitor.txt
+
+
+
+androsyn 2005/04/08 22:00:05 UTC (20050408_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src commio.c
+ Log:
+ used the data pointer we saved, not what just got nulled
+
+ Revision Changes Path
+ 1.27.4.1 +1 -1 ircd-ratbox/src/commio.c
+
+
+
+leeh 2005/04/05 12:14:32 UTC (20050405_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_resv.c m_xline.c
+ Log:
+ - fix broken propagation of xline/resv
+
+ Revision Changes Path
+ 1.74.4.1 +2 -2 ircd-ratbox/modules/m_resv.c
+ 1.67.4.1 +2 -2 ircd-ratbox/modules/m_xline.c
+
+
+
+leeh 2005/04/04 18:32:37 UTC (20050404_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src s_auth.c
+ Log:
+ - properly increment bad auth count for stats T when we timeout an auth
+
+ Revision Changes Path
+ 7.192.4.2 +1 -0 ircd-ratbox/src/s_auth.c
+
+
+
+leeh 2005/04/04 17:24:14 UTC (20050404_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ doc monitor.txt
+ include client.h
+ modules/core m_nick.c
+ Log:
+ - fix a bit that didnt make sense in monitor.txt
+ - make HOSTIPLEN always v6 sized, so we can always store a v6 clients ip
+
+ Revision Changes Path
+ 1.3.4.1 +1 -1 ircd-ratbox/doc/monitor.txt
+ 7.266.4.1 +2 -4 ircd-ratbox/include/client.h
+ 1.161.4.2 +2 -13 ircd-ratbox/modules/core/m_nick.c
+
+
+
+androsyn 2005/03/28 21:55:44 UTC (20050328_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src s_auth.c
+ Log:
+ removing dlink nodes from auth_poll_list twice is bad
+
+ Revision Changes Path
+ 7.192.4.1 +0 -1 ircd-ratbox/src/s_auth.c
+
+
+
+leeh 2005/03/28 02:17:38 UTC (20050328_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules m_stats.c
+ Log:
+ - move stats L back to RPL_STATSLINKINFO, im not quite sure why this got
+ changed to RPL_STATSDEBUG
+
+ Revision Changes Path
+ 1.243.4.1 +4 -4 ircd-ratbox/modules/m_stats.c
+
+
+
+leeh 2005/03/27 02:19:04 UTC (20050327_0)
+
+ Added files: (Branch: RATBOX_2_1)
+ doc tgchange.txt
+ Log:
+ - add some documentation about target change
+
+ Revision Changes Path
+ 1.1.2.1 +38 -0 ircd-ratbox/doc/tgchange.txt (new)
+
+
+
+leeh 2005/03/25 16:46:29 UTC (20050325_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include supported.h
+ modules/core m_message.c
+ Log:
+ - remove extra argument to 005
+ - disallow messaging of UIDs
+
+ Revision Changes Path
+ 7.5.4.2 +1 -1 ircd-ratbox/include/supported.h
+ 1.162.4.2 +11 -3 ircd-ratbox/modules/core/m_message.c
+
+
+
+leeh 2005/03/25 14:20:13 UTC (20050325_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ src parse.c
+ Log:
+ - fix a longstanding parser bug with wrong limit checking, causing us to
+ accept one less parameter than we're allowed to accept.
+
+ Revision Changes Path
+ 7.187.4.1 +7 -4 ircd-ratbox/src/parse.c
+
+
+
+leeh 2005/03/24 13:41:45 UTC (20050324_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules/core m_message.c
+ Log:
+ - exempt users messaging themselves from target change
+
+ Revision Changes Path
+ 1.162.4.1 +5 -1 ircd-ratbox/modules/core/m_message.c
+
+
+
+leeh 2005/03/22 13:15:53 UTC (20050322_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include supported.h
+ Log:
+ - stop violating MAXPARA on 005.
+
+ Revision Changes Path
+ 7.5.4.1 +3 -4 ircd-ratbox/include/supported.h
+
+
+
+leeh 2005/03/20 17:41:00 UTC (20050320_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ modules/core m_nick.c
+ Log:
+ - dont store an ipv6 sockhost if we're not compiled with v6 support
+
+ Revision Changes Path
+ 1.161.4.1 +13 -2 ircd-ratbox/modules/core/m_nick.c
+
+
+
+leeh 2005/03/20 00:32:04 UTC (20050320_0)
+
+ Modified files: (Branch: RATBOX_2_1)
+ include stdinc.h
+ Log:
+ - remove some vms includes
+
+ Revision Changes Path
+ 1.19.4.1 +0 -46 ircd-ratbox/include/stdinc.h
+
+
+
+leeh 2005/03/18 16:47:38 UTC (20050318_1)
+
+ Modified files: (Branch: RATBOX_2_1)
+ . ChangeLog
+ include serno.h
+ Log:
+ - force commit for new branch
+
+ Revision Changes Path
+ 1.1694.2.1 +0 -0 ircd-ratbox/ChangeLog
+ 7.5463.2.1 +0 -0 ircd-ratbox/include/serno.h
+
+
+
+leeh 2005/03/18 16:44:47 UTC (20050318_0)
+
+ Modified files:
+ . RELNOTES configure configure.ac
+ include patchlevel.h
+ Log:
+ - revved patchlevel to 2.1.0
+
+ Revision Changes Path
+ 1.114 +6 -2 ircd-ratbox/RELNOTES
+ 7.249 +11 -11 ircd-ratbox/configure
+ 7.63 +3 -3 ircd-ratbox/configure.ac
+ 7.73 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/03/04 13:31:32 EST (20050304_2)
+
+ Modified files:
+ . RELNOTES
+ include patchlevel.h
+ Log:
+ - update RELNOTES
+ - revved patchlevel to 2.1.0beta2
+
+ Revision Changes Path
+ 1.113 +12 -0 ircd-ratbox/RELNOTES
+ 7.72 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/03/04 13:27:05 EST (20050304_1)
+
+ Modified files:
+ doc whats-new-2.1.txt
+ src channel.c
+ Log:
+ - update whats-new-2.1
+ - when we're handling global NAMES, dont output channels if there are no
+ members within them we can show.
+
+ Revision Changes Path
+ 7.3 +9 -2 ircd-ratbox/doc/whats-new-2.1.txt
+ 7.436 +12 -2 ircd-ratbox/src/channel.c
+
+
+
+androsyn 2005/03/04 12:38:07 EST (20050304_0)
+
+ Modified files:
+ src patricia.c
+ Log:
+ That would be a node_heap not a prefix_heap..oops
+
+ Revision Changes Path
+ 7.30 +1 -1 ircd-ratbox/src/patricia.c
+
+
+
+androsyn 2005/02/26 19:38:35 EST (20050227_4)
+
+ Modified files:
+ include stdinc.h
+ Log:
+ sort out some alloca related stupidness. if we have gcc just use the builtin for it
+ otherwise..the other macros might work????
+
+ Revision Changes Path
+ 1.19 +15 -6 ircd-ratbox/include/stdinc.h
+
+
+
+androsyn 2005/02/26 19:26:04 EST (20050227_3)
+
+ Modified files:
+ . configure configure.ac
+ Log:
+ i hate autoconf
+
+ Revision Changes Path
+ 7.248 +5 -5 ircd-ratbox/configure
+ 7.62 +5 -5 ircd-ratbox/configure.ac
+
+
+
+androsyn 2005/02/26 19:15:55 EST (20050227_2)
+
+ Modified files:
+ . configure configure.ac
+ Log:
+ i hate autoconf
+
+ Revision Changes Path
+ 7.247 +3 -2 ircd-ratbox/configure
+ 7.61 +3 -2 ircd-ratbox/configure.ac
+
+
+
+androsyn 2005/02/26 19:13:45 EST (20050227_1)
+
+ Modified files:
+ . configure configure.ac
+ Log:
+ doh
+
+ Revision Changes Path
+ 7.246 +6 -6 ircd-ratbox/configure
+ 7.60 +4 -4 ircd-ratbox/configure.ac
+
+
+
+androsyn 2005/02/26 19:10:17 EST (20050227_0)
+
+ Modified files:
+ . configure configure.ac
+ include stdinc.h
+ Log:
+ Doh these changes got put on RATBOX_2_0 when they were meant for
+ head..oops...
+ Also merged in the monitor heap size stuff, not that i think monitor has
+ been moved to head
+
+ Revision Changes Path
+ 7.245 +12 -3 ircd-ratbox/configure
+ 7.59 +11 -3 ircd-ratbox/configure.ac
+ 1.18 +57 -20 ircd-ratbox/include/stdinc.h
+
+
+
+androsyn 2005/02/26 18:52:24 EST (20050226_0)
+
+ Modified files:
+ include stdinc.h
+ Log:
+ Add more robust alloca checking
+
+ Revision Changes Path
+ 1.17 +20 -11 ircd-ratbox/include/stdinc.h
+
+
+
+leeh 2005/02/24 15:27:17 EST (20050224_9)
+
+ Modified files:
+ contrib m_42.c
+ Log:
+ - fix the copyright on m_42.c :p
+
+ Revision Changes Path
+ 1.4 +2 -2 ircd-ratbox/contrib/m_42.c
+
+
+
+leeh 2005/02/24 15:22:53 EST (20050224_8)
+
+ Modified files:
+ include supported.h
+ modules m_dline.c
+ Log:
+ - fix a core in undline on bad masks
+ - remove an unwanted space from beginning of second 005 numeric
+
+ Revision Changes Path
+ 7.5 +1 -1 ircd-ratbox/include/supported.h
+ 1.49 +8 -1 ircd-ratbox/modules/m_dline.c
+
+
+
+leeh 2005/02/24 15:18:59 EST (20050224_7)
+
+ Modified files:
+ modules m_monitor.c
+ Log:
+ - use max_monitor when adding nicknames
+ - add in monitor s
+ that should be everything now..
+
+ Revision Changes Path
+ 1.3 +90 -1 ircd-ratbox/modules/m_monitor.c
+
+
+
+androsyn 2005/02/24 15:13:52 EST (20050224_6)
+
+ Modified files:
+ contrib m_42.c
+ Log:
+ 42
+
+ Revision Changes Path
+ 1.3 +1 -1 ircd-ratbox/contrib/m_42.c
+
+
+
+androsyn 2005/02/24 15:13:06 EST (20050224_5)
+
+ Modified files:
+ contrib m_42.c
+ Log:
+ 42
+
+ Revision Changes Path
+ 1.2 +1 -1 ircd-ratbox/contrib/m_42.c
+
+
+
+androsyn 2005/02/24 15:12:12 EST (20050224_4)
+
+ Added files:
+ contrib m_42.c
+ Log:
+ The Answer to Life, the Universe, and Everything
+
+ Revision Changes Path
+ 1.1 +35 -0 ircd-ratbox/contrib/m_42.c (new)
+
+
+
+leeh 2005/02/24 14:53:04 EST (20050224_3)
+
+ Modified files:
+ include monitor.h
+ modules m_monitor.c
+ src ircd.c monitor.c
+ Log:
+ - call init_monitor() on startup
+ - add in support for adding/deleting/listing monitor entries
+
+ Revision Changes Path
+ 7.2 +3 -1 ircd-ratbox/include/monitor.h
+ 1.2 +155 -1 ircd-ratbox/modules/m_monitor.c
+ 7.374 +2 -0 ircd-ratbox/src/ircd.c
+ 7.3 +15 -4 ircd-ratbox/src/monitor.c
+
+
+
+leeh 2005/02/23 21:20:10 EST (20050224_2)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ include s_conf.h supported.h
+ modules Makefile.in
+ src client.c newconf.c s_conf.c
+ Added files:
+ modules m_monitor.c
+ Log:
+ - add the max_monitor config option
+ - advertise MONITOR=%d in 005
+ - clear a local clients monitor list on exit
+ - add the framework for the MONITOR command
+ - bed.
+
+ Revision Changes Path
+ 7.261 +5 -0 ircd-ratbox/doc/example.conf
+ 7.89 +5 -0 ircd-ratbox/doc/example.efnet.conf
+ 7.315 +1 -0 ircd-ratbox/include/s_conf.h
+ 7.4 +4 -2 ircd-ratbox/include/supported.h
+ 1.119 +1 -0 ircd-ratbox/modules/Makefile.in
+ 1.1 +95 -0 ircd-ratbox/modules/m_monitor.c (new)
+ 7.492 +1 -0 ircd-ratbox/src/client.c
+ 7.202 +1 -0 ircd-ratbox/src/newconf.c
+ 7.511 +1 -0 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/23 20:57:51 EST (20050224_1)
+
+ Modified files:
+ . configure configure.ac
+ include setup.h.in
+ src monitor.c
+ Log:
+ - move MONITOR_HEAP_SIZE over to configure
+
+ Revision Changes Path
+ 7.244 ircd-ratbox/configure
+ 7.58 +4 -2 ircd-ratbox/configure.ac
+ 7.95 +3 -0 ircd-ratbox/include/setup.h.in
+ 7.2 +0 -2 ircd-ratbox/src/monitor.c
+
+
+
+leeh 2005/02/23 20:48:08 EST (20050224_0)
+
+ Modified files:
+ doc monitor.txt
+ include client.h numeric.h
+ modules/core m_nick.c
+ src Makefile.in client.c messages.tab
+ s_user.c
+ Added files:
+ include monitor.h
+ src monitor.c
+ Log:
+ - first half of my server-side notify list implementation..
+
+ Revision Changes Path
+ 1.3 +2 -2 ircd-ratbox/doc/monitor.txt
+ 7.266 +3 -0 ircd-ratbox/include/client.h
+ 7.1 +30 -0 ircd-ratbox/include/monitor.h (new)
+ 7.58 +6 -0 ircd-ratbox/include/numeric.h
+ 1.161 +17 -3 ircd-ratbox/modules/core/m_nick.c
+ 7.155 +1 -0 ircd-ratbox/src/Makefile.in
+ 7.491 +3 -0 ircd-ratbox/src/client.c
+ 7.126 +5 -5 ircd-ratbox/src/messages.tab
+ 7.1 +182 -0 ircd-ratbox/src/monitor.c (new)
+ 7.342 +2 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/02/23 18:42:59 EST (20050223_0)
+
+ Modified files:
+ include hash.h
+ Log:
+ - double the size of the client and channel hashtables (64k -> 128k and
+ 32k -> 64k). The improvements are quite significant..
+
+ Revision Changes Path
+ 7.54 +4 -4 ircd-ratbox/include/hash.h
+
+
+
+leeh 2005/02/22 14:55:56 EST (20050222_1)
+
+ Modified files:
+ doc monitor.txt
+ modules m_services.c
+ Log:
+ - remove a couple of unused vars
+ - update monitor.txt
+
+ Revision Changes Path
+ 1.2 +14 -0 ircd-ratbox/doc/monitor.txt
+ 1.6 +1 -4 ircd-ratbox/modules/m_services.c
+
+
+
+leeh 2005/02/21 19:47:24 EST (20050222_0)
+
+ Added files:
+ doc monitor.txt
+ Log:
+ - add in my documentation on the upcoming MONITOR command
+
+ Revision Changes Path
+ 1.1 +100 -0 ircd-ratbox/doc/monitor.txt (new)
+
+
+
+leeh 2005/02/21 12:09:34 EST (20050221_0)
+
+ Modified files:
+ . configure configure.ac
+ doc whats-new-2.1.txt
+ tools README.mkpasswd
+ Removed files:
+ src crypt.c
+ Log:
+ - update whats-new-2.1.txt some more
+ - we dont have vms mkpasswd anymore
+ - remove the unused crypt.c
+
+ Revision Changes Path
+ 7.243 +3 -6 ircd-ratbox/configure
+ 7.57 +2 -4 ircd-ratbox/configure.ac
+ 7.2 +2 -0 ircd-ratbox/doc/whats-new-2.1.txt
+ 7.13 +0 -504 ircd-ratbox/src/crypt.c (dead)
+ 1.9 +0 -3 ircd-ratbox/tools/README.mkpasswd
+
+
+
+leeh 2005/02/19 12:38:09 EST (20050219_3)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ include ircd.h
+ modules m_pong.c
+ src channel.c client.c ircd.c s_conf.c
+ Log:
+ - rework the splitcode, splitservers is now how many servers we've marked as
+ EOB, rather than how many are linked. Thus pull ourselves out of
+ splitmode immediately once this is satisfied
+
+ Revision Changes Path
+ 7.260 +8 -9 ircd-ratbox/doc/example.conf
+ 7.88 +10 -11 ircd-ratbox/doc/example.efnet.conf
+ 7.83 +1 -0 ircd-ratbox/include/ircd.h
+ 1.60 +2 -1 ircd-ratbox/modules/m_pong.c
+ 7.435 +16 -36 ircd-ratbox/src/channel.c
+ 7.490 +2 -0 ircd-ratbox/src/client.c
+ 7.373 +2 -1 ircd-ratbox/src/ircd.c
+ 7.510 +11 -3 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/19 09:02:34 EST (20050219_2)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ include ircd.h s_conf.h
+ modules m_set.c
+ src channel.c ircd.c newconf.c s_conf.c
+ Log:
+ - remove split_delay
+
+ Revision Changes Path
+ 7.259 +0 -5 ircd-ratbox/doc/example.conf
+ 7.87 +0 -5 ircd-ratbox/doc/example.efnet.conf
+ 7.82 +0 -1 ircd-ratbox/include/ircd.h
+ 7.314 +0 -1 ircd-ratbox/include/s_conf.h
+ 1.81 +1 -20 ircd-ratbox/modules/m_set.c
+ 7.434 +2 -7 ircd-ratbox/src/channel.c
+ 7.372 +0 -1 ircd-ratbox/src/ircd.c
+ 7.201 +0 -1 ircd-ratbox/src/newconf.c
+ 7.509 +0 -1 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/19 08:48:05 EST (20050219_1)
+
+ Modified files:
+ include client.h
+ modules m_cap.c m_who.c
+ src channel.c
+ Log:
+ - implemented multi-prefix client capability, which allows stacking of @+ in
+ names and who
+
+ Revision Changes Path
+ 7.265 +1 -1 ircd-ratbox/include/client.h
+ 1.6 +6 -15 ircd-ratbox/modules/m_cap.c
+ 1.115 +4 -3 ircd-ratbox/modules/m_who.c
+ 7.433 +4 -6 ircd-ratbox/src/channel.c
+
+
+
+leeh 2005/02/19 06:27:58 EST (20050219_0)
+
+ Modified files:
+ modules m_etrace.c
+ src newconf.c s_conf.c s_newconf.c
+ Log:
+ - removed some unused vars/functions
+
+ Revision Changes Path
+ 1.15 +1 -2 ircd-ratbox/modules/m_etrace.c
+ 7.200 +0 -15 ircd-ratbox/src/newconf.c
+ 7.508 +0 -1 ircd-ratbox/src/s_conf.c
+ 7.67 +0 -1 ircd-ratbox/src/s_newconf.c
+
+
+
+leeh 2005/02/16 12:58:24 EST (20050216_2)
+
+ Modified files:
+ . RELNOTES configure configure.ac
+ include patchlevel.h
+ Log:
+ - update configure to reflect this is 'devel'
+ - update RELNOTES
+ - revved patchlevel to 2.1.0beta1
+
+ Revision Changes Path
+ 1.112 +9 -1 ircd-ratbox/RELNOTES
+ 7.242 +11 -11 ircd-ratbox/configure
+ 7.56 +3 -3 ircd-ratbox/configure.ac
+ 7.71 +1 -1 ircd-ratbox/include/patchlevel.h
+
+
+
+leeh 2005/02/16 12:46:30 EST (20050216_1)
+
+ Modified files:
+ . configure configure.ac
+ include client.h numeric.h s_conf.h setup.h.in
+ supported.h
+ modules Makefile.in
+ modules/core m_nick.c
+ src Makefile.in client.c ircd.c messages.tab
+ newconf.c s_conf.c s_user.c
+ Removed files:
+ include watch.h
+ modules m_watch.c
+ src watch.c
+ Log:
+ - remove watch, the protocol for this sucks so hard I just dont want it
+ here ;-)
+
+ Revision Changes Path
+ 7.241 +2 -12 ircd-ratbox/configure
+ 7.55 +2 -4 ircd-ratbox/configure.ac
+ 7.264 +0 -2 ircd-ratbox/include/client.h
+ 7.57 +0 -11 ircd-ratbox/include/numeric.h
+ 7.313 +0 -1 ircd-ratbox/include/s_conf.h
+ 7.94 +0 -3 ircd-ratbox/include/setup.h.in
+ 7.3 +2 -3 ircd-ratbox/include/supported.h
+ 7.4 +0 -53 ircd-ratbox/include/watch.h (dead)
+ 1.118 +0 -1 ircd-ratbox/modules/Makefile.in
+ 1.160 +1 -16 ircd-ratbox/modules/core/m_nick.c
+ 1.8 +0 -272 ircd-ratbox/modules/m_watch.c (dead)
+ 7.154 +0 -1 ircd-ratbox/src/Makefile.in
+ 7.489 +0 -3 ircd-ratbox/src/client.c
+ 7.371 +0 -2 ircd-ratbox/src/ircd.c
+ 7.125 +9 -9 ircd-ratbox/src/messages.tab
+ 7.199 +0 -1 ircd-ratbox/src/newconf.c
+ 7.507 +0 -1 ircd-ratbox/src/s_conf.c
+ 7.341 +0 -2 ircd-ratbox/src/s_user.c
+ 1.7 +0 -239 ircd-ratbox/src/watch.c (dead)
+
+
+
+leeh 2005/02/15 19:13:31 EST (20050216_0)
+
+ Modified files:
+ include stdinc.h
+ src event.c ircd_lexer.l ircd_signal.c
+ modules.c
+ Removed files:
+ servlink descrip.mms
+ Log:
+ - remove a few vms bits
+
+ Revision Changes Path
+ 1.16 +0 -46 ircd-ratbox/include/stdinc.h
+ 1.4 +0 -15 ircd-ratbox/servlink/descrip.mms (dead)
+ 7.47 +0 -54 ircd-ratbox/src/event.c
+ 1.168 +1 -5 ircd-ratbox/src/ircd_lexer.l
+ 7.27 +0 -25 ircd-ratbox/src/ircd_signal.c
+ 7.152 +0 -3 ircd-ratbox/src/modules.c
+
+
+
+leeh 2005/02/15 18:53:32 EST (20050215_0)
+
+ Modified files:
+ include hostmask.h ircd.h s_conf.h s_newconf.h
+ modules m_dline.c m_kline.c m_rehash.c m_resv.c
+ m_xline.c
+ src hostmask.c ircd.c ircd_signal.c s_conf.c
+ s_newconf.c
+ Log:
+ - we now no longer rehash kline.conf etc on rehash, only ircd.conf
+ - SIGUSR2 or /rehash bans will now reread kline.conf etc.
+
+ Revision Changes Path
+ 1.42 +1 -0 ircd-ratbox/include/hostmask.h
+ 7.81 +1 -0 ircd-ratbox/include/ircd.h
+ 7.312 +1 -0 ircd-ratbox/include/s_conf.h
+ 7.46 +1 -0 ircd-ratbox/include/s_newconf.h
+ 1.48 +2 -2 ircd-ratbox/modules/m_dline.c
+ 1.200 +2 -2 ircd-ratbox/modules/m_kline.c
+ 1.89 +11 -1 ircd-ratbox/modules/m_rehash.c
+ 1.74 +2 -2 ircd-ratbox/modules/m_resv.c
+ 1.67 +2 -2 ircd-ratbox/modules/m_xline.c
+ 7.106 +35 -1 ircd-ratbox/src/hostmask.c
+ 7.370 +7 -0 ircd-ratbox/src/ircd.c
+ 7.26 +10 -0 ircd-ratbox/src/ircd_signal.c
+ 7.506 +59 -47 ircd-ratbox/src/s_conf.c
+ 7.66 +7 -0 ircd-ratbox/src/s_newconf.c
+
+
+
+leeh 2005/02/13 10:21:41 EST (20050213_4)
+
+ Modified files:
+ doc services.txt
+ Added files:
+ doc whats-new-2.0.txt whats-new-2.1.txt
+ Removed files:
+ doc whats-new.txt
+ Log:
+ - move whats-new.txt to whats-new-2.0.txt
+ - add in whats-new-2.1.txt
+ - update services.txt with the whois for logged in users
+
+ Revision Changes Path
+ 7.2 +5 -0 ircd-ratbox/doc/services.txt
+ 7.1 +113 -0 ircd-ratbox/doc/whats-new-2.0.txt (new)
+ 7.1 +60 -0 ircd-ratbox/doc/whats-new-2.1.txt (new)
+ 7.51 +0 -113 ircd-ratbox/doc/whats-new.txt (dead)
+
+
+
+leeh 2005/02/13 09:20:37 EST (20050213_3)
+
+ Modified files:
+ include supported.h
+ modules/core m_message.c
+ Log:
+ - fix a compile error in m_message.c
+ - update 005 to the spec and add CPRIVMSG/CNOTICE
+
+ Revision Changes Path
+ 7.2 +31 -37 ircd-ratbox/include/supported.h
+ 1.162 +2 -2 ircd-ratbox/modules/core/m_message.c
+
+
+
+leeh 2005/02/13 09:14:12 EST (20050213_2)
+
+ Modified files:
+ src channel.c
+ Log:
+ - fix the membership memleak
+
+ Revision Changes Path
+ 7.432 +0 -3 ircd-ratbox/src/channel.c
+
+
+
+leeh 2005/02/12 21:51:56 EST (20050213_1)
+
+ Modified files:
+ include client.h
+ modules/core m_message.c
+ Log:
+ - add a bitmask to track when they send their first message, only allowing
+ clearing stuff after that.
+
+ Revision Changes Path
+ 7.263 +4 -0 ircd-ratbox/include/client.h
+ 1.161 +13 -2 ircd-ratbox/modules/core/m_message.c
+
+
+
+leeh 2005/02/12 21:17:52 EST (20050213_0)
+
+ Modified files:
+ include patricia.h s_newconf.h
+ modules/core m_message.c
+ src patricia.c s_newconf.c s_user.c
+ Log:
+ - add in the patricia for tracking who fills up targets, give them a reduced
+ count on connect
+
+ Revision Changes Path
+ 7.20 +1 -1 ircd-ratbox/include/patricia.h
+ 7.45 +17 -0 ircd-ratbox/include/s_newconf.h
+ 1.160 +43 -4 ircd-ratbox/modules/core/m_message.c
+ 7.29 +1 -1 ircd-ratbox/src/patricia.c
+ 7.65 +36 -0 ircd-ratbox/src/s_newconf.c
+ 7.340 +4 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/02/12 18:35:10 EST (20050212_0)
+
+ Modified files:
+ include ircd_defs.h
+ src class.c reject.c
+ Log:
+ - add a PATRICIA_BITS define, make calls to New_Patricia() use it.
+
+ Revision Changes Path
+ 7.55 +5 -0 ircd-ratbox/include/ircd_defs.h
+ 7.68 +1 -5 ircd-ratbox/src/class.c
+ 1.33 +1 -5 ircd-ratbox/src/reject.c
+
+
+
+androsyn 2005/02/11 17:11:57 EST (20050211_1)
+
+ Modified files:
+ modules m_watch.c
+ Log:
+ remove stupid memory leak
+
+ Revision Changes Path
+ 1.7 +1 -2 ircd-ratbox/modules/m_watch.c
+
+
+
+leeh 2005/02/11 06:42:48 EST (20050211_0)
+
+ Modified files:
+ modules m_gline.c
+ Log:
+ - workaround hyb6 allowing empty gline reasons
+
+ Revision Changes Path
+ 1.150 +10 -2 ircd-ratbox/modules/m_gline.c
+
+
+
+leeh 2005/02/09 14:39:13 EST (20050209_2)
+
+ Modified files:
+ include s_conf.h
+ modules m_dline.c m_kline.c m_rehash.c m_stats.c
+ src ircd.c s_conf.c
+ Log:
+ - move temp dlines and temp klines over to an array, rather than completely
+ seperate dlinks.
+
+ Revision Changes Path
+ 7.311 +11 -20 ircd-ratbox/include/s_conf.h
+ 1.47 +4 -15 ircd-ratbox/modules/m_dline.c
+ 1.199 +4 -15 ircd-ratbox/modules/m_kline.c
+ 1.88 +42 -26 ircd-ratbox/modules/m_rehash.c
+ 1.243 +22 -31 ircd-ratbox/modules/m_stats.c
+ 7.369 +0 -5 ircd-ratbox/src/ircd.c
+ 7.505 +78 -104 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/09 14:02:13 EST (20050209_1)
+
+ Modified files:
+ include s_user.h
+ modules m_cap.c m_pong.c m_user.c
+ modules/core m_nick.c
+ src s_user.c
+ Log:
+ - remove 'nick' param from register_local_user(), its not needed.
+
+ Revision Changes Path
+ 7.35 +1 -1 ircd-ratbox/include/s_user.h
+ 1.159 +2 -2 ircd-ratbox/modules/core/m_nick.c
+ 1.5 +2 -2 ircd-ratbox/modules/m_cap.c
+ 1.59 +2 -3 ircd-ratbox/modules/m_pong.c
+ 1.46 +2 -2 ircd-ratbox/modules/m_user.c
+ 7.339 +6 -6 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/02/09 13:12:53 EST (20050209_0)
+
+ Modified files:
+ modules m_cmessage.c
+ Log:
+ - dont send numerics when we're dealing with CNOTICE
+ - add in checking for +g, and resetting idle
+
+ Revision Changes Path
+ 1.2 +41 -7 ircd-ratbox/modules/m_cmessage.c
+
+
+
+leeh 2005/02/08 11:37:50 EST (20050208_2)
+
+ Modified files:
+ src s_newconf.c
+ Log:
+ - fix operator blocks to work on ip spoofs
+
+ Revision Changes Path
+ 7.64 +9 -8 ircd-ratbox/src/s_newconf.c
+
+
+
+leeh 2005/02/07 19:23:22 EST (20050208_1)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ src newconf.c
+ Log:
+ - removed ability to set klines/dlines/xlines/resvs in ircd.conf
+
+ Revision Changes Path
+ 7.258 +0 -39 ircd-ratbox/doc/example.conf
+ 7.86 +0 -42 ircd-ratbox/doc/example.efnet.conf
+ 7.198 +0 -272 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/02/07 19:19:32 EST (20050208_0)
+
+ Modified files:
+ src s_conf.c
+ Log:
+ - added support for kline.conf.perm et al, these take the same formats
+ as their non-permanent partners, but you cant remove them via the ircd.
+
+ Revision Changes Path
+ 7.504 +33 -67 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/02 19:18:59 EST (20050203_1)
+
+ Modified files:
+ help Makefile.in
+ help/opers index
+ help/users index
+ Added files:
+ help/opers cnotice cprivmsg
+ Log:
+ - added help files for cprivmsg/cnotice
+
+ Revision Changes Path
+ 1.23 +3 -2 ircd-ratbox/help/Makefile.in
+ 1.1 +5 -0 ircd-ratbox/help/opers/cnotice (new)
+ 1.1 +5 -0 ircd-ratbox/help/opers/cprivmsg (new)
+ 1.10 +19 -19 ircd-ratbox/help/opers/index
+ 1.7 +10 -9 ircd-ratbox/help/users/index
+
+
+
+leeh 2005/02/02 19:14:25 EST (20050203_0)
+
+ Modified files:
+ include numeric.h
+ modules Makefile.in
+ src messages.tab
+ Added files:
+ modules m_cmessage.c
+ Log:
+ - implemented CPRIVMSG/CNOTICE, stolen from undernet. Take the form:
+ CPRIVMSG <nick> <channel> :<text>. Work if sender is +ov in channel, and
+ nick is a member. These bypass any target change limitations.
+ - added ERR_VOICENEEDED, numeric 489.
+
+ Revision Changes Path
+ 7.56 +2 -0 ircd-ratbox/include/numeric.h
+ 1.117 +1 -0 ircd-ratbox/modules/Makefile.in
+ 1.1 +122 -0 ircd-ratbox/modules/m_cmessage.c (new)
+ 7.124 +1 -1 ircd-ratbox/src/messages.tab
+
+
+
+leeh 2005/02/02 16:58:16 EST (20050202_4)
+
+ Modified files:
+ help/opers etrace
+ Log:
+ - update etrace help
+
+ Revision Changes Path
+ 1.3 +7 -1 ircd-ratbox/help/opers/etrace
+
+
+
+leeh 2005/02/02 16:55:04 EST (20050202_3)
+
+ Modified files:
+ modules m_etrace.c
+ Log:
+ - tidy up etrace slightly, stop showing fullcaps for spoofed users as mirc
+ can put its external ip address in there..
+
+ Revision Changes Path
+ 1.14 +31 -41 ircd-ratbox/modules/m_etrace.c
+
+
+
+leeh 2005/02/02 16:41:06 EST (20050202_2)
+
+ Modified files:
+ modules m_etrace.c
+ Log:
+ - patch via nenolod, allows ETRACE <nick>, gets sent remotely over ENCAP
+ if its a non-local client. These will just get "lost" if the remote
+ server doesnt support this..
+
+ Revision Changes Path
+ 1.13 +66 -4 ircd-ratbox/modules/m_etrace.c
+
+
+
+leeh 2005/02/02 16:12:12 EST (20050202_1)
+
+ Modified files:
+ include client.h numeric.h s_conf.h
+ modules/core m_message.c
+ src messages.tab newconf.c s_conf.c
+ Log:
+ - first part of the target change code, add the storage of targets for
+ localuser, throttle messages when they fill all the available slots
+
+ Revision Changes Path
+ 7.262 +5 -1 ircd-ratbox/include/client.h
+ 7.55 +2 -0 ircd-ratbox/include/numeric.h
+ 7.310 +1 -0 ircd-ratbox/include/s_conf.h
+ 1.159 +65 -1 ircd-ratbox/modules/core/m_message.c
+ 7.123 +1 -1 ircd-ratbox/src/messages.tab
+ 7.197 +1 -0 ircd-ratbox/src/newconf.c
+ 7.503 +1 -0 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/02/02 13:28:10 EST (20050202_0)
+
+ Modified files:
+ modules m_resv.c m_stats.c m_testline.c
+ modules/core m_join.c
+ src hash.c kdparse.c messages.tab s_newconf.c
+ Log:
+ - patch via nenolod, <nenolod -at- noderebellion.net> to add counter
+ tracking of when resvs get hit
+
+ Revision Changes Path
+ 1.164 +7 -1 ircd-ratbox/modules/core/m_join.c
+ 1.73 +3 -1 ircd-ratbox/modules/m_resv.c
+ 1.242 +5 -5 ircd-ratbox/modules/m_stats.c
+ 1.55 +6 -1 ircd-ratbox/modules/m_testline.c
+ 7.114 +3 -0 ircd-ratbox/src/hash.c
+ 7.43 +2 -0 ircd-ratbox/src/kdparse.c
+ 7.122 +1 -1 ircd-ratbox/src/messages.tab
+ 7.63 +3 -0 ircd-ratbox/src/s_newconf.c
+
+
+
+leeh 2005/01/31 09:04:10 EST (20050131_2)
+
+ Modified files:
+ src s_log.c
+ Log:
+ - fflush() logfiles
+
+ Revision Changes Path
+ 7.79 +2 -0 ircd-ratbox/src/s_log.c
+
+
+
+leeh 2005/01/31 08:59:09 EST (20050131_1)
+
+ Modified files:
+ src commio.c
+ Log:
+ - rename fd_dump() to comm_dump()
+
+ Revision Changes Path
+ 1.27 +2 -2 ircd-ratbox/src/commio.c
+
+
+
+leeh 2005/01/30 19:16:08 EST (20050131_0)
+
+ Modified files:
+ doc hooks.txt
+ include hook.h
+ modules m_services.c
+ modules/core m_server.c
+ src hook.c s_serv.c
+ Log:
+ - added hook for server_introduced
+ - fixed up services support for hooks
+
+ Revision Changes Path
+ 1.4 +10 -0 ircd-ratbox/doc/hooks.txt
+ 1.31 +1 -0 ircd-ratbox/include/hook.h
+ 1.152 +6 -1 ircd-ratbox/modules/core/m_server.c
+ 1.5 +8 -22 ircd-ratbox/modules/m_services.c
+ 7.36 +2 -0 ircd-ratbox/src/hook.c
+ 7.426 +5 -0 ircd-ratbox/src/s_serv.c
+
+
+
+androsyn 2005/01/29 20:18:12 EST (20050130_1)
+
+ Modified files:
+ src commio.c
+ Log:
+ Add back in the comm_fd_hack thing for solaris
+
+ Revision Changes Path
+ 1.26 +26 -1 ircd-ratbox/src/commio.c
+
+
+
+androsyn 2005/01/29 19:59:17 EST (20050130_0)
+
+ Modified files:
+ adns adns.h
+ include commio.h s_conf.h watch.h
+ modules m_dline.c m_kline.c m_resv.c m_stats.c
+ m_watch.c m_xline.c
+ modules/core m_nick.c
+ src balloc.c cache.c client.c commio.c
+ epoll.c ircd.c ircd_lexer.l kdparse.c
+ listener.c s_auth.c s_conf.c s_log.c
+ s_serv.c watch.c
+ Log:
+ Do the fb* to f* mangle and then fix watch to prevent stupid crap
+
+ Revision Changes Path
+ 1.18 +0 -2 ircd-ratbox/adns/adns.h
+ 1.14 +6 -37 ircd-ratbox/include/commio.h
+ 7.309 +6 -6 ircd-ratbox/include/s_conf.h
+ 7.3 +2 -2 ircd-ratbox/include/watch.h
+ 1.158 +3 -3 ircd-ratbox/modules/core/m_nick.c
+ 1.46 +13 -13 ircd-ratbox/modules/m_dline.c
+ 1.198 +12 -12 ircd-ratbox/modules/m_kline.c
+ 1.72 +11 -11 ircd-ratbox/modules/m_resv.c
+ 1.241 +3 -3 ircd-ratbox/modules/m_stats.c
+ 1.6 +60 -21 ircd-ratbox/modules/m_watch.c
+ 1.66 +16 -16 ircd-ratbox/modules/m_xline.c
+ 7.85 +1 -1 ircd-ratbox/src/balloc.c
+ 1.24 +5 -5 ircd-ratbox/src/cache.c
+ 7.488 +4 -4 ircd-ratbox/src/client.c
+ 1.25 +10 -280 ircd-ratbox/src/commio.c
+ 1.33 +1 -1 ircd-ratbox/src/epoll.c
+ 7.368 +4 -4 ircd-ratbox/src/ircd.c
+ 1.167 +6 -6 ircd-ratbox/src/ircd_lexer.l
+ 7.42 +8 -8 ircd-ratbox/src/kdparse.c
+ 7.125 +8 -8 ircd-ratbox/src/listener.c
+ 7.192 +6 -6 ircd-ratbox/src/s_auth.c
+ 7.502 +21 -21 ircd-ratbox/src/s_conf.c
+ 7.78 +20 -20 ircd-ratbox/src/s_log.c
+ 7.425 +8 -8 ircd-ratbox/src/s_serv.c
+ 1.6 +22 -15 ircd-ratbox/src/watch.c
+
+
+
+androsyn 2005/01/29 12:18:38 EST (20050129_0)
+
+ Modified files:
+ modules/core m_mode.c
+ Log:
+ remove two unused variables
+
+ Revision Changes Path
+ 1.121 +1 -3 ircd-ratbox/modules/core/m_mode.c
+
+
+
+leeh 2005/01/28 15:31:40 EST (20050128_1)
+
+ Modified files:
+ modules m_kline.c
+ src s_conf.c
+ Log:
+ - mo_kline() needs minpara of 3, not 2
+ - drop ms_kline() minpara to 5, to counter a bug in 1.5-3
+ - require me.info is never blank
+
+ Revision Changes Path
+ 1.197 +9 -2 ircd-ratbox/modules/m_kline.c
+ 7.501 +2 -2 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/01/28 15:26:28 EST (20050128_0)
+
+ Modified files:
+ modules/core m_mode.c m_sjoin.c
+ Log:
+ - patch via jilles to fix +eI lists being shown to lusers when handling
+ protocol stuff over TS6
+
+ Revision Changes Path
+ 1.120 +7 -3 ircd-ratbox/modules/core/m_mode.c
+ 1.205 +8 -8 ircd-ratbox/modules/core/m_sjoin.c
+
+
+
+leeh 2005/01/25 19:47:38 EST (20050126_0)
+
+ Modified files:
+ include channel.h
+ modules/core m_join.c m_mode.c m_sjoin.c
+ src channel.c messages.tab s_serv.c
+ Log:
+ - remove loc_channel_modes(), made channel_modes() handle IsMe() and make
+ an operspy call with &me
+ - remove modebuf/parabuf params from channel_modes(), we now generate a
+ buffer internally which we return.
+
+ Revision Changes Path
+ 7.163 +1 -1 ircd-ratbox/include/channel.h
+ 1.163 +12 -14 ircd-ratbox/modules/core/m_join.c
+ 1.119 +4 -47 ircd-ratbox/modules/core/m_mode.c
+ 1.204 +9 -12 ircd-ratbox/modules/core/m_sjoin.c
+ 7.431 +25 -18 ircd-ratbox/src/channel.c
+ 7.121 +1 -1 ircd-ratbox/src/messages.tab
+ 7.424 +6 -14 ircd-ratbox/src/s_serv.c
+
+
+
+alz 2005/01/25 18:09:18 EST (20050125_5)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ include s_conf.h
+ modules m_info.c
+ src listener.c newconf.c s_conf.c
+ Log:
+ Added dline_with_reason config option (default yes):
+
+ /* dline reason: show the user the dline reason when they connect
+ * and are dlined.
+ */
+ dline_with_reason = yes;
+
+ Revision Changes Path
+ 7.257 +6 -1 ircd-ratbox/doc/example.conf
+ 7.85 +6 -1 ircd-ratbox/doc/example.efnet.conf
+ 7.308 +1 -0 ircd-ratbox/include/s_conf.h
+ 1.122 +7 -1 ircd-ratbox/modules/m_info.c
+ 7.124 +1 -1 ircd-ratbox/src/listener.c
+ 7.196 +1 -0 ircd-ratbox/src/newconf.c
+ 7.500 +1 -0 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/01/25 13:21:17 EST (20050125_4)
+
+ Modified files:
+ src newconf.c
+ Log:
+ - make conf_set_generic_string() test len exists before it uses it.
+
+ Revision Changes Path
+ 7.195 +1 -1 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/01/25 13:10:56 EST (20050125_3)
+
+ Modified files:
+ doc example.conf
+ src newconf.c
+ Log:
+ - rename 'type' to 'flags' in cluster {};
+ - add stacking of servers in cluster {}; documented in example.conf
+
+ Revision Changes Path
+ 7.256 +18 -10 ircd-ratbox/doc/example.conf
+ 7.194 +39 -7 ircd-ratbox/src/newconf.c
+
+
+
+alz 2005/01/25 12:48:54 EST (20050125_2)
+
+ Modified files:
+ include s_conf.h
+ src listener.c s_conf.c
+ Log:
+ Added dline reasons, connecting/banned clients now see ban reason.
+
+ Revision Changes Path
+ 7.307 +1 -1 ircd-ratbox/include/s_conf.h
+ 7.123 +17 -4 ircd-ratbox/src/listener.c
+ 7.499 +5 -5 ircd-ratbox/src/s_conf.c
+
+
+
+leeh 2005/01/25 07:44:37 EST (20050125_1)
+
+ Modified files:
+ doc example.conf example.efnet.conf
+ src newconf.c
+ Log:
+ - implement stacking of shared {}; blocks, documented in example.conf
+
+ Revision Changes Path
+ 7.255 +26 -13 ircd-ratbox/doc/example.conf
+ 7.84 +27 -14 ircd-ratbox/doc/example.efnet.conf
+ 7.193 +51 -36 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/01/24 19:08:29 EST (20050125_0)
+
+ Modified files:
+ doc example.conf
+ include client.h s_conf.h
+ modules/core m_join.c
+ src newconf.c s_user.c
+ Log:
+ - added jupe_exempt to auth {};, exempts the user from generating warnings
+ when they attempt to join juped channels.
+
+ Revision Changes Path
+ 7.254 +2 -0 ircd-ratbox/doc/example.conf
+ 7.261 +3 -0 ircd-ratbox/include/client.h
+ 7.306 +2 -0 ircd-ratbox/include/s_conf.h
+ 1.162 +5 -2 ircd-ratbox/modules/core/m_join.c
+ 7.192 +1 -0 ircd-ratbox/src/newconf.c
+ 7.338 +8 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/01/24 18:57:02 EST (20050124_6)
+
+ Modified files:
+ src newconf.c
+ Log:
+ - rework shared {};, the format is now:
+ shared {
+ oper = "flame@*.leeh.co.uk", "*.lan";
+ flags = kline;
+ };
+
+ With no privs:
+ shared {
+ oper = "flame@*.leeh.co.uk", "*.lan";
+ flags = none;
+ };
+
+ Revision Changes Path
+ 7.191 +55 -23 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/01/24 17:25:58 EST (20050124_5)
+
+ Modified files:
+ include modules.h
+ Log:
+ - fix the prototype on load_static_modules()
+
+ Revision Changes Path
+ 7.61 +1 -1 ircd-ratbox/include/modules.h
+
+
+
+leeh 2005/01/24 16:00:30 EST (20050124_4)
+
+ Modified files:
+ modules m_cap.c
+ Log:
+ - have cap end call register_local_user() with its own copy of
+ source_p->username so its safe for unidented users..
+
+ Revision Changes Path
+ 1.4 +6 -2 ircd-ratbox/modules/m_cap.c
+
+
+
+leeh 2005/01/24 15:48:09 EST (20050124_3)
+
+ Modified files:
+ include newconf.h s_conf.h
+ modules m_info.c
+ src newconf.c s_conf.c s_log.c
+ Log:
+ - move the conf parser over to a table based structure, with generic setting
+ of integers/strings
+
+ Revision Changes Path
+ 7.34 +9 -8 ircd-ratbox/include/newconf.h
+ 7.305 +13 -13 ircd-ratbox/include/s_conf.h
+ 1.121 +13 -16 ircd-ratbox/modules/m_info.c
+ 7.190 +264 -808 ircd-ratbox/src/newconf.c
+ 7.498 +11 -13 ircd-ratbox/src/s_conf.c
+ 7.77 +13 -13 ircd-ratbox/src/s_log.c
+
+
+
+leeh 2005/01/24 13:11:30 EST (20050124_2)
+
+ Modified files:
+ doc example.conf
+ src newconf.c
+ Log:
+ - added stacking of ips in exempt {};
+
+ Revision Changes Path
+ 7.253 +4 -0 ircd-ratbox/doc/example.conf
+ 7.189 +11 -30 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/01/24 12:59:57 EST (20050124_1)
+
+ Modified files:
+ include tools.h
+ src channel.c client.c hash.c hook.c
+ newconf.c s_user.c watch.c
+ Log:
+ - moved dlinkFind*() to be (node, list) rather than (list, node) so its
+ consistent with the rest of the dlink code.
+
+ Revision Changes Path
+ 1.54 +7 -7 ircd-ratbox/include/tools.h
+ 7.430 +2 -2 ircd-ratbox/src/channel.c
+ 7.487 +6 -6 ircd-ratbox/src/client.c
+ 7.113 +5 -5 ircd-ratbox/src/hash.c
+ 7.35 +1 -1 ircd-ratbox/src/hook.c
+ 7.188 +2 -2 ircd-ratbox/src/newconf.c
+ 7.337 +1 -1 ircd-ratbox/src/s_user.c
+ 1.5 +4 -4 ircd-ratbox/src/watch.c
+
+
+
+leeh 2005/01/24 12:47:13 EST (20050124_0)
+
+ Modified files:
+ modules m_cap.c
+ Log:
+ - cheap hack on sticky capabs..
+
+ Revision Changes Path
+ 1.3 +4 -2 ircd-ratbox/modules/m_cap.c
+
+
+
+leeh 2005/01/22 11:36:54 EST (20050122_0)
+
+ Modified files:
+ modules m_cap.c
+ Log:
+ - updated my clicap implementation to match the spec so far..
+
+ Revision Changes Path
+ 1.2 +84 -11 ircd-ratbox/modules/m_cap.c
+
+
+
+leeh 2005/01/21 07:14:43 EST (20050121_2)
+
+ Modified files:
+ doc hooks.txt
+ include hook.h
+ modules m_services.c
+ src hook.c s_serv.c
+ Log:
+ - added hooks for when we're sending a burst
+ - rewrote hooks.txt
+ - fix up the hooks ive already done in services compatibility, ill add the
+ hooks for server/client introductions in a bit.
+
+ Revision Changes Path
+ 1.3 +71 -33 ircd-ratbox/doc/hooks.txt
+ 1.30 +4 -0 ircd-ratbox/include/hook.h
+ 1.4 +24 -35 ircd-ratbox/modules/m_services.c
+ 7.34 +7 -0 ircd-ratbox/src/hook.c
+ 7.423 +26 -2 ircd-ratbox/src/s_serv.c
+
+
+
+leeh 2005/01/21 06:34:03 EST (20050121_1)
+
+ Modified files:
+ contrib example_module.c spy_admin_notice.c
+ spy_info_notice.c spy_links_notice.c
+ spy_motd_notice.c spy_stats_notice.c
+ spy_stats_p_notice.c spy_trace_notice.c
+ spy_whois_notice.c
+ spy_whois_notice_global.c
+ include hook.h
+ modules m_admin.c m_info.c m_links.c m_motd.c
+ m_services.c m_stats.c m_trace.c
+ m_whois.c static_modules.c.SH
+ modules/core m_server.c
+ src client.c hook.c ircd.c modules.c packet.c
+ s_auth.c s_serv.c s_user.c send.c
+ Log:
+ - add a better implementation of the hook system, its now a slow leaking
+ array and events are created whenever we try adding a hook for it, or
+ theyre registered for the caller.
+
+ Ive temporarily fucked services support and removed most of the other
+ hooks.. I shall fix this soon.
+
+ Revision Changes Path
+ 1.13 +6 -7 ircd-ratbox/contrib/example_module.c
+ 1.14 +6 -8 ircd-ratbox/contrib/spy_admin_notice.c
+ 1.14 +6 -8 ircd-ratbox/contrib/spy_info_notice.c
+ 1.20 +8 -8 ircd-ratbox/contrib/spy_links_notice.c
+ 1.14 +6 -8 ircd-ratbox/contrib/spy_motd_notice.c
+ 1.21 +22 -22 ircd-ratbox/contrib/spy_stats_notice.c
+ 1.13 +6 -8 ircd-ratbox/contrib/spy_stats_p_notice.c
+ 1.15 +10 -12 ircd-ratbox/contrib/spy_trace_notice.c
+ 1.20 +15 -14 ircd-ratbox/contrib/spy_whois_notice.c
+ 1.9 +14 -14 ircd-ratbox/contrib/spy_whois_notice_global.c
+ 1.29 +34 -70 ircd-ratbox/include/hook.h
+ 1.151 +1 -3 ircd-ratbox/modules/core/m_server.c
+ 1.62 +5 -6 ircd-ratbox/modules/m_admin.c
+ 1.120 +5 -6 ircd-ratbox/modules/m_info.c
+ 1.70 +6 -6 ircd-ratbox/modules/m_links.c
+ 1.58 +5 -6 ircd-ratbox/modules/m_motd.c
+ 1.3 +13 -1 ircd-ratbox/modules/m_services.c
+ 1.240 +10 -11 ircd-ratbox/modules/m_stats.c
+ 1.107 +8 -9 ircd-ratbox/modules/m_trace.c
+ 1.147 +8 -8 ircd-ratbox/modules/m_whois.c
+ 1.10 +2 -2 ircd-ratbox/modules/static_modules.c.SH
+ 7.486 +1 -28 ircd-ratbox/src/client.c
+ 7.33 +131 -137 ircd-ratbox/src/hook.c
+ 7.367 +1 -1 ircd-ratbox/src/ircd.c
+ 7.151 +6 -10 ircd-ratbox/src/modules.c
+ 7.138 +10 -14 ircd-ratbox/src/packet.c
+ 7.191 +0 -3 ircd-ratbox/src/s_auth.c
+ 7.422 +0 -16 ircd-ratbox/src/s_serv.c
+ 7.336 +0 -6 ircd-ratbox/src/s_user.c
+ 7.286 +8 -6 ircd-ratbox/src/send.c
+
+
+
+leeh 2005/01/20 19:19:20 EST (20050121_0)
+
+ Modified files:
+ include hostmask.h
+ Log:
+ - remove an unused struct
+
+ Revision Changes Path
+ 1.41 +0 -9 ircd-ratbox/include/hostmask.h
+
+
+
+leeh 2005/01/20 13:38:39 EST (20050120_1)
+
+ Modified files:
+ . configure configure.ac
+ include client.h numeric.h patchlevel.h
+ modules Makefile.in
+ src messages.tab s_user.c
+ Added files:
+ modules m_cap.c
+ Log:
+ - drop back to -O0, fix patchlevel.h
+ - first stab at client capabilities.. this still needs work.
+
+ Revision Changes Path
+ 7.240 +3 -3 ircd-ratbox/configure
+ 7.54 +3 -3 ircd-ratbox/configure.ac
+ 7.260 +3 -0 ircd-ratbox/include/client.h
+ 7.54 +2 -0 ircd-ratbox/include/numeric.h
+ 7.70 +1 -3 ircd-ratbox/include/patchlevel.h
+ 1.116 +1 -0 ircd-ratbox/modules/Makefile.in
+ 1.1 +405 -0 ircd-ratbox/modules/m_cap.c (new)
+ 7.120 +1 -1 ircd-ratbox/src/messages.tab
+ 7.335 +3 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/01/20 06:04:41 EST (20050120_0)
+
+ Modified files:
+ . ChangeLog RELNOTES
+ include config.h config.h.dist memory.h
+ patchlevel.h
+ modules m_stats.c
+ src commio.c crypt.c getopt.c ircd.c s_serv.c
+ Removed files:
+ . README.VMS clean.com make.com
+ include setup.h_vms
+ modules descrip.mms static_modules_c.com
+ modules/core descrip.mms
+ src descrip.mms qio.c version.com
+ tools descrip.mms mkpasswd_vms.c
+ Log:
+ - clean changelog, relnotes
+ - mark patchlevel as 2.1.0beta
+ - remove VMS support
+
+ Revision Changes Path
+ 1.1613 +0 -27165 ircd-ratbox/ChangeLog
+ 7.2 +0 -46 ircd-ratbox/README.VMS (dead)
+ 1.111 +1 -348 ircd-ratbox/RELNOTES
+ 7.2 +0 -10 ircd-ratbox/clean.com (dead)
+ 7.182 +0 -42 ircd-ratbox/include/config.h
+ 7.79 +0 -42 ircd-ratbox/include/config.h.dist
+ 7.50 +0 -4 ircd-ratbox/include/memory.h
+ 7.69 +1 -6 ircd-ratbox/include/patchlevel.h
+ 7.16 +0 -124 ircd-ratbox/include/setup.h_vms (dead)
+ 7.2 +0 -58 ircd-ratbox/make.com (dead)
+ 1.5 +0 -24 ircd-ratbox/modules/core/descrip.mms (dead)
+ 1.10 +0 -33 ircd-ratbox/modules/descrip.mms (dead)
+ 1.239 +1 -10 ircd-ratbox/modules/m_stats.c
+ 1.6 +0 -125 ircd-ratbox/modules/static_modules_c.com (dead)
+ 1.24 +7 -30 ircd-ratbox/src/commio.c
+ 7.12 +0 -4 ircd-ratbox/src/crypt.c
+ 7.15 +0 -44 ircd-ratbox/src/descrip.mms (dead)
+ 7.24 +0 -4 ircd-ratbox/src/getopt.c
+ 7.366 +4 -19 ircd-ratbox/src/ircd.c
+ 7.8 +0 -221 ircd-ratbox/src/qio.c (dead)
+ 7.421 +1 -8 ircd-ratbox/src/s_serv.c
+ 7.8 +0 -101 ircd-ratbox/src/version.com (dead)
+ 7.9 +0 -25 ircd-ratbox/tools/descrip.mms (dead)
+ 7.4 +0 -458 ircd-ratbox/tools/mkpasswd_vms.c (dead)
+
+
+
+androsyn 2005/01/18 11:55:13 EST (20050118_7)
+
+ Modified files:
+ include watch.h
+ src watch.c
+ Log:
+ not using the return values on a few watch functions so make them void
+
+ Revision Changes Path
+ 7.2 +5 -5 ircd-ratbox/include/watch.h
+ 1.4 +19 -28 ircd-ratbox/src/watch.c
+
+
+androsyn 2005/01/14 13:10:41 EST (20050114_5)
+
+ Modified files:
+ modules m_watch.c
+ Log:
+ Make watch throttle, don't accept letter commands stacked
+
+ Revision Changes Path
+ 1.5 +126 -122 ircd-ratbox/modules/m_watch.c
+
+
+
+androsyn 2005/01/14 13:06:06 EST (20050114_4)
+
+ Modified files:
+ modules m_gline.c
+ Log:
+ fix merge error
+
+ Revision Changes Path
+ 1.149 +1 -1 ircd-ratbox/modules/m_gline.c
+
+
+
+androsyn 2005/01/14 12:12:37 EST (20050114_3)
+
+ Modified files:
+ . ChangeLog README.FIRST RELNOTES configure
+ configure.ac
+ adns adns.h internal.h parse.c transmit.c
+ types.c
+ contrib example_module.c spy_admin_notice.c
+ spy_info_notice.c spy_links_notice.c
+ spy_motd_notice.c spy_stats_notice.c
+ spy_stats_p_notice.c spy_trace_notice.c
+ spy_whois_notice.c
+ spy_whois_notice_global.c
+ doc example.conf example.efnet.conf ircd.motd
+ server-version-info whats-new.txt
+ help/opers umode xline
+ help/users umode
+ include cache.h channel.h class.h client.h
+ commio.h config.h config.h.dist hash.h
+ hook.h hostmask.h irc_string.h ircd.h
+ ircd_defs.h m_info.h memory.h msg.h
+ newconf.h numeric.h packet.h patchlevel.h
+ patricia.h s_conf.h s_gline.h s_newconf.h
+ s_serv.h s_user.h scache.h serno.h
+ setup.h.in sprintf_irc.h stdinc.h tools.h
+ modules .depend Makefile.in m_admin.c m_away.c
+ m_dline.c m_encap.c m_gline.c m_info.c
+ m_kline.c m_links.c m_list.c m_lusers.c
+ m_motd.c m_oper.c m_operspy.c m_rehash.c
+ m_restart.c m_resv.c m_set.c m_stats.c
+ m_svinfo.c m_testline.c m_testmask.c
+ m_topic.c m_trace.c m_watch.c m_who.c
+ m_whois.c m_whowas.c m_xline.c
+ static_modules.c.SH
+ modules/core m_error.c m_message.c m_mode.c m_quit.c
+ m_server.c m_squit.c
+ src .depend Makefile.in adns.c balloc.c
+ cache.c channel.c class.c client.c
+ commio.c crypt.c devpoll.c epoll.c
+ event.c getopt.c hash.c hook.c hostmask.c
+ irc_string.c ircd.c ircd_lexer.l
+ ircd_parser.y ircd_signal.c listener.c
+ modules.c newconf.c numeric.c packet.c
+ parse.c patricia.c poll.c reject.c
+ restart.c s_auth.c s_conf.c s_log.c
+ s_newconf.c s_serv.c s_user.c scache.c
+ select.c send.c snprintf.c tools.c
+ version.c.SH watch.c whowas.c
+ tools README.mkpasswd mkpasswd.c
+ Added files:
+ . README.VMS clean.com make.com
+ doc services.txt
+ include common.h s_stats.h setup.h_vms
+ supported.h
+ modules descrip.mms m_challenge.c m_etrace.c
+ m_invite.c m_names.c m_pass.c m_ping.c
+ m_pong.c m_services.c m_tb.c m_user.c
+ m_users.c m_version.c
+ static_modules_c.com
+ modules/core descrip.mms m_join.c m_kick.c m_nick.c
+ m_part.c m_sjoin.c
+ servlink descrip.mms
+ src descrip.mms kdparse.c messages.tab qio.c
+ s_gline.c s_stats.c version.com
+ tools descrip.mms mkpasswd_vms.c
+ Removed files:
+ doc 005.txt
+ include banconf.h
+ modules/core channels.c users.c
+ src banconf.c
+ Log:
+ merge from RATBOX_2_0
+
+ Revision Changes Path
+ 1.1601 +25853 -1906 ircd-ratbox/ChangeLog
+ 7.40 +1 -0 ircd-ratbox/README.FIRST
+ 7.1 +46 -0 ircd-ratbox/README.VMS (new)
+ 1.110 +114 -6 ircd-ratbox/RELNOTES
+ 1.17 +4 -0 ircd-ratbox/adns/adns.h
+ 1.17 +4 -4 ircd-ratbox/adns/internal.h
+ 1.12 +38 -38 ircd-ratbox/adns/parse.c
+ 1.15 +3 -3 ircd-ratbox/adns/transmit.c
+ 1.19 +13 -13 ircd-ratbox/adns/types.c
+ 7.1 +10 -0 ircd-ratbox/clean.com (new)
+ 7.239 +47 -29 ircd-ratbox/configure
+ 7.53 +40 -32 ircd-ratbox/configure.ac
+ 1.12 +7 -6 ircd-ratbox/contrib/example_module.c
+ 1.13 +9 -7 ircd-ratbox/contrib/spy_admin_notice.c
+ 1.13 +9 -7 ircd-ratbox/contrib/spy_info_notice.c
+ 1.19 +9 -9 ircd-ratbox/contrib/spy_links_notice.c
+ 1.13 +9 -7 ircd-ratbox/contrib/spy_motd_notice.c
+ 1.20 +22 -22 ircd-ratbox/contrib/spy_stats_notice.c
+ 1.12 +8 -6 ircd-ratbox/contrib/spy_stats_p_notice.c
+ 1.14 +12 -12 ircd-ratbox/contrib/spy_trace_notice.c
+ 1.19 +14 -15 ircd-ratbox/contrib/spy_whois_notice.c
+ 1.8 +14 -14 ircd-ratbox/contrib/spy_whois_notice_global.c
+ 1.2 +0 -46 ircd-ratbox/doc/005.txt (dead)
+ 7.252 +68 -22 ircd-ratbox/doc/example.conf
+ 7.83 +70 -19 ircd-ratbox/doc/example.efnet.conf
+ 7.4 +2 -2 ircd-ratbox/doc/ircd.motd
+ 7.18 +2 -0 ircd-ratbox/doc/server-version-info
+ 7.1 +37 -0 ircd-ratbox/doc/services.txt (new)
+ 7.50 +21 -3 ircd-ratbox/doc/whats-new.txt
+ 1.5 +2 -1 ircd-ratbox/help/opers/umode
+ 1.7 +1 -1 ircd-ratbox/help/opers/xline
+ 1.2 +1 -0 ircd-ratbox/help/users/umode
+ 7.3 +0 -15 ircd-ratbox/include/banconf.h (dead)
+ 1.7 +8 -0 ircd-ratbox/include/cache.h
+ 7.162 +18 -16 ircd-ratbox/include/channel.h
+ 7.25 +4 -0 ircd-ratbox/include/class.h
+ 7.259 +34 -28 ircd-ratbox/include/client.h
+ 1.13 +45 -7 ircd-ratbox/include/commio.h
+ 7.9 +68 -0 ircd-ratbox/include/common.h (new)
+ 7.181 +74 -16 ircd-ratbox/include/config.h
+ 7.78 +74 -16 ircd-ratbox/include/config.h.dist
+ 7.53 +2 -0 ircd-ratbox/include/hash.h
+ 1.28 +73 -27 ircd-ratbox/include/hook.h
+ 1.40 +15 -2 ircd-ratbox/include/hostmask.h
+ 7.61 +7 -1 ircd-ratbox/include/irc_string.h
+ 7.80 +6 -31 ircd-ratbox/include/ircd.h
+ 7.54 +4 -0 ircd-ratbox/include/ircd_defs.h
+ 7.56 +14 -8 ircd-ratbox/include/m_info.h
+ 7.49 +4 -0 ircd-ratbox/include/memory.h
+ 7.53 +2 -0 ircd-ratbox/include/msg.h
+ 7.33 +9 -9 ircd-ratbox/include/newconf.h
+ 7.53 +12 -8 ircd-ratbox/include/numeric.h
+ 7.27 +1 -1 ircd-ratbox/include/packet.h
+ 7.68 +7 -1 ircd-ratbox/include/patchlevel.h
+ 7.19 +25 -1 ircd-ratbox/include/patricia.h
+ 7.304 +80 -25 ircd-ratbox/include/s_conf.h
+ 7.20 +12 -0 ircd-ratbox/include/s_gline.h
+ 7.44 +1 -48 ircd-ratbox/include/s_newconf.h
+ 7.97 +7 -1 ircd-ratbox/include/s_serv.h
+ 7.20 +80 -0 ircd-ratbox/include/s_stats.h (new)
+ 7.34 +13 -9 ircd-ratbox/include/s_user.h
+ 7.15 +1 -1 ircd-ratbox/include/scache.h
+ 7.5366 +1 -1 ircd-ratbox/include/serno.h
+ 7.93 +3 -0 ircd-ratbox/include/setup.h.in
+ 7.15 +124 -0 ircd-ratbox/include/setup.h_vms (new)
+ 7.18 +2 -7 ircd-ratbox/include/sprintf_irc.h
+ 1.15 +47 -47 ircd-ratbox/include/stdinc.h
+ 7.1 +124 -0 ircd-ratbox/include/supported.h (new)
+ 1.53 +10 -10 ircd-ratbox/include/tools.h
+ 7.1 +58 -0 ircd-ratbox/make.com (new)
+ 1.45 +338 -182 ircd-ratbox/modules/.depend
+ 1.115 +20 -4 ircd-ratbox/modules/Makefile.in
+ 1.14 +0 -1963 ircd-ratbox/modules/core/channels.c (dead)
+ 1.4 +24 -0 ircd-ratbox/modules/core/descrip.mms (new)
+ 1.11 +2 -1 ircd-ratbox/modules/core/m_error.c
+ 1.161 +747 -0 ircd-ratbox/modules/core/m_join.c (new)
+ 1.81 +201 -0 ircd-ratbox/modules/core/m_kick.c (new)
+ 1.158 +6 -186 ircd-ratbox/modules/core/m_message.c
+ 1.118 +97 -195 ircd-ratbox/modules/core/m_mode.c
+ 1.157 +1026 -0 ircd-ratbox/modules/core/m_nick.c (new)
+ 1.94 +155 -0 ircd-ratbox/modules/core/m_part.c (new)
+ 1.50 +5 -2 ircd-ratbox/modules/core/m_quit.c
+ 1.150 +10 -987 ircd-ratbox/modules/core/m_server.c
+ 1.203 +759 -0 ircd-ratbox/modules/core/m_sjoin.c (new)
+ 1.82 +3 -2 ircd-ratbox/modules/core/m_squit.c
+ 1.26 +0 -2316 ircd-ratbox/modules/core/users.c (dead)
+ 1.9 +33 -0 ircd-ratbox/modules/descrip.mms (new)
+ 1.61 +6 -5 ircd-ratbox/modules/m_admin.c
+ 1.59 +3 -3 ircd-ratbox/modules/m_away.c
+ 1.72 +273 -0 ircd-ratbox/modules/m_challenge.c (new)
+ 1.45 +229 -44 ircd-ratbox/modules/m_dline.c
+ 1.21 +2 -1 ircd-ratbox/modules/m_encap.c
+ 1.12 +154 -0 ircd-ratbox/modules/m_etrace.c (new)
+ 1.148 +29 -82 ircd-ratbox/modules/m_gline.c
+ 1.119 +50 -42 ircd-ratbox/modules/m_info.c
+ 1.83 +203 -0 ircd-ratbox/modules/m_invite.c (new)
+ 1.196 +154 -5 ircd-ratbox/modules/m_kline.c
+ 1.69 +8 -64 ircd-ratbox/modules/m_links.c
+ 1.80 +4 -4 ircd-ratbox/modules/m_list.c
+ 1.46 +2 -37 ircd-ratbox/modules/m_lusers.c
+ 1.57 +6 -5 ircd-ratbox/modules/m_motd.c
+ 1.81 +193 -0 ircd-ratbox/modules/m_names.c (new)
+ 1.90 +4 -299 ircd-ratbox/modules/m_oper.c
+ 1.6 +2 -1 ircd-ratbox/modules/m_operspy.c
+ 1.49 +101 -0 ircd-ratbox/modules/m_pass.c (new)
+ 1.58 +115 -0 ircd-ratbox/modules/m_ping.c (new)
+ 1.58 +134 -0 ircd-ratbox/modules/m_pong.c (new)
+ 1.87 +34 -60 ircd-ratbox/modules/m_rehash.c
+ 1.46 +2 -1 ircd-ratbox/modules/m_restart.c
+ 1.71 +98 -3 ircd-ratbox/modules/m_resv.c
+ 1.2 +172 -0 ircd-ratbox/modules/m_services.c (new)
+ 1.80 +31 -1 ircd-ratbox/modules/m_set.c
+ 1.238 +173 -570 ircd-ratbox/modules/m_stats.c
+ 1.63 +2 -1 ircd-ratbox/modules/m_svinfo.c
+ 1.9 +115 -0 ircd-ratbox/modules/m_tb.c (new)
+ 1.54 +7 -6 ircd-ratbox/modules/m_testline.c
+ 1.4 +2 -1 ircd-ratbox/modules/m_testmask.c
+ 1.90 +2 -127 ircd-ratbox/modules/m_topic.c
+ 1.106 +12 -105 ircd-ratbox/modules/m_trace.c
+ 1.45 +107 -0 ircd-ratbox/modules/m_user.c (new)
+ 1.45 +72 -0 ircd-ratbox/modules/m_users.c (new)
+ 1.68 +157 -0 ircd-ratbox/modules/m_version.c (new)
+ 1.4 +1 -2 ircd-ratbox/modules/m_watch.c
+ 1.114 +2 -1 ircd-ratbox/modules/m_who.c
+ 1.146 +14 -11 ircd-ratbox/modules/m_whois.c
+ 1.51 +2 -1 ircd-ratbox/modules/m_whowas.c
+ 1.65 +105 -13 ircd-ratbox/modules/m_xline.c
+ 1.9 +2 -2 ircd-ratbox/modules/static_modules.c.SH
+ 1.5 +125 -0 ircd-ratbox/modules/static_modules_c.com (new)
+ 1.3 +15 -0 ircd-ratbox/servlink/descrip.mms (new)
+ 7.48 +162 -119 ircd-ratbox/src/.depend
+ 7.153 +3 -1 ircd-ratbox/src/Makefile.in
+ 7.75 +5 -5 ircd-ratbox/src/adns.c
+ 7.84 +1 -1 ircd-ratbox/src/balloc.c
+ 7.7 +0 -355 ircd-ratbox/src/banconf.c (dead)
+ 1.23 +75 -7 ircd-ratbox/src/cache.c
+ 7.429 +342 -79 ircd-ratbox/src/channel.c
+ 7.67 +42 -2 ircd-ratbox/src/class.c
+ 7.485 +245 -85 ircd-ratbox/src/client.c
+ 1.23 +349 -43 ircd-ratbox/src/commio.c
+ 7.11 +4 -0 ircd-ratbox/src/crypt.c
+ 7.14 +44 -0 ircd-ratbox/src/descrip.mms (new)
+ 7.36 +3 -1 ircd-ratbox/src/devpoll.c
+ 1.32 +4 -8 ircd-ratbox/src/epoll.c
+ 7.46 +63 -6 ircd-ratbox/src/event.c
+ 7.23 +4 -0 ircd-ratbox/src/getopt.c
+ 7.112 +8 -7 ircd-ratbox/src/hash.c
+ 7.32 +135 -133 ircd-ratbox/src/hook.c
+ 7.105 +117 -17 ircd-ratbox/src/hostmask.c
+ 7.76 +79 -26 ircd-ratbox/src/irc_string.c
+ 7.365 +56 -48 ircd-ratbox/src/ircd.c
+ 1.166 +11 -7 ircd-ratbox/src/ircd_lexer.l
+ 1.275 +1 -0 ircd-ratbox/src/ircd_parser.y
+ 7.25 +25 -10 ircd-ratbox/src/ircd_signal.c
+ 7.41 +309 -0 ircd-ratbox/src/kdparse.c (new)
+ 7.122 +14 -13 ircd-ratbox/src/listener.c
+ 7.119 +1025 -0 ircd-ratbox/src/messages.tab (new)
+ 7.150 +17 -8 ircd-ratbox/src/modules.c
+ 7.187 +1196 -344 ircd-ratbox/src/newconf.c
+ 7.35 +34 -1003 ircd-ratbox/src/numeric.c
+ 7.137 +55 -42 ircd-ratbox/src/packet.c
+ 7.187 +8 -15 ircd-ratbox/src/parse.c
+ 7.28 +2 -4 ircd-ratbox/src/patricia.c
+ 7.82 +3 -1 ircd-ratbox/src/poll.c
+ 7.7 +221 -0 ircd-ratbox/src/qio.c (new)
+ 1.32 +8 -3 ircd-ratbox/src/reject.c
+ 7.34 +1 -0 ircd-ratbox/src/restart.c
+ 7.190 +60 -52 ircd-ratbox/src/s_auth.c
+ 7.497 +892 -156 ircd-ratbox/src/s_conf.c
+ 7.1 +167 -0 ircd-ratbox/src/s_gline.c (new)
+ 7.76 +32 -35 ircd-ratbox/src/s_log.c
+ 7.62 +10 -329 ircd-ratbox/src/s_newconf.c
+ 7.420 +999 -4 ircd-ratbox/src/s_serv.c
+ 7.40 +385 -0 ircd-ratbox/src/s_stats.c (new)
+ 7.334 +773 -2 ircd-ratbox/src/s_user.c
+ 7.27 +2 -1 ircd-ratbox/src/scache.c
+ 7.44 +2 -0 ircd-ratbox/src/select.c
+ 7.285 +12 -12 ircd-ratbox/src/send.c
+ 1.16 +0 -58 ircd-ratbox/src/snprintf.c
+ 7.46 +0 -1 ircd-ratbox/src/tools.c
+ 7.28 +4 -1 ircd-ratbox/src/version.c.SH
+ 7.7 +101 -0 ircd-ratbox/src/version.com (new)
+ 1.3 +4 -4 ircd-ratbox/src/watch.c
+ 7.32 +1 -0 ircd-ratbox/src/whowas.c
+ 1.8 +5 -0 ircd-ratbox/tools/README.mkpasswd
+ 7.8 +25 -0 ircd-ratbox/tools/descrip.mms (new)
+ 7.16 +2 -30 ircd-ratbox/tools/mkpasswd.c
+ 7.3 +458 -0 ircd-ratbox/tools/mkpasswd_vms.c (new)
+
+
+
+androsyn 2005/01/13 22:17:53 EST (20050114_2)
+
+ Modified files: (Branch: RATBOX_2_0)
+ src client.c
+ Log:
+ a remote client is never going to have a watch list..duh
+
+ Revision Changes Path
+ 7.463.2.13 +0 -1 ircd-ratbox/src/client.c
+
+
+
+androsyn 2005/01/13 20:49:55 EST (20050114_1)
+
+ Added files: (Branch: RATBOX_2_0)
+ modules m_watch.c
+ Log:
+ get that one too
+
+ Revision Changes Path
+ 1.3.2.1 +231 -0 ircd-ratbox/modules/m_watch.c (new)
+
+
+
+androsyn 2005/01/13 20:39:28 EST (20050114_0)
+
+ Added files: (Branch: RATBOX_2_0)
+ include watch.h
+ src watch.c
+ Log:
+ helps if we actually include the .c/.h files
+
+ Revision Changes Path
+ 7.1.2.1 +53 -0 ircd-ratbox/include/watch.h (new)
+ 1.2.2.1 +241 -0 ircd-ratbox/src/watch.c (new)
+
+
+
+androsyn 2005/01/13 13:57:16 EST (20050113_0)
+
+ Modified files: (Branch: RATBOX_2_0)
+ . configure configure.ac
+ include client.h numeric.h s_conf.h setup.h.in
+ supported.h
+ modules Makefile.in
+ modules/core m_nick.c
+ src Makefile.in client.c ircd.c messages.tab
+ newconf.c s_conf.c s_user.c
+ Log:
+ backport watch from devel
+
+ Revision Changes Path
+ 7.229.2.10 +12 -2 ircd-ratbox/configure
+ 7.43.2.10 +4 -2 ircd-ratbox/configure.ac
+ 7.246.2.12 +4 -0 ircd-ratbox/include/client.h
+ 7.46.2.5 +10 -0 ircd-ratbox/include/numeric.h
+ 7.278.2.9 +1 -0 ircd-ratbox/include/s_conf.h
+ 7.89.2.3 +3 -0 ircd-ratbox/include/setup.h.in
+ 1.41.2.3 +4 -2 ircd-ratbox/include/supported.h
+ 1.98.2.3 +1 -0 ircd-ratbox/modules/Makefile.in
+ 1.152.2.5 +24 -5 ircd-ratbox/modules/core/m_nick.c
+ 7.148.2.1 +1 -0 ircd-ratbox/src/Makefile.in
+ 7.463.2.12 +4 -0 ircd-ratbox/src/client.c
+ 7.343.2.3 +2 -0 ircd-ratbox/src/ircd.c
+ 7.114.2.9 +10 -10 ircd-ratbox/src/messages.tab
+ 7.156.2.16 +7 -0 ircd-ratbox/src/newconf.c
+ 7.470.2.8 +1 -0 ircd-ratbox/src/s_conf.c
+ 7.323.2.10 +2 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/01/12 10:12:40 EST (20050112_1)
+
+ Modified files: (Branch: RATBOX_2_0)
+ include numeric.h
+ modules m_services.c m_whois.c
+ src messages.tab
+ Log:
+ - add RPL_WHOISLOGGEDIN, make m_services.c hook into whois and output this
+ when the user is logged in
+
+ Revision Changes Path
+ 7.46.2.4 +1 -0 ircd-ratbox/include/numeric.h
+ 1.1.2.3 +18 -1 ircd-ratbox/modules/m_services.c
+ 1.140.2.3 +4 -1 ircd-ratbox/modules/m_whois.c
+ 7.114.2.8 +2 -2 ircd-ratbox/src/messages.tab
+
+
+
+leeh 2005/01/11 19:47:14 EST (20050112_0)
+
+ Modified files: (Branch: RATBOX_2_0)
+ include supported.h
+ Added files: (Branch: RATBOX_2_0)
+ doc services.txt
+ Log:
+ - add +r to 005
+ - added doc/services.txt, outlining the compatibility code
+
+ Revision Changes Path
+ 1.1.2.1 +37 -0 ircd-ratbox/doc/services.txt (new)
+ 1.41.2.2 +9 -2 ircd-ratbox/include/supported.h
+
+
+
+leeh 2005/01/11 18:38:10 EST (20050111_5)
+
+ Modified files: (Branch: RATBOX_2_0)
+ include client.h hook.h
+ modules m_services.c
+ modules/core m_server.c
+ src hook.c s_serv.c
+ Log:
+ - more services compatibility code:
+ - hook into a server being linked, mark it FLAGS_SERVICE if we find an
+ appropriate service {}; entry, only accept SU from these.
+ - hook into us finishing nick burst, and have services burst a list of
+ logged in users
+
+ Revision Changes Path
+ 7.246.2.11 +1 -0 ircd-ratbox/include/client.h
+ 1.25.2.1 +2 -0 ircd-ratbox/include/hook.h
+ 1.133.2.1 +4 -1 ircd-ratbox/modules/core/m_server.c
+ 1.1.2.2 +52 -5 ircd-ratbox/modules/m_services.c
+ 7.30.2.1 +6 -0 ircd-ratbox/src/hook.c
+ 7.406.2.9 +7 -1 ircd-ratbox/src/s_serv.c
+
+
+
+leeh 2005/01/11 17:32:42 EST (20050111_4)
+
+ Modified files: (Branch: RATBOX_2_0)
+ . configure configure.ac
+ include client.h
+ modules Makefile.in
+ src channel.c
+ Added files: (Branch: RATBOX_2_0)
+ modules m_services.c
+ Log:
+ - more services compatibility code:
+ - encap handlers for SU (services marking client as logged in)
+ - and for LOGIN (servers bursting logged in status)
+ - move suser from Client -> User
+
+ Revision Changes Path
+ 7.229.2.9 +9 -3 ircd-ratbox/configure
+ 7.43.2.9 +7 -2 ircd-ratbox/configure.ac
+ 7.246.2.10 +5 -4 ircd-ratbox/include/client.h
+ 1.98.2.2 +3 -1 ircd-ratbox/modules/Makefile.in
+ 1.1.2.1 +108 -0 ircd-ratbox/modules/m_services.c (new)
+ 7.417.2.5 +1 -1 ircd-ratbox/src/channel.c
+
+
+
+leeh 2005/01/11 16:46:34 EST (20050111_3)
+
+ Modified files: (Branch: RATBOX_2_0)
+ include ircd_defs.h
+ Log:
+ - whoops, missing #endif
+
+ Revision Changes Path
+ 7.50.4.7 +1 -0 ircd-ratbox/include/ircd_defs.h
+
+
+
+leeh 2005/01/11 15:56:57 EST (20050111_2)
+
+ Modified files: (Branch: RATBOX_2_0)
+ include ircd_defs.h
+ Log:
+ - cygwin doesnt have struct sockaddr_in6, so make GET_SS_LEN() when we dont
+ have ipv6 just report sizeof(struct sockaddr_in)
+
+ Revision Changes Path
+ 7.50.4.6 +3 -0 ircd-ratbox/include/ircd_defs.h
+
+
+
+leeh 2005/01/10 20:19:35 EST (20050111_1)
+
+ Modified files: (Branch: RATBOX_2_0)
+ src newconf.c
+ Log:
+ - fix a gcc warning
+
+ Revision Changes Path
+ 7.156.2.15 +3 -2 ircd-ratbox/src/newconf.c
+
+
+
+leeh 2005/01/10 20:10:35 EST (20050111_0)
+
+ Modified files: (Branch: RATBOX_2_0)
+ adns internal.h parse.c transmit.c types.c
+ Log:
+ - fbsd5.3 has introduced fls(), so rename fls -> flstate in adns to avoid
+ conflict
+
+ Revision Changes Path
+ 1.12.14.4 +4 -4 ircd-ratbox/adns/internal.h
+ 1.9.6.4 +38 -38 ircd-ratbox/adns/parse.c
+ 1.13.6.3 +3 -3 ircd-ratbox/adns/transmit.c
+ 1.14.6.4 +13 -13 ircd-ratbox/adns/types.c
+
+
+
+leeh 2005/01/10 17:48:48 EST (20050110_3)
+
+ Modified files: (Branch: RATBOX_2_0)
+ modules m_xline.c
+ Log:
+ - send out the reformatted xline to opers (\s -> ' ')
+
+ Revision Changes Path
+ 1.52.2.6 +3 -3 ircd-ratbox/modules/m_xline.c
+
+
+
+leeh 2005/01/10 16:18:53 EST (20050110_2)
+
+ Modified files: (Branch: RATBOX_2_0)
+ help/opers umode
+ help/users umode
+ include client.h supported.h
+ src messages.tab s_user.c send.c
+ Log:
+ - alzs diff to add usermode +D, "deaf", which shields a user from seeing
+ channel privmsgs.
+
+ Revision Changes Path
+ 1.3.6.2 +1 -0 ircd-ratbox/help/opers/umode
+ 1.1.22.1 +1 -0 ircd-ratbox/help/users/umode
+ 7.246.2.9 +5 -2 ircd-ratbox/include/client.h
+ 1.41.2.1 +9 -9 ircd-ratbox/include/supported.h
+ 7.114.2.7 +1 -1 ircd-ratbox/src/messages.tab
+ 7.323.2.9 +2 -1 ircd-ratbox/src/s_user.c
+ 7.280.2.2 +3 -0 ircd-ratbox/src/send.c
+
+
+
+leeh 2005/01/10 14:50:47 EST (20050110_1)
+
+ Modified files: (Branch: RATBOX_2_0)
+ doc example.conf example.efnet.conf
+ Log:
+ - I dont remember ts6 desyncing on bans, so im not sure why the example
+ confs say so.
+
+ Revision Changes Path
+ 7.243.2.9 +1 -2 ircd-ratbox/doc/example.conf
+ 7.75.2.10 +1 -2 ircd-ratbox/doc/example.efnet.conf
+
+
+
+leeh 2005/01/10 13:31:10 EST (20050110_0)
+
+ Modified files: (Branch: RATBOX_2_0)
+ . configure configure.ac
+ include channel.h client.h numeric.h s_conf.h
+ s_serv.h setup.h.in
+ modules/core m_join.c m_kick.c m_mode.c m_nick.c
+ m_sjoin.c
+ src channel.c messages.tab newconf.c s_conf.c
+ s_serv.c s_user.c
+ Log:
+ - added --enable-services to configure, which enables some ratbox-services
+ compatibility code:
+ - chanmode +r, registered users only
+ - usermode +S, prevents deop/kick of a service
+ - service { }; block in conf for the above umode
+
+ Revision Changes Path
+ 7.229.2.8 +28 -16 ircd-ratbox/configure
+ 7.43.2.8 +19 -16 ircd-ratbox/configure.ac
+ 7.152.4.5 +4 -3 ircd-ratbox/include/channel.h
+ 7.246.2.8 +10 -4 ircd-ratbox/include/client.h
+ 7.46.2.3 +2 -1 ircd-ratbox/include/numeric.h
+ 7.278.2.8 +4 -0 ircd-ratbox/include/s_conf.h
+ 7.94.2.1 +2 -1 ircd-ratbox/include/s_serv.h
+ 7.89.2.2 +3 -0 ircd-ratbox/include/setup.h.in
+ 1.156.2.1 +9 -1 ircd-ratbox/modules/core/m_join.c
+ 1.79.2.1 +11 -1 ircd-ratbox/modules/core/m_kick.c
+ 1.112.2.4 +56 -1 ircd-ratbox/modules/core/m_mode.c
+ 1.152.2.4 +24 -1 ircd-ratbox/modules/core/m_nick.c
+ 1.201.2.4 +9 -1 ircd-ratbox/modules/core/m_sjoin.c
+ 7.417.2.4 +14 -1 ircd-ratbox/src/channel.c
+ 7.114.2.6 +2 -2 ircd-ratbox/src/messages.tab
+ 7.156.2.14 +35 -0 ircd-ratbox/src/newconf.c
+ 7.470.2.7 +15 -0 ircd-ratbox/src/s_conf.c
+ 7.406.2.8 +3 -0 ircd-ratbox/src/s_serv.c
+ 7.323.2.8 +12 -0 ircd-ratbox/src/s_user.c
+
+
+
+leeh 2005/01/09 08:23:30 EST (20050109_0)
+
+ Modified files: (Branch: RATBOX_2_0)
+ help/opers umode
+ Log:
+ - remove a tab, and add +C to opers umode help
+
+ Revision Changes Path
+ 1.3.6.1 +1 -0 ircd-ratbox/help/opers/umode
+
--- /dev/null
+ Hybrid INSTALL Document
+
+ $Id: INSTALL 1837 2006-08-22 14:05:58Z nenolod $
+
+ Copyright (c) 2001 by ircd-hybrid team
+ Copyright (c) 2002-2004 ircd-ratbox development team
+
+ ----------------------------------------------------------------------
+
+ +------------------------------------------------------------------------+
+ | Note for those who dont bother reading docs |
+ | |
+ | Reading INSTALL is now a must, as the old DPATH is now specified when |
+ | configure is run. |
+ | |
+ | - You now need to ./configure --prefix="/path/to/install/it" |
+ | |
+ | Important: The old config format WILL NOT WORK. Please see point 6! |
+ | |
+ | The old kline format WILL NOT WORK. Please see point 7! |
+ +------------------------------------------------------------------------+
+
+ ----------------------------------------------------------------------
+
+ HOW TO BUILD
+
+ As of hybrid-4, the distribution uses GNU autoconf instead of the old
+ Config script. The Makefile has also been updated to include CFLAGS
+ defines for popular modern OSes.
+
+ 1.
+
+ Read the ChangeLog file to find out about the exciting new features in
+ this version. Other good reads are doc/whats-new.txt, BUGS,
+ doc/example.conf, and README.FIRST.
+
+ An example.conf for EFnet is in doc/ with the values "approved" on 12
+ December 2001.
+
+ 2.
+
+ Run the configure script. It will create include/setup.h and the
+ Makefiles to match your system. In ircd-ratbox, the paths are now handled
+ with the --prefix option to configure, not in config.h.
+ /usr/local/ircd is the default if no prefix is specified.
+
+ ./configure --prefix="/usr/local/ircd"
+
+ Note: There are some special optional parameters to the configure
+ script that some admins may wish to use.
+
+ *
+
+ --enable-kqueue - Use the superior kqueue(2) system call as
+ opposed to the default poll(2). This is currently only available
+ on FreeBSD 4.1 or higher.
+
+ *
+
+ --enable-devpoll - Enable the superior /dev/poll support on
+ Solaris. Linux /dev/poll is broken and will not work with this
+ option.
+
+ *
+
+ --enable-epoll - Enable the superior Linux Edge-Triggered Polling
+ system. This is currently only available on 2.5 Linux kernel
+ versions or later.
+
+ *
+
+ --enable-openssl - Enable the openssl dependent crypto functions.
+ This will allow CHALLENGE to work and encrypted links. On systems
+ where the configure script can automatically detect OpenSSL, this
+ option is not necessary. If configure cannot find OpenSSL, you
+ must specify a path with this option
+ (--enable-openssl=/path/to/openssl)
+
+ *
+
+ --enable-ipv6 - Enable IPv6 support.
+
+ *
+
+ --disable-shared-modules - Disable module support. This option is
+ more secure, but reduces a lot of the flexibility in Hybrid 7.
+ This may need to be used on some systems without a working dl
+ library.
+
+ *
+
+ --disable-assert - Disable some of the debugging code. This
+ should be used on all production servers for maximum speed and to
+ prevent cores from things that shouldn't normally happen.
+
+ *
+
+ --enable-small-net - Tunes the server for smaller networks by
+ reducing the startup memory footprint. This should really only be
+ used for *small* networks, as this tends to be a performance hit
+ on larger networks.
+
+ *
+
+ --with-nicklen - Sets the maximum NICK length. Note that this
+ must be consistant across your entire network.
+
+ *
+
+ --with-maxclients - Sets the maximum number of clients support by
+ the server. Note that this also twiddles the HARD_FDLIMIT_ define
+ so it is no longer necessary to modify include/config.h for this.
+ If HARD_FDLIMIT_ ends up being larger that FD_SETSIZE when using
+ select() for your I/O loop, s_bsd_select.c will refuse to compile
+ (and tell you to use poll instead). Take this error's advice and
+ use --enable-poll or something a bit more efficient. You'll be
+ happier at the end of the day for it.
+
+ 3.
+
+ Look over the "include/config.h" file. This allows you to change the
+ few remaining hard coded options of how the ircd will operate. Most
+ admins will only have to change a few settings. USE_SYSLOG is the only
+ one that most admins will need to edit.
+
+ Note: Note that you must have permission by the sysadmin to send
+ messages to the system log files.
+
+ All other settings in config.h are not necessary to edit.
+
+ 4.
+
+ make should build ircd.
+
+ 5.
+
+ make install will install the server, modules(1), and tools in the
+ path defined in config.h and the prefix specified when configure was
+ run.
+
+ (1) Unless the server was compiled without module support.
+
+ 6.
+
+ If you wish to enable the user log, oper log, and failed oper log,
+ issue these commands at the shell prompt (in the prefix directory)
+
+ $ touch logs/userlog
+ $ touch logs/operlog
+ $ touch logs/foperlog
+
+ Note: If you use different names in ircd.conf, you must 'touch' the
+ specific names.
+
+ 7.
+
+ If you are upgrading from Hybrid 5 or Hybrid 6, the config file has
+ changed drastically...
+
+ There is a utility to convert your old config file to the new format.
+ In prefix/bin there is something called "convertconf". Its usage is:
+ ./convertconf (old config file to convert) (converted file name)
+
+ Convertconf will NOT convert I: lines. You must use "convertilines"
+ for this which contains a much superior method of conversion and
+ will group I: together under one auth {};.
+
+ Once this is done, move your new config to prefix/etc/ircd.conf and
+ EDIT IT! There are still things that need changing in the config,
+ including the fact that classes MUST be above auth/connect blocks!
+
+ 8.
+
+ If you are upgrading from Hybrid 5 or Hybrid 6, the kline file has
+ also changed...
+
+ There is a utility to convert the old kline configuration file to the
+ new format. In prefix/bin there is a program called "convertklines".
+ Its usage is: ./convertklines (old kline.conf filename) (new
+ kline.conf filename) (dline.conf filename).
+
+ Once this is done, move the new files into the prefix/etc/ directory
+ under their proper names. By default, the kline file is named
+ kline.conf and the dline file is named dline.conf.
+
+ ----------------------------------------------------------------------
+
+ HOW TO GET HELP
+
+ Send Check or Money Order to... just kidding! You're on your own for
+ support. Try asking other ircd-ratbox admins on EFnet if you can't fix it
+ yourself. If you do fix anything, however, please send context or unified
+ diffs to ircd-ratbox@lists.ratbox.org so the fixes can be incorporated into
+ the next release of ircd-hybrid. If ratbox crashes on you, PLEASE contact
+ ircd-ratbox@lists.ratbox.org ASAP with a backtrace of the core.
+
+ DISCUSSION: There is a mailing list for discussion of ratbox issues,
+ To subscribe, visit:
+ http://lists.ratbox.org/cgi-bin/mailman/listinfo/ircd-ratbox
+
+ ----------------------------------------------------------------------
+
+ NOTES
+
+ The best way to get a backtrace of the core is to follow this sequence of
+ instructions:
+
+ 1.
+
+ Change to the directory containing the core file
+
+ 2.
+
+ Run gdb on the binary and the core file. With an unmodified ircd-ratbox
+ installation, an example command line is below (in the /usr/local/ircd
+ directory)
+
+ $ gdb bin/ircd ircd.core
+
+ 3.
+
+ At the "(gdb)" prompt, enter the command "bt"
+
+ 4.
+
+ Save the output of the backtrace command and send it to
+ ircd-ratbox@lists.ratbox.org
+
+ 5.
+
+ Be sure to save the ircd binary, the modules, and the core file in a
+ safe place in case the developers need to look deeper than a backtrace
+ provides.
+
+ ----------------------------------------------------------------------
+
+ OPENSSL NOTES
+
+ Older FreeBSD machines sometimes have the obsolete ports version of
+ OpenSSL libcrypto in /usr/local/lib. When configure is used with
+ --enable-openssl, and libintl is detected in /usr/local/lib, the
+ /usr/local/lib directory will be searched BEFORE the system /usr/lib for
+ libraries by the linker. The linker may try to link to the old
+ /usr/local/lib libcrypto instead of the system /usr/lib libcrypto. Some
+ older versions may cause error messages similar to the following:
+
+ gcc -g -O2 -DIRCD_PREFIX=\"/home/wcampbel/ircd\" -Wl,-export-dynamic
+ -L/usr/local/lib -o ircd blalloc.o channel.o vchannel.o class.o client.o
+ dline_conf.o event.o fdlist.o fileio.o hash.o irc_string.o ircd.o ircdauth.o
+ ircd_signal.o linebuf.o list.o listener.o m_error.o match.o memdebug.o
+ modules.o motd.o mtrie_conf.o oldparse.o numeric.o packet.o parse.o res.o rsa.o
+ restart.o s_auth.o s_bsd.o s_bsd_kqueue.o s_conf.o s_debug.o s_gline.o s_log.o
+ s_misc.o s_serv.o s_stats.o s_user.o scache.o send.o sprintf_irc.o tools.o
+ whowas.o lex.yy.o y.tab.o version.o -lintl -ldescrypt -lcrypto -lfl
+ rsa.o: In function `get_randomness':
+ /home/wcampbel/dev/ircd-ratbox/src/rsa.c(.text+0x60): undefined reference to
+ `RAND_pseudo_bytes'
+ /usr/local/lib/libcrypto.so: undefined reference to `ERR_load_RSAREF_strings'
+ /usr/local/lib/libcrypto.so: undefined reference to `RSA_PKCS1_RSAref'
+ *** Error code 1
+
+ If this is the case, you may need to rerun configure without the
+ --enable-openssl option, manually edit src/Makefile and modules/Makefile
+ to put -L/usr/lib before the -L/usr/local/lib in LDFLAGS, or remove the
+ old OpenSSL from /usr/local, and recompile all applications that use
+ libcrypto to use the system one.
--- /dev/null
+# $Id: LICENSE 6 2005-09-10 01:02:21Z nenolod $
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+#************************************************************************
+#* IRC - Internet Relay Chat, Makefile
+#* Copyright (C) 1990, Jarkko Oikarinen
+#*
+#* 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.
+#*
+#* $Id: Makefile.in 1347 2006-05-17 14:49:13Z nenolod $
+#*/
+
+RM=@RM@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+mandir = @mandir@
+moduledir = @moduledir@
+helpdir = @helpdir@
+confdir = @confdir@
+logdir = @logdir@
+
+# Default CFLAGS
+# CFLAGS = -g -O2 -DNDEBUG
+CFLAGS = @CFLAGS@
+# Developers CFLAGS
+#CFLAGS= -g -O2 -Wunused -Wall -ggdb -pedantic -Wshadow -Wmissing-declarations
+
+# Default make flags - you may want to uncomment this on a multicpu machine
+#MFLAGS = -j 4
+
+#
+# For developers
+#CFLAGS= -g -O2 -Wall
+
+# You may need to define the FD_SETSIZE in order to overrule
+# the system one.
+#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
+SHELL=/bin/sh
+SUBDIRS=modules extensions libcharybdis src tools servlink doc help
+CLEANDIRS = ${SUBDIRS}
+RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
+
+MAKE = make ${MFLAGS}
+
+all: build
+
+
+autoconf: configure.ac
+ autoconf
+ autoheader
+ ${RM} -f config.cache
+
+build:
+ -@if [ ! -f include/setup.h ] ; then \
+ echo "Hmm...doesn't look like you've run configure..."; \
+ echo "Doing so now."; \
+ sh configure; \
+ fi
+ @for i in $(SUBDIRS); do \
+ echo "build ==> $$i";\
+ cd $$i;\
+ ${MAKE} build || exit; cd ..;\
+ done
+
+clean:
+ ${RM} -f *~ core rsa_respond.tar rsa_respond.tar.gz
+ @for i in $(CLEANDIRS); do \
+ echo "clean ==> $$i";\
+ cd $$i;\
+ ${MAKE} clean; cd ..;\
+ done
+ -@if [ -f include/setup.h ] ; then \
+ echo "To really restart installation, make distclean" ; \
+ fi
+
+distclean:
+ ${RM} -f Makefile *~ *.rej *.orig core ircd.core
+ ${RM} -f config.status config.cache config.log
+ cd include; ${RM} -f setup.h *~ *.rej *.orig ; cd ..
+ @for i in $(CLEANDIRS); do \
+ echo "distclean ==> $$i";\
+ cd $$i;\
+ ${MAKE} distclean; cd ..;\
+ done
+
+depend:
+ @for i in $(SUBDIRS); do \
+ echo "depend ==> $$i";\
+ cd $$i;\
+ ${MAKE} depend; cd ..;\
+ done
+
+lint:
+ @for i in $(SUBDIRS); do \
+ echo "lint ==> $$i";\
+ cd $$i;\
+ ${MAKE} lint; cd ..;\
+ done
+
+install-mkdirs:
+ @echo "ircd: setting up ircd directory structure"
+ -@if test ! -d $(DESTDIR)$(prefix); then \
+ mkdir $(DESTDIR)$(prefix); \
+ fi
+ -@if test ! -d $(DESTDIR)$(bindir); then \
+ mkdir $(DESTDIR)$(bindir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(confdir); then \
+ mkdir $(DESTDIR)$(confdir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(mandir); then \
+ mkdir $(DESTDIR)$(mandir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(moduledir); then \
+ mkdir $(DESTDIR)$(moduledir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(helpdir); then \
+ mkdir $(DESTDIR)$(helpdir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(logdir); then \
+ mkdir $(DESTDIR)$(logdir); \
+ fi
+
+install: install-mkdirs all
+ @for i in $(SUBDIRS); do \
+ echo "install ==> $$i";\
+ cd $$i;\
+ ${MAKE} install; \
+ cd ..; \
+ done
+
+rsa_respond:
+ @cd tools;\
+ echo "Creating rsa_respond.tar.gz";\
+ tar cf ../rsa_respond.tar $(RSA_FILES);\
+ cd ..;\
+ gzip rsa_respond.tar
--- /dev/null
+This is charybdis 2.1.2, Copyright (c) 2005-2006 Charybdis team.
+See LICENSE for licensing details (GPL v2).
+
+-- charybdis-2.1.2
+
+- Fix bug that could cause all hostmangled users to be exempted when a
+ single ban exception existed on a channel.
+- Tweak \s code a little.
+- Add a minor clarification to the SGML docs.
+- Avoid truncation in ip_cloaking (by removing components on the other side).
+ Note that this may cause channel +bqeI modes set on such very long hosts
+ to no longer match.
+
+-- charybdis-2.1.1
+
+- Search the shortest list (user's/channel's) when looking up channel
+ memberships.
+- Make the SID-collision notice look right under all conditions.
+- Move kills from services from +s to +k snomask.
+- When no_tilde is present on an auth{} block, check the non-tilde version
+ of the user@host against k:lines as well.
+- Put full reason in the SQUIT reason when a server is rejected for
+ insufficient parameters being passed to a command.
+- Don't redirect users to an existing domain, irc.fi.
+- Improve communication of servlink-related error messages.
+
+-- charybdis-2.1.0
+
+- Our official website is now http;//www.ircd-charybdis.org/.
+- Make RPL_ISUPPORT (005 numeric) modularizable.
+- Also do forwarding if the channel limit (+l) is exceeded.
+- Don't count opers on service{} servers in /lusers.
+- Allow servers to send to @#chan and +#chan.
+- Allow +S clients (services) to send to channels and @/+ channels always.
+- Allow normal match() on IP address also in /masktrace.
+- Add new testmask from ratbox 2.2. Allows matches on nick, ip and gecos
+ in addition to user and host, and is fully analogous to masktrace.
+ The numeric has changed from 724 to 727 and fields in it have changed.
+- Show IP addresses to opers in /whowas.
+- Add extb_extgecos extban option ($x:nick!user@host#gecos), from sorcery
+ modules.
+- Add extb_canjoin extban option ($j:#channel), matches if the user is banned
+ from the other channel.
+- Allow opers to /who based on realhost.
+- Allow opers to /masktrace, /testmask based on realhost.
+- Add general::operspy_dont_care_user_info, limits operspy accountability to
+ channel-related information.
+- Make host mangling more reliable.
+- Prevent ban evasion by enabling/disabling host mangling.
+- Add EUID, sends real host and services account in the same command as other
+ user information.
+- Make it possible to send CHGHOST without ENCAP (fixes problems with old
+ services).
+- Allow service{} servers to manipulate the nick delay table (for "nickserv
+ enforcement", aka SVSHOLD).
+- Send server notices about connections initiated by remote opers network wide.
+- Fix too early truncation of JOIN channel list.
+- Make the newconf system available to modules.
+- Add /stats s to the hurt module to list active hurts.
+- Add general::servicestring, shown in /whois for opered services (+oS).
+- Show real host/IP behind dynamic spoof in /whois to the user themselves
+ and opers.
+- Document option to disable nick delay.
+- Improve logging of server connections.
+- Clean up handling of hostnames in connect blocks.
+- Remove support for resolving ip6.int, people should be using ip6.arpa.
+- Unbreak --disable-balloc (useful for debugging with tools like valgrind).
+- Make Solaris 10 I/O ports code compile.
+- Add WEBIRC module to allow showing the real host/IP of CGI:IRC users.
+- Comment out blacklist{} block in example confs, as AHBL requires
+ notification before use.
+- Fix some bugs relating to the resolver.
+
+-- charybdis-2.0.0
+
+- Replace ADNS with a new smaller resolver from ircu and hybrid.
+- Make services shortcuts (/chanserv etc) configurable in ircd.conf.
+- Add extban: extensible +bqeI matching via modules. Syntax is
+ $<type>[:<data>]. By default no modules are loaded.
+- Add DNS blacklist checking.
+- Change operator{} block user@host from host to orighost. This means that
+ services/+h spoofs do not work in operator{} blocks; auth{} spoofs still
+ work. Check your operator{} blocks!
+- Split contrib/ into extensions/ and unsupported/.
+- Change CHGHOST do show the change to all other clients on common channels
+ with quit/join/mode.
+- Add /rehash nickdelay to clear out the nickdelay tables.
+- Glines are now disabled in the example confs.
+- Show more error messages on stderr.
+- Add OMODE command to extensions/ for easier oper mode hacking.
+- Add HURT system to extensions/; this shuns clients matching certain host/ip
+ unless and until they identify to services. Mainly intended for SorceryNet.
+- Show SASL success and failure counts in /stats t.
+- Allow more frequent autoconnects to servers.
+- Messaging services by nickname no longer uses target change slots.
+- Only accept SASL from servers in a service{} block.
+- New auth{} flag need_sasl to reject users who haven't done SASL
+ authentication.
+- Expand blah.blah and blah:blah to *!*@... instead of ...!*@* for bans
+- Don't allow opers to fake locops/operwall to +w.
+- Documentation updates.
+- Many bugfixes.
+
+-- charybdis-1.1.0
+
+- Implement SAFELIST.
+- Incorporate ircu's match() algorithm.
+- Improve usermode modularization.
+- Seperate server notices into a seperate snomask, freeing up many
+ usermodes to be used.
+- Add support for SIGNON originating from Hyperion2.
+- Modularize many server notices into seperate modules.
+- Add hooks for can_join and can_create_channel.
+- Add support for SASL authentication.
+- Add introduce_user hook for adding new messages when a user is bursted.
+- Move a large part of the ircd into libcharybdis.
+- Don't complain "unknown user mode" if a user tries to unset
+ a mode they do not have access to.
+- Update our challenge specification to the challenge implementation in
+ ratbox 2.2 for interoperability.
+- Make +f notices network-wide (local host, global host,
+ global user@host, local class), other notices tied to +f remain local.
+- Allow ENCAP REALHOST outside of netburst.
+- Add general::global_snotices option to make server notices be
+ network-wide or not.
+- Add sno_farconnect.c to contrib, provides farconnect support.
+ Could be useful for BOPM.
+- Add sno_routing.c which displays information about netsplits, netjoins
+ and the clients affected by them.
+- Add CHANTRACE and TRACEMASK commands from ratbox 3.0
+- Use IsOperAdmin() instead of IsAdmin() when sending admin-only messages,
+ that way hidden admins get them too.
+- Add m_error to core_module_table, somehow it was missing.
+- Correct a format string bug that occurs when a read error is
+ received.
+- Add some logging in places where we drop servers and only notify
+ server operators.
+- Track hostmask limits based on a client's original host, if
+ available.
+- Move HIDE_SPOOF_IPS into the general {} block in ircd.conf
+
+-- charybdis-1.0.3
+
+- Fix /invite UID leak. (Found by logiclrd@EFnet.)
+- Incorporate ratbox bugfixes for the MONITOR system.
+- Made show_ip() less braindead.
+- Show real errno if we fail to connect to a server.
+- Don't disclose server IP's when a connection fails.
+- Do not show the channels a service is sitting in.
+- Reverted the aline code from hybrid-7.2
+- Make sure TS6 services are recognized properly if connected remotely.
+- Tweak something in services support for cyrix boxes.
+
+-- charybdis-1.0.2
+
+- Fix propagation of an empty SJOIN (permanant channels).
+- Fix an exploit involving a malformed /trace request.
+- Don't display a blank RPL_WHOISCHANNELS in a remote whois request.
+- Allow modules to provide new usermodes.
+- On a nickname collision, change the collided nick to their unique ID,
+ if general::collision_fnc is enabled in the config.
+- Don't allow UID lookups in /monitor + and /monitor s
+- Fix a garbage issue with channel mode +j.
+- Apply proper capability flags to the proper server in me_gcap().
+- Use find_named_person() instead of find_person() in a nick collision.
+- Prevent UID disclosure in cmode setting.
+- Prevent UID disclosure to remote clients in /kick.
+- Do not allow users to query via /whois <server> <UID>.
+- Don't allow local users to use UID's in local usermode changes.
+- Propagate +q lists on netjunction.
+- Clear +q lists on a lowerTS SJOIN.
+- Ported a generic k/d/x-line parser from hybrid-7.2 which resulted in
+ duplicate code reduction.
+- Fix linebuf raw code to not truncate lines longer than 512 bytes;
+ improves ziplink reliability on net junction.
+- Use find_named_person() vs find_person() in services alias code.
+- Fix issue where channel forwarding token can be lost on net junction.
+- Fix empty channel desync issues involving +P.
+- Remove unused non-ENCAP CHGHOST support.
+- Use TS6 form for SQUIT wallops.
+- Propagate nickname changes for remote clients in TS6 form if possible,
+ even if sent in TS5 format.
+- Only clear oper_only_umodes for local clients on deoper.
+
+-- charybdis-1.0.1
+
+- Display logged in status on non-local clients too.
+- Documentation updates
+- Fix a bug with forward target authorization.
+- Fix a bug with mode propagation (+Q/+F).
+- Change ERR_NOSUCHNICK to ERR_SERVICESOFFLINE in services aliases.
+- Add remote rehashing.
+- Document service { } blocks (u:lines on ircu).
+- Document identify_service and identify_command in reference.conf.
+
+-- charybdis-1.0
+- Implement channel mode +L for channel list limit exemptions.
+- Implement channel mode +P primarily as a status mode, permanant
+ channel -- this is usually enforced via services registrations.
+- Change behaviour of /stats p: now displays all staff members instead
+ of local ones only.
+- Make oper_list global, add local_oper_list for local traffic.
+- Strip control codes from parts and quits.
+- Add channel mode +c which strips control codes from messages sent to
+ the channel.
+- Add channel mode +g which enables free use of the /invite command.
+- Add channel mode +z which sends rejected messages to channel ops.
+ Could be useful for Q&A sessions or other similar events.
+- Add channel quietmasks. These are recommended over the use of channel
+ bans used to remove a user's ability to participate in the channel.
+- Add channel join throttling mode, +j. Used to throttle channel join
+ traffic, i.e. join/part flood attacks. Syntax: +j <joins>:<timeslice>
+- Improvements to channel_modes(), from shadowircd -- allows for
+ better construction of the mode string.
+- Use the undernet throttle notice instead of bancache message when
+ dealing with rejected clients. (stolen from ircu2.10.12)
+- Add channel forwarding, via channel mode +f, behaves similarly to
+ dancer-ircd version.
+- Update example.conf to reflect AthemeNET changes. Original ratbox
+ config is now reference.conf.
+- Services account names are now tracked globally.
+- Add channel mode +Q which disables the effects of channel forwarding
+ on a temporary basis.
+- Add channel mode +F which allows anybody to disable forwarding target
+ authorisation, voluntarily on their channels.
+- Make wallops behave like normal wallops.
+- Add services aliases: /ns, /cs, /os, /nickserv, /chanserv, /operserv.
+- Add simple hack that enables use of server password for automatic
+ identify.
+
+-- ircd-ratbox-2.1.5+datadrain
+- fix a buffer overflow and an unterminated buffer when TS6 forces us
+ to remove bans
+- fix potential junk SJOIN generation when splitting it into multiple
+ lines
+- make servlink check for an uncompressed ERROR
+- change NICKLEN to 15.
+- change TOPICLEN to 390.
+- force services extensions to be enabled always
+- change patchlevel.h to get it's information from 'configure'
+- add m_chghost.c, ghetto rigged hostcloaking module, using elite ENCAP
+ technique
+
+-- ircd-ratbox-2.1.4
+- fix minor time bug which occurs on december 31st
+- dont drop a servers link when we get a malformed WHOIS
+- disallow commas in channel keys
+- fix compile problem with abort_list
+- fix build on darwin
+- fix compilation with gcc4
+- userhost was only allowing 4 targets instead of 5
+- invalidate channel ban cache on nickchange
+- add TARGMAX to 005, detailing maximum targets for messages
+- fix counting of clients on accept list when adding users
+- use ID instead of name when bursting SJOIN to TS6 servers
+- lower id in struct User, which was one byte bigger than it needs to be
+
+-- ircd-ratbox-2.1.3
+- removed sendq_eob as it just doesnt work on efnet
+- dont allow MONITOR from an unregistered client
+- add some uniqueness into the auth process for bopm
+- fix resvs to check whether target server is us properly
+- fix a core in cidr channel ban matching
+- raise max temptime to a year
+- fix cores when we receive extra params to NICK/UID
+- remove no_oper_resvs, add resv_exempt auth flag
+- fix flattened links
+- clean up the accept code, and dont clear a users own list of accepted
+ clients on nickchange
+- non-efnet:
+ - make services {}; blocks be displayed on stats U
+ - make services {}; blocks apply on rehash, you must now have only ONE
+ service {}; block, but you may have multiple name=""; entries within.
+ - only show services logged in info for local clients
+
+-- ircd-ratbox-2.1.2
+- fix missing end comment tag in example confs
+- fix display problem with unauthorised conn notice
+- remove some unused defines from INFO
+- fix tabs for spaces in some helpfiles
+- add in missing links_delay conf option
+- fix cores under amd64
+- disallow bans beginning with ':' over BMASK
+- disallow bans with a space in chm_ban()
+- stop counting hidden opers in stats p count output
+- match() params of remote unresv were inverted, causing it to never match
+- fix possibility of clients setting blank keys
+- fix UID problems with trace
+- raise default topiclen to 160
+- add in forced nick change for ratbox-services, when compiled with
+ --enable-services
+
+-- ircd-ratbox-2.1.1
+- remove an 005 token to hack around the parser bug
+- exempt users messaging themselves from target change
+- disallow messaging towards UIDs
+- add in doc/tgchange.txt
+- move stats L back to RPL_STATSLINKINFO
+- fix some minor auth problems
+- properly store ipv6 ips when we're compiled for v4 only
+- fix propagation of xline/resv
+- sync remote kline reasons with form used for local klines
+
+-- ircd-ratbox-2.1.0
+- no changes
+
+-- ircd-ratbox-2.1.0beta2
+- fix a few compile warnings
+- added multi-prefix clicap, for showing "@+" in NAMES/WHO replies
+- remove split_delay, make split servers now work on how many servers have
+ issued EOB, rather than how many exist.
+- server-side notify lists. See doc/monitor.txt
+- fix undline core
+- remove an unwanted space from beginning of second 005
+- fix a potential core with the patricia when removing classes
+- when we're handling global NAMES, dont output channels whose users are all
+ invisible
+
+-- ircd-ratbox-2.1.0beta1
+- No release notes, see doc/whats-new-2.1.txt
+
+--------------------------------------------------------------------------------
+
+BUGS: Major bugs in this release are listed in BUGS
+
+BUG REPORTS: If you run this code and encounter problems, you must report
+via IRC to irc.atheme.net, #athemenet-dev.
+
+Please include a gdb backtrace and keep the core file, binaries and
+modules in case the developers need them.
+
+Other files recommended for reading: BUGS, README.FIRST, INSTALL
+
+--------------------------------------------------------------------------------
+$Id: NEWS 2813 2006-12-05 13:24:19Z jilles $
+
--- /dev/null
+If you don't read this first, we won't help you.
+:-)
+
+******************************* IMPORTANT *************************************
+
+ *********** Note for those who dont bother reading docs *****************
+ * - Reading INSTALL is now a must, as the old DPATH is now specified *
+ * when configure is run. *
+ * You now need to ./configure --prefix="/path/to/install/it" *
+ * - The old config format WILL NOT WORK. Please see doc/example.conf ! *
+ * - The old kline format WILL NOT WORK. Please use convertklines which *
+ * will be installed with your ircd! *
+ *************************************************************************
+
+ ALSO, IF YOU ARE UPGRADING YOUR CURRENT SOURCE TREE, AND YOU TRY TO BUILD
+ IN IT WITHOUT PERFORMING AT LEAST 'make clean', THINGS _WILL_ BREAK. IT IS
+ RECOMMENDED THAT YOU RUN 'make distclean' AND THEN RERUN './configure'!
+
+******************************* REQUIREMENTS **********************************
+
+Necessary Requirements:
+
+- A supported platform (look below)
+
+- A working dynamic load library, unless
+ compiling as static, without module
+ support.
+
+- A working lex. Solaris /usr/ccs/bin/lex
+ appears to be broken, on this system flex
+ should be used.
+
+
+Feature Specific Requirements:
+
+- For the SSL Challenge controlled OPER feature and encrypted server links,
+ a working OpenSSL library
+
+- For encrypted oper and (optional) server passwords, a working DES and/or
+ MD5 library
+
+*******************************************************************************
+
+- To report bugs in ircd-ratbox, send the bug report to ircd-ratbox@lists.ratbox.org
+
+- Known bugs are listed in the BUGS file
+
+- See the INSTALL document for info on configuring and compiling
+ ircd-ratbox.
+
+- Please read doc/index.txt to get an overview of the current documentation.
+
+- Old Hybrid 5/6 configuration files are no longer supported. All conf
+ files will have to be converted to the new format. A convertconf
+ utility is provided and installed into bin/.
+
+- If you are wondering why config.h is practically empty, its because many
+ things that were once in config.h are now specified in the 'general'
+ block of ircd.conf. Look at example.conf for more information about
+ these options.
+
+- The files, /etc/services, /etc/protocols, and /etc/resolv.conf, MUST be
+ readable by the user running the server in order for ircd to start.
+ Errors from adns causing the ircd to refuse to start up are often related
+ to permission problems on these files.
+
+- There is a mailing list for ircd-ratbox. To subscribe to this list
+ visit http://lists.ratbox.org/cgi-bin/mailman/listinfo/ircd-ratbox
+ Note that this list also gets the commit emails from the CVS server.
+
+- FREEBSD USERS: if you are compiling with ipv6 you may experience
+ problems with ipv4 due to the way the socket code is written. To
+ fix this you must: "sysctl net.inet6.ip6.v6only=0"
+
+- SOLARIS USERS: this code appears to tickle a bug in older gcc and
+ egcs ONLY on 64-bit Solaris7. gcc-2.95 and SunPro C on 64bit should
+ work fine, and any gcc or SunPro compiled on 32bit.
+
+- DARWIN AND MACOS X USERS: You must be using at least the December 2001
+ Development Tools from Apple to build ircd-ratbox with shared modules.
+ Before then you MUST disable shared modules, as we do not have the proper
+ flags for cc(1) prior to that point to produce shared modules.
+
+- SUPPORTED PLATFORMS: this code should compile without any warnings
+ on FreeBSD 3.x/4.x, RedHat 6.2, Debian Potato and Solaris 7/8 sparc.
+ Please let us know if you find otherwise.
+ It probably does not compile on AIX, IRIX or libc5 Linux.
+
+- TESTED PLATFORMS: The code has been tested on the following platforms, and
+ is known to run properly.
+ FreeBSD 3.x/4.x
+ Linux glibc
+ Solaris 2.6/7/8
+ OpenBSD 2.8
+ NetBSD 1.4
+
+- Please read doc/whats-new.txt for information about what is in this release
+
+- Other files recommended for reading: BUGS, INSTALL
+
+--------------------------------------------------------------------------------
+$Id: README.FIRST 1837 2006-08-22 14:05:58Z nenolod $
--- /dev/null
+The charybdis repository is available for anonymous access:
+ svn co http://svn.atheme.org/charybdis/trunk charybdis-devel
+
+For the latest stable:
+ svn co http://svn.atheme.org/charybdis/branches/stable charybdis-stable
--- /dev/null
+# $Id: aclocal.m4 918 2006-02-23 18:17:21Z nenolod $ - aclocal.m4 - Autoconf fun...
+AC_DEFUN([AC_DEFINE_DIR], [
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo [$]$2`
+ ac_define_dir=`eval echo [$]ac_define_dir`
+ $1="$ac_define_dir"
+ AC_SUBST($1)
+ ifelse($3, ,
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
+AC_DEFUN([AC_SUBST_DIR], [
+ ifelse($2,,,$1="[$]$2")
+ $1=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""[$]$1"\"
+ )`
+ AC_SUBST($1)
+])
+
+dnl CHARYBDIS_C_GCC_TRY_FLAGS(<warnings>,<cachevar>)
+AC_DEFUN([CHARYBDIS_C_GCC_TRY_FLAGS],[
+ AC_MSG_CHECKING([GCC flag(s) $1])
+ if test "${GCC-no}" = yes
+ then
+ AC_CACHE_VAL($2,[
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} $1 -Werror"
+ AC_TRY_COMPILE([
+#include <string.h>
+#include <stdio.h>
+int main(void);
+],[
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+], [$2=yes], [$2=no])
+ CFLAGS="${oldcflags}"])
+ if test "x$$2" = xyes; then
+ CWARNS="${CWARNS}$1 "
+ AC_MSG_RESULT(ok)
+ else
+ $2=''
+ AC_MSG_RESULT(no)
+ fi
+ else
+ AC_MSG_RESULT(no, not using GCC)
+ fi
+])
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for charybdis 2.1.2.
+#
+# $Id: configure 2811 2006-12-05 13:18:39Z jilles $
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='charybdis'
+PACKAGE_TARNAME='charybdis'
+PACKAGE_VERSION='2.1.2'
+PACKAGE_STRING='charybdis 2.1.2'
+PACKAGE_BUGREPORT=''
+
+ac_default_prefix=$HOME/ircd
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT MKDEP MAKEDEPEND STDOUT CPP EGREP SET_MAKE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RM CP MV LN SED AR LD RANLIB TOUCH YACC LEX LEXLIB LEX_OUTPUT_ROOT CRYPT_LIB VICONF ALLOCA ENCSPEED ZLIB_LD ETC_DIR confdir LOG_DIR logdir HELP_DIR helpdir MODULE_DIR moduledir SELECT_TYPE FNVHASH_S MODULES_LIBS MOD_TARGET SSL_SRCS_ENABLE SSL_INCLUDES SSL_LIBS PICFLAGS IRC_CFLAGS SEDOBJ LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures charybdis 2.1.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of charybdis 2.1.2:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-ipv6 Enable IPv6 support
+ --enable-openssl=DIR Enable OpenSSL support (DIR optional).
+ --disable-openssl Disable OpenSSL support.
+ --disable-zlib Disable ziplinks support
+ --enable-poll Force poll() usage.
+ --enable-select Force select() usage.
+ --enable-kqueue Force kqueue() usage.
+ --enable-devpoll Force usage of /dev/poll.
+ --enable-epoll Force sys_epoll usage (Linux only).
+ --enable-assert Enable assert(). Choose between soft(warnings) and
+ hard(aborts the daemon)
+ --enable-iodebug Enable IO Debugging hooks
+ --enable-profile Enable profiling
+ --disable-balloc Disable the block allocator.
+ --enable-ricer-hashing Enable assembly-based hashing routines.
+ --enable-small-net Enable small network support.
+ --disable-shared-modules
+ Disable shared modules.
+ --enable-warnings Enable all sorts of warnings for debugging.
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-zlib-path=DIR Path to libz.so for ziplinks support.
+ --with-confdir=DIR Directory to install config files.
+ --with-logdir=DIR Directory where to write logfiles.
+ --with-helpdir=DIR Directory to install help files.
+ --with-moduledir=DIR Directory to install modules.
+ --with-nicklen=LENGTH Set the nick length to LENGTH (default 15, max 50)
+ --with-topiclen=NUMBER Set the max topic length to NUMBER (default 390, max
+ 390)
+ --with-maxclients=NUMBER
+ Maximum number of connections the ircd can handle
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+charybdis configure 2.1.2
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+
+$Id: configure 2811 2006-12-05 13:18:39Z jilles $
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by charybdis $as_me 2.1.2, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_headers="$ac_config_headers include/setup.h"
+
+
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+
+
+OLD_CFLAGS="$CFLAGS"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+CFLAGS="$OLD_CFLAGS"
+
+
+if test "$ac_cv_c_compiler_gnu" != yes; then
+
+SGS=no
+echo "$as_me:$LINENO: checking $CC -version for TenDRA or MIPSpro" >&5
+echo $ECHO_N "checking $CC -version for TenDRA or MIPSpro... $ECHO_C" >&6
+case `$CC -version 2>&1` in
+*TenDRA*)
+ echo "$as_me:$LINENO: result: yes, TenDRA" >&5
+echo "${ECHO_T}yes, TenDRA" >&6
+ IRC_CFLAGS=""
+ CPPFLAGS="$CPPFLAGS -Ylonglong -Yansi -I/usr/include"
+ SGS=yes
+ TenDRA=yes
+;;
+*MIPSpro*)
+ echo "$as_me:$LINENO: result: yes, MIPSpro" >&5
+echo "${ECHO_T}yes, MIPSpro" >&6
+ MIPSpro=yes
+ SGS=yes
+;;
+*)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ TenDRA=no
+ MIPSpro=no
+;;
+esac
+
+echo "$as_me:$LINENO: checking $CC -V for Sun Workshop, Forte, HPUX or Tru64 cc" >&5
+echo $ECHO_N "checking $CC -V for Sun Workshop, Forte, HPUX or Tru64 cc... $ECHO_C" >&6
+case `$CC -V 2>&1` in
+*Sun*WorkShop* | *Forte*Developer*)
+ echo "$as_me:$LINENO: result: Sun Workshop/Forte" >&5
+echo "${ECHO_T}Sun Workshop/Forte" >&6
+ IRC_CFLAGS="-fast -xinline=dlinkAdd,dlinkAddBefore,dlinkAddTail,dlinkDelete,dlink_list_length,dlink_node,dlinkMoveList,_MyMalloc,_MyRealloc,_MyFree,_DupString"
+ SunWorkShop=yes
+ SGS=yes
+;;
+*Tru64*)
+ echo "$as_me:$LINENO: result: Tru64 cc" >&5
+echo "${ECHO_T}Tru64 cc" >&6
+ IRC_CFLAGS="-O2"
+ CPPFLAGS="-I/usr/local/include"
+ Tru=yes
+;;
+*HP*ANSI*)
+ echo "$as_me:$LINENO: result: HPUX cc" >&5
+echo "${ECHO_T}HPUX cc" >&6
+ HPUX=yes
+ IRC_CFLAGS="+e"
+;;
+*)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+;;
+esac
+
+fi
+
+echo "$as_me:$LINENO: checking uname -s for Cygwin, Solaris, AIX or HPUX" >&5
+echo $ECHO_N "checking uname -s for Cygwin, Solaris, AIX or HPUX... $ECHO_C" >&6
+OSNAME=`uname -s`
+case "$OSNAME" in
+ HP-UX*)
+
+ if test "$HPUX" != yes -a "$ac_cv_c_compiler_gnu" = no; then
+ echo "$as_me:$LINENO: result: assuming old HPUX with its own cc" >&5
+echo "${ECHO_T}assuming old HPUX with its own cc" >&6
+ IRC_CFLAGS="$IRC_CFLAGS +e"
+ HPUX=yes
+ else
+ echo "$as_me:$LINENO: result: already using newer HPUX" >&5
+echo "${ECHO_T}already using newer HPUX" >&6
+ fi
+ ;;
+ CYGWIN*)
+ echo "$as_me:$LINENO: result: Cygwin" >&5
+echo "${ECHO_T}Cygwin" >&6
+ CYGWIN=yes
+ ;;
+ SunOS*)
+ echo "$as_me:$LINENO: result: SunOS or Solaris" >&5
+echo "${ECHO_T}SunOS or Solaris" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define __EXTENSIONS__ 1
+_ACEOF
+
+ SUN=yes
+ ;;
+ AIX*)
+ echo "$as_me:$LINENO: result: AIX - Sorry you poor bastard..really we are" >&5
+echo "${ECHO_T}AIX - Sorry you poor bastard..really we are" >&6
+ IRC_CFLAGS="$IRC_CFLAGS -Wl,-brtl -Wl,-G"
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ ;;
+esac
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+ echo "$as_me:$LINENO: checking if $CC is Apple GCC" >&5
+echo $ECHO_N "checking if $CC is Apple GCC... $ECHO_C" >&6
+
+ case `$CC -v 2>&1 | tail -n 1` in
+ *Apple*)
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ AppleGCC=yes
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ AppleGCC=no
+ ;;
+ esac
+
+ IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall"
+fi
+
+if test "$ac_cv_prog_cc_g" = yes; then
+ if test "$Tru" = yes; then
+ IRC_CFLAGS="$IRC_CFLAGS -g3"
+ else
+ IRC_CFLAGS="$IRC_CFLAGS -g"
+ fi
+fi
+
+echo "$as_me:$LINENO: checking if $CC supports the SVR4 SGS interfaces" >&5
+echo $ECHO_N "checking if $CC supports the SVR4 SGS interfaces... $ECHO_C" >&6
+if test "$SGS" = "yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "mkdep", so it can be a program name with args.
+set dummy mkdep; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MKDEP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MKDEP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MKDEP="$MKDEP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MKDEP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+MKDEP=$ac_cv_path_MKDEP
+
+if test -n "$MKDEP"; then
+ echo "$as_me:$LINENO: result: $MKDEP" >&5
+echo "${ECHO_T}$MKDEP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "makedepend", so it can be a program name with args.
+set dummy makedepend; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MAKEDEPEND+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAKEDEPEND in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MAKEDEPEND="$MAKEDEPEND" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MAKEDEPEND="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+MAKEDEPEND=$ac_cv_path_MAKEDEPEND
+
+if test -n "$MAKEDEPEND"; then
+ echo "$as_me:$LINENO: result: $MAKEDEPEND" >&5
+echo "${ECHO_T}$MAKEDEPEND" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+echo "$as_me:$LINENO: checking how to generate dependency info" >&5
+echo $ECHO_N "checking how to generate dependency info... $ECHO_C" >&6
+
+STDOUT="> .depend"
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+ echo "$as_me:$LINENO: result: gcc -MM" >&5
+echo "${ECHO_T}gcc -MM" >&6
+ MKDEP="$CC -MM"
+elif test ! -z "$MKDEP"; then
+ echo "$as_me:$LINENO: result: mkdep" >&5
+echo "${ECHO_T}mkdep" >&6
+
+ if test -z "$Tru"; then
+ STDOUT=""
+ else
+ STDOUT=" 2> /dev/null"
+ fi
+elif test "$SunWorkShop" = yes; then
+ echo "$as_me:$LINENO: result: $CC -xM" >&5
+echo "${ECHO_T}$CC -xM" >&6
+ MKDEP="$CC -xM"
+ STDOUT="> .depend 2> /dev/null"
+elif test ! -z "$MAKEDEPEND"; then
+ echo "$as_me:$LINENO: result: makedepend" >&5
+echo "${ECHO_T}makedepend" >&6
+ MKDEP="$MAKEDEPEND -f-"
+else
+ echo "$as_me:$LINENO: result: nothing suitable.. forget it!" >&5
+echo "${ECHO_T}nothing suitable.. forget it!" >&6
+ MKDEP=":"
+fi
+
+
+
+
+echo "$as_me:$LINENO: checking for /dev/null" >&5
+echo $ECHO_N "checking for /dev/null... $ECHO_C" >&6
+if test -c /dev/null ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PATH_DEVNULL "/dev/null"
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define PATH_DEVNULL "devnull.log"
+_ACEOF
+
+ echo "$as_me:$LINENO: result: no - using devnull.log" >&5
+echo "${ECHO_T}no - using devnull.log" >&6
+fi
+
+if test ! -z "$CFLAGS"; then
+ IRC_CFLAGS="$IRC_CFLAGS $CFLAGS"
+fi
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+ for ac_lib in cposix; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror ();
+int
+main ()
+{
+strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_strerror="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+ test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+if test $ac_cv_c_compiler_gnu = yes; then
+ echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then
+ ac_cv_prog_gcc_traditional=yes
+else
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Extract the first word of "rm", so it can be a program name with args.
+set dummy rm; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_RM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $RM in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RM="$RM" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+RM=$ac_cv_path_RM
+
+if test -n "$RM"; then
+ echo "$as_me:$LINENO: result: $RM" >&5
+echo "${ECHO_T}$RM" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "cp", so it can be a program name with args.
+set dummy cp; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $CP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CP="$CP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+CP=$ac_cv_path_CP
+
+if test -n "$CP"; then
+ echo "$as_me:$LINENO: result: $CP" >&5
+echo "${ECHO_T}$CP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "mv", so it can be a program name with args.
+set dummy mv; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MV+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MV in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MV="$MV" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+MV=$ac_cv_path_MV
+
+if test -n "$MV"; then
+ echo "$as_me:$LINENO: result: $MV" >&5
+echo "${ECHO_T}$MV" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "ln", so it can be a program name with args.
+set dummy ln; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_LN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $LN in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LN="$LN" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+LN=$ac_cv_path_LN
+
+if test -n "$LN"; then
+ echo "$as_me:$LINENO: result: $LN" >&5
+echo "${ECHO_T}$LN" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "sed", so it can be a program name with args.
+set dummy sed; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_SED+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $SED in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SED="$SED" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+SED=$ac_cv_path_SED
+
+if test -n "$SED"; then
+ echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $AR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_AR="$AR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "ld", so it can be a program name with args.
+set dummy ld; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $LD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LD="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+LD=$ac_cv_path_LD
+
+if test -n "$LD"; then
+ echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $RANLIB in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+RANLIB=$ac_cv_path_RANLIB
+
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Extract the first word of "touch", so it can be a program name with args.
+set dummy touch; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_TOUCH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $TOUCH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_TOUCH="$TOUCH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_TOUCH="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+TOUCH=$ac_cv_path_TOUCH
+
+if test -n "$TOUCH"; then
+ echo "$as_me:$LINENO: result: $TOUCH" >&5
+echo "${ECHO_T}$TOUCH" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+if test "$YACC" = "yacc" -a -z "`which $YACC 2>/dev/null`"; then
+ { { echo "$as_me:$LINENO: error: could not locate a suitable parser generator; install bison, yacc, or byacc" >&5
+echo "$as_me: error: could not locate a suitable parser generator; install bison, yacc, or byacc" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+for ac_prog in flex lex
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_LEX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LEX="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+ echo "$as_me:$LINENO: result: $LEX" >&5
+echo "${ECHO_T}$LEX" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test -z "$LEXLIB"
+then
+ echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5
+echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6
+if test "${ac_cv_lib_fl_yywrap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_fl_yywrap=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_fl_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6
+if test $ac_cv_lib_fl_yywrap = yes; then
+ LEXLIB="-lfl"
+else
+ echo "$as_me:$LINENO: checking for yywrap in -ll" >&5
+echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6
+if test "${ac_cv_lib_l_yywrap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ll $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_l_yywrap=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_l_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6
+if test $ac_cv_lib_l_yywrap = yes; then
+ LEXLIB="-ll"
+fi
+
+fi
+
+fi
+
+if test "x$LEX" != "x:"; then
+ echo "$as_me:$LINENO: checking lex output file root" >&5
+echo $ECHO_N "checking lex output file root... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_root+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+cat >conftest.l <<_ACEOF
+%%
+%%
+_ACEOF
+{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5
+ (eval $LEX conftest.l) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5
+echo "$as_me: error: cannot find output from $LEX; giving up" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_root" >&6
+rm -f conftest.l
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5
+echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS=$LIBS
+LIBS="$LIBS $LEXLIB"
+cat >conftest.$ac_ext <<_ACEOF
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define YYTEXT_POINTER 1
+_ACEOF
+
+fi
+
+fi
+
+if test "$LEX" = ":"; then
+ { { echo "$as_me:$LINENO: error: could not locate a suitable lexical generator, install flex or lex." >&5
+echo "$as_me: error: could not locate a suitable lexical generator, install flex or lex." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+if test "$libexecdir" = '${exec_prefix}/libexec' &&
+ test "$localstatedir" = '${prefix}/var'; then
+ libexecdir='${bindir}'
+ localstatedir='${prefix}'
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in crypt.h sys/resource.h sys/param.h errno.h sys/syslog.h stddef.h sys/wait.h wait.h sys/epoll.h sys/uio.h machine/endian.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ }
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+if test "$ac_cv_header_machine_endian_h" = "no" ; then
+ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+ # try to guess the endianness by grepping values into an object file
+ ac_cv_c_bigendian=unknown
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+ ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+ yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+ no)
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
+fi
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+ return 0;
+if (sizeof (pid_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_pid_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+ return 0;
+if (sizeof (size_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_size_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for short" >&5
+echo $ECHO_N "checking for short... $ECHO_C" >&6
+if test "${ac_cv_type_short+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((short *) 0)
+ return 0;
+if (sizeof (short))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_short=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_short=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5
+echo "${ECHO_T}$ac_cv_type_short" >&6
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_short" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_short=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (short)); }
+unsigned long ulongval () { return (long) (sizeof (short)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (short))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (short))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (short))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_short=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_short=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+ return 0;
+if (sizeof (int))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_int=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
+
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_int" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (int))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (int))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (int))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_int=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_int=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+ return 0;
+if (sizeof (long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_long" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (long))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (long))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (long))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_long=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((long long *) 0)
+ return 0;
+if (sizeof (long long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_long_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
+
+echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (long long)); }
+unsigned long ulongval () { return (long) (sizeof (long long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (long long))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (long long))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (long long))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_long_long=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_long_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+
+
+echo "$as_me:$LINENO: checking the system's memory page size" >&5
+echo $ECHO_N "checking the system's memory page size... $ECHO_C" >&6
+pagesize="no"
+if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main(void) {
+ FILE *fp = fopen("conftest.malloc", "w");
+
+ if (fp != NULL) {
+ fprintf(fp, "%d\n", getpagesize());
+ fclose(fp);
+ } else
+ exit(1);
+ exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+if test -f "conftest.malloc" ; then
+ pagesize=`cat conftest.malloc`
+fi
+
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+if test "$pagesize" != "no" ; then
+ echo "$as_me:$LINENO: result: $pagesize" >&5
+echo "${ECHO_T}$pagesize" >&6
+else
+ if test "$ac_cv_sizeof_int" = "4" ; then
+ pagesize=4096
+ else
+ pagesize=8192
+ fi
+ echo "$as_me:$LINENO: result: $pagesize (guessing)" >&5
+echo "${ECHO_T}$pagesize (guessing)" >&6
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define MALLOC_PAGESIZE $pagesize
+_ACEOF
+
+
+
+echo "$as_me:$LINENO: checking for library containing socket" >&5
+echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6
+if test "${ac_cv_search_socket+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_socket=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket ();
+int
+main ()
+{
+socket ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_socket="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_socket" = no; then
+ for ac_lib in socket; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket ();
+int
+main ()
+{
+socket ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_socket="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5
+echo "${ECHO_T}$ac_cv_search_socket" >&6
+if test "$ac_cv_search_socket" != no; then
+ test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: You have no socket()! Aborting." >&5
+echo "$as_me: error: You have no socket()! Aborting." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+if test x"$SUN" = xyes; then
+ echo "$as_me:$LINENO: checking for library containing inet_ntoa" >&5
+echo $ECHO_N "checking for library containing inet_ntoa... $ECHO_C" >&6
+if test "${ac_cv_search_inet_ntoa+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_inet_ntoa=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_inet_ntoa="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_inet_ntoa" = no; then
+ for ac_lib in nsl; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_ntoa ();
+int
+main ()
+{
+inet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_inet_ntoa="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_search_inet_ntoa" >&6
+if test "$ac_cv_search_inet_ntoa" != no; then
+ test "$ac_cv_search_inet_ntoa" = "none required" || LIBS="$ac_cv_search_inet_ntoa $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: libnsl not found! Aborting." >&5
+echo "$as_me: error: libnsl not found! Aborting." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5
+echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_sa_len+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (ac_aggr.sa_len)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_sockaddr_sa_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (sizeof ac_aggr.sa_len)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_member_struct_sockaddr_sa_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_sa_len=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6
+if test $ac_cv_member_struct_sockaddr_sa_len = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SOCKADDR_IN_HAS_LEN 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ac_cv_type_socklen_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+if ((socklen_t *) 0)
+ return 0;
+if (sizeof (socklen_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_socklen_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_socklen_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
+if test $ac_cv_type_socklen_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define socklen_t unsigned int
+_ACEOF
+
+fi
+
+
+# Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+ enableval="$enable_ipv6"
+ ipv6=$enableval
+else
+ ipv6=no
+fi;
+
+if test $ipv6 != yes; then
+ have_v6="no"
+else
+echo "$as_me:$LINENO: checking for core IPv6 support" >&5
+echo $ECHO_N "checking for core IPv6 support... $ECHO_C" >&6
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define IN_AUTOCONF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int
+main ()
+{
+struct sockaddr_in6 s;
+ s.sin6_family = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ if test "$CYGWIN" = "yes"; then
+ echo "$as_me:$LINENO: result: no, Cygwin's IPv6 is incomplete" >&5
+echo "${ECHO_T}no, Cygwin's IPv6 is incomplete" >&6
+ have_v6=no
+ else
+ have_v6=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define IPV6 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ echo "$as_me:$LINENO: checking for struct in6addr_any" >&5
+echo $ECHO_N "checking for struct in6addr_any... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define IN_AUTOCONF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int
+main ()
+{
+struct in6_addr a = in6addr_any;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_IN6ADDR_ANY 1
+_ACEOF
+
+ inet_misc=1
+
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+have_v6="no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+echo "$as_me:$LINENO: checking for library containing crypt" >&5
+echo $ECHO_N "checking for library containing crypt... $ECHO_C" >&6
+if test "${ac_cv_search_crypt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_crypt=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char crypt ();
+int
+main ()
+{
+crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_crypt="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_crypt" = no; then
+ for ac_lib in crypt descrypt; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char crypt ();
+int
+main ()
+{
+crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_crypt="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_crypt" >&5
+echo "${ECHO_T}$ac_cv_search_crypt" >&6
+if test "$ac_cv_search_crypt" != no; then
+ test "$ac_cv_search_crypt" = "none required" || LIBS="$ac_cv_search_crypt $LIBS"
+
+fi
+
+
+CRYPT_LIB=$ac_cv_search_crypt
+
+if test "$CRYPT_LIB" = "none required"; then
+ unset CRYPT_LIB
+elif test "$CRYPT_LIB" = no; then
+ unset CRYPT_LIB
+fi
+
+
+
+if test "$ac_cv_header_sys_wait_h" = yes -o "$ac_cv_header_wait_h" = yes; then
+ VICONF=viconf
+ else
+ VICONF=""
+fi
+
+
+
+echo "$as_me:$LINENO: checking whether string.h and strings.h may both be included" >&5
+echo $ECHO_N "checking whether string.h and strings.h may both be included... $ECHO_C" >&6
+if test "${gcc_cv_header_string+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+#include <string.h>
+ #include <strings.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gcc_cv_header_string=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_header_string=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_header_string" >&5
+echo "${ECHO_T}$gcc_cv_header_string" >&6
+
+if test "$gcc_cv_header_string" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STRING_WITH_STRINGS 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+ # try to guess the endianness by grepping values into an object file
+ ac_cv_c_bigendian=unknown
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+ ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+ yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+ no)
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
+
+if test "${ac_cv_header_stdarg_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for stdarg.h" >&5
+echo $ECHO_N "checking for stdarg.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdarg_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdarg_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdarg_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking stdarg.h usability" >&5
+echo $ECHO_N "checking stdarg.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <stdarg.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking stdarg.h presence" >&5
+echo $ECHO_N "checking stdarg.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: stdarg.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: stdarg.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: stdarg.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: stdarg.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: stdarg.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: stdarg.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: stdarg.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: stdarg.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: stdarg.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for stdarg.h" >&5
+echo $ECHO_N "checking for stdarg.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdarg_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_stdarg_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdarg_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdarg_h" >&6
+
+fi
+if test $ac_cv_header_stdarg_h = yes; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: ** stdarg.h could not be found - ircd-ratbox will not compile without it **" >&5
+echo "$as_me: error: ** stdarg.h could not be found - ircd-ratbox will not compile without it **" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+
+echo "$as_me:$LINENO: checking for strlcpy" >&5
+echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS -Wimplicit -Werror"
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+ #include <stdlib.h>
+int
+main ()
+{
+char *a = malloc(6);
+ strlcpy(a, "hello", 6);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRLCPY 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking for strlcat" >&5
+echo $ECHO_N "checking for strlcat... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+ #include <stdlib.h>
+int
+main ()
+{
+char *a = malloc(6);
+ a[0] = '\0';
+ strlcat(a, "hello", 6);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRLCAT 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+CFLAGS=$save_CFLAGS
+
+else
+
+
+
+
+for ac_func in strlcat strlcpy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+fi
+
+echo "$as_me:$LINENO: checking for u_int32_t" >&5
+echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int32_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((u_int32_t *) 0)
+ return 0;
+if (sizeof (u_int32_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_u_int32_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int32_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6
+if test $ac_cv_type_u_int32_t = yes; then
+ :
+else
+
+ echo "$as_me:$LINENO: checking for uint32_t" >&5
+echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint32_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((uint32_t *) 0)
+ return 0;
+if (sizeof (uint32_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_uint32_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint32_t" >&6
+if test $ac_cv_type_uint32_t = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define u_int32_t uint32_t
+_ACEOF
+
+
+else
+
+ { echo "$as_me:$LINENO: WARNING: system has no u_int32_t or uint32_t, default to unsigned long int" >&5
+echo "$as_me: WARNING: system has no u_int32_t or uint32_t, default to unsigned long int" >&2;}
+
+cat >>confdefs.h <<\_ACEOF
+#define u_int32_t unsigned long int
+_ACEOF
+
+
+fi
+
+
+fi
+
+
+echo "$as_me:$LINENO: checking for u_int16_t" >&5
+echo $ECHO_N "checking for u_int16_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int16_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((u_int16_t *) 0)
+ return 0;
+if (sizeof (u_int16_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_u_int16_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int16_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int16_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int16_t" >&6
+if test $ac_cv_type_u_int16_t = yes; then
+ :
+else
+
+ echo "$as_me:$LINENO: checking for uint16_t" >&5
+echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint16_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((uint16_t *) 0)
+ return 0;
+if (sizeof (uint16_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_uint16_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint16_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint16_t" >&6
+if test $ac_cv_type_uint16_t = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define u_int16_t uint16_t
+_ACEOF
+
+
+else
+
+ { echo "$as_me:$LINENO: WARNING: system has no u_int16_t or uint16_t, default to unsigned short int" >&5
+echo "$as_me: WARNING: system has no u_int16_t or uint16_t, default to unsigned short int" >&2;}
+
+cat >>confdefs.h <<\_ACEOF
+#define u_int16_t unsigned short int
+_ACEOF
+
+
+fi
+
+
+fi
+
+
+echo "$as_me:$LINENO: checking for in_port_t" >&5
+echo $ECHO_N "checking for in_port_t... $ECHO_C" >&6
+if test "${ac_cv_type_in_port_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <netinet/in.h>
+
+int
+main ()
+{
+if ((in_port_t *) 0)
+ return 0;
+if (sizeof (in_port_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_in_port_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_in_port_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_in_port_t" >&5
+echo "${ECHO_T}$ac_cv_type_in_port_t" >&6
+if test $ac_cv_type_in_port_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define in_port_t u_int16_t
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for sa_family_t" >&5
+echo $ECHO_N "checking for sa_family_t... $ECHO_C" >&6
+if test "${ac_cv_type_sa_family_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+if ((sa_family_t *) 0)
+ return 0;
+if (sizeof (sa_family_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_sa_family_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_sa_family_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_sa_family_t" >&5
+echo "${ECHO_T}$ac_cv_type_sa_family_t" >&6
+if test $ac_cv_type_sa_family_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define sa_family_t u_int16_t
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for uintptr_t" >&5
+echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
+if test "${ac_cv_type_uintptr_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((uintptr_t *) 0)
+ return 0;
+if (sizeof (uintptr_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_uintptr_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uintptr_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
+echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
+if test $ac_cv_type_uintptr_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINTPTR_T 1
+_ACEOF
+
+
+fi
+
+
+
+
+
+
+
+
+for ac_func in socketpair vsnprintf mmap gettimeofday strdup strndup
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_working_alloca_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_alloca_works=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+ exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_stack_direction=1
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for nanosleep" >&5
+echo $ECHO_N "checking for nanosleep... $ECHO_C" >&6
+if test "${ac_cv_func_nanosleep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define nanosleep to an innocuous variant, in case <limits.h> declares nanosleep.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define nanosleep innocuous_nanosleep
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char nanosleep (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef nanosleep
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nanosleep ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_nanosleep) || defined (__stub___nanosleep)
+choke me
+#else
+char (*f) () = nanosleep;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != nanosleep;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_nanosleep=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_nanosleep=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_nanosleep" >&5
+echo "${ECHO_T}$ac_cv_func_nanosleep" >&6
+if test $ac_cv_func_nanosleep = yes; then
+ :
+else
+ echo "$as_me:$LINENO: checking for nanosleep in -lrt" >&5
+echo $ECHO_N "checking for nanosleep in -lrt... $ECHO_C" >&6
+if test "${ac_cv_lib_rt_nanosleep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nanosleep ();
+int
+main ()
+{
+nanosleep ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_rt_nanosleep=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rt_nanosleep=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rt_nanosleep" >&5
+echo "${ECHO_T}$ac_cv_lib_rt_nanosleep" >&6
+if test $ac_cv_lib_rt_nanosleep = yes; then
+ LIBS="${LIBS} -lrt"
+else
+ echo "$as_me:$LINENO: checking for nanosleep in -lposix4" >&5
+echo $ECHO_N "checking for nanosleep in -lposix4... $ECHO_C" >&6
+if test "${ac_cv_lib_posix4_nanosleep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix4 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nanosleep ();
+int
+main ()
+{
+nanosleep ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_posix4_nanosleep=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_posix4_nanosleep=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_posix4_nanosleep" >&5
+echo "${ECHO_T}$ac_cv_lib_posix4_nanosleep" >&6
+if test $ac_cv_lib_posix4_nanosleep = yes; then
+ LIBS="${LIBS} -lposix4"
+
+fi
+
+fi
+
+fi
+
+if test x$ac_cv_func_nanosleep = xno && test x$ac_cv_lib_posix4_nanosleep = xno && test x$ac_cv_lib_rt_nanosleep = xno
+then
+ echo "$as_me:$LINENO: result: \"nanosleep not found..using select for delay\"" >&5
+echo "${ECHO_T}\"nanosleep not found..using select for delay\"" >&6
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_NANOSLEEP 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for OpenSSL" >&5
+echo $ECHO_N "checking for OpenSSL... $ECHO_C" >&6
+# Check whether --enable-openssl or --disable-openssl was given.
+if test "${enable_openssl+set}" = set; then
+ enableval="$enable_openssl"
+ cf_enable_openssl=$enableval
+else
+ cf_enable_openssl="auto"
+fi;
+
+if test "$cf_enable_openssl" != "no" ; then
+ cf_openssl_basedir=""
+ if test "$cf_enable_openssl" != "auto" &&
+ test "$cf_enable_openssl" != "yes" ; then
+ cf_openssl_basedir="`echo ${cf_enable_openssl} | sed 's/\/$//'`"
+ else
+ for dirs in /usr/local/ssl /usr/pkg /usr/local \
+ /usr/local/openssl ; do
+ if test -f "${dirs}/include/openssl/opensslv.h" ; then
+ cf_openssl_basedir="${dirs}"
+ break
+ fi
+ done
+ unset dirs
+ fi
+ if test ! -z "$cf_openssl_basedir"; then
+ if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h" ; then
+ SSL_INCLUDES="-I${cf_openssl_basedir}/include"
+ SSL_LIBS="-L${cf_openssl_basedir}/lib"
+ else
+ cf_openssl_basedir=""
+ fi
+ else
+ if test -f "/usr/include/openssl/opensslv.h" ; then
+ cf_openssl_basedir="/usr"
+ fi
+ fi
+
+ if test ! -z "$cf_openssl_basedir"; then
+ echo "$as_me:$LINENO: result: $cf_openssl_basedir" >&5
+echo "${ECHO_T}$cf_openssl_basedir" >&6
+ cf_enable_openssl="yes"
+ else
+ echo "$as_me:$LINENO: result: not found. Specify a correct path?" >&5
+echo "${ECHO_T}not found. Specify a correct path?" >&6
+ cf_enable_openssl="no"
+ fi
+ unset cf_openssl_basedir
+else
+ echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $SSL_INCLUDES"
+save_LIBS="$LIBS"
+LIBS="$LIBS $SSL_LIBS"
+if test "$cf_enable_openssl" != no; then
+ echo "$as_me:$LINENO: checking for OpenSSL 0.9.6 or above" >&5
+echo $ECHO_N "checking for OpenSSL 0.9.6 or above... $ECHO_C" >&6
+ if test "$cross_compiling" = yes; then
+ cf_openssl_version_ok=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <openssl/opensslv.h>
+ #include <stdlib.h>
+int
+main ()
+{
+if ( OPENSSL_VERSION_NUMBER >= 0x00906000)
+ exit(0); else exit(1);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cf_openssl_version_ok=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+cf_openssl_version_ok=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "$cf_openssl_version_ok" = yes; then
+ echo "$as_me:$LINENO: result: found" >&5
+echo "${ECHO_T}found" >&6
+
+ ENCSPEED=encspeed
+
+
+ CPPFLAGS="$CPPFLAGS $SSL_LIBS"
+
+echo "$as_me:$LINENO: checking for RSA_free in -lcrypto" >&5
+echo $ECHO_N "checking for RSA_free in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_RSA_free+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char RSA_free ();
+int
+main ()
+{
+RSA_free ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_crypto_RSA_free=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_RSA_free=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_RSA_free" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_RSA_free" >&6
+if test $ac_cv_lib_crypto_RSA_free = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPTO 1
+_ACEOF
+
+ LIBS="-lcrypto $LIBS"
+
+fi
+
+ SSL_LIBS="$SSL_LIBS -lcrypto"
+ SSL_SRCS_ENABLE='$(SSL_SRCS)'
+ else
+ echo "$as_me:$LINENO: result: no - OpenSSL support disabled" >&5
+echo "${ECHO_T}no - OpenSSL support disabled" >&6
+ fi
+fi
+
+CPPFLAGS="$save_CPPFLAGS"
+LIBS="$save_LIBS"
+
+
+
+
+
+# Check whether --with-zlib-path or --without-zlib-path was given.
+if test "${with_zlib_path+set}" = set; then
+ withval="$with_zlib_path"
+ LIBS="$LIBS -L$withval"
+fi;
+
+# Check whether --enable-zlib or --disable-zlib was given.
+if test "${enable_zlib+set}" = set; then
+ enableval="$enable_zlib"
+ zlib=$enableval
+else
+ zlib=yes
+fi;
+
+if test "$zlib" = yes; then
+
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for zlib.h" >&5
+echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_zlib_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking zlib.h usability" >&5
+echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <zlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking zlib.h presence" >&5
+echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <zlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for zlib.h" >&5
+echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_zlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_zlib_h" >&6
+
+fi
+if test $ac_cv_header_zlib_h = yes; then
+
+ echo "$as_me:$LINENO: checking for zlibVersion in -lz" >&5
+echo $ECHO_N "checking for zlibVersion in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_zlibVersion+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char zlibVersion ();
+int
+main ()
+{
+zlibVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_z_zlibVersion=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_zlibVersion=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_zlibVersion" >&5
+echo "${ECHO_T}$ac_cv_lib_z_zlibVersion" >&6
+if test $ac_cv_lib_z_zlibVersion = yes; then
+
+ ZLIB_LD=-lz
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+
+else
+ zlib=no
+fi
+
+
+else
+ zlib=no
+fi
+
+
+
+fi
+
+
+# Check whether --enable-poll or --disable-poll was given.
+if test "${enable_poll+set}" = set; then
+ enableval="$enable_poll"
+ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="poll"
+ else
+ use_poll=no
+ fi
+
+fi;
+
+# Check whether --enable-select or --disable-select was given.
+if test "${enable_select+set}" = set; then
+ enableval="$enable_select"
+ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="select"
+ else
+ use_select=no
+ fi
+
+fi;
+
+# Check whether --enable-kqueue or --disable-kqueue was given.
+if test "${enable_kqueue+set}" = set; then
+ enableval="$enable_kqueue"
+ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="kqueue"
+ else
+ use_kqueue=no
+ fi
+
+fi;
+
+# Check whether --enable-devpoll or --disable-devpoll was given.
+if test "${enable_devpoll+set}" = set; then
+ enableval="$enable_devpoll"
+ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="devpoll"
+
+
+for ac_header in sys/devpoll.h devpoll.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ else
+ use_devpoll=no;
+ fi
+
+fi;
+
+# Check whether --enable-epoll or --disable-epoll was given.
+if test "${enable_epoll+set}" = set; then
+ enableval="$enable_epoll"
+ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="epoll"
+ else
+ use_epoll=no
+ fi
+
+fi;
+
+
+echo "$as_me:$LINENO: checking whether to modify confdir" >&5
+echo $ECHO_N "checking whether to modify confdir... $ECHO_C" >&6
+
+# Check whether --with-confdir or --without-confdir was given.
+if test "${with_confdir+set}" = set; then
+ withval="$with_confdir"
+ confdir=`echo $withval | sed 's/\/$//'`
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $confdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ ETC_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define ETC_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ confdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$confdir"\"
+ )`
+
+
+else
+ confdir='${prefix}/etc'
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $confdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ ETC_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define ETC_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ confdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$confdir"\"
+ )`
+
+
+
+fi;
+
+
+echo "$as_me:$LINENO: checking whether to modify logdir" >&5
+echo $ECHO_N "checking whether to modify logdir... $ECHO_C" >&6
+
+# Check whether --with-logdir or --without-logdir was given.
+if test "${with_logdir+set}" = set; then
+ withval="$with_logdir"
+ logdir=`echo $withval | sed 's/\/$//'`
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $logdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ LOG_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define LOG_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ logdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$logdir"\"
+ )`
+
+
+else
+ logdir='${prefix}/logs'
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $logdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ LOG_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define LOG_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ logdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$logdir"\"
+ )`
+
+
+
+fi;
+
+
+echo "$as_me:$LINENO: checking whether to modify helpdir" >&5
+echo $ECHO_N "checking whether to modify helpdir... $ECHO_C" >&6
+
+# Check whether --with-helpdir or --without-helpdir was given.
+if test "${with_helpdir+set}" = set; then
+ withval="$with_helpdir"
+ helpdir=`echo $withval | sed 's/\/$//'`
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $helpdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ HELP_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define HELP_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ helpdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$helpdir"\"
+ )`
+
+
+else
+ helpdir='${prefix}/help'
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $helpdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ HELP_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define HELP_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ helpdir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$helpdir"\"
+ )`
+
+
+
+fi;
+
+
+echo "$as_me:$LINENO: checking whether to modify moduledir" >&5
+echo $ECHO_N "checking whether to modify moduledir... $ECHO_C" >&6
+
+# Check whether --with-moduledir or --without-moduledir was given.
+if test "${with_moduledir+set}" = set; then
+ withval="$with_moduledir"
+ moduledir=`echo $withval | sed 's/\/$//'`
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $moduledir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ MODULE_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define MODULE_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ moduledir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$moduledir"\"
+ )`
+
+
+else
+ moduledir='${prefix}/modules'
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $moduledir`
+ ac_define_dir=`eval echo $ac_define_dir`
+ MODULE_DIR="$ac_define_dir"
+
+
+cat >>confdefs.h <<_ACEOF
+#define MODULE_DIR "$ac_define_dir"
+_ACEOF
+
+
+
+
+ moduledir=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$moduledir"\"
+ )`
+
+
+
+fi;
+
+if test ! -z "$SELECT_TYPE_EXPLICIT"; then
+ SELECT_TYPE="$SELECT_TYPE_EXPLICIT";
+ echo "Forcing $SELECT_TYPE to be enabled"
+else
+
+if test ! "x$use_select" = "xno"; then
+
+for ac_func in select
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ haveselect=yes
+else
+ haveselect=no
+fi
+done
+
+ if test "x$haveselect" = "xyes" ; then
+ SELECT_TYPE="select"
+ fi
+fi
+
+if test ! "x$use_poll" = "xno"; then
+
+for ac_func in poll
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ havepoll=yes
+else
+ havepoll=no
+fi
+done
+
+ if test "x$havepoll" = "xyes" ; then
+ SELECT_TYPE="poll"
+ fi
+fi
+
+if test ! "x$use_devpoll" = "xno"; then
+ echo "$as_me:$LINENO: checking for /dev/poll" >&5
+echo $ECHO_N "checking for /dev/poll... $ECHO_C" >&6
+ if test -c "/dev/poll"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+
+for ac_header in devpoll.h sys/devpoll.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ SELECT_TYPE="devpoll"
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+fi
+
+if test ! "x$use_kqueue" = "xno"; then
+
+for ac_func in kevent
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ havekqueue=yes
+else
+ havekqueue=no
+fi
+done
+
+ if test "x$havekqueue" = "xyes" ; then
+ SELECT_TYPE="kqueue"
+ fi
+fi
+
+if test ! "x$use_epoll" = "xno"; then
+
+for ac_func in epoll_ctl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ haveepoll=yes
+else
+ haveepoll=no
+fi
+done
+
+ if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ if test "x$haveepoll" = "xyes" ; then
+ echo "$as_me:$LINENO: checking for epoll support in kernel" >&5
+echo $ECHO_N "checking for epoll support in kernel... $ECHO_C" >&6
+ if test "$cross_compiling" = yes; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/epoll.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+ int epfd;
+
+ epfd = epoll_create(256);
+ exit (epfd == -1 ? 1 : 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_EPOLL 1
+_ACEOF
+
+ SELECT_TYPE="epoll"
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+ fi
+ fi
+
+haveepollsyscall=no
+
+if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ if test "x$haveepoll" = "xno" ; then
+ echo "$as_me:$LINENO: checking for epoll system call" >&5
+echo $ECHO_N "checking for epoll system call... $ECHO_C" >&6
+ if test "$cross_compiling" = yes; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/epoll.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int
+epoll_create(int size)
+{
+ return (syscall(__NR_epoll_create, size));
+}
+
+int
+main(int argc, char **argv)
+{
+ int epfd;
+
+ epfd = epoll_create(256);
+ exit (epfd == -1 ? 1 : 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_EPOLL 1
+_ACEOF
+
+ SELECT_TYPE="epoll"
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+ fi
+fi
+
+fi
+
+fi
+
+if test -z "$SELECT_TYPE"; then
+ { { echo "$as_me:$LINENO: error: Unable to find a usable IO interface" >&5
+echo "$as_me: error: Unable to find a usable IO interface" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+echo "Using $SELECT_TYPE for select loop."
+
+
+cat >>confdefs.h <<_ACEOF
+#define SELECT_TYPE "$SELECT_TYPE"
+_ACEOF
+
+
+
+
+
+# Check whether --enable-assert or --disable-assert was given.
+if test "${enable_assert+set}" = set; then
+ enableval="$enable_assert"
+ assert=$enableval
+else
+ assert=no
+fi;
+
+if test "$assert" = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NDEBUG 1
+_ACEOF
+
+elif test "$assert" = soft; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SOFT_ASSERT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define NDEBUG 1
+_ACEOF
+
+elif test "$assert" = yes; then
+ assert = "hard";
+fi
+
+echo "$as_me:$LINENO: checking if you want IO Debugging hooks" >&5
+echo $ECHO_N "checking if you want IO Debugging hooks... $ECHO_C" >&6
+# Check whether --enable-iodebug or --disable-iodebug was given.
+if test "${enable_iodebug+set}" = set; then
+ enableval="$enable_iodebug"
+ iodebug=$enableval
+else
+ iodebug=no
+fi;
+
+if test "$iodebug" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_IODEBUG_HOOKS 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+echo "$as_me:$LINENO: checking if you want to do a profile build" >&5
+echo $ECHO_N "checking if you want to do a profile build... $ECHO_C" >&6
+# Check whether --enable-profile or --disable-profile was given.
+if test "${enable_profile+set}" = set; then
+ enableval="$enable_profile"
+ profile=$enableval
+else
+ profile=no
+fi;
+
+if test "$profile" = yes; then
+ if test "$ac_cv_c_compiler_gnu" = yes; then
+ IRC_CFLAGS="$IRC_CFLAGS -pg"
+ echo "$as_me:$LINENO: result: yes, adding -pg" >&5
+echo "${ECHO_T}yes, adding -pg" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define CHARYBDIS_PROFILE 1
+_ACEOF
+
+ else
+ echo "$as_me:$LINENO: result: no, profile builds only work with gcc" >&5
+echo "${ECHO_T}no, profile builds only work with gcc" >&6
+ fi
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+# Check whether --enable-balloc or --disable-balloc was given.
+if test "${enable_balloc+set}" = set; then
+ enableval="$enable_balloc"
+ balloc=$enableval
+else
+ balloc=yes
+fi;
+
+if test "$balloc" = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NOBALLOC 1
+_ACEOF
+
+fi
+
+# Check whether --enable-ricer-hashing or --disable-ricer-hashing was given.
+if test "${enable_ricer_hashing+set}" = set; then
+ enableval="$enable_ricer_hashing"
+ ricer_hashing=$enableval
+else
+ ricer_hashing=no
+fi;
+
+FNVHASH_S=""
+
+if test "$ricer_hashing" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define RICER_HASHING 1
+_ACEOF
+
+ FNVHASH_S="fnvhash.s"
+fi
+
+
+
+# Check whether --enable-small-net or --disable-small-net was given.
+if test "${enable_small_net+set}" = set; then
+ enableval="$enable_small_net"
+ small_net=$enableval
+else
+ small_net=no
+fi;
+
+if test "$small_net" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NICKNAMEHISTORYLENGTH 1500
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CHANNEL_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define BAN_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CLIENT_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LCLIENT_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define PCLIENT_HEAP_SIZE 32
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USER_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define DNODE_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define TOPIC_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINEBUF_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MEMBER_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define ND_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CONFITEM_HEAP_SIZE 128
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MONITOR_HEAP_SIZE 128
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NICKNAMEHISTORYLENGTH 15000
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CHANNEL_HEAP_SIZE 8192
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define BAN_HEAP_SIZE 4096
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CLIENT_HEAP_SIZE 8192
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LCLIENT_HEAP_SIZE 1024
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define PCLIENT_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USER_HEAP_SIZE 8192
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define DNODE_HEAP_SIZE 8192
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define TOPIC_HEAP_SIZE 4096
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINEBUF_HEAP_SIZE 2048
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MEMBER_HEAP_SIZE 32768
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define ND_HEAP_SIZE 512
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CONFITEM_HEAP_SIZE 256
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define MONITOR_HEAP_SIZE 1024
+_ACEOF
+
+fi
+
+
+# Check whether --with-nicklen or --without-nicklen was given.
+if test "${with_nicklen+set}" = set; then
+ withval="$with_nicklen"
+
+ if test $withval -ge 50; then
+ NICKLEN=50
+ { echo "$as_me:$LINENO: WARNING: NICKLEN has a hard limit of 50. Setting NICKLEN=50" >&5
+echo "$as_me: WARNING: NICKLEN has a hard limit of 50. Setting NICKLEN=50" >&2;}
+ else
+ NICKLEN="$withval"
+ fi
+
+else
+ NICKLEN=15
+fi;
+
+
+# Check whether --with-topiclen or --without-topiclen was given.
+if test "${with_topiclen+set}" = set; then
+ withval="$with_topiclen"
+
+ if test $withval -ge 390; then
+ TOPICLEN=390
+ { echo "$as_me:$LINENO: WARNING: TOPICLEN has a hard limit of 390. Setting TOPICLEN=390" >&5
+echo "$as_me: WARNING: TOPICLEN has a hard limit of 390. Setting TOPICLEN=390" >&2;}
+ else
+ TOPICLEN=$withval
+ fi
+
+else
+ TOPICLEN=390
+fi;
+
+
+# Check whether --with-maxclients or --without-maxclients was given.
+if test "${with_maxclients+set}" = set; then
+ withval="$with_maxclients"
+ MAX_CLIENTS="$withval"
+else
+ MAX_CLIENTS=3000
+fi;
+
+
+if test "$MAX_CLIENTS" = yes; then
+ MAX_CLIENTS=3000
+fi
+
+if test $MAX_CLIENTS -gt 65536; then
+ MAX_CLIENTS=65536
+ { echo "$as_me:$LINENO: WARNING: Max connections cannot be larger than 65536!" >&5
+echo "$as_me: WARNING: Max connections cannot be larger than 65536!" >&2;}
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TOPICLEN ${TOPICLEN}
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define NICKLEN (${NICKLEN}+1)
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAX_CLIENTS ${MAX_CLIENTS}
+_ACEOF
+
+
+# Check whether --enable-shared-modules or --disable-shared-modules was given.
+if test "${enable_shared_modules+set}" = set; then
+ enableval="$enable_shared_modules"
+ shared_modules=$enableval
+else
+ shared_modules="yes"
+fi;
+
+if test "$shared_modules" = yes; then
+
+ if test "$CYGWIN" = yes; then
+ { echo "$as_me:$LINENO: WARNING: disabling shared modules; Cygwin is at present unable to build them." >&5
+echo "$as_me: WARNING: disabling shared modules; Cygwin is at present unable to build them." >&2;}
+ shared_modules="no"
+ fi
+
+ if test "$CC" = tcc -a "$TenDRA" = "no"; then
+ { echo "$as_me:$LINENO: WARNING: disabling shared modules: Tiny C Compiler can't create PIC" >&5
+echo "$as_me: WARNING: disabling shared modules: Tiny C Compiler can't create PIC" >&2;}
+ shared_modules="no"
+ fi
+fi
+
+if test "$shared_modules" = yes; then
+ DYNLINK_C=dynlink.c
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ echo "$as_me:$LINENO: checking for library containing shl_load" >&5
+echo $ECHO_N "checking for library containing shl_load... $ECHO_C" >&6
+if test "${ac_cv_search_shl_load+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_shl_load=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_shl_load="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_shl_load" = no; then
+ for ac_lib in dld; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_shl_load="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_shl_load" >&5
+echo "${ECHO_T}$ac_cv_search_shl_load" >&6
+if test "$ac_cv_search_shl_load" != no; then
+ test "$ac_cv_search_shl_load" = "none required" || LIBS="$ac_cv_search_shl_load $LIBS"
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHL_LOAD 1
+_ACEOF
+
+ SUFFIX=".sl"
+ MOD_TARGET=hpux_shared
+ SEDOBJ="s/\.o/.sl/g"
+
+else
+
+ echo "$as_me:$LINENO: checking for library containing dlopen" >&5
+echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6
+if test "${ac_cv_search_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_dlopen=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_dlopen="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_dlopen" = no; then
+ for ac_lib in dl c_r; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_dlopen="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5
+echo "${ECHO_T}$ac_cv_search_dlopen" >&6
+if test "$ac_cv_search_dlopen" != no; then
+ test "$ac_cv_search_dlopen" = "none required" || LIBS="$ac_cv_search_dlopen $LIBS"
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DLOPEN 1
+_ACEOF
+
+ SUFFIX=".so"
+ MOD_TARGET=shared_modules
+ SEDOBJ="s/\.o/.so/g"
+ if test "$AppleGCC" = yes; then
+
+for ac_header in mach-o/dyld.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ fi
+ echo "$as_me:$LINENO: checking for dlsym" >&5
+echo $ECHO_N "checking for dlsym... $ECHO_C" >&6
+if test "${ac_cv_func_dlsym+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define dlsym to an innocuous variant, in case <limits.h> declares dlsym.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define dlsym innocuous_dlsym
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlsym (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef dlsym
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlsym ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlsym) || defined (__stub___dlsym)
+choke me
+#else
+char (*f) () = dlsym;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlsym;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_dlsym=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlsym=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlsym" >&5
+echo "${ECHO_T}$ac_cv_func_dlsym" >&6
+if test $ac_cv_func_dlsym = yes; then
+ :
+else
+
+ { echo "$as_me:$LINENO: WARNING: dlsym is not available, shared modules disabled" >&5
+echo "$as_me: WARNING: dlsym is not available, shared modules disabled" >&2;}
+ shared_modules=no
+
+fi
+
+
+for ac_func in dlfunc
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+else
+
+ shared_modules=no
+
+fi
+
+
+fi
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SHARED_SUFFIX "$SUFFIX"
+_ACEOF
+
+
+if test "$shared_modules" = yes; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ echo "$as_me:$LINENO: checking for the ld -export-dynamic flag" >&5
+echo $ECHO_N "checking for the ld -export-dynamic flag... $ECHO_C" >&6
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+int i;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ found=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+found=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$hold_ldflags
+
+ if expr "`uname -s`" : ^IRIX >/dev/null 2>&1; then
+ found="no, IRIX ld uses -B,dynamic"
+ LDFLAGS="${LDFLAGS} -Wl,-B,dynamic"
+ fi
+
+ if expr "`uname -s`" : ^AIX >/dev/null 2>&1; then
+ found="no, AIX ld uses -G -brtl"
+ LDFLAGS="${LDFLAGS} -Wl,-G,-brtl"
+ fi
+
+ echo "$as_me:$LINENO: result: $found" >&5
+echo "${ECHO_T}$found" >&6
+
+ if test "$found" = yes; then
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ fi
+
+ echo "$as_me:$LINENO: checking for compiler option to produce PIC" >&5
+echo $ECHO_N "checking for compiler option to produce PIC... $ECHO_C" >&6
+ if test "$SGS" = "yes"; then
+ echo "$as_me:$LINENO: result: SVR4 SGS interfaces: -KPIC -DPIC -G" >&5
+echo "${ECHO_T}SVR4 SGS interfaces: -KPIC -DPIC -G" >&6
+ PICFLAGS="-KPIC -DPIC -G"
+ fi
+
+ if test "$AppleGCC" = "yes"; then
+ echo "$as_me:$LINENO: result: Darwin Mach-O bundles: -fno-common -bundle -flat_namespace -undefined suppress" >&5
+echo "${ECHO_T}Darwin Mach-O bundles: -fno-common -bundle -flat_namespace -undefined suppress" >&6
+ PICFLAGS="-fno-common -bundle -flat_namespace -undefined suppress"
+ fi
+ if test "$HPUX" = "yes" -a "$CC" != gcc; then
+ echo "$as_me:$LINENO: result: HP-UX cc: +z -r -q -n" >&5
+echo "${ECHO_T}HP-UX cc: +z -r -q -n" >&6
+ PICFLAGS="+z -r -q -n -c"
+ echo "$as_me:$LINENO: checking if +ESfic is required on this platform" >&5
+echo $ECHO_N "checking if +ESfic is required on this platform... $ECHO_C" >&6
+
+ if expr "`$CC +ESfic 2>&1`" : ".*neither supported.*" >/dev/null; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ else
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ PICFLAGS="$PICFLAGS +ESfic"
+ fi
+
+ LDFLAGS="${LDFLAGS} -Wl,-E"
+ fi
+ if test "$Tru" = yes -a "$CC" != gcc; then
+ echo "$as_me:$LINENO: result: Tru64: -shared -expect_unresolved '*'" >&5
+echo "${ECHO_T}Tru64: -shared -expect_unresolved '*'" >&6
+ PICFLAGS="-shared -expect_unresolved '*' "
+ LDFLAGS="-call_shared"
+ fi
+ if test -z "$PICFLAGS"; then
+ if test "$ac_cv_c_compiler_gnu" = "yes"; then
+ echo "$as_me:$LINENO: result: gcc: -fPIC -DPIC -shared" >&5
+echo "${ECHO_T}gcc: -fPIC -DPIC -shared" >&6
+ PICFLAGS="-fPIC -DPIC -shared"
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ shared_modules=no
+ fi
+ fi
+fi
+
+# This must be down here, or it will mess up checks like the ones
+# for -Wl,-export-dynamic
+# -- jilles
+# Check whether --enable-warnings or --disable-warnings was given.
+if test "${enable_warnings+set}" = set; then
+ enableval="$enable_warnings"
+
+IRC_CFLAGS="$IRC_CFLAGS -O0"
+CFLAGS="$IRC_CFLAGS"
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wall" >&5
+echo $ECHO_N "checking GCC flag(s) -Wall... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_all+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wall -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_all=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_all=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_all" = xyes; then
+ CWARNS="${CWARNS}-Wall "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_all=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wpointer-arith" >&5
+echo $ECHO_N "checking GCC flag(s) -Wpointer-arith... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_pointer_arith+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wpointer-arith -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_pointer_arith=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_pointer_arith=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_pointer_arith" = xyes; then
+ CWARNS="${CWARNS}-Wpointer-arith "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_pointer_arith=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wimplicit -Wnested-externs" >&5
+echo $ECHO_N "checking GCC flag(s) -Wimplicit -Wnested-externs... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_implicit+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wimplicit -Wnested-externs -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_implicit=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_implicit=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_implicit" = xyes; then
+ CWARNS="${CWARNS}-Wimplicit -Wnested-externs "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_implicit=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wcast-align" >&5
+echo $ECHO_N "checking GCC flag(s) -Wcast-align... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_cast_align+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wcast-align -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_cast_align=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_cast_align=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_cast_align" = xyes; then
+ CWARNS="${CWARNS}-Wcast-align "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_cast_align=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wcast-qual" >&5
+echo $ECHO_N "checking GCC flag(s) -Wcast-qual... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_cast_qual+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wcast-qual -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_cast_qual=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_cast_qual=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_cast_qual" = xyes; then
+ CWARNS="${CWARNS}-Wcast-qual "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_cast_qual=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations" >&5
+echo $ECHO_N "checking GCC flag(s) -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_prototypes+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_prototypes=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_prototypes=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_prototypes" = xyes; then
+ CWARNS="${CWARNS}-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_prototypes=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wparenthesis" >&5
+echo $ECHO_N "checking GCC flag(s) -Wparenthesis... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_parenthesis+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wparenthesis -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_parenthesis=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_parenthesis=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_parenthesis" = xyes; then
+ CWARNS="${CWARNS}-Wparenthesis "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_parenthesis=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -W -Wno-unused" >&5
+echo $ECHO_N "checking GCC flag(s) -W -Wno-unused... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -W -Wno-unused -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w" = xyes; then
+ CWARNS="${CWARNS}-W -Wno-unused "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wextra" >&5
+echo $ECHO_N "checking GCC flag(s) -Wextra... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_extra+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wextra -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_extra=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_extra=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_extra" = xyes; then
+ CWARNS="${CWARNS}-Wextra "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_extra=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wshadow" >&5
+echo $ECHO_N "checking GCC flag(s) -Wshadow... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_shadow+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wshadow -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_shadow=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_shadow=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_shadow" = xyes; then
+ CWARNS="${CWARNS}-Wshadow "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_shadow=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wmissing-noreturn" >&5
+echo $ECHO_N "checking GCC flag(s) -Wmissing-noreturn... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_missing_noreturn+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wmissing-noreturn -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_missing_noreturn=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_missing_noreturn=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_missing_noreturn" = xyes; then
+ CWARNS="${CWARNS}-Wmissing-noreturn "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_missing_noreturn=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wundef" >&5
+echo $ECHO_N "checking GCC flag(s) -Wundef... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_undef+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wundef -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_undef=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_undef=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_undef" = xyes; then
+ CWARNS="${CWARNS}-Wundef "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_undef=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wpacked" >&5
+echo $ECHO_N "checking GCC flag(s) -Wpacked... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_packed+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wpacked -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_packed=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_packed=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_packed" = xyes; then
+ CWARNS="${CWARNS}-Wpacked "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_packed=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wnested-externs" >&5
+echo $ECHO_N "checking GCC flag(s) -Wnested-externs... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_nested_externs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wnested-externs -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_nested_externs=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_nested_externs=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_nested_externs" = xyes; then
+ CWARNS="${CWARNS}-Wnested-externs "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_nested_externs=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wbad-function-cast" >&5
+echo $ECHO_N "checking GCC flag(s) -Wbad-function-cast... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_bad_function_cast+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wbad-function-cast -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_bad_function_cast=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_bad_function_cast=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_bad_function_cast" = xyes; then
+ CWARNS="${CWARNS}-Wbad-function-cast "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_bad_function_cast=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wunused-function -Wunused-label -Wunused-value -Wunused-variable" >&5
+echo $ECHO_N "checking GCC flag(s) -Wunused-function -Wunused-label -Wunused-value -Wunused-variable... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_unused+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_unused=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_unused=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_unused" = xyes; then
+ CWARNS="${CWARNS}-Wunused-function -Wunused-label -Wunused-value -Wunused-variable "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_unused=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wredundant-decls" >&5
+echo $ECHO_N "checking GCC flag(s) -Wredundant-decls... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_redundant_decls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wredundant-decls -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_redundant_decls=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_redundant_decls=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_redundant_decls" = xyes; then
+ CWARNS="${CWARNS}-Wredundant-decls "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_redundant_decls=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wfloat-equal" >&5
+echo $ECHO_N "checking GCC flag(s) -Wfloat-equal... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_float_equal+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wfloat-equal -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_float_equal=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_float_equal=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_float_equal" = xyes; then
+ CWARNS="${CWARNS}-Wfloat-equal "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_float_equal=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -Wformat=2" >&5
+echo $ECHO_N "checking GCC flag(s) -Wformat=2... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_w_format+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -Wformat=2 -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_w_format=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_w_format=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_w_format" = xyes; then
+ CWARNS="${CWARNS}-Wformat=2 "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_w_format=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+ echo "$as_me:$LINENO: checking GCC flag(s) -pedantic" >&5
+echo $ECHO_N "checking GCC flag(s) -pedantic... $ECHO_C" >&6
+ if test "${GCC-no}" = yes
+ then
+ if test "${charybdis_cv_c_gcc_pedantic+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ oldcflags="${CFLAGS-}"
+ CFLAGS="${CFLAGS-} ${CWARNS} -pedantic -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <string.h>
+#include <stdio.h>
+int main(void);
+
+int
+main ()
+{
+
+ strcmp("a","b"); fprintf(stdout,"test ok\n");
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ charybdis_cv_c_gcc_pedantic=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+charybdis_cv_c_gcc_pedantic=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="${oldcflags}"
+fi
+
+ if test "x$charybdis_cv_c_gcc_pedantic" = xyes; then
+ CWARNS="${CWARNS}-pedantic "
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ charybdis_cv_c_gcc_pedantic=''
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+
+IRC_CFLAGS="$CFLAGS"
+
+fi;
+
+if test "$shared_modules" = no; then
+ DYNLINK_C=""
+ MOD_TARGET="libmodules.a"
+ MODULES_LIBS="../modules/libmodules.a"
+ SEDOBJ=""
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_MODULES 1
+_ACEOF
+
+ { echo "$as_me:$LINENO: WARNING: shared module support has been disabled!" >&5
+echo "$as_me: WARNING: shared module support has been disabled!" >&2;}
+fi
+
+if test "$shared_modules" = yes; then
+
+ echo "$as_me:$LINENO: checking for nlist" >&5
+echo $ECHO_N "checking for nlist... $ECHO_C" >&6
+if test "${ac_cv_func_nlist+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define nlist to an innocuous variant, in case <limits.h> declares nlist.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define nlist innocuous_nlist
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char nlist (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef nlist
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nlist ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_nlist) || defined (__stub___nlist)
+choke me
+#else
+char (*f) () = nlist;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != nlist;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_nlist=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_nlist=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_nlist" >&5
+echo "${ECHO_T}$ac_cv_func_nlist" >&6
+if test $ac_cv_func_nlist = yes; then
+ :
+else
+ echo "$as_me:$LINENO: checking for nlist in -ldl" >&5
+echo $ECHO_N "checking for nlist in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_nlist+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nlist ();
+int
+main ()
+{
+nlist ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dl_nlist=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_nlist=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_nlist" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_nlist" >&6
+if test $ac_cv_lib_dl_nlist = yes; then
+ nlist_lib="-ldl"
+else
+ echo "$as_me:$LINENO: checking for nlist in -lelf" >&5
+echo $ECHO_N "checking for nlist in -lelf... $ECHO_C" >&6
+if test "${ac_cv_lib_elf_nlist+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lelf $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char nlist ();
+int
+main ()
+{
+nlist ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_elf_nlist=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_elf_nlist=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_elf_nlist" >&5
+echo "${ECHO_T}$ac_cv_lib_elf_nlist" >&6
+if test $ac_cv_lib_elf_nlist = yes; then
+ nlist_lib="-lelf"
+fi
+
+
+fi
+
+
+fi
+
+
+ if test "${ac_cv_header_libelf_nlist_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for libelf/nlist.h" >&5
+echo $ECHO_N "checking for libelf/nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_libelf_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libelf_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_libelf_nlist_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking libelf/nlist.h usability" >&5
+echo $ECHO_N "checking libelf/nlist.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <libelf/nlist.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking libelf/nlist.h presence" >&5
+echo $ECHO_N "checking libelf/nlist.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <libelf/nlist.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libelf/nlist.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libelf/nlist.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libelf/nlist.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libelf/nlist.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libelf/nlist.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libelf/nlist.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libelf/nlist.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: libelf/nlist.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libelf/nlist.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for libelf/nlist.h" >&5
+echo $ECHO_N "checking for libelf/nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_libelf_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_libelf_nlist_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libelf_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_libelf_nlist_h" >&6
+
+fi
+if test $ac_cv_header_libelf_nlist_h = yes; then
+ nlist_h="libelf/nlist.h"
+fi
+
+
+ if test "${ac_cv_header_elf_nlist_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for elf/nlist.h" >&5
+echo $ECHO_N "checking for elf/nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_elf_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_elf_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_elf_nlist_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking elf/nlist.h usability" >&5
+echo $ECHO_N "checking elf/nlist.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <elf/nlist.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking elf/nlist.h presence" >&5
+echo $ECHO_N "checking elf/nlist.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <elf/nlist.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: elf/nlist.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: elf/nlist.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: elf/nlist.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: elf/nlist.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: elf/nlist.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: elf/nlist.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: elf/nlist.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: elf/nlist.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: elf/nlist.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for elf/nlist.h" >&5
+echo $ECHO_N "checking for elf/nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_elf_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_elf_nlist_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_elf_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_elf_nlist_h" >&6
+
+fi
+if test $ac_cv_header_elf_nlist_h = yes; then
+ nlist_h="elf/nlist.h"
+fi
+
+
+ if test "${ac_cv_header_nlist_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for nlist.h" >&5
+echo $ECHO_N "checking for nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_nlist_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking nlist.h usability" >&5
+echo $ECHO_N "checking nlist.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <nlist.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking nlist.h presence" >&5
+echo $ECHO_N "checking nlist.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <nlist.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: nlist.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: nlist.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: nlist.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: nlist.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: nlist.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: nlist.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: nlist.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: nlist.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: nlist.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: nlist.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: nlist.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to the charybdis lists. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for nlist.h" >&5
+echo $ECHO_N "checking for nlist.h... $ECHO_C" >&6
+if test "${ac_cv_header_nlist_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_nlist_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_nlist_h" >&5
+echo "${ECHO_T}$ac_cv_header_nlist_h" >&6
+
+fi
+if test $ac_cv_header_nlist_h = yes; then
+ nlist_h="nlist.h"
+fi
+
+
+ if test x"$nlist_h" = "x"; then
+
+cat >>confdefs.h <<_ACEOF
+#define SYMBOL_PREFIX ""
+_ACEOF
+
+ else
+ echo "$as_me:$LINENO: checking for extra underscores prepended to symbol names" >&5
+echo $ECHO_N "checking for extra underscores prepended to symbol names... $ECHO_C" >&6
+ if test "${symbol_underscores+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+cat << EOF > conftest.c
+#include <$nlist_h>
+#include <stdio.h>
+#include <stdlib.h>
+void _modinit(void);
+int main(int argc, char *argv[]) {
+ int i;
+ struct nlist nl[5];
+
+ /* fill the names in this way, so it'll work almost everywhere */
+ nl[0].n_name = "_modinit";
+ nl[1].n_name = "__modinit";
+ nl[2].n_name = "___modinit";
+ nl[3].n_name = "____modinit";
+ nl[0].n_value = nl[1].n_value = nl[2].n_value = nl[3].n_value = nl[4].n_name = NULL;
+
+ if(argc < 2 || (nlist(argv[1], nl)) == -1) exit(-1);
+ for(i = 0; i < 4; i++) {
+ if(nl[i].n_value != NULL)
+ {
+ int j;
+ for(j = 0; j < i; j++)
+ printf("_");
+ exit(i);
+ }
+ }
+ exit(-1);
+}
+void _modinit(void) { return; }
+EOF
+ $CC $CPPFLAGS $IRC_CFLAGS -o conftest conftest.c $nlist_lib >/dev/null 2>&1
+ symbol_underscores=`./conftest conftest`
+ echo "$as_me:$LINENO: result: $symbol_underscores" >&5
+echo "${ECHO_T}$symbol_underscores" >&6
+ $RM -f conftest conftest.c
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SYMBOL_PREFIX "${symbol_underscores}"
+_ACEOF
+
+ fi
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test "$prefix" = "NONE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define IRCD_PREFIX "$ac_default_prefix"
+_ACEOF
+
+
+else
+
+
+ prefix=`echo $prefix | sed 's/\/$//'`
+
+cat >>confdefs.h <<_ACEOF
+#define IRCD_PREFIX "$prefix"
+_ACEOF
+
+
+fi
+
+ ac_config_files="$ac_config_files Makefile libcharybdis/Makefile servlink/Makefile extensions/Makefile unsupported/Makefile src/Makefile modules/Makefile tools/Makefile doc/Makefile help/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
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by charybdis $as_me 2.1.2, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+charybdis config.status 2.1.2
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "libcharybdis/Makefile" ) CONFIG_FILES="$CONFIG_FILES libcharybdis/Makefile" ;;
+ "servlink/Makefile" ) CONFIG_FILES="$CONFIG_FILES servlink/Makefile" ;;
+ "extensions/Makefile" ) CONFIG_FILES="$CONFIG_FILES extensions/Makefile" ;;
+ "unsupported/Makefile" ) CONFIG_FILES="$CONFIG_FILES unsupported/Makefile" ;;
+ "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "modules/Makefile" ) CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;;
+ "tools/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
+ "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "help/Makefile" ) CONFIG_FILES="$CONFIG_FILES help/Makefile" ;;
+ "include/setup.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/setup.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@MKDEP@,$MKDEP,;t t
+s,@MAKEDEPEND@,$MAKEDEPEND,;t t
+s,@STDOUT@,$STDOUT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@RM@,$RM,;t t
+s,@CP@,$CP,;t t
+s,@MV@,$MV,;t t
+s,@LN@,$LN,;t t
+s,@SED@,$SED,;t t
+s,@AR@,$AR,;t t
+s,@LD@,$LD,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@TOUCH@,$TOUCH,;t t
+s,@YACC@,$YACC,;t t
+s,@LEX@,$LEX,;t t
+s,@LEXLIB@,$LEXLIB,;t t
+s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t
+s,@CRYPT_LIB@,$CRYPT_LIB,;t t
+s,@VICONF@,$VICONF,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@ENCSPEED@,$ENCSPEED,;t t
+s,@ZLIB_LD@,$ZLIB_LD,;t t
+s,@ETC_DIR@,$ETC_DIR,;t t
+s,@confdir@,$confdir,;t t
+s,@LOG_DIR@,$LOG_DIR,;t t
+s,@logdir@,$logdir,;t t
+s,@HELP_DIR@,$HELP_DIR,;t t
+s,@helpdir@,$helpdir,;t t
+s,@MODULE_DIR@,$MODULE_DIR,;t t
+s,@moduledir@,$moduledir,;t t
+s,@SELECT_TYPE@,$SELECT_TYPE,;t t
+s,@FNVHASH_S@,$FNVHASH_S,;t t
+s,@MODULES_LIBS@,$MODULES_LIBS,;t t
+s,@MOD_TARGET@,$MOD_TARGET,;t t
+s,@SSL_SRCS_ENABLE@,$SSL_SRCS_ENABLE,;t t
+s,@SSL_INCLUDES@,$SSL_INCLUDES,;t t
+s,@SSL_LIBS@,$SSL_LIBS,;t t
+s,@PICFLAGS@,$PICFLAGS,;t t
+s,@IRC_CFLAGS@,$IRC_CFLAGS,;t t
+s,@SEDOBJ@,$SEDOBJ,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+if test "$cf_openssl_version_ok" = yes; then
+ openssl="yes"
+else
+ openssl="no"
+fi
+
+if test "$shared_modules" = yes; then
+ modules=shared
+else
+ modules=static
+fi
+
+echo "
+Configuration:
+ Install directory : $prefix
+
+ Ziplinks : $zlib
+ OpenSSL : $openssl
+ Modules : $modules
+ IPv6 support : $have_v6
+ Socket Engine : $SELECT_TYPE
+ Small network : $small_net
+ Block allocator : $balloc
+ ASM hashing code : $ricer_hashing
+
+ Nickname length : $NICKLEN
+ Topic length : $TOPICLEN
+
+Use make to compile Charybdis, then make install to install it.
+"
--- /dev/null
+dnl $Id: configure.ac 2809 2006-12-05 13:18:19Z jilles $
+dnl Process this file with autoconf to produce a configure script.
+
+dnl TODO: clean up all the OpenSSL and shared module checking stuff;
+dnl the most major changes have already been made and it looks like
+dnl said functions need to be just about as complex as they already are.
+
+AC_PREREQ(2.57)
+
+dnl Sneaky way to get an Id tag into the configure script
+AC_COPYRIGHT([$Id: configure.ac 2809 2006-12-05 13:18:19Z jilles $])
+
+AC_INIT([charybdis],[2.1.2])
+
+AC_CONFIG_HEADER(include/setup.h)
+
+AC_PREFIX_DEFAULT($HOME/ircd)
+
+AC_GNU_SOURCE
+
+OLD_CFLAGS="$CFLAGS"
+dnl Checks for programs.
+AC_PROG_CC
+AC_LANG(C)
+
+dnl Make sure autoconf doesn't interfere with cflags -jmallett
+CFLAGS="$OLD_CFLAGS"
+
+dnl Check for various compilers. -jmallett
+dnl But if $CC turns out to be gcc, sure as hell it's, well, gcc. -joshk
+
+if test "$ac_cv_c_compiler_gnu" != yes; then
+
+SGS=no
+AC_MSG_CHECKING($CC -version for TenDRA or MIPSpro)
+case `$CC -version 2>&1` in
+*TenDRA*)
+ AC_MSG_RESULT([yes, TenDRA])
+ IRC_CFLAGS=""
+ CPPFLAGS="$CPPFLAGS -Ylonglong -Yansi -I/usr/include"
+ SGS=yes
+ TenDRA=yes
+;;
+*MIPSpro*)
+ AC_MSG_RESULT([yes, MIPSpro])
+ MIPSpro=yes
+ SGS=yes
+;;
+*)
+ AC_MSG_RESULT(no)
+ TenDRA=no
+ MIPSpro=no
+;;
+esac
+
+AC_MSG_CHECKING([$CC -V for Sun Workshop, Forte, HPUX or Tru64 cc])
+case `$CC -V 2>&1` in
+*Sun*WorkShop* | *Forte*Developer*)
+ AC_MSG_RESULT(Sun Workshop/Forte)
+ IRC_CFLAGS="-fast -xinline=dlinkAdd,dlinkAddBefore,dlinkAddTail,dlinkDelete,dlink_list_length,dlink_node,dlinkMoveList,_MyMalloc,_MyRealloc,_MyFree,_DupString"
+ SunWorkShop=yes
+ SGS=yes
+;;
+*Tru64*)
+ AC_MSG_RESULT(Tru64 cc)
+ IRC_CFLAGS="-O2"
+ CPPFLAGS="-I/usr/local/include"
+ Tru=yes
+;;
+*HP*ANSI*)
+ AC_MSG_RESULT(HPUX cc)
+ HPUX=yes
+ IRC_CFLAGS="+e"
+;;
+*)
+ AC_MSG_RESULT(no)
+;;
+esac
+
+fi
+
+AC_MSG_CHECKING([uname -s for Cygwin, Solaris, AIX or HPUX])
+OSNAME=`uname -s`
+case "$OSNAME" in
+ HP-UX*)
+ dnl only do this if we haven't already detected the newer one
+ dnl and we're not already using gcc
+
+ if test "$HPUX" != yes -a "$ac_cv_c_compiler_gnu" = no; then
+ AC_MSG_RESULT(assuming old HPUX with its own cc)
+ IRC_CFLAGS="$IRC_CFLAGS +e"
+ HPUX=yes
+ else
+ AC_MSG_RESULT(already using newer HPUX)
+ fi
+ ;;
+ CYGWIN*)
+ AC_MSG_RESULT(Cygwin)
+ CYGWIN=yes
+ ;;
+ SunOS*)
+ AC_MSG_RESULT(SunOS or Solaris)
+ AC_DEFINE(__EXTENSIONS__, 1, [This is needed to use strtok_r on Solaris.])
+ SUN=yes
+ ;;
+ AIX*)
+ AC_MSG_RESULT(AIX - Sorry you poor bastard..really we are)
+ IRC_CFLAGS="$IRC_CFLAGS -Wl,-brtl -Wl,-G"
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+esac
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+ AC_MSG_CHECKING(if $CC is Apple GCC)
+
+ case `$CC -v 2>&1 | tail -n 1` in
+ *Apple*)
+ AC_MSG_RESULT(yes)
+ AppleGCC=yes
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ AppleGCC=no
+ ;;
+ esac
+
+ IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall"
+fi
+
+dnl If we support -g, use it!
+if test "$ac_cv_prog_cc_g" = yes; then
+ dnl Tru64 needs -g3 for -O2
+ if test "$Tru" = yes; then
+ IRC_CFLAGS="$IRC_CFLAGS -g3"
+ else
+ IRC_CFLAGS="$IRC_CFLAGS -g"
+ fi
+fi
+
+dnl SVR4 SGS based on what we know about the compiler -jmallett
+AC_MSG_CHECKING(if $CC supports the SVR4 SGS interfaces)
+if test "$SGS" = "yes"; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+dnl We prefer gcc -MM because it's a lot less bloated
+AC_PATH_PROG(MKDEP, mkdep)
+AC_PATH_PROG(MAKEDEPEND, makedepend)
+
+AC_MSG_CHECKING(how to generate dependency info)
+
+STDOUT="> .depend"
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+ AC_MSG_RESULT(gcc -MM)
+ MKDEP="$CC -MM"
+elif test ! -z "$MKDEP"; then
+ AC_MSG_RESULT(mkdep)
+
+ dnl Tru64's mkdep is very loud
+ if test -z "$Tru"; then
+ STDOUT=""
+ else
+ STDOUT=" 2> /dev/null"
+ fi
+elif test "$SunWorkShop" = yes; then
+ AC_MSG_RESULT($CC -xM)
+ MKDEP="$CC -xM"
+ STDOUT="> .depend 2> /dev/null"
+elif test ! -z "$MAKEDEPEND"; then
+ AC_MSG_RESULT(makedepend)
+ MKDEP="$MAKEDEPEND -f-"
+else
+ AC_MSG_RESULT([nothing suitable.. forget it!])
+ MKDEP=":"
+fi
+
+AC_SUBST(MKDEP)
+AC_SUBST(STDOUT)
+
+dnl check for /dev/null so we can use it to hold evil fd's
+AC_MSG_CHECKING([for /dev/null])
+if test -c /dev/null ; then
+ AC_DEFINE(PATH_DEVNULL, "/dev/null", [Path to /dev/null])
+ AC_MSG_RESULT(yes)
+else
+ AC_DEFINE(PATH_DEVNULL, "devnull.log", [Path to /dev/null])
+ AC_MSG_RESULT(no - using devnull.log)
+fi
+
+dnl jdc -- If CFLAGS is defined, best use it everywhere...
+dnl NOTE: jv says it must be added to the *END*, because things like
+dnl "gcc -O9 -O2" will result in -O2 getting preference. How stupid.
+if test ! -z "$CFLAGS"; then
+ IRC_CFLAGS="$IRC_CFLAGS $CFLAGS"
+fi
+
+AC_ISC_POSIX
+AC_C_INLINE
+AC_PROG_GCC_TRADITIONAL
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+AC_PATH_PROG(RM, rm)
+AC_PATH_PROG(CP, cp)
+AC_PATH_PROG(MV, mv)
+AC_PATH_PROG(LN, ln)
+AC_PATH_PROG(SED, sed)
+AC_PATH_PROG(AR, ar)
+AC_PATH_PROG(LD, ld)
+AC_PATH_PROG(RANLIB, ranlib)
+AC_PATH_PROG(TOUCH, touch)
+
+AC_PROG_YACC
+
+dnl AC_PROG_YACC defaults to yacc unconditionally if nothing can be found
+if test "$YACC" = "yacc" -a -z "`which $YACC 2>/dev/null`"; then
+ AC_MSG_ERROR([could not locate a suitable parser generator; install bison, yacc, or byacc])
+fi
+
+AC_PROG_LEX
+
+if test "$LEX" = ":"; then
+ AC_MSG_ERROR([could not locate a suitable lexical generator, install flex or lex.])
+fi
+
+dnl use directory structure of cached as default (hack)
+if test "$libexecdir" = '${exec_prefix}/libexec' &&
+ test "$localstatedir" = '${prefix}/var'; then
+ libexecdir='${bindir}'
+ localstatedir='${prefix}'
+fi
+
+dnl Checks for header files.
+AC_HEADER_STDC
+
+AC_CHECK_HEADERS([crypt.h sys/resource.h sys/param.h errno.h sys/syslog.h stddef.h sys/wait.h wait.h sys/epoll.h sys/uio.h machine/endian.h])
+
+dnl Stuff that the memory manager (imalloc) depends on
+dnl ==================================================
+
+AC_C_CONST
+if test "$ac_cv_header_machine_endian_h" = "no" ; then
+ AC_C_BIGENDIAN
+fi
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+
+dnl Memory manager
+dnl ==============
+
+AC_MSG_CHECKING([the system's memory page size])
+pagesize="no"
+AC_TRY_RUN([
+#include <stdio.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main(void) {
+ FILE *fp = fopen("conftest.malloc", "w");
+
+ if (fp != NULL) {
+ fprintf(fp, "%d\n", getpagesize());
+ fclose(fp);
+ } else
+ exit(1);
+ exit(0);
+}],[
+if test -f "conftest.malloc" ; then
+ pagesize=`cat conftest.malloc`
+fi
+])
+if test "$pagesize" != "no" ; then
+ AC_MSG_RESULT($pagesize)
+else
+ if test "$ac_cv_sizeof_int" = "4" ; then
+ pagesize=4096
+ else
+ pagesize=8192
+ fi
+ AC_MSG_RESULT([$pagesize (guessing)])
+fi
+AC_DEFINE_UNQUOTED(MALLOC_PAGESIZE, $pagesize,
+ [the system's memory page size])
+
+dnl Networking Functions
+dnl ====================
+
+AC_SEARCH_LIBS(socket, socket, , [AC_MSG_ERROR([You have no socket()! Aborting.])])
+
+dnl SunOS/Solaris required libnsl for inet_ntoa()
+if test x"$SUN" = xyes; then
+ AC_SEARCH_LIBS(inet_ntoa, nsl,, [AC_MSG_ERROR([libnsl not found! Aborting.])])
+fi
+
+AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE(SOCKADDR_IN_HAS_LEN, 1, [Define to 1 if sockaddr has a 'sa_len'
+member.])],,[[#include <sys/types.h>
+#include <sys/socket.h>
+]])
+
+AC_CHECK_TYPE(socklen_t, ,
+[AC_DEFINE([socklen_t], [unsigned int],
+[If we don't have a real socklen_t, unsigned int is good enough.])],
+[#include <sys/types.h>
+#include <sys/socket.h>])
+
+AC_ARG_ENABLE(ipv6,
+AC_HELP_STRING([--enable-ipv6],[Enable IPv6 support]),[ipv6=$enableval],[ipv6=no])
+
+if test $ipv6 != yes; then
+ have_v6="no"
+else
+AC_MSG_CHECKING([for core IPv6 support])
+
+AC_COMPILE_IFELSE(
+[AC_LANG_PROGRAM(
+ [[#define IN_AUTOCONF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>]],
+ [[struct sockaddr_in6 s;
+ s.sin6_family = 0;]]
+ )],
+[
+ if test "$CYGWIN" = "yes"; then
+ AC_MSG_RESULT([no, Cygwin's IPv6 is incomplete])
+ have_v6=no
+ else
+ have_v6=yes
+ AC_DEFINE(IPV6, 1, [Define if IPv6 support is present and available.])
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING([for struct in6addr_any])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#define IN_AUTOCONF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>]],
+ [[struct in6_addr a = in6addr_any;]]
+ )],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(NO_IN6ADDR_ANY, 1, [Define to 1 if your system has no in6addr_any.])
+ inet_misc=1
+ ]
+ )
+ fi
+],
+[AC_MSG_RESULT(no)
+have_v6="no"])
+fi
+
+AC_SEARCH_LIBS(crypt, [crypt descrypt],,)
+
+CRYPT_LIB=$ac_cv_search_crypt
+
+if test "$CRYPT_LIB" = "none required"; then
+ unset CRYPT_LIB
+elif test "$CRYPT_LIB" = no; then
+ unset CRYPT_LIB
+fi
+
+AC_SUBST(CRYPT_LIB)
+
+if test "$ac_cv_header_sys_wait_h" = yes -o "$ac_cv_header_wait_h" = yes; then
+ VICONF=viconf
+ dnl We need one of the above to build viconf. Just a sanity check,
+ dnl we don't want to stop people from building the rest of ircd
+ dnl just because they can't build viconf.
+else
+ VICONF=""
+fi
+
+AC_SUBST(VICONF)
+
+dnl See whether we can include both string.h and strings.h.
+AC_CACHE_CHECK([whether string.h and strings.h may both be included],
+gcc_cv_header_string,
+[
+ AC_COMPILE_IFELSE(
+ [#include <string.h>
+ #include <strings.h>],
+ [gcc_cv_header_string=yes],
+ [gcc_cv_header_string=no])
+])
+
+if test "$gcc_cv_header_string" = "yes"; then
+ AC_DEFINE(STRING_WITH_STRINGS, 1, [Define to 1 if string.h may be included along with strings.h])
+fi
+
+AC_C_BIGENDIAN
+
+dnl Check for stdarg.h - if we can't find it, halt configure
+AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - ircd-ratbox will not compile without it **])])
+
+dnl Checks for the existence of strlcat, strlcpy, basename...
+dnl This more reliable test only works with gcc though.
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+
+AC_MSG_CHECKING(for strlcpy)
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS -Wimplicit -Werror"
+
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <string.h>
+ #include <stdlib.h>]],
+ [[char *a = malloc(6);
+ strlcpy(a, "hello", 6);]]
+ )],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_STRLCPY, 1, [Define if strlcpy is available (most BSDs.)])],
+ [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for strlcat)
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <string.h>
+ #include <stdlib.h>]],
+ [[char *a = malloc(6);
+ a[0] = '\0';
+ strlcat(a, "hello", 6);]]
+ )],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_STRLCAT, 1, [Define if strlcat is available (most BSDs.)])],
+ [AC_MSG_RESULT(no)]
+)
+
+CFLAGS=$save_CFLAGS
+
+else
+
+dnl Better than nothing. The more complicated test above probably fixes powerpc,
+dnl so who cares.
+
+AC_CHECK_FUNCS([strlcat strlcpy])
+
+fi
+
+AC_CHECK_TYPE([u_int32_t], [],
+[
+ AC_CHECK_TYPE([uint32_t],
+ [
+ AC_DEFINE(u_int32_t, [uint32_t], [If system does not define u_int32_t, define a reasonable substitute.])
+ ],
+ [
+ AC_MSG_WARN([system has no u_int32_t or uint32_t, default to unsigned long int])
+ AC_DEFINE(u_int32_t, [unsigned long int], [If system does not define u_int32_t, define to unsigned long int here.])
+ ])
+])
+
+AC_CHECK_TYPE([u_int16_t], [],
+[
+ AC_CHECK_TYPE([uint16_t],
+ [
+ AC_DEFINE(u_int16_t, [uint16_t], [If system does not define u_int16_t, define a usable substitute])
+ ],
+ [
+ AC_MSG_WARN([system has no u_int16_t or uint16_t, default to unsigned short int])
+ AC_DEFINE(u_int16_t, [unsigned short int], [If system does not define u_int16_t, define a usable substitute.])
+ ])
+])
+
+AC_CHECK_TYPE([in_port_t], [],
+[AC_DEFINE(in_port_t, [u_int16_t], [If system does not define in_port_t, define it to what it should be.])],
+[[#include <sys/types.h>
+#include <netinet/in.h>]])
+
+AC_CHECK_TYPE([sa_family_t], [],
+[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
+[[#include <sys/types.h>
+#include <sys/socket.h>]])
+
+AC_CHECK_TYPES([uintptr_t])
+
+dnl check for various functions...
+AC_CHECK_FUNCS([socketpair vsnprintf mmap gettimeofday strdup strndup ])
+
+AC_FUNC_ALLOCA
+
+dnl Specialized functions checks
+dnl ============================
+
+dnl check for nanosleep
+AC_CHECK_FUNC(nanosleep,,[AC_CHECK_LIB(rt,nanosleep,
+ LIBS="${LIBS} -lrt",
+ [AC_CHECK_LIB(posix4,nanosleep, LIBS="${LIBS} -lposix4"
+ )])])
+if test x$ac_cv_func_nanosleep = xno && test x$ac_cv_lib_posix4_nanosleep = xno && test x$ac_cv_lib_rt_nanosleep = xno
+then
+ AC_MSG_RESULT("nanosleep not found..using select for delay")
+else
+ AC_DEFINE([HAVE_NANOSLEEP], 1, [Define if nanosleep exists])
+fi
+
+dnl OpenSSL support
+AC_MSG_CHECKING(for OpenSSL)
+AC_ARG_ENABLE(openssl,
+[AC_HELP_STRING([--enable-openssl[=DIR]],[Enable OpenSSL support (DIR optional).])
+AC_HELP_STRING([--disable-openssl],[Disable OpenSSL support.])],
+[cf_enable_openssl=$enableval],
+[cf_enable_openssl="auto"])
+
+if test "$cf_enable_openssl" != "no" ; then
+ cf_openssl_basedir=""
+ if test "$cf_enable_openssl" != "auto" &&
+ test "$cf_enable_openssl" != "yes" ; then
+ dnl Support for --enable-openssl=/some/place
+ cf_openssl_basedir="`echo ${cf_enable_openssl} | sed 's/\/$//'`"
+ else
+ dnl Do the auto-probe here. Check some common directory paths.
+ for dirs in /usr/local/ssl /usr/pkg /usr/local \
+ /usr/local/openssl ; do
+ if test -f "${dirs}/include/openssl/opensslv.h" ; then
+ cf_openssl_basedir="${dirs}"
+ break
+ fi
+ done
+ unset dirs
+ fi
+ dnl Now check cf_openssl_found to see if we found anything.
+ if test ! -z "$cf_openssl_basedir"; then
+ if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h" ; then
+ SSL_INCLUDES="-I${cf_openssl_basedir}/include"
+ SSL_LIBS="-L${cf_openssl_basedir}/lib"
+ else
+ dnl OpenSSL wasn't found in the directory specified. Naughty
+ dnl administrator...
+ cf_openssl_basedir=""
+ fi
+ else
+ dnl Check for stock FreeBSD 4.x and 5.x systems, since their files
+ dnl are in /usr/include and /usr/lib. In this case, we don't want to
+ dnl change INCLUDES or LIBS, but still want to enable OpenSSL.
+ dnl We can't do this check above, because some people want two versions
+ dnl of OpenSSL installed (stock FreeBSD 4.x/5.x and /usr/local/ssl)
+ dnl and they want /usr/local/ssl to have preference.
+ if test -f "/usr/include/openssl/opensslv.h" ; then
+ cf_openssl_basedir="/usr"
+ fi
+ fi
+
+ dnl If we have a basedir defined, then everything is okay. Otherwise,
+ dnl we have a problem.
+ if test ! -z "$cf_openssl_basedir"; then
+ AC_MSG_RESULT($cf_openssl_basedir)
+ cf_enable_openssl="yes"
+ else
+ AC_MSG_RESULT([not found. Specify a correct path?])
+ cf_enable_openssl="no"
+ fi
+ unset cf_openssl_basedir
+else
+ dnl If --disable-openssl was specified
+ AC_MSG_RESULT(disabled)
+fi
+
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $SSL_INCLUDES"
+save_LIBS="$LIBS"
+LIBS="$LIBS $SSL_LIBS"
+if test "$cf_enable_openssl" != no; then
+ dnl Check OpenSSL version (must be 0.9.6 or above!)
+ AC_MSG_CHECKING(for OpenSSL 0.9.6 or above)
+ AC_RUN_IFELSE(
+ AC_LANG_PROGRAM(
+ [#include <openssl/opensslv.h>
+ #include <stdlib.h>],
+ [[if ( OPENSSL_VERSION_NUMBER >= 0x00906000)
+ exit(0); else exit(1);]]),
+ cf_openssl_version_ok=yes,
+ cf_openssl_version_ok=no,
+ cf_openssl_version_ok=no)
+
+ if test "$cf_openssl_version_ok" = yes; then
+ AC_MSG_RESULT(found)
+
+ dnl Work around pmake/gmake conditional incompatibilities
+ AC_SUBST(ENCSPEED, encspeed)
+
+ dnl Do all the HAVE_LIBCRYPTO magic -- and check for ciphers
+ CPPFLAGS="$CPPFLAGS $SSL_LIBS"
+ AC_CHECK_LIB(crypto, RSA_free)
+ SSL_LIBS="$SSL_LIBS -lcrypto"
+ SSL_SRCS_ENABLE='$(SSL_SRCS)'
+ else
+ AC_MSG_RESULT(no - OpenSSL support disabled)
+ fi
+fi
+
+CPPFLAGS="$save_CPPFLAGS"
+LIBS="$save_LIBS"
+
+dnl End OpenSSL detection
+
+
+dnl Specialized functions and libraries
+dnl ===================================
+
+AC_ARG_WITH(zlib-path,
+AC_HELP_STRING([--with-zlib-path=DIR],[Path to libz.so for ziplinks support.]),
+[LIBS="$LIBS -L$withval"],)
+
+AC_ARG_ENABLE(zlib,
+AC_HELP_STRING([--disable-zlib],[Disable ziplinks support]),
+[zlib=$enableval],[zlib=yes])
+
+if test "$zlib" = yes; then
+
+AC_CHECK_HEADER(zlib.h, [
+ AC_CHECK_LIB(z, zlibVersion,
+ [
+ AC_SUBST(ZLIB_LD, -lz)
+ AC_DEFINE(HAVE_LIBZ, 1, [Define to 1 if zlib (-lz) is available.])
+ ], zlib=no)
+], zlib=no)
+
+fi
+
+dnl IO Loop Selection
+dnl =================
+
+AC_ARG_ENABLE(poll, AC_HELP_STRING([--enable-poll],[Force poll() usage.]),
+[ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="poll"
+ else
+ use_poll=no
+ fi
+],)
+
+AC_ARG_ENABLE(select, AC_HELP_STRING([--enable-select],[Force select() usage.]),
+[ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="select"
+ else
+ use_select=no
+ fi
+],)
+
+AC_ARG_ENABLE(kqueue, AC_HELP_STRING([--enable-kqueue],[Force kqueue() usage.]),
+[ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="kqueue"
+ else
+ use_kqueue=no
+ fi
+],)
+
+AC_ARG_ENABLE(devpoll,AC_HELP_STRING([--enable-devpoll],[Force usage of /dev/poll.]),
+[ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="devpoll"
+ dnl These need to be defined or not defined
+ AC_CHECK_HEADERS([sys/devpoll.h devpoll.h])
+ else
+ use_devpoll=no;
+ fi
+],)
+
+AC_ARG_ENABLE(epoll, AC_HELP_STRING([--enable-epoll],[Force sys_epoll usage (Linux only).]),
+[ if test $enableval = yes; then
+ SELECT_TYPE_EXPLICIT="epoll"
+ else
+ use_epoll=no
+ fi
+],)
+
+dnl **********************************************************************
+dnl Check for --with-confdir
+dnl **********************************************************************
+
+AC_MSG_CHECKING([whether to modify confdir])
+AC_ARG_WITH(confdir,
+AC_HELP_STRING([--with-confdir=DIR],
+ [Directory to install config files.]),
+ [ confdir=`echo $withval | sed 's/\/$//'`
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_DIR(ETC_DIR, confdir, [Prefix where config files are installed.])
+ AC_SUBST_DIR([confdir]) ],
+ [ confdir='${prefix}/etc'
+ AC_MSG_RESULT(no)
+ AC_DEFINE_DIR(ETC_DIR, confdir, [Prefix where config files are installed.])
+ AC_SUBST_DIR([confdir])]
+)
+
+dnl **********************************************************************
+dnl Check for --with-logdir
+dnl **********************************************************************
+
+AC_MSG_CHECKING([whether to modify logdir])
+AC_ARG_WITH(logdir,
+AC_HELP_STRING([--with-logdir=DIR],
+ [Directory where to write logfiles.]),
+ [ logdir=`echo $withval | sed 's/\/$//'`
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_DIR(LOG_DIR, logdir, [Prefix where to write logfiles.])
+ AC_SUBST_DIR([logdir]) ],
+ [ logdir='${prefix}/logs'
+ AC_MSG_RESULT(no)
+ AC_DEFINE_DIR(LOG_DIR, logdir, [Prefix where to write logfiles.])
+ AC_SUBST_DIR([logdir])]
+)
+
+dnl **********************************************************************
+dnl Check for --with-helpdir
+dnl **********************************************************************
+
+AC_MSG_CHECKING([whether to modify helpdir])
+AC_ARG_WITH(helpdir,
+AC_HELP_STRING([--with-helpdir=DIR],
+ [Directory to install help files.]),
+ [ helpdir=`echo $withval | sed 's/\/$//'`
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_DIR(HELP_DIR, helpdir, [Prefix where help files are installed.])
+ AC_SUBST_DIR([helpdir]) ],
+ [ helpdir='${prefix}/help'
+ AC_MSG_RESULT(no)
+ AC_DEFINE_DIR(HELP_DIR, helpdir, [Prefix where help file are installed.])
+ AC_SUBST_DIR([helpdir])]
+)
+
+dnl **********************************************************************
+dnl Check for --with-moduledir
+dnl **********************************************************************
+
+AC_MSG_CHECKING([whether to modify moduledir])
+AC_ARG_WITH(moduledir,
+AC_HELP_STRING([--with-moduledir=DIR],
+ [Directory to install modules.]),
+ [ moduledir=`echo $withval | sed 's/\/$//'`
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_DIR(MODULE_DIR, moduledir, [Prefix where modules are installed.])
+ AC_SUBST_DIR([moduledir]) ],
+ [ moduledir='${prefix}/modules'
+ AC_MSG_RESULT(no)
+ AC_DEFINE_DIR(MODULE_DIR, moduledir, [Prefix where modules are installed.])
+ AC_SUBST_DIR([moduledir])]
+)
+
+if test ! -z "$SELECT_TYPE_EXPLICIT"; then
+ SELECT_TYPE="$SELECT_TYPE_EXPLICIT";
+ echo "Forcing $SELECT_TYPE to be enabled"
+else
+
+if test ! "x$use_select" = "xno"; then
+ AC_CHECK_FUNCS(select, [haveselect=yes], [haveselect=no])
+ if test "x$haveselect" = "xyes" ; then
+ SELECT_TYPE="select"
+ fi
+fi
+
+if test ! "x$use_poll" = "xno"; then
+ AC_CHECK_FUNCS(poll, [havepoll=yes], [havepoll=no])
+ if test "x$havepoll" = "xyes" ; then
+ SELECT_TYPE="poll"
+ fi
+fi
+
+if test ! "x$use_devpoll" = "xno"; then
+ AC_MSG_CHECKING(for /dev/poll)
+ if test -c "/dev/poll"; then
+ AC_MSG_RESULT(yes)
+ AC_CHECK_HEADERS([devpoll.h sys/devpoll.h])
+ SELECT_TYPE="devpoll"
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+if test ! "x$use_kqueue" = "xno"; then
+ AC_CHECK_FUNCS(kevent, [havekqueue=yes], [havekqueue=no])
+ if test "x$havekqueue" = "xyes" ; then
+ SELECT_TYPE="kqueue"
+ fi
+fi
+
+if test ! "x$use_epoll" = "xno"; then
+ AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], [haveepoll=no])
+ if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ if test "x$haveepoll" = "xyes" ; then
+ AC_MSG_CHECKING(for epoll support in kernel)
+ AC_TRY_RUN(
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/epoll.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+ int epfd;
+
+ epfd = epoll_create(256);
+ exit (epfd == -1 ? 1 : 0);
+}, [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_EPOLL, 1,
+ [Define if your system supports the epoll system calls])
+ SELECT_TYPE="epoll"],
+ AC_MSG_RESULT(no), AC_MSG_RESULT(no))
+ fi
+ fi
+
+haveepollsyscall=no
+
+if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ if test "x$haveepoll" = "xno" ; then
+ AC_MSG_CHECKING(for epoll system call)
+ AC_TRY_RUN(
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/epoll.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int
+epoll_create(int size)
+{
+ return (syscall(__NR_epoll_create, size));
+}
+
+int
+main(int argc, char **argv)
+{
+ int epfd;
+
+ epfd = epoll_create(256);
+ exit (epfd == -1 ? 1 : 0);
+}, [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_EPOLL, 1,
+ [Define if your system supports the epoll system calls])
+ SELECT_TYPE="epoll"],
+ AC_MSG_RESULT(no), AC_MSG_RESULT(no))
+ fi
+fi
+
+fi
+
+fi
+
+if test -z "$SELECT_TYPE"; then
+ AC_MSG_ERROR([Unable to find a usable IO interface],)
+fi
+
+echo "Using $SELECT_TYPE for select loop."
+
+AC_DEFINE_UNQUOTED(SELECT_TYPE, "$SELECT_TYPE", [This is the type of IO loop we are using])
+AC_SUBST(SELECT_TYPE)
+
+
+dnl Debug-related options
+dnl =====================
+
+AC_ARG_ENABLE(assert,
+AC_HELP_STRING([--enable-assert],[Enable assert(). Choose between soft(warnings) and hard(aborts the daemon)]),
+[assert=$enableval], [assert=no])
+
+if test "$assert" = no; then
+ AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
+elif test "$assert" = soft; then
+ AC_DEFINE(SOFT_ASSERT, 1, [Define this to enable soft asserts.])
+ AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
+elif test "$assert" = yes; then
+ assert = "hard";
+fi
+
+AC_MSG_CHECKING(if you want IO Debugging hooks)
+AC_ARG_ENABLE(iodebug,
+AC_HELP_STRING([--enable-iodebug],[Enable IO Debugging hooks]),
+[iodebug=$enableval], [iodebug=no])
+
+if test "$iodebug" = yes; then
+ AC_DEFINE(USE_IODEBUG_HOOKS, 1, [Define this to enable IO Debug hooks.])
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+
+AC_MSG_CHECKING(if you want to do a profile build)
+AC_ARG_ENABLE(profile,
+AC_HELP_STRING([--enable-profile],[Enable profiling]),
+[profile=$enableval], [profile=no])
+
+if test "$profile" = yes; then
+ if test "$ac_cv_c_compiler_gnu" = yes; then
+ IRC_CFLAGS="$IRC_CFLAGS -pg"
+ AC_MSG_RESULT([yes, adding -pg])
+ AC_DEFINE(CHARYBDIS_PROFILE, 1, [Define this if you are profiling.])
+ else
+ AC_MSG_RESULT([no, profile builds only work with gcc])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_ARG_ENABLE(balloc,
+AC_HELP_STRING([--disable-balloc],[Disable the block allocator.]),
+[balloc=$enableval], [balloc=yes])
+
+if test "$balloc" = no; then
+ AC_DEFINE([NOBALLOC], 1, [Define to 1 if you wish to disable the block allocator.])
+fi
+
+AC_ARG_ENABLE(ricer-hashing,
+AC_HELP_STRING([--enable-ricer-hashing],[Enable assembly-based hashing routines.]),
+[ricer_hashing=$enableval], [ricer_hashing=no])
+
+FNVHASH_S=""
+
+if test "$ricer_hashing" = "yes"; then
+ AC_DEFINE([RICER_HASHING], 1, [Define to 1 if you are using the assembly-based hashing routines.])
+ FNVHASH_S="fnvhash.s"
+fi
+
+AC_SUBST(FNVHASH_S)
+
+AC_ARG_ENABLE(small-net,
+AC_HELP_STRING([--enable-small-net],[Enable small network support.]),
+[small_net=$enableval], [small_net=no])
+
+if test "$small_net" = yes; then
+dnl AC_DEFINE([HASHSIZE], 4096, [Max number of buckets in hash tables.])
+ AC_DEFINE([NICKNAMEHISTORYLENGTH], 1500, [Size of the WHOWAS array.])
+ AC_DEFINE([CHANNEL_HEAP_SIZE], 256, [Size of the channel heap.])
+ AC_DEFINE([BAN_HEAP_SIZE], 128, [Size of the ban heap.])
+ AC_DEFINE([CLIENT_HEAP_SIZE], 256, [Size of the client heap.])
+ AC_DEFINE([LCLIENT_HEAP_SIZE], 128, [Size of the local client heap.])
+ AC_DEFINE([PCLIENT_HEAP_SIZE], 32, [Size of the pre-client heap.])
+ AC_DEFINE([USER_HEAP_SIZE], 128, [Size of the user heap.])
+ AC_DEFINE([DNODE_HEAP_SIZE], 256, [Size of the dlink_node heap.])
+ AC_DEFINE([TOPIC_HEAP_SIZE], 256, [Size of the topic heap.])
+ AC_DEFINE([LINEBUF_HEAP_SIZE], 128, [Size of the linebuf heap.])
+ AC_DEFINE([MEMBER_HEAP_SIZE], 256, [Sizeof member heap.])
+ AC_DEFINE([ND_HEAP_SIZE], 128, [Size of the nick delay heap.])
+ AC_DEFINE([CONFITEM_HEAP_SIZE], 128, [Size of the confitem heap.])
+ AC_DEFINE([MONITOR_HEAP_SIZE], 128, [Size of the monitor heap.])
+else
+dnl These settings are for a large network like efnet..they will use lots of memory
+dnl so enable small net unless you really need this much support
+ AC_DEFINE([NICKNAMEHISTORYLENGTH], 15000, [Size of the WHOWAS array.])
+ AC_DEFINE([CHANNEL_HEAP_SIZE], 8192, [Size of the channel heap.])
+ AC_DEFINE([BAN_HEAP_SIZE], 4096, [Size of the ban heap.])
+ AC_DEFINE([CLIENT_HEAP_SIZE], 8192, [Size of the client heap.])
+ AC_DEFINE([LCLIENT_HEAP_SIZE], 1024, [Size of the local client heap.])
+ AC_DEFINE([PCLIENT_HEAP_SIZE], 256, [Size of the pre-client heap.])
+ AC_DEFINE([USER_HEAP_SIZE], 8192, [Size of the user heap.])
+ AC_DEFINE([DNODE_HEAP_SIZE], 8192, [Size of the dlink_node heap.])
+ AC_DEFINE([TOPIC_HEAP_SIZE], 4096, [Size of the topic heap.])
+ AC_DEFINE([LINEBUF_HEAP_SIZE], 2048, [Size of the linebuf heap.])
+ AC_DEFINE([MEMBER_HEAP_SIZE], 32768, [Sizeof member heap.])
+ AC_DEFINE([ND_HEAP_SIZE], 512, [Size of the nick delay heap.])
+ AC_DEFINE([CONFITEM_HEAP_SIZE], 256, [Size of the confitem heap.])
+ AC_DEFINE([MONITOR_HEAP_SIZE], 1024, [Size of the monitor heap.])
+fi
+
+AC_ARG_WITH(nicklen,
+AC_HELP_STRING([--with-nicklen=LENGTH],[Set the nick length to LENGTH (default 15, max 50)]),
+[
+ if test $withval -ge 50; then
+ NICKLEN=50
+ AC_MSG_WARN([NICKLEN has a hard limit of 50. Setting NICKLEN=50])
+ else
+ NICKLEN="$withval"
+ fi
+], [NICKLEN=15])
+
+AC_ARG_WITH(topiclen,
+AC_HELP_STRING([--with-topiclen=NUMBER],[Set the max topic length to NUMBER (default 390, max 390)]),
+[
+ if test $withval -ge 390; then
+ TOPICLEN=390
+ AC_MSG_WARN([TOPICLEN has a hard limit of 390. Setting TOPICLEN=390])
+ else
+ TOPICLEN=$withval
+ fi
+], [TOPICLEN=390])
+
+AC_ARG_WITH(maxclients,
+AC_HELP_STRING([--with-maxclients=NUMBER],[Maximum number of connections the ircd can handle]),
+ MAX_CLIENTS="$withval", MAX_CLIENTS=3000)
+
+
+if test "$MAX_CLIENTS" = yes; then
+ MAX_CLIENTS=3000
+fi
+
+if test $MAX_CLIENTS -gt 65536; then
+ MAX_CLIENTS=65536
+ AC_MSG_WARN([Max connections cannot be larger than 65536!])
+fi
+
+AC_DEFINE_UNQUOTED(TOPICLEN, ${TOPICLEN}, [Maximum topic length (<=390)])
+AC_DEFINE_UNQUOTED(NICKLEN, (${NICKLEN}+1), [Nickname length])
+AC_DEFINE_UNQUOTED(MAX_CLIENTS, ${MAX_CLIENTS}, [Maximum number of network connections])
+
+AC_ARG_ENABLE(shared-modules,
+AC_HELP_STRING([--disable-shared-modules],[ Disable shared modules.]),
+[shared_modules=$enableval], [shared_modules="yes"])
+
+dnl Some first-stage sanity checks.
+if test "$shared_modules" = yes; then
+
+ if test "$CYGWIN" = yes; then
+ AC_MSG_WARN([disabling shared modules; Cygwin is at present unable to build them.])
+ shared_modules="no"
+ fi
+
+ dnl TenDRA's cc is called tcc too.
+ if test "$CC" = tcc -a "$TenDRA" = "no"; then
+ AC_MSG_WARN([disabling shared modules: Tiny C Compiler can't create PIC])
+ shared_modules="no"
+ fi
+fi
+
+dnl Second stage: check for functions and headers.
+if test "$shared_modules" = yes; then
+ DYNLINK_C=dynlink.c
+ AC_CHECK_HEADERS(dlfcn.h)
+ AC_SEARCH_LIBS(shl_load, dld,
+ [
+ AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if the shl_load function is available.])
+ SUFFIX=".sl"
+ MOD_TARGET=hpux_shared
+ SEDOBJ="s/\.o/.sl/g"
+ ],
+ dnl !shl_load:
+ [
+ dnl standard dlopen
+ AC_SEARCH_LIBS(dlopen, [dl c_r],
+ [
+ AC_DEFINE(HAVE_DLOPEN, 1, [Define if the dlopen function is available.])
+ SUFFIX=".so"
+ MOD_TARGET=shared_modules
+ SEDOBJ="s/\.o/.so/g"
+ if test "$AppleGCC" = yes; then
+ AC_CHECK_HEADERS([mach-o/dyld.h])
+ fi
+ AC_CHECK_FUNC(dlsym, ,
+ [
+ AC_MSG_WARN([dlsym is not available, shared modules disabled])
+ shared_modules=no
+ ])
+ AC_CHECK_FUNCS(dlfunc)
+ ],
+ [
+ shared_modules=no
+ ])
+ ])
+fi
+
+AC_DEFINE_UNQUOTED(SHARED_SUFFIX, "$SUFFIX", [Suffix for shared libraries on this platform.])
+
+dnl Third stage - wrangling the linker.
+if test "$shared_modules" = yes; then
+ # The GNU linker requires the -export-dynamic option to make
+ # all symbols visible in the dynamic symbol table.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for the ld -export-dynamic flag)
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic -Werror"
+ AC_LINK_IFELSE(AC_LANG_PROGRAM([],[int i;]), found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+
+ if expr "`uname -s`" : ^IRIX >/dev/null 2>&1; then
+ found="no, IRIX ld uses -B,dynamic"
+ LDFLAGS="${LDFLAGS} -Wl,-B,dynamic"
+ fi
+
+ if expr "`uname -s`" : ^AIX >/dev/null 2>&1; then
+ found="no, AIX ld uses -G -brtl"
+ LDFLAGS="${LDFLAGS} -Wl,-G,-brtl"
+ fi
+
+ AC_MSG_RESULT($found)
+
+ if test "$found" = yes; then
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ fi
+
+ AC_MSG_CHECKING(for compiler option to produce PIC)
+ dnl The order should be here to check for groups of compilers,
+ dnl then for odd compilers, then if no PICFLAGS were set up,
+ dnl check for GCC and set defaults, or else error. -jmallett
+ if test "$SGS" = "yes"; then
+ AC_MSG_RESULT([SVR4 SGS interfaces: -KPIC -DPIC -G])
+ PICFLAGS="-KPIC -DPIC -G"
+ fi
+
+ if test "$AppleGCC" = "yes"; then
+ AC_MSG_RESULT([Darwin Mach-O bundles: -fno-common -bundle -flat_namespace -undefined suppress])
+ PICFLAGS="-fno-common -bundle -flat_namespace -undefined suppress"
+ fi
+ dnl Please note, that on HPUX two different stages of module compilation occurs, since
+ dnl while compiling modules, the compiler does not allow you to give arguments
+ dnl to the linker. (I did not design this)
+ dnl So we need -c in the first stage of module compilation.
+ dnl In the second stage, we link the modules via ld -b.
+ dnl Additionally, HPUX does not like -export-dynamic, it likes -E instead.
+ dnl -TimeMr14C
+ if test "$HPUX" = "yes" -a "$CC" != gcc; then
+ AC_MSG_RESULT(HP-UX cc: +z -r -q -n)
+ PICFLAGS="+z -r -q -n -c"
+ AC_MSG_CHECKING([if +ESfic is required on this platform])
+
+ if expr "`$CC +ESfic 2>&1`" : ".*neither supported.*" >/dev/null; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(yes)
+ PICFLAGS="$PICFLAGS +ESfic"
+ fi
+
+ LDFLAGS="${LDFLAGS} -Wl,-E"
+ fi
+ if test "$Tru" = yes -a "$CC" != gcc; then
+ AC_MSG_RESULT([Tru64: -shared -expect_unresolved '*'])
+ PICFLAGS="-shared -expect_unresolved '*' "
+ LDFLAGS="-call_shared"
+ fi
+ if test -z "$PICFLAGS"; then
+ if test "$ac_cv_c_compiler_gnu" = "yes"; then
+ AC_MSG_RESULT(gcc: -fPIC -DPIC -shared)
+ PICFLAGS="-fPIC -DPIC -shared"
+ else
+ AC_MSG_RESULT(no)
+ shared_modules=no
+ fi
+ fi
+fi
+
+# This must be down here, or it will mess up checks like the ones
+# for -Wl,-export-dynamic
+# -- jilles
+AC_ARG_ENABLE(warnings,
+AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]),
+[
+IRC_CFLAGS="$IRC_CFLAGS -O0"
+CFLAGS="$IRC_CFLAGS"
+
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wall], charybdis_cv_c_gcc_w_all)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wpointer-arith], charybdis_cv_c_gcc_w_pointer_arith)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wimplicit -Wnested-externs], charybdis_cv_c_gcc_w_implicit)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-align], charybdis_cv_c_gcc_w_cast_align)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-qual], charybdis_cv_c_gcc_w_cast_qual)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], charybdis_cv_c_gcc_prototypes)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wparenthesis], charybdis_cv_c_gcc_parenthesis)
+CHARYBDIS_C_GCC_TRY_FLAGS([-W -Wno-unused], charybdis_cv_c_gcc_w)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wextra], charybdis_cv_c_gcc_w_extra)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wshadow], charybdis_cv_c_gcc_w_shadow)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wmissing-noreturn], charybdis_cv_c_gcc_w_missing_noreturn)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wundef], charybdis_cv_c_gcc_w_undef)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wpacked], charybdis_cv_c_gcc_w_packed)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wnested-externs], charybdis_cv_c_gcc_w_nested_externs)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wbad-function-cast], charybdis_cv_c_gcc_w_bad_function_cast)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wunused-function -Wunused-label -Wunused-value -Wunused-variable], charybdis_cv_c_gcc_w_unused)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wredundant-decls], charybdis_cv_c_gcc_w_redundant_decls)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wfloat-equal], charybdis_cv_c_gcc_w_float_equal)
+CHARYBDIS_C_GCC_TRY_FLAGS([-Wformat=2], charybdis_cv_c_gcc_w_format)
+CHARYBDIS_C_GCC_TRY_FLAGS([-pedantic], charybdis_cv_c_gcc_pedantic)
+
+IRC_CFLAGS="$CFLAGS"
+],[])
+
+if test "$shared_modules" = no; then
+ DYNLINK_C=""
+ MOD_TARGET="libmodules.a"
+ MODULES_LIBS="../modules/libmodules.a"
+ SEDOBJ=""
+ AC_DEFINE(STATIC_MODULES, 1, [Define to 1 if dynamic modules can't be used.])
+ AC_MSG_WARN([shared module support has been disabled!])
+fi
+
+dnl Stage 5 - underscores in front of symbol names.
+if test "$shared_modules" = yes; then
+
+ AC_CHECK_FUNC(nlist,,
+ AC_CHECK_LIB(dl, nlist, nlist_lib="-ldl",
+ AC_CHECK_LIB(elf, nlist, nlist_lib="-lelf",)
+ )
+ )
+
+ dnl We need to find out whether underscores are appended to symbol
+ dnl names in executable files. First, though, we need to see
+ dnl where nlist.h is hiding.
+ AC_CHECK_HEADER(libelf/nlist.h, [ nlist_h="libelf/nlist.h" ], )
+ AC_CHECK_HEADER(elf/nlist.h, [ nlist_h="elf/nlist.h" ], )
+ AC_CHECK_HEADER(nlist.h, [ nlist_h="nlist.h" ], )
+ if test x"$nlist_h" = "x"; then
+ AC_DEFINE_UNQUOTED(SYMBOL_PREFIX, "", [String containing extra underscores prepended to symbols loaded from modules.])
+ else
+ AC_MSG_CHECKING(for extra underscores prepended to symbol names)
+ AC_CACHE_VAL(symbol_underscores,
+ [
+cat << EOF > conftest.c
+#include <$nlist_h>
+#include <stdio.h>
+#include <stdlib.h>
+void _modinit(void);
+int main(int argc, char *argv[[]]) {
+ int i;
+ struct nlist nl[[5]];
+
+ /* fill the names in this way, so it'll work almost everywhere */
+ nl[[0]].n_name = "_modinit";
+ nl[[1]].n_name = "__modinit";
+ nl[[2]].n_name = "___modinit";
+ nl[[3]].n_name = "____modinit";
+ nl[[0]].n_value = nl[[1]].n_value = nl[[2]].n_value = nl[[3]].n_value = nl[[4]].n_name = NULL;
+
+ if(argc < 2 || (nlist(argv[[1]], nl)) == -1) exit(-1);
+ for(i = 0; i < 4; i++) {
+ if(nl[[i]].n_value != NULL)
+ {
+ int j;
+ for(j = 0; j < i; j++)
+ printf("_");
+ exit(i);
+ }
+ }
+ exit(-1);
+}
+void _modinit(void) { return; }
+EOF
+ $CC $CPPFLAGS $IRC_CFLAGS -o conftest conftest.c $nlist_lib >/dev/null 2>&1
+ symbol_underscores=`./conftest conftest`
+ AC_MSG_RESULT($symbol_underscores)
+ $RM -f conftest conftest.c
+ ])
+ AC_DEFINE_UNQUOTED(SYMBOL_PREFIX, "${symbol_underscores}", [String containing extra underscores prepended to symbols loaded from modules.])
+ fi
+fi
+
+AC_SUBST(MODULES_LIBS)
+AC_SUBST(MOD_TARGET)
+
+AC_SUBST(SSL_SRCS_ENABLE)
+AC_SUBST(SSL_INCLUDES)
+AC_SUBST(SSL_LIBS)
+
+AC_SUBST(LDFLAGS)
+AC_SUBST(PICFLAGS)
+AC_SUBST(IRC_CFLAGS)
+AC_SUBST(SEDOBJ)
+
+
+if test "$prefix" = "NONE"; then
+ AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$ac_default_prefix", [Prefix where the ircd is installed.])
+
+else
+
+dnl Don't get bitten by Cygwin's stupidity if the user specified
+dnl a custom prefix with a trailing slash
+
+ prefix=`echo $prefix | sed 's/\/$//'`
+ AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$prefix", [Prefix where the ircd is installed.])
+
+fi
+
+AC_CONFIG_FILES( \
+ Makefile \
+ libcharybdis/Makefile \
+ servlink/Makefile \
+ extensions/Makefile \
+ unsupported/Makefile \
+ src/Makefile \
+ modules/Makefile \
+ tools/Makefile \
+ doc/Makefile \
+ help/Makefile \
+)
+
+AC_OUTPUT
+
+if test "$cf_openssl_version_ok" = yes; then
+ openssl="yes"
+else
+ openssl="no"
+fi
+
+if test "$shared_modules" = yes; then
+ modules=shared
+else
+ modules=static
+fi
+
+echo "
+Configuration:
+ Install directory : $prefix
+
+ Ziplinks : $zlib
+ OpenSSL : $openssl
+ Modules : $modules
+ IPv6 support : $have_v6
+ Socket Engine : $SELECT_TYPE
+ Small network : $small_net
+ Block allocator : $balloc
+ ASM hashing code : $ricer_hashing
+
+ Nickname length : $NICKLEN
+ Topic length : $TOPICLEN
+
+Use make to compile Charybdis, then make install to install it.
+"
--- /dev/null
+$Id: CIDR.txt 6 2005-09-10 01:02:21Z nenolod $
+
+CIDR Information
+----------------
+ Presently, we all use IPv4. The format of IPv4 is the following:
+
+A.B.C.D
+
+ Where letters 'A' through 'D' are 8-bit values. In English, this
+ means each digit can have a value of 0 to 255. Example:
+
+129.56.4.234
+
+ Digits are called octets. Oct meaning 8, hence 8-bit values. An
+ octet cannot be greater than 255, and cannot be less than 0 (eg. a
+ negative number).
+
+ CIDR stands for "classless inter domain routing", details covered
+ in RFC's 1518 and 1519. It was introduced mainly due to waste within
+ A and B classes space. The goal was to make it possible to use
+ smaller nets than it would seem from (above) IP classes, for instance
+ by dividing one B class into 256 "C like" classes. The other goal was
+ to allow aggregation of routing information, so that routers could use
+ one aggregated route (like 194.145.96.0/20) instead of
+ advertising 16 C classes.
+
+ Class A are all these addresses which first bit is "0",
+ bitmap: 0nnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh (n=net, h=host)
+ IP range is 0.0.0.0 - 127.255.255.255
+
+ Class B are all these addresses which first two bits are "10",
+ bitmap: 10nnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh (n=net, h=host)
+ IP range is 128.0.0.0 - 191.255.255.255
+
+ Class C are all these addresses which first three bits are "110",
+ bitmap: 110nnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh (n=net, h=host)
+ IP range is 192.0.0.0 - 223.255.255.255
+
+ Class D are all these addresses which first four bits are "1110",
+ this is multicast class and net/host bitmap doesn't apply here
+ IP range is 224.0.0.0 - 239.255.255.255
+ I bet they will never IRC, unless someone creates multicast IRC :)
+
+ Class E are all these addresses which first five bits are "11110",
+ this class is reserved for future use
+ IP range is 240.0.0.0 - 247.255.255.255
+
+ So, here is how CIDR notation comes into play.
+
+ For those of you who have real basic exposure to how networks are
+ set up, you should be aware of the term "netmask." Basically, this
+ is a IPv4 value which specifies the "size" of a network. You can
+ assume the word "size" means "range" if you want.
+
+ A chart describing the different classes in CIDR format and their
+ wildcard equivalents would probably help at this point:
+
+CIDR version dot notation (netmask) Wildcard equivalent
+-----------------------------------------------------------------
+A.0.0.0/8 A.0.0.0/255.0.0.0 A.*.*.* or A.*
+A.B.0.0/16 A.B.0.0/255.255.0.0 A.B.*.* or A.B.*
+A.B.C.0/24 A.B.C.0/255.255.255.0 A.B.C.* or A.B.C.*
+A.B.C.D/32 A.B.C.D/255.255.255.255 A.B.C.D
+
+
+ The question on any newbies mind at this point is "So what do all
+ of those values & numbers actually mean?"
+
+ Everything relating to computers is based on binary values (1s and
+ zeros). Binary plays a *tremendous* role in CIDR notation. Let's
+ break it down to the following table:
+
+ A B C D
+ -------- -------- -------- --------
+/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0
+/16 == 11111111 . 11111111 . 00000000 . 00000000 == 255.255.0.0
+/24 == 11111111 . 11111111 . 11111111 . 00000000 == 255.255.255.0
+/32 == 11111111 . 11111111 . 11111111 . 11111111 == 255.255.255.255
+
+ The above is basically a binary table for the most common netblock
+ sizes. The "1"s you see above are the 8-bit values for each octet.
+ If you split an 8-bit value into each of it's bits, you find the
+ following:
+
+00000000
+^^^^^^^^_ 1sts place (1)
+|||||||__ 2nds place (2)
+||||||___ 3rds place (4)
+|||||____ 4ths place (8)
+||||_____ 5ths place (16)
+|||______ 6ths place (32)
+||_______ 7ths place (64)
+|________ 8ths place (128)
+
+ Now, since computers consider zero a number, you pretty much have
+ to subtract one (so-to-speak; this is not really how its done, but
+ just assume it's -1 :-) ) from all the values possible. Some
+ examples of decimal values in binary:
+
+15 == 00001111 (from left to right: 8+4+2+1)
+16 == 00010000 (from left to right: 16)
+53 == 00110101 (from left to right: 32+16+4+1)
+79 == 01001111 (from left to right: 64+8+4+1)
+254 == 11111110 (from left to right: 128+64+32+16+8+4+2)
+
+ So, with 8 bits, the range (as I said before) is zero to 255.
+
+ If none of this is making sense to you at this point, you should
+ back up and re-read all of the above. I realize it's a lot, but
+ it'll do you some good to re-read it until you understand :-).
+
+ So, let's modify the original table a bit by providing CIDR info
+ for /1 through /8:
+
+ A B C D
+ -------- -------- -------- --------
+/1 == 10000000 . 00000000 . 00000000 . 00000000 == 128.0.0.0
+/2 == 11000000 . 00000000 . 00000000 . 00000000 == 192.0.0.0
+/3 == 11100000 . 00000000 . 00000000 . 00000000 == 224.0.0.0
+/4 == 11110000 . 00000000 . 00000000 . 00000000 == 240.0.0.0
+/5 == 11111000 . 00000000 . 00000000 . 00000000 == 248.0.0.0
+/6 == 11111100 . 00000000 . 00000000 . 00000000 == 252.0.0.0
+/7 == 11111110 . 00000000 . 00000000 . 00000000 == 254.0.0.0
+/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0
+
+ At this point, all of this should making a lot of sense, and you
+ should be able to see the precision that you can get by using CIDR
+ at this point. If not, well, I guess the best way to put it would
+ be that wildcards always assume /8, /16, or /24 (yes hello Piotr,
+ we can argue this later: I am referring to IPs *ONLY*, not domains
+ or FQDNs :-) ).
+
+ This table will provide a reference to all of the IPv4 CIDR values
+
+cidr|netmask (dot notation)
+----+---------------------
+/1 | 128.0.0.0
+/2 | 192.0.0.0
+/3 | 224.0.0.0
+/4 | 240.0.0.0
+/5 | 248.0.0.0
+/6 | 252.0.0.0
+/7 | 254.0.0.0
+/8 | 255.0.0.0
+/9 | 255.128.0.0
+/10 | 255.192.0.0
+/11 | 255.224.0.0
+/12 | 255.240.0.0
+/13 | 255.248.0.0
+/14 | 255.252.0.0
+/15 | 255.254.0.0
+/16 | 255.255.0.0
+/17 | 255.255.128.0
+/18 | 255.255.192.0
+/19 | 255.255.224.0
+/20 | 255.255.240.0
+/21 | 255.255.248.0
+/22 | 255.255.252.0
+/23 | 255.255.254.0
+/24 | 255.255.255.0
+/25 | 255.255.255.128
+/26 | 255.255.255.192
+/27 | 255.255.255.224
+/28 | 255.255.255.240
+/29 | 255.255.255.248
+/30 | 255.255.255.252
+/31 | 255.255.255.254
+/32 | 255.255.255.255
+
+ So, let's take all of the information above, and apply it to a
+ present-day situation on IRC.
+
+ Let's say you have a set of flooding clients who all show up from
+ the following hosts. For lack-of a better example, I'll use a
+ subnet here at Best:
+
+nick1 (xyz@shell9.ba.best.com) [206.184.139.140]
+nick2 (abc@shell8.ba.best.com) [206.184.139.139]
+nick3 (foo@shell12.ba.best.com) [206.184.139.143]
+
+ Most people will assume the they were all in the same class C
+ (206.184.139.0/24 or 206.184.139.*).
+
+ This, as a matter of fact, is not true. Now, the reason *I* know
+ this is solely because I work on the network here; those IPs are
+ not delegated to a class C, but two portions of a class C (128 IPs
+ each). That means the class C is actually split into these two
+ portions:
+
+Netblock IP range
+-------- --------
+206.184.139.0/25 206.184.139.0 to 206.184.139.127
+206.184.139.128/25 206.184.139.128 to 206.184.139.255
+
+ For the record, 206.184.139.0 and 206.184.139.128 are both known as
+ "network addresses" (not to be confused with "netblocks" or "Ethernet
+ hardware addresses" or "MAC addresses"). Network addresses are
+ *ALWAYS EVEN*.
+
+ 206.184.139.127 and 206.184.139.255 are what are known as broadcast
+ addresses. Broadcast addresses are *ALWAYS ODD*.
+
+ Now, the aforementioned list of clients are in the 2nd subnet shown
+ above, not the first. The reason for this should be obvious.
+
+ The remaining question is, "Well that's nice, you know what the netblock
+ is for Best. What about us? We don't know that!"
+
+ Believe it or not, you can find out the network block size by using
+ whois -h WHOIS.ARIN.NET on the IP in question. ARIN keeps a list of
+ all network blocks and who owns them -- quite useful, trust me. I
+ think I use ARIN 5 or 6 times a day, especially when dealing with
+ D-lines. Example:
+
+$ whois -h whois.arin.net 206.184.139.140
+Best Internet Communications, Inc. (NETBLK-NBN-206-184-BEST)
+345 East Middlefield Road
+Mountain View, CA 94043
+
+Netname: NBN-206-184-BEST
+Netblock: 206.184.0.0 - 206.184.255.255
+Maintainer: BEST
+
+ Does this mean you should D-line 206.184.0.0/16? Probably not.
+ That's an entire class B-sized block, while you're only trying
+ to deny access to a subnetted class C.
+
+ So then how do you get the *real* info? Well, truth is, you don't.
+ You have to pretty much take a guess at what it is, if ARIN reports
+ something that's overly vague. Best, for example, was assigned the
+ above class B-sized block. We can subnet it however we want without
+ reporting back to ARIN how we have it subnetted. We own the block,
+ and that's all that matters (to ARIN).
+
+ Not all subnets are like this, however. Smaller subnets you may
+ find partitioned and listed on ARIN; I've seen /29 blocks for DSL
+ customers show up in ARIN before.
+
+ So, use ARIN any chance you get. The more precision the better!
+
+ Now, there is a small issue I want to address regarding use of CIDR
+ notation. Let's say you D-line the following in CIDR format (hi
+ sion ;-) ):
+
+205.100.132.18/24
+
+ Entries like this really makes my blood boil, solely because it adds
+ excessive confusion and is just basically pointless. If you
+ examine the above, you'll see the /24 is specifying an entire
+ class C -- so then what's the purpose of using .18 versus .0?
+
+ There IS no purpose. The netmask itself will mask out the .18 and
+ continue to successfully use 205.100.132.0/24.
+
+ Doing things this way just adds confusion, especially on non-octet-
+ aligned subnets (such as /8, /16, /24, or /32). Seeing that on a
+ /27 or a /19 might make people go "wtf?"
+
+ I know for a fact this doc lacks a lot of necessary information,
+ like how the actual netmask/CIDR value play a role in "masking out"
+ the correct size, and what to do is WHOIS.ARIN.NET returns no
+ netblock information but instead a few different company names with
+ NIC handles. I'm sure you can figure this stuff out on your own,
+ or just ask an administrator friend of yours who DOES know. A lot
+ of us admins are BOFH types, but if you ask us the right questions,
+ you'll benefit from the answer quite thoroughly.
+
+ Oh, I almost forgot. Most Linux systems use a different version of
+ "whois" than FreeBSD does. The syntax for whois on Linux is
+ "whois <INFO>@whois.arin.net", while under FreeBSD it is
+ "whois -h whois.arin.net <INFO>" Debian uses yet another version
+ of whois that is incompatible with the above syntax options.
+
+ Note that the FreeBSD whois client has shortcuts for the most commonly
+ used whois servers. "whois -a <INFO>" is the shortcut for ARIN.
+
+ Also note that ARIN is not authoritative for all IP blocks on the
+ Internet. Take for example 212.158.123.66. A whois query to ARIN
+ will return the following information:
+
+$ whois -h whois.arin.net 212.158.123.66
+European Regional Internet Registry/RIPE NCC (NET-RIPE-NCC-)
+ These addresses have been further assigned to European users.
+ Contact information can be found in the RIPE database, via the
+ WHOIS and TELNET servers at whois.ripe.net, and at
+ http://www.ripe.net/db/whois.html
+
+ Netname: RIPE-NCC-212
+ Netblock: 212.0.0.0 - 212.255.255.255
+ Maintainer: RIPE
+
+ This query tells us that it is a European IP block, and is further
+ handled by RIPE's whois server. We must then query whois.ripe.net
+ to get more information.
+
+$ whois -h whois.ripe.net 212.158.123.66
+
+% Rights restricted by copyright. See
+ http://www.ripe.net/ripencc/pub-services/db/copyright.html
+
+inetnum: 212.158.120.0 - 212.158.123.255
+netname: INSNET-P2P
+descr: Point to Point Links for for London Nodes
+country: GB
+--snip--
+
+ This tells us the actual IP block that the query was a part of.
+
+ Other whois servers that you may see blocks referred to are:
+ whois.ripn.net for Russia, whois.apnic.net for Asia, Australia, and
+ the Pacific, and whois.6bone.net for IPv6 blocks.
+
+Contributed by Jeremy Chadwick <jdc@best.net>
+Piotr Kucharski <chopin@sgh.waw.pl>
+W. Campbell <wcampbel@botbay.net> and
+Ariel Biener <ariel@fireball.tau.ac.il>
--- /dev/null
+$Id: Hybrid-team 54 2005-09-10 05:12:55Z nenolod $
+
+The hybrid team is a group of ircd coders who were frustrated
+with the instability and all-out "dirtiness" of the EFnet ircd's
+available. "hybrid" is the name for the collective efforts of a group
+of people, all of us.
+
+Anyone is welcome to contribute to this effort. You are encouraged
+to participate in the Hybrid mailing list. To subscribe to the
+Hybrid List, use this link:
+ https://lists.ircd-hybrid.org/mailman/listinfo/hybrid
+
+The core team as, of this major release:
+
+adx, Piotr Nizynski <adx@irc7.pl>
+billy-jon, William Bierman III <bill@mu.org>
+cryogen, Stuart Walsh <stu@ipng.org.uk>
+Dianora, Diane Bruce <db@db.net>
+joshk, Joshua Kwan <joshk@triplehelix.org>
+kire, Erik Small <smalle@hawaii.edu>
+knight, Alan LeVee <alan.levee@prometheus-designs.net>
+metalrock, Jack Low <jclow@csupomona.edu>
+Michael, Michael Wobst <michael.wobst@gmail.com>
+Rodder, Jon Lusky <lusky@blown.net>
+Wohali, Joan Touzet <joant@ieee.org>
+
+The following people have contributed blood, sweat, and/or code to
+recent releases of Hybrid, in nick alphabetical order:
+
+A1kmm, Andrew Miller <a1kmm@mware.virtualave.net>
+AndroSyn, Aaron Sethman <androsyn@ratbox.org>
+bane, Dragan Dosen <bane@idolnet.org>
+bysin, Ben Kittridge <bkittridge@cfl.rr.com>
+cosine, Patrick Alken <wnder@uwns.underworld.net>
+David-T, David Taylor <davidt@yadt.co.uk>
+fl, Lee Hardy <lee@leeh.co.uk>
+Garion, Joost Vunderink <garion@efnet.nl>
+Habeeb, David Supuran <habeeb@cfl.rr.com>
+Hwy101, W. Campbell <wcampbel@botbay.net>
+jmallett, Juli Mallett <jmallett@FreeBSD.org>
+jv, Jakub Vlasek <jv@pilsedu.cz>
+k9, Jeremy Chadwick <ircd@jdc.parodius.com>
+kre, Dinko Korunic <kreator@fly.srk.fer.hr>
+madmax, Paul Lomax <madmax@efnet.org>
+nenolod, William Pitcock <nenolod@nenolod.net>
+Riedel, Dennis Vink, <riedel@chaotic.nl>
+scuzzy, David Todd <scuzzy@aniverse.net>
+spookey, David Colburn <spookey@spookey.org>
+TimeMr14C, Yusuf Iskenderoglu <uhc0@stud.uni-karlsruhe.de>
+toot, Toby Verrall <to7@antipope.fsnet.co.uk>
+vx0, Mark Miller <mark@oc768.net>
+wiz, Jason Dambrosio <jason@wiz.cx>
+Xride, Søren Straarup <xride@x12.dk>
+zb^3, Alfred Perlstein <alfred@freebsd.org>
+
+Others are welcome. Always. And if we left anyone off the above list,
+be sure to let us know that too. Many others have contributed to
+previous versions of this ircd and its ancestors, too many to list
+here.
+
+Send bug fixes/complaints/rotten tomatoes to bugs@ircd-hybrid.org.
--- /dev/null
+# $Id: Makefile.in 138 2005-09-12 00:48:18Z nenolod $
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_BIN = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+RM = @RM@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+LDFLAGS = @LDFLAGS@
+MKDEP = ${CC} -MM
+MV = @MV@
+RM = @RM@
+CP = @CP@
+TOUCH = @TOUCH@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+exec_suffix = @exec_suffix@
+bindir = @bindir@
+libexecdir = @libexecdir@
+confdir = @confdir@
+localstatedir = @localstatedir@
+# Change this later! -- adrian
+moduledir = @moduledir@
+automoduledir = @moduledir@/autoload
+
+# Local to the etc Makefile
+mandir = @mandir@/man8
+MANPAGES = ircd.8
+
+CONFS = example.conf reference.conf
+DEFAULTCONFS = kline.conf dline.conf xline.conf resv.conf
+
+SSL_LIBS = @SSL_LIBS@
+SSL_INCLUDES = @SSL_INCLUDES@
+
+IRCDLIBS = @LIBS@ $(SSL_LIBS)
+
+INCLUDES = -I../include $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+install-mkdirs:
+ -@if test ! -d $(DESTDIR)$(confdir); then \
+ echo "mkdir $(confdir)"; \
+ mkdir $(DESTDIR)$(confdir); \
+ fi
+
+ -@if test ! -d $(DESTDIR)$(mandir); then \
+ echo "mkdir $(mandir)"; \
+ mkdir $(DESTDIR)$(mandir); \
+ fi
+
+install: install-mkdirs build
+ @echo "ircd: installing example config files ($(CONFS))"
+ @for i in $(CONFS); do \
+ if test -f $(DESTDIR)$(confdir)/$$i; then \
+ $(MV) $(DESTDIR)$(confdir)/$$i $(DESTDIR)$(confdir)/$$i.old; \
+ fi; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(confdir); \
+ done
+
+ @for i in $(DEFAULTCONFS); do \
+ if test ! -f $(DESTDIR)$(confdir)/$$i; then \
+ echo "ircd: creating config file ($$i)"; \
+ ${TOUCH} $(DESTDIR)$(confdir)/$$i; \
+ fi; \
+ done
+
+ -@if test ! -f $(DESTDIR)$(confdir)/ircd.motd; then \
+ echo "ircd: installing motd file (ircd.motd)"; \
+ $(INSTALL_DATA) ircd.motd $(DESTDIR)$(confdir); \
+ fi
+
+ -@if test -f $(DESTDIR)$(confdir)/links.txt; then \
+ $(RM) $(DESTDIR)$(confdir)/links.txt; \
+ fi
+
+ @echo "ircd: installing manpage"
+ @for i in $(MANPAGES); do \
+ if test ! -f $(DESTDIR)$(mandir)/$$i; then \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(mandir); \
+ fi; \
+ done
+
+build:
+
+clean:
+
+depend:
+
+lint:
+
+distclean:
+ ${RM} -f Makefile
--- /dev/null
+$Id: README.cidr_bans 6 2005-09-10 01:02:21Z nenolod $
+
+
+Basically what this patch does is allow for users to use cidr masks when
+setting bans, exceptions, and invite invex(modes beI respectively). This
+works for both IPv4 and IPv6 addresses.
+
+I won't go into details of how cidr works here, but to use them, you could
+do something like:
+
+/mode #foo +b *!*@10.0.0.0/8
+/mode #foo +e *!*@10.0.10.0/24
+
+Aaron Sethman <androsyn@ratbox.org>
+August 06, 2002
+
+
--- /dev/null
+$Id: Ratbox-team 1640 2006-06-05 00:02:19Z jilles $
+
+ircd-ratbox is an evolution where ircd-hybrid left off around version 7-rc1.
+Currently the ircd-ratbox team consists of the following developers:
+
+AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
+anfl, Lee Hardy <lee -at- leeh.co.uk>
+
+Special thanks for support, code and ideas to:
+
+Hwy, W. Campbell <wcampbel -at- botbay.net>
+jilles, Jilles Tjoelker <jilles -at- stack.nl>
+larne, Edward Brocklesby <ejb -at- sdf.lonestar.org>
+
+Of course our work is based on the work of many, many others over the past
+10 or so years since irc has existed, including the work done by the Hybrid
+team, our thanks goes to them.
+
--- /dev/null
+
+The Tao of Internet Relay Chat
+Copyright (C) Ove Ruben R Olsen 1994
+Version of 940110
+Contributing masters: Master ScottM
+
+-----
+Something is formed by the electrons, born in the silent cable. Shaping
+and growing and ungrowing. It is there yet not there. It is the source of
+Internet Relay Chat. I do not know the name, thus I will call it the Tao
+of Internet Relay Chat.
+
+If the Tao is great, then the IRC is running ceaselessly. If the IRC is
+great then the server is running without ever stoping. If the server is
+great then the client will always be the server. The luser is then pleased
+and there is Chat in the world.
+
+The Tao of IRC squits far away and connects on returning.
+
+
+-----
+The genetic potential of birth, a lot to know, yet unknown.
+
+In the begining there was nothing.
+
+Out of nothing the Tao gave birth to tolsun.oulu.fi. tolsun gave birth to
+OuluBox.
+
+OuluBox gave birth to rmsg.
+
+rmsg was not Tao, so MUT gave birth to IRC.
+
+No one knows when IRC came into existance, the mighty master WiZ have it
+to be at the end of the eight month in the year of the Dragon.
+
+
+-----
+Each channel has its purpose, however humble. Each channel is the Yin and
+Yang of IRC. Each channels has it's place within the IRC.
+
+In the beginning there was only channel 0, thus channel 0 is the soil of
+IRC.
+
+Channel 1 to channel 10 then was open as the sea. Channel 11 to 999 was the
+trees and forests of IRC. Channels above 999 should not be mentioned, and
+channels below 0 were unborn and contained many secrets.
+
+This was not the right Tao, so IRC gave birth to +channels.
+
++channels had the yin and yang. Mode does not.
+
+This was not the right Tao still, so IRC gave birth to #channels.
+
+#channels have the yin and yang.
+
+Only channel 0 is the right path to Tao, but avoid speaking on channel 0.
+
+
+-----
+There was a great dispute among the Broom-Walkers of the Relay. Some of them
+wanted neither yin nor yang. Out of this Eris came into existance. Some of the
+Broom-Walkers then created Eris Free-net.
+
+This was the right Tao.
+
+Kind Gentle and Boring Net was another wrong path to the Tao of Internet Relay
+Chat.
+
+Some time later there was a quantity of some lusers who wanted to be
+Broom-Walkers also. The Eris Free Broom-Walkers did not agree with them,
+thus a new IRC was born. This IRC is called the Undernet.
+
+But this is not the right Tao, either.
+
+
+-----
+There will always be disputes among the Broom-Walkers of Internet Relay Chat.
+
+This is the very nature of the IRC.
+
+
+-----
+Lusers that do not understand the Tao is always using the yang of Mode on
+their channels. Lusers that do understand the Tao are always using Ignore
+on their channels.
+
+How could this not be so ?
+
+
+-----
+The wise sage luser is told about the Chat and uses it. The luser is told
+about the IRC and is looking for it. The flock are told about the Tao and
+make a fool of the IRC.
+
+If there was no laughter, there would be no Tao.
+
+
+-----
+The master says:
+"Without the Tao of Internet Relay Chat, life becomes meaningless."
+
+The Relay of the old time was mysterious and sacred. We can neither imagine
+its thoughts nor path; we are left but to describe.
+
+
+-----
+The sage luser must be aware like a frog crossing the highway.
+
+
+-----
+The great master Wumpus once dreamed that he was an automaton. When he awoke
+he exclaimed:
+ "I don't know whether I am Wumpus dreaming that I am a client,
+ or a client dreaming that I am Wumpus!"
+
+So was the first Automata born.
+
+The master Nap then said:
+ "Any automata should not speak unless spoken to.
+ Any automata shall only whisper when spoken to."
+
+Thus replied the master Gnarfer:
+ "The lusers shall keep in mind that a automata can be either good or
+ bad. Create good automata, and the IRC will hail you and you will
+ gain fame and fortune. Create bad automata and people will start to
+ hate you, and finaly you will be /KILLed to ethernal damnation"
+
+Many lusers have fallen into the clutches of ethernal damnation. They where
+not following the Tao.
+
+
+-----
+There once was a luser who went to #BotSex. Each day he saw the automatons.
+The luser decided that he also would have such a automata.
+He asked another luser for his automata. The other luser gave his automata
+away.
+
+The luser was not within the Tao, so he just started the automata. The automata
+had only Yang inside so all the lusers files where deleted.
+
+Some moons laither the same luser then had become a sage luser, and did create
+his automata from the very grounds with materials found inside the IRC.
+The luser was now within the Tao and his automata lived happily ever after.
+
+
+-----
+There once was a master who wrote automatons without the help of master Phone.
+A novice luser, seeking to imitate him, began with the help of master Phone.
+When the novice luser asked the master to evaluate his automata the master
+replied: "What is a working automata for the master is not for the luser.
+You must must BE the IRC before automating."
+
+
+-----
+Master BigCheese gave birth to master Troy; his duty clear. Master Troy gave
+birth to master Phone, for the Tao of Irc must be eternal and must flow as the
+ceaseless river of Time itself.
+
+
+-----
+Master Phone once said about the ircII client:
+ "public_msg is for a message from someone NOT on the channel
+ public_other is for a message on a channel that doesn't belong to
+ a window. public is for a message on a channel that belongs to a
+ window!"
+
+Out of this raised the mighty chaos.
+
+
+-----
+The sage luser came to the master who wrote automata without the help of
+master Phone. The sage luser asked the master who wrote automata: "Which is
+easiest to make. A automata with the help of master Phone or an automata
+made with the help of a language ?"
+
+The master who wrote automata then replied:
+ "With the help of a language."
+
+The sage luser was disapointed and exclaimed: "But, with master Phone you
+do not need to know anything about the soil of IRC. Is not that the easiet
+way ?"
+
+"Not really" said the master who wrote automata, "when using master Phone
+you are closed inside a box. For sure, it is a great box for the lusers,
+but the master will need more power, thus a language is the only path to go.
+With the language the master will never have to limit himself. When using
+such a language the master will seek the best between the need and the
+availibility."
+
+"I see", said the sage luser.
+
+This is the essence of Tao of IRC automatas.
+
+
+-----
+A client should be light and be used for communication. The spirit of a good
+client is that it should be very convinient for the luser to use, but hard
+for the luser who want to create automata.
+There should never ever be too many functions or too few functions.
+
+There should always be a ignore.
+
+Without ignore the client is not within the Tao of Chating.
+
+The client should always respond the luser with messages that will not
+astnonish him too much. The server likewise. If the server does not, then it
+is the clients job to explain what the server says.
+
+A client which fails this, will be useless and cause confusion for the lusers.
+The only way to correct this is to use another client or to write a new one.
+
+
+-----
+A luser asked the masters on #IrcHelp: "My client does not work".
+The masters replied: "Upgrade your client".
+The luser then wondered why the master knew. The master then told him about
+the Protocol.
+
+"Your client does not work beaucse it does not understand the server. Why
+should it always work ? Only a fool would expect such. But, clients are made
+by humans, and humans are not perfect. Only Tao is.
+
+The IRC is solid. The IRC is floating, and will always be dynamic. Live with
+that or /quit."
+
+
+-----
+The luser came to the masters of #IrcHelp, asking about the Tao of IRC within
+the client.
+The masters then said that the Tao of IRC always lies inside the client
+regardless of how the client connects to the server.
+
+"Is the Tao in irc ?" asked the luser.
+"It so is" replied the masters of #IrcHelp.
+"Is the Tao in the ircII, Kiwi, rxirc, vms, rockers and msa ?" asked the
+luser.
+"In all of them and in the TPC, irchat, zenirc, zircon X11-irc and even the
+dos irc has the Tao" said the master quietly.
+"Is the Tao in a telnet connection directly to the server ?"
+
+The master then was quiet for a long time and said. "Please leave, such
+questions are not within the Tao of IRC".
+
+
+-----
+The master says: "Without the Protocol of TCP the messages will not travel.
+ Without the client, the server is useless."
+
+
+-----
+There once was a luser who used the ircII client. "ircII can do anything I
+ever need for using IRC" said the emacs client user, "I have /ON's, I have
+assignments, I have aliasing. Why don't you use this instead of the huge
+emacs client, which also has a messy screen?"
+The emacs client user then replied by saying that "it is better to have a
+scripting language that is the client instead of have a client that has
+a scripting language." Upon hearing this, the ircII client luser fell silent.
+
+
+-----
+The master Wumpus said: "Time for you to leave. I did, now I'm happy."
+The master Gnarfer replied: "Use, but never overuse IRC, then you will also
+be happy within IRC"
+
+
+-----
+A luser came unto the masters of #EU-Opers and asked, "How can I be, yet not
+be, a user@host within the IRC?"
+The masters of #EU-Opers replied: "To be Tao is to be ones true self. To hide
+ones self is not Tao, and is not IRC, you have much to learn before you shall
+be at rest within the Flow of Irc. Please leave"
+
--- /dev/null
+------------------------------------------------------
+- Oper Challenge/Response System Documentation -
+- Copyright (C) 2006 Lee Hardy <lee -at- leeh.co.uk> -
+- Copyright (C) 2006 ircd-ratbox development team -
+------------------------------------------------------
+
+The challenge/response system allows the ability to oper though public key
+authentication, without the insecurity of oper passwords.
+
+The challenge system documented here was redesigned in
+ircd-ratbox-2.2/charybdis-1.1 and is not compatible with earlier versions.
+
+This document does not describe the technical details of the challenge
+system. If you are reading this as part of the ircd distribution, the
+programs referred to are contained in ratbox-respond, see
+http://respond.ircd-ratbox.org for more information and downloads.
+
+
+- Challenge basics -
+--------------------
+When a user requests a challenge to oper up, the ircd takes some random
+data, encodes it using the opers public key, encodes this output in base64
+and sends it to the user as a challenge. The server then stores a hash of
+the original random data.
+
+The user must then decrypt the data using their private key and generate a
+hash of the decrypted data. Then the hash is base64 encoded and sent back
+to the server.
+
+If the stored hash the server has matches the reply from the client, they
+are opered up.
+
+
+- Generating a public/private keypair -
+---------------------------------------
+The first step is to use the makekeypair script to generate a public and
+private key. The public key is set in the ircd config (operator {};
+rsa_public_key_file) instead of a password, and the private key should
+be kept secret. It is highly recommended that the key is generated with
+a secure password. Generating keys without a password is fundamentally
+insecure.
+
+
+The commands used in makekeypair to generate keys are as follows:
+ openssl genrsa -out private.key -aes256 2048
+ openssl rsa -in private.key -out public.key -pubout
+
+If aes256 is not available, the following is used instead:
+ openssl genrsa -out private.key -des3 2048
+
+
+- Building ratbox-respond -
+---------------------------
+If you are using the unix based ratbox-respond this must be built. For the
+windows version, ratbox-winrespond, please see http://respond.ircd-ratbox.org
+
+ratbox-respond takes the challenge from the server, and together with your
+private key file generates a response to be sent back. ratbox-respond
+requires the openssl headers (ie, development files) and openssl libraries
+are installed for compilation.
+
+Change into the ratbox-respond directory, and run:
+ ./configure
+ make
+
+This will generate a 'ratbox-respond' binary, which you may place wherever
+you like. If configure does not detect your openssl installation, you may
+pass it the directory where it is installed to via --enable-openssl, this
+should be the base directory which has lib/ and include/openssl/ within it:
+ ./configure --enable-openssl=/path/to/opensslbase
+
+
+- Opering up -
+--------------
+Once you have your public key set in ircd and built ratbox-respond, you oper
+up by issuing "/challenge <opername>". You should then run:
+ /path/to/ratbox-respond /path/to/private.key
+and input the challenge. This will give you a response to paste back to the
+server. The ratbox-respond binary also accepts piped input, see
+ratbox-respond/README for more information.
+
+A number of scripts for clients have already been written to automate this
+process, see client-scripts/README for more information.
+
+--
+$Id: challenge.txt 678 2006-02-03 20:25:01Z jilles $
--- /dev/null
+Nick collision FNC
+Jilles Tjoelker <jilles -at- stack.nl>
+--------------------------------------
+
+Nick collision FNC performs a forced nick change to the user's UID instead
+of a kill. The criteria for which user may keep the nick are the same as
+before. Server notices will say the clients are being "saved" instead of
+"killed". The client will get a 043 numeric, like this:
+:<server> 043 <uid> :Nick collision, forcing nick change to your unique ID
+
+The following conditions must be fulfilled:
+
+- All servers on the network must allow remote nicks starting with a digit.
+ This is not checked; if this is not fulfilled, users will be killed right
+ after being FNCed.
+
+- All servers on the path between the two clients must support TS6 and
+ nick collision FNC (SAVE capab). If this is not fulfilled, the collision is
+ resolved with kills as before. (This uses the ENCAP GCAP data for remotes.)
+
+- The general::collision_fnc option must be enabled on the server(s) that
+ detect the collision.
+
+Technical details:
+
+The following message is used to propagate the nick change coming from the
+server that detected the collision:
+
+:<sid> SAVE <uid> <ts>
+
+The TS is compared to the current nick TS for the user; if it is not equal,
+the message is dropped. This prevents nick desyncs if the user changed their
+nick after being collided. A SAVE message also generates a server notice to
++k.
+
+The SAVE message is used for propagation to the target's server, and also
+in several other cases if the destination supports SAVE. In other cases, a
+normal nick change or introduction with the UID as nick is sent.
+
+--
+$Id: collision_fnc.txt 276 2005-10-02 20:23:15Z jilles $
--- /dev/null
+/* doc/example.conf - brief example configuration file
+ *
+ * Copyright (C) 2000-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis development team
+ *
+ * $Id: example.conf 3131 2007-01-21 15:36:31Z jilles $
+ *
+ * See reference.conf for more information.
+ */
+
+/* Extensions */
+#loadmodule "extensions/createauthonly.so";
+#loadmodule "extensions/extb_account.so";
+#loadmodule "extensions/extb_canjoin.so";
+#loadmodule "extensions/extb_channel.so";
+#loadmodule "extensions/extb_extgecos.so";
+#loadmodule "extensions/extb_oper.so";
+#loadmodule "extensions/extb_realname.so";
+#loadmodule "extensions/extb_server.so";
+#loadmodule "extensions/hurt.so";
+#loadmodule "extensions/ip_cloaking.so";
+#loadmodule "extensions/m_findforwards.so";
+#loadmodule "extensions/m_identify.so";
+#loadmodule "extensions/no_oper_invis.so";
+#loadmodule "extensions/sno_farconnect.so";
+#loadmodule "extensions/sno_globalkline.so";
+#loadmodule "extensions/sno_globaloper.so";
+
+serverinfo {
+ name = "hades.arpa";
+ use_ts6 = yes;
+ sid = "42X";
+ description = "charybdis test server";
+ network_name = "AthemeNET";
+ network_desc = "Your IRC network.";
+ hub = yes;
+
+ /* On multi-homed hosts you may need the following. These define
+ * the addresses we connect from to other servers. */
+ /* for IPv4 */
+ #vhost = "192.169.0.1";
+ /* for IPv6 */
+ #vhost6 = "3ffe:80e8:546::2";
+};
+
+admin {
+ name = "Lazy admin (lazya)";
+ description = "AthemeNET client server";
+ email = "nobody@127.0.0.1";
+};
+
+log {
+ fname_userlog = "logs/userlog";
+ #fname_fuserlog = "logs/fuserlog";
+ fname_operlog = "logs/operlog";
+ #fname_foperlog = "logs/foperlog";
+ fname_serverlog = "logs/serverlog";
+ fname_glinelog = "logs/glinelog";
+ #fname_klinelog = "logs/klinelog";
+ fname_killlog = "logs/killlog";
+ fname_operspylog = "logs/operspylog";
+ #fname_ioerrorlog = "logs/ioerror";
+};
+
+/* class {} blocks MUST be specified before anything that uses them. That
+ * means they must be defined before auth {} and before connect {}.
+ */
+class "users" {
+ ping_time = 2 minutes;
+ number_per_ident = 10;
+ number_per_ip = 10;
+ number_per_ip_global = 50;
+ cidr_bitlen = 64;
+ number_per_cidr = 8;
+ max_number = 3000;
+ sendq = 400 kbytes;
+};
+
+class "opers" {
+ ping_time = 5 minutes;
+ number_per_ip = 10;
+ max_number = 1000;
+ sendq = 1 megabyte;
+};
+
+class "server" {
+ ping_time = 5 minutes;
+ connectfreq = 5 minutes;
+ max_number = 1;
+ sendq = 4 megabytes;
+};
+
+listen {
+ /* If you want to listen on a specific IP only, specify host.
+ * host definitions apply only to the following port line.
+ */
+ #host = "192.169.0.1";
+ port = 5000, 6665 .. 6669;
+
+ /* Listen on IPv6 (if you used host= above). */
+ #host = "3ffe:1234:a:b:c::d";
+ #port = 5000, 6665 .. 6669;
+};
+
+/* auth {}: allow users to connect to the ircd (OLD I:)
+ * auth {} blocks MUST be specified in order of precedence. The first one
+ * that matches a user will be used. So place spoofs first, then specials,
+ * then general access, then restricted.
+ */
+auth {
+ /* user: the user@host allowed to connect. multiple IPv4/IPv6 user
+ * lines are permitted per auth block.
+ */
+ user = "*@172.16.0.0/12";
+ user = "*test@123D:B567:*";
+
+ /* password: an optional password that is required to use this block.
+ * By default this is not encrypted, specify the flag "encrypted" in
+ * flags = ...; below if it is.
+ */
+ password = "letmein";
+
+ /* spoof: fake the users user@host to be be this. You may either
+ * specify a host or a user@host to spoof to. This is free-form,
+ * just do everyone a favour and dont abuse it. (OLD I: = flag)
+ */
+ spoof = "I.still.hate.packets";
+
+ /* Possible flags in auth:
+ *
+ * encrypted | password is encrypted with mkpasswd
+ * spoof_notice | give a notice when spoofing hosts
+ * exceed_limit (old > flag) | allow user to exceed class user limits
+ * kline_exempt (old ^ flag) | exempt this user from k/g/xlines&dnsbls
+ * dnsbl_exempt | exempt this user from dnsbls
+ * gline_exempt (old _ flag) | exempt this user from glines
+ * spambot_exempt | exempt this user from spambot checks
+ * shide_exempt | exempt this user from serverhiding
+ * jupe_exempt | exempt this user from generating
+ * warnings joining juped channels
+ * resv_exempt | exempt this user from resvs
+ * flood_exempt | exempt this user from flood limits
+ * USE WITH CAUTION.
+ * no_tilde (old - flag) | don't prefix ~ to username if no ident
+ * need_ident (old + flag) | require ident for user in this class
+ * need_sasl | require SASL id for user in this class
+ */
+ flags = kline_exempt, exceed_limit;
+
+ /* class: the class the user is placed in */
+ class = "opers";
+};
+
+auth {
+ user = "*@*";
+ class = "users";
+};
+
+operator "god" {
+ /* name: the name of the oper must go above */
+
+ /* user: the user@host required for this operator. CIDR *is*
+ * supported now. auth{} spoofs work here, other spoofs do not.
+ * multiple user="" lines are supported.
+ */
+ user = "*god@127.0.0.1";
+
+ /* password: the password required to oper. Unless ~encrypted is
+ * contained in flags = ...; this will need to be encrypted using
+ * mkpasswd, MD5 is supported
+ */
+ password = "etcnjl8juSU1E";
+
+ /* rsa key: the public key for this oper when using Challenge.
+ * A password should not be defined when this is used, see
+ * doc/challenge.txt for more information.
+ */
+ #rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
+
+ /* umodes: the specific umodes this oper gets when they oper.
+ * If this is specified an oper will not be given oper_umodes
+ * These are described above oper_only_umodes in general {};
+ */
+ #umodes = locops, servnotice, operwall, wallop;
+
+ /* snomask: specific server notice mask on oper up.
+ * If this is specified an oper will not be given oper_snomask.
+ */
+ snomask = "+Zbfkrsuy";
+
+ /* privileges: controls the activities and commands an oper is
+ * allowed to do on the server. You may prefix an option with ~ to
+ * disable it, ie ~operwall
+ *
+ * Default flags are operwall, remoteban and encrypted.
+ *
+ * Available options:
+ *
+ * encrypted: the password above is encrypted [DEFAULT]
+ * local_kill: allows local users to be /KILL'd
+ * global_kill: allows local and remote users to be
+ * /KILL'd (OLD 'O' flag)
+ * remote: allows remote SQUIT and CONNECT (OLD 'R' flag)
+ * kline: allows KILL, KLINE and DLINE (OLD 'K' flag)
+ * unkline: allows UNKLINE and UNDLINE (OLD 'U' flag)
+ * gline: allows GLINE (OLD 'G' flag)
+ * nick_changes: allows oper to see nickchanges (OLD 'N' flag)
+ * via usermode +n
+ * rehash: allows oper to REHASH config (OLD 'H' flag)
+ * die: allows DIE and RESTART (OLD 'D' flag)
+ * admin: gives admin privileges. admins
+ * may (un)load modules and see the
+ * real IPs of servers.
+ * hidden_admin: gives admin privileges except
+ * will not have the admin lines in
+ * stats p and whois.
+ * xline: allows use of /quote xline/unxline
+ * operwall: allows the oper to send operwalls [DEFAULT]
+ * oper_spy: allows 'operspy' features to see through +s
+ * channels etc. see /quote help operspy
+ * hidden_oper: hides the oper from /stats p (OLD UMODE +p)
+ * remoteban: allows remote kline etc [DEFAULT]
+ */
+ flags = global_kill, remote, kline, unkline, gline,
+ die, rehash, admin, xline, operwall;
+};
+
+connect "irc.uplink.com" {
+ host = "192.168.0.1";
+ send_password = "password";
+ accept_password = "anotherpassword";
+ port = 6666;
+ hub_mask = "*";
+ class = "server";
+ flags = compressed, topicburst;
+
+ /* If the connection is IPv6, uncomment below */
+ #aftype = ipv6;
+};
+
+service {
+ name = "services.int";
+};
+
+cluster {
+ name = "*";
+ flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
+};
+
+shared {
+ oper = "*@*", "*";
+ flags = all, rehash;
+};
+
+/* exempt {}: IPs that are exempt from Dlines. (OLD d:) */
+exempt {
+ ip = "127.0.0.1";
+};
+
+channel {
+ use_invex = yes;
+ use_except = yes;
+ use_knock = yes;
+ use_forward = yes;
+ invite_ops_only = yes;
+ knock_delay = 5 minutes;
+ knock_delay_channel = 1 minute;
+ max_chans_per_user = 15;
+ max_bans = 100;
+ max_bans_large = 500;
+ default_split_user_count = 0;
+ default_split_server_count = 0;
+ no_create_on_split = no;
+ no_join_on_split = no;
+ burst_topicwho = yes;
+ kick_on_split_riding = no;
+};
+
+serverhide {
+ flatten_links = yes;
+ links_delay = 5 minutes;
+ hidden = no;
+ disable_hidden = no;
+};
+
+/* These are the blacklist settings.
+ * You can have multiple combinations of host and rejection reasons.
+ * They are used in pairs of one host/rejection reason.
+ *
+ * These settings should be adequate for most networks, and are (presently)
+ * required for use on AthemeNet.
+ *
+ * Word to the wise: Do not use blacklists like SPEWS for blocking IRC
+ * connections.
+ *
+ * Note: AHBL (the providers of the below BLs) request that they be
+ * contacted, via email, at admins@2mbit.com before using these BLs.
+ * See <http://www.ahbl.org/services.php> for more information.
+ */
+#blacklist {
+# host = "ircbl.ahbl.org";
+# reject_reason = "You have a host listed in the ircbl.ahbl.org blacklist.";
+#
+# host = "tor.ahbl.org";
+# reject_reason = "You are connecting from a TOR exit node.";
+#};
+
+alias "NickServ" {
+ target = "NickServ";
+};
+
+alias "ChanServ" {
+ target = "ChanServ";
+};
+
+alias "OperServ" {
+ target = "OperServ";
+};
+
+alias "MemoServ" {
+ target = "MemoServ";
+};
+
+alias "NS" {
+ target = "NickServ";
+};
+
+alias "CS" {
+ target = "ChanServ";
+};
+
+alias "OS" {
+ target = "OperServ";
+};
+
+alias "MS" {
+ target = "MemoServ";
+};
+
+general {
+ hide_error_messages = opers;
+ hide_spoof_ips = yes;
+
+ /*
+ * default_umodes: umodes to enable on connect.
+ * If you have enabled the ip_cloaking module, and you want
+ * to make use of it, add +h to this option, i.e.:
+ * default_umodes = "+ih";
+ */
+ default_umodes = "+i";
+
+ default_operstring = "is an IRC Operator";
+ default_adminstring = "is a Server Administrator";
+ servicestring = "is a Network Service";
+ disable_fake_channels = no;
+ tkline_expire_notices = no;
+ default_floodcount = 10;
+ failed_oper_notice = yes;
+ dots_in_ident=2;
+ dot_in_ip6_addr = no;
+ min_nonwildcard = 4;
+ min_nonwildcard_simple = 3;
+ max_accept = 100;
+ max_monitor = 100;
+ anti_nick_flood = yes;
+ max_nick_time = 20 seconds;
+ max_nick_changes = 5;
+ anti_spam_exit_message_time = 5 minutes;
+ ts_warn_delta = 30 seconds;
+ ts_max_delta = 5 minutes;
+ client_exit = yes;
+ collision_fnc = yes;
+ global_snotices = yes;
+ dline_with_reason = yes;
+ kline_delay = 0 seconds;
+ kline_with_reason = yes;
+ kline_reason = "K-Lined";
+ identify_service = "NickServ@services.int";
+ identify_command = "IDENTIFY";
+ non_redundant_klines = yes;
+ warn_no_nline = yes;
+ stats_e_disabled = no;
+ stats_c_oper_only=no;
+ stats_h_oper_only=no;
+ stats_y_oper_only=no;
+ stats_o_oper_only=yes;
+ stats_P_oper_only=no;
+ stats_i_oper_only=masked;
+ stats_k_oper_only=masked;
+ map_oper_only = no;
+ operspy_admin_only = no;
+ operspy_dont_care_user_info = no;
+ caller_id_wait = 1 minute;
+ pace_wait_simple = 1 second;
+ pace_wait = 10 seconds;
+ short_motd = no;
+ ping_cookie = no;
+ connect_timeout = 30 seconds;
+ disable_auth = no;
+ no_oper_flood = yes;
+ glines = no;
+ gline_time = 1 day;
+ gline_min_cidr = 16;
+ idletime = 0;
+ max_targets = 4;
+ client_flood = 20;
+ use_whois_actually = no;
+ oper_only_umodes = operwall, locops, servnotice;
+ oper_umodes = locops, servnotice, operwall, wallop;
+ oper_snomask = "+s";
+ burst_away = yes;
+ nick_delay = 0 seconds; # 15 minutes if you want to enable this
+ reject_ban_time = 1 minute;
+ reject_after_count = 3;
+ reject_duration = 5 minutes;
+};
+
+modules {
+ path = "modules";
+ path = "modules/autoload";
+};
--- /dev/null
+Extended bans
+Jilles Tjoelker <jilles -at- stack.nl>
+--------------------------------------
+
+Extended bans (ban conditionals) allow different checks than the usual
+nick!user@host or nick!user@ip match to determine whether someone should
+be banned, quieted, exempted or invited.
+
+Extended bans are of the form $[~]<type>[:<data>]. The <type> is one
+character (case insensitive) and determines the type of match. Most types
+allow or require an extra field <data>. If the tilde (~) is present, the
+result of the comparison will be negated, unless the ban is invalid in which
+case it will never match. Invalid bans are ones where <data> is missing but
+required or where <data> is otherwise invalid as noted below.
+
+Unless noted below, all types can be used with +b, +q, +e and +I.
+
+If any extended ban types are loaded, they are listed in 005 (RPL_ISUPPORT)
+as EXTBAN=$:<types>.
+
+Local users cannot add extended bans of an unknown type or invalid bans. If a
+remote user adds an extended ban of an unknown type, the mode change is
+processed normally. Furthermore, extended bans of an unknown type can always be
+listed or removed.
+
+The ability to send to a channel is cached; this cache may not be updated
+if a condition for an extended ban changes. To work around this, part and
+rejoin the channel, or add or remove a +b, +q or +e entry.
+
+The extban types that come with charybdis are:
+
+extb_account.so
+ $a
+matches all logged in users
+ $a:<mask>
+matches users logged in with a username matching the mask (* and ? wildcards)
+
+extb_channel.so
+ $c:<channel>
+matches users who are on the given channel; this is only valid if the channel
+exists and is not +s or +p. (The ops of the channel the ban is on cannot
+necessarily see whether the user is in the target channel, so it should not
+influence whether they can join either.)
+
+extb_oper.so
+ $o
+matches opers (most useful with +I)
+
+extb_realname.so
+ $r:<mask>
+matches users with a realname (gecos) matching the mask (* and ? wildcards);
+this can only be used with +b and +q
+
+extb_server.so
+ $s:<mask>
+matches users connected to a server matching the mask (* and ? wildcards);
+this can only be used with +b and +q
+
+Comparisons:
+
++b $~a is similar to +r but also prevents not logged in users talking or
+changing their nick while on channel.
+
++iI $o is the same as +O in dreamforge-derived ircds.
+
+Creating extban types:
+
+extban_table, indexed by the extban character, contains function pointers
+of the following type:
+typedef int (*ExtbanFunc)(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type);
+
+The arguments are as follows:
+data: the text after the colon, NULL if there was no colon
+client_p: the client to check; this is always a local client, which may be
+on or off channel
+chptr: the channel
+mode_type: CHFL_BAN, CHFL_QUIET, CHFL_EXCEPTION or CHFL_INVEX
+
+The return value:
+EXTBAN_INVALID: the mask is invalid, it never matches even if negated and
+cannot be added; if this is returned for one client_p it must be returned
+for all
+EXTBAN_NOMATCH: the client_p does not match the mask
+EXTBAN_MATCH: the client_p matches the mask
+
+The function is called whenever a (local) client needs to be checked against
+a +bqeI entry of the given extban type, and whenever a local client tries to
+add such an entry. (Clients are allowed to add bans matching themselves.)
+
+--
+$Id: extban.txt 1639 2006-06-04 23:26:47Z jilles $
--- /dev/null
+Hook documentation - <lee -at- leeh.co.uk>
+------------------------------------------
+
+Documentation on how to actually develop code to use hooks is contained in
+contrib/example_module.c, this document simply describes which hooks are
+available.
+
+There are various hook structures available that may be passed to hooks:
+hook_data - struct Client *client; const void *arg1;
+ const void *arg2;
+hook_data_int - struct Client *client; const void *arg1; int arg2;
+hook_data_client - struct Client *client; struct Client *target;
+hook_data_channel - struct Client *client; struct Channel *chptr;
+
+
+Spy Hooks
+---------
+The following spy hooks are called only when the request is handled by the
+local server. They will not be called if the command is being sent remotely
+for another server to handle:
+"doing_admin" - Passes hook_data:
+ hdata->client = client requesting ADMIN
+
+"doing_info" - Passes hook_data:
+ hdata->client = client requesting INFO
+
+"doing_links" - Passes hook_data:
+ hdata->client = client doing LINKS
+ (const char *) hdata->arg1 = optional mask
+
+"doing_motd" - Passes hook_data:
+ hdata->client = client doing MOTD
+
+"doing_stats" - Passes hook_data_int:
+ hdata->client = client doing STATS
+ (const char *) hdata->arg1 = optional stats l target
+ (char) hdata->arg2 = statchar being requested
+
+"doing_stats_p" - Passes hook_data:
+ hdata->client = client doing STATS p
+
+"doing_trace" - Passes hook_data_client:
+ hdata->client = client doing TRACE
+ hdata->target = optional target of TRACE
+
+"doing_whois" - Passes hook_data_client:
+ hdata->client = local client doing WHOIS
+ hdata->target = target of WHOIS
+
+"doing_whois_global" - Passes hook_data_client:
+ hdata->client = remote client doing WHOIS
+ hdata->target = target of WHOIS
+
+
+Netburst Hooks
+--------------
+The following burst hooks are called when we are sending a netburst to a
+server.
+
+"burst_client" - Sent after we have just burst a user.
+ Passes hook_data_client:
+ hdata->client = server we are bursting to
+ hdata->target = user we have just burst
+
+"burst_channel" - Sent after we have just burst a channel.
+ Passes hook_data_channel:
+ hdata->client = server we are bursting to
+ hdata->chptr = channel we have just burst
+
+"burst_finished" - Sent after we have just finished bursting users/chans
+ Passes hook_data_client:
+ hdata->client = server we are bursting to
+
+
+Server Hooks
+------------
+The following hooks are called during server connects/exits.
+
+"server_eob" - Sent after a server finishes bursting to us.
+ Passes struct Client, the server that has
+ finished bursting.
+
+"server_introduced" - Sent after a server is introduced to the network,
+ local or remote.
+ Passes hook_data_client:
+ hdata->client = uplink server (&me if local)
+ hdata->target = server being introduced
+
+
+Client Hooks
+------------
+The following hooks are called during various events related to clients.
+
+"introduce_client" - Sent after introducing a client to the (rest of the)
+ network.
+ Passes hook_data_client:
+ hdata->client = server that introduced this client
+ hdata->target = client being introduced
+
+"new_local_user" - Sent just before introducing a new local user
+ to the network.
+ Passes struct Client, the client being introduced.
+
+"new_remote_user" - Sent just before introducing a new remote user
+ to the rest of the network.
+ Passes struct Client, the client being introduced.
+
+"umode_changed" - Sent each time a user's mode or snomask changes.
+ Passes hook_data_umode_changed:
+ client = client whose modes are changing
+ oldumodes = new user mode field
+ oldsnomask = new snomask field
+
+
+The following are for debugging and take struct hook_io_data for arguments.
+These can be used for a variety of purposes, but are aimed at the developer
+community.
+"iosend"
+"iorecv"
+"iorecvctrl"
+
+$Id: hooks.txt 710 2006-02-06 03:10:01Z gxti $
--- /dev/null
+
+# $Id: index.txt 6 2005-09-10 01:02:21Z nenolod $
+Here is the overview of the documents in the doc/ directory.
+
+CIDR.txt - Description of CIDR in IPv4
+Tao-of-IRC.940110 - No comment...
+challenge.txt - Overview of the challenge/response system for
+ obtaining operator status
+example.conf - An example ircd.conf file describing most of the
+ user settable options
+guidelines.txt - Documentation guidelines
+hooks.txt - Overview of the hooks available
+index.txt - This file
+ircd.8 - The new revised manpage, read with the following
+ commands in the prefix directory:
+ man -M . ircd
+ircd.motd - A default ircd.motd used by make install
+logfiles.txt - Description of formatting of some logfiles
+modeg.txt - An in depth description of the server side silence
+ user mode (+g)
+modes.txt - A list of all user and channel modes
+operguide.txt - EFnet operator's guide
+opermyth.txt - Oper myth's, describes what opers can and cannot do
+server-version-info - Overview of the flags shown in /version
+whats-new.txt - What new features are available
+
+Also in the contrib/ directory you will find:
+example_module.c - An example module, detailing what the code in a module
+ does. Useful for building your own modules.
--- /dev/null
+.\" @(#)ircd.8 2.0 22 April 2004
+.\" $Id: ircd.8 6 2005-09-10 01:02:21Z nenolod $
+.TH IRCD 8 "ircd-ratbox 22 April 2004
+.SH NAME
+ircd \- The Internet Relay Chat Program Server
+.SH SYNOPSIS
+.hy 0
+.IP \fBircd\fP
+[-dlinefile filename] [-configfile filename] [-klinefile filename]
+[-logfile filename] [-pidfile filename] [-resvfile filename]
+[-xlinefile filename] [-conftest] [-foreground] [-version]
+.SH DESCRIPTION
+.LP
+\fIircd\fP is the server (daemon) program for the Internet Relay Chat
+Program. The \fIircd\fP is a server in that its function is to "serve"
+the client program \fIirc(1)\fP with messages and commands. All commands
+and user messages are passed directly to the \fIircd\fP for processing
+and relaying to other ircd sites.
+.SH OPTIONS
+.TP
+.B \-dlinefile filename
+Specifies the D-line file to be used. This file is used for both reading
+D-lines at startup, and writing to while \fIircd\fP is running.
+.TP
+.B \-configfile filename
+Specifies the ircd.conf file to be used for this ircdaemon. The option
+is used to override the default ircd.conf given at compile time.
+.TP
+.B \-klinefile filename
+Specifies the K-line file to be used. This file is used for both reading
+K-lines at startup, and writing to while \fIircd\fP is running.
+.TP
+.B \-logfile filename
+Specifies an alternative logfile to be used than that specified in config.h
+.TP
+.B \-pidfile filename
+Specifies the ircd.pid used. The option is used to override the default
+ircd.pid given at compile time.
+.TP
+.B \-resvfile filename
+Specifies the resv.conf file to be used for this ircdaemon. The option
+is used to override the default resv.conf given at compile time.
+.TP
+.B \-xlinefile filename
+Specifies the xline.conf file to be used for this ircdaemon. The option
+is used to override the default xline.conf given at compile time.
+.TP
+.B \-conftest
+Makes \fIircd\fP check the ircd.conf for errors
+.TP
+.B \-foreground
+Makes \fIircd\fP run in the foreground
+.TP
+.B \-version
+Makes \fIircd\fP print its version, and exit.
+.SH USAGE
+If you plan to connect your \fIircd\fP server to an existing Irc-Network,
+you will need to alter your local IRC configuration file (typically named
+"ircd.conf") so that it will accept and make connections to other \fIircd\fP
+servers. This file contains the hostnames, Network Addresses, and sometimes
+passwords for connections to other ircds around the world. Because
+description of the actual file format of the "ircd.conf" file is beyond the
+scope of this document, please refer to the file INSTALL in the IRC source
+files documentation directory.
+.LP
+.SH BOOTING THE SERVER
+The \fIircd\fP server can be started as part of the
+Unix boot procedure or just by placing the server into Unix Background.
+Keep in mind that if it is \fBnot\fP part of your Unix's boot-up procedure
+then you will have to manually start the \fIircd\fP server each time your
+Unix is rebooted. This means if your Unix is prone to crashing
+or going for for repairs a lot it would make sense to start the \fIircd\fP
+server as part of your UNIX bootup procedure.
+.SH EXAMPLE
+.RS
+.nf
+tolsun% \fBbin/ircd\fP
+.fi
+.RE
+.LP
+Places \fIircd\fP into Unix background and starts up the server for use.
+Note: You do not have to add the "&" to this command, the program will
+automatically detach itself from tty.
+.RS
+.nf
+leguin% \fBbin/ircd -foreground\fP
+.fi
+.RE
+.LP
+Runs ircd in the foreground.
+.RS
+.nf
+.SH COPYRIGHT
+(c) 1988,1989 University of Oulu, Computing Center, Finland,
+.LP
+(c) 1988,1989 Department of Information Processing Science,
+University of Oulu, Finland
+.LP
+(c) 1988,1989,1990,1991 Jarkko Oikarinen
+.LP
+(c) 1997,1998,1999,2000,2001 The IRCD-Hybrid project.
+.LP
+For full COPYRIGHT see LICENSE file with IRC package.
+.LP
+.RE
+.SH FILES
+ "ircd.conf"
+.SH "SEE ALSO"
+ircd.conf(5)
+.SH BUGS
+None... ;-) if somebody finds one, please inform author
+.SH AUTHOR
+irc2.8 and earlier: Jarkko Oikarinen, currently jto@tolsun.oulu.fi.
+.LP
+ircd-hybrid-7: IRCD-Hybrid Project, ircd-hybrid@the-project.org.
+.LP
+manual page written by Jeff Trim, jtrim@orion.cair.du.edu,
+later modified by jto@tolsun.oulu.fi.
+.LP
+modified for ircd-hybrid-7 by Edward Brocklesby, ejb@klamath.uucp.leguin.org.uk.
+.LP
+updated by W. Campbell, wcampbel@botbay.net
--- /dev/null
+This is charybdis MOTD you might replace it, but if not your friends will
+laugh at you.
--- /dev/null
+ircd-ratbox logfiles - Lee H <lee -at- leeh.co.uk>
+$Id: logfiles.txt 6 2005-09-10 01:02:21Z nenolod $
+---------------------------
+
+fname_killlog
+-------------
+<date> <time> <token> <source> <target> <targets server> <reason>
+
+Where token is one of:
+ L = local oper, local target
+ G = local oper, remote target
+ R = remote oper, remote target
+ O = remote oper, local target
+ S = server
+
+fname_glinelog
+--------------
+<date> <time> <token> <src nick> <src username> <src host> <src server> <user> <host> <reason>
+
+Where token is one of:
+ R = gline request
+ T = gline trigger, always by previous three requests
+
+fname_klinelog
+--------------
+<date> <time> [U]<token> <source> <time> <info> <reason>[|<oper_reason>]
+
+Time is always in minutes, 0 for permanent
+
+
+If 'U' is specified before token, it is a removal rather than an addition.
+Token is one of:
+ K = kline
+ D = dline
+ X = xline
+ R = resv
--- /dev/null
+ User Mode +g Documentation
+
+Hybrid 7 includes a new and power feature that all users can take advantage
+of to help prevent flooding and unwanted messages. This new feature is
+invoked by setting user mode +g. When a client is set +g, that user will
+be in "Caller ID" mode. Any user that messages a +g client will receive
+a notice saying that they are in +g (server side ignore) mode. The target
+client (who is set +g) will also receive a notice saying that so and so
+messaged them, and that they are in +g mode.
+
+The target of the message will only receive one notification per minute, from
+any client, in order to help prevent flooding. The sender will NOT have the
+rate limit, and will receive a notice saying the target is in +g mode every
+time they send a message. Note that this behavior is similar to the way AWAY
+messages are done.
+
+There are numerous benefits for both opers and regular users, including the
+ability to stop spambot messages from ever reaching your client, stopping
+private message and CTCP floods, and being able to sit on IRC in privacy.
+
+One question that arises is how to message specific users, while blocking
+out everyone else. The command ACCEPT is your answer. To add a user to
+your accept list, issue the raw command ACCEPT <nick>,<nick>,<nick>,...
+
+You will not receive a reply from the ACCEPT command if it is succesful,
+only if an error has occured. There are three possible errors, shown by
+numerics:
+
+ ERR_ACCEPTFULL (456): :irc.server 456 client :Accept list is full
+ - This is sent when an accept list is full.
+ ERR_ACCEPTEXIST (457): :irc.server 457 client target :already exists
+ - This is sent when a client tries to add a user to the accept list
+ that already exists there
+ ERR_ACCEPTNOT (458): :irc.server 458 client target :doesnt exist
+ - This is sent when a client tries to remove a user from their accept
+ list who is not on the accept list.
+
+That user will now be able to send messages to your client until the
+association is broken.
+
+Associations break in one of the following situations: when an accepted user
+QUIT's (or is on the other side of a split), you QUIT, or the accepted user
+changes their nick. The reason why a remote user's nick change will remove
+them from your accept list is so that you cannot track a user after they
+changed their nick.
+
+Viewing the accept list is also very easy. Issue the raw command ACCEPT *.
+Removing a user from your accept list is also simple. Issue the command
+ACCEPT -<nick>.
+
+ Sample Session
+
+The easiest way to see how this works is by experiencing it. Seeing a sample
+session can help understand what goes on though.
+
+Client Hwy-LL is set +g initially.
+Client Hwy101 wants to message Hwy-LL
+
+Note that some clients may have to use /quote ACCEPT instead of /accept.
+
+--
+
+Client Hwy101: /msg Hwy-LL hi
+Hwy101 will see: -Hwy-LL- *** I'm in +g mode (server side ignore).
+ -Hwy-LL- *** I've been informed you messaged me.
+
+Hwy-LL will see: Client Hwy101 [wcampbel@admin.irc.monkie.org] is messaging
+ you and you are +g
+
+The sender will receive the NOTICE from the target of the message, while
+the recipient will receive the NOTICE from the server.
+
+--
+
+If Hwy101 sends another message to Hwy-LL (before the minute expires), he will
+see: -Hwy-LL- *** I'm in +g mode (server side ignore).
+and will not receive the second notice
+
+Hwy-LL will NOT see any notice.
+
+--
+
+Hwy-LL now wishes to see messages from Hwy101 and SpamBot
+
+Client Hwy-LL: /accept Hwy101,SpamBot
+
+Neither side will be told of the change in the accept list, Hwy-LL should
+presume that the accept was succesful if no error occurs.
+
+Now Hwy-LL can see messages from Hwy101 and SpamBot without any blockage.
+If Hwy101 was also set +g, then he would have to issue /accept Hwy-LL
+before he would be able to see messages from Hwy-LL.
+
+--
+
+Hwy-LL now wants to see who is on his accept list.
+
+Client Hwy-LL: /accept *
+
+Hwy-LL will see:
+ irc.server 281 Hwy-LL Hwy101 SpamBot
+ irc.server 282 Hwy-LL :End of /ACCEPT list
+
+The replies are in numeric form to help parsing by scripts.
+--
+
+Hwy-LL realises he added a spambot to his list, and wants to remove it, and
+allow messages from services
+
+Client Hwy-LL: /accept -SpamBot,services
+
+Hwy-LL will now only accept messages from Hwy101 and services.
+
+--
+
+The nicks to be added can be in ANY order, however you cannot add or remove
+AND list.
+ /ACCEPT x,y,-z,f,-a would be acceptable.
+ /ACCEPT x,y,-z,* would ignore the * and generate an invalid nick
+ response.
+
+Like Dalnet and Undernet's SILENCE system, the accept list only exists while
+you are connected to IRC. In order for you to have the same accept list
+every time you come onto IRC, you must put the accept commands into your
+client's auto-perform, or manually issue the commands each time.
+
+This system may seem similar to the SILENCE system, but it is actually a
+reverse SILENCE. SILENCE ignores certain users and allows the rest. Mode
++g ignores all users except certain ones (on your accept list.) Both systems
+have their place, but the mode +g in Hybrid 7 is what the developers thought
+would be most useful for clients.
+
+The goals of this user mode is to provide protection from flooding and
+spamming, and to provide users with a means to keep their privacy.
+
+We hope that these goals are obtained.
+
+--
+W. Campbell
+$Id: modeg.txt 6 2005-09-10 01:02:21Z nenolod $
--- /dev/null
+Standard user modes are listed in help/opers/umode
+Standard server notice masks are listed in help/opers/snomask
+Standard channel modes are listed in help/opers/cmode
+
+The sgml docs have more detailed descriptions.
+
+User mode +h (hide hostname) is provided by contrib/ip_cloaking.so
+Server notice mask +F (far connects) is provided by contrib/sno_farconnect.so
+
+# $Id: modes.txt 996 2006-03-09 01:14:34Z jilles $
--- /dev/null
+MONITOR - Protocol for notification of when clients become online/offline
+ Lee Hardy <lee -at- leeh.co.uk>
+$Id: monitor.txt 6 2005-09-10 01:02:21Z nenolod $
+-------------------------------------------------------------------------
+
+Currently, ISON requests by clients use a large amount of bandwidth. It is
+expected that it is more efficient for this to be done by the server at the
+expense of cpu cycles. The WATCH implementation that was designed to counter
+this is (in my opinion) severely flawed. This protocol was designed to
+provide a cleaner implementation.
+
+The command used throughout this specification is "MONITOR".
+
+Each use of the MONITOR command takes a special modifier, indicating
+the operation being performed. The client MUST NOT attempt to specify
+more than one modifier. Only one special modifier may be used per MONITOR
+command.
+
+Thus it is impossible to combine additions to the list with removals from
+the list -- these MUST be done with two seperate commands.
+
+A client MUST NOT issue the MONITOR command more than once per second.
+Any attempts to do so will generate an error.
+
+In commands and numerics where multiple nicknames may occur, the length of
+the nickname list is limited only by the buffer size of 512 chars, as
+defined in RFC1459.
+
+Support of this specification is indicated by the MONITOR token in
+RPL_ISUPPORT (005). This token takes an optional parameter, of the maximum
+amount of nicknames a client may have in their monitor list. If no
+parameter is specified, there is no limit. A typical token would be:
+MONITOR=100
+
+MONITOR + nick[,nick2]*
+-----------------------
+Adds the given list of nicknames to the list of nicknames being monitored.
+
+If any of the nicknames being added are online, the server will generate
+RPL_MONONLINE numerics listing those nicknames that are online.
+
+If any of the nicknames being added are offline, the server will generate
+RPL_MONOFFLINE numerics listing those nicknames that are offline.
+
+MONITOR - nick[,nick2]*
+-----------------------
+Removes the given list of nicknames from the list of nicknames being
+monitored. No output will be returned for use of this command.
+
+MONITOR C
+---------
+Clears the list of nicknames being monitored. No output will be returned
+for use of this command.
+
+MONITOR L
+---------
+Outputs the current list of nicknames being monitored. All output will use
+RPL_MONLIST, and the output will be terminated with RPL_ENDOFMONLIST
+
+MONITOR S
+---------
+Outputs for each nickname in the list being monitored, whether the client is
+online or offline. All nicks that are online will be sent using
+RPL_MONONLINE, all nicks that are offline will be sent using RPL_MONOFFLINE.
+The list will be terminated with RPL_ENDOFMONLIST.
+
+
+Numeric replies
+---------------
+
+730 - RPL_MONONLINE
+-------------------
+:<server> 730 <nick> :nick!user@host[,nick!user@host]*
+
+This numeric is used to indicate to a client that either a nickname has just
+become online, or that a nickname they have added to their monitor list is
+online.
+
+731 - RPL_MONOFFLINE
+--------------------
+:<server> 731 <nick> :nick[,nick1]*
+
+This numeric is used to indicate to a client that either a nickname has just
+left the irc network, or that a nickname they have added to their monitor
+list is offline.
+
+The argument is a chained list of nicknames that are offline.
+
+732 - RPL_MONLIST
+-----------------
+:<server> 732 <nick> :nick[,nick1]*
+
+This numeric is used to indicate to a client the list of nicknames they have
+in their monitor list.
+
+733 - RPL_ENDOFMONLIST
+------------------------
+:<server> 733 <nick> :End of MONITOR list
+
+This numeric is used to indicate to a client the end of a monitor list.
+
+734 - ERR_MONLISTFULL
+---------------------
+:<server> 734 <nick> <limit> <nicks> :Monitor list is full.
+
+This numeric is used to indicate to a client that their monitor list is
+full, so the command failed. The <limit> parameter is the maximum number of
+nicknames a client may have in their list, the <nicks> parameter is the list
+of nicknames, as the client sent them, that cannot be added.
+
+
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, doc/AUTHORS
+ * Copyright (C) 1990
+ *
+ * AUTHORS FILE:
+ * This file attempts to remember all contributors to the IRC
+ * developement. Names can be only added this file, no name
+ * should never be removed. This file must be included into all
+ * distributions of IRC and derived works.
+ *
+ * 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.
+ */
+
+IRC was conceived of and written by Jarkko Oikarinen <jto@tolsun.oulu.fi>.
+IRC was originally written in University of Oulu, Computing Center.
+Jan 1991 - IRC 2.6 jto@tolsun.oulu.fi
+ - Multiple Channels and protocol changes
+
+Contributions were made by a cast of dozens, including the following:
+
+Markku Jarvinen <mta@tut.fi>: Emacs-like editing facility for the client
+
+Kimmo Suominen <kim@kannel.lut.fi>: HP-UX port
+
+Jeff Trim <jtrim@orion.cair.du.edu>: enhancements and advice
+
+Vijay Subramaniam <vijay@lll-winken.llnl.gov>: advice and ruthless publicity
+
+Karl Kleinpaste <karl@cis.ohio-state.edu>: user's manual
+
+Greg Lindahl <gl8f@virginia.edu>: AUTOMATON code, the Wumpus GM automaton,
+myriad bug fixes
+
+Bill Wisner <wisner@hayes.fai.alaska.edu>: numerous bug fixes and code
+enhancements
+
+Tom Davis <conslt16@zeus.unl.edu> and Tim Russell <russell@zeus.unl.edu>:
+VMS modifications
+
+Markku Savela <msa@tel4.tel.vtt.fi>: advice, support, and being the
+incentive to do some of our *own* coding. :)
+
+Tom Hopkins <hoppie@buengf.bu.edu>: bug fixes, quarantine lines,
+consolidation of various patches.
+
+Christopher Davis <ckd@cs.bu.edu>: EFnet/Anet gateway coding,
+many automata ;), documentation fixing.
+
+Helen Rose <hrose@cs.bu.edu>: documentation updating, and fixing.
+
+Tom Hinds <rocker@bucsf.bu.edu>: emacs client updating.
+
+Tim Miller <cerebus@bu-pub.bu.edu>: various server and client-breaking
+features.
+
+Darren Reed <avalon@coombs.anu.edu.au>: various bug fixes and enhancements.
+Introduced nickname and channelname hash tables into the server.
+
+The version 2.2 release was coordinated by Mike Bolotski
+<mikeb@salmon.ee.ubc.ca>.
+
+The version 2.4 release was coordinated by Markku Savela and
+Chelsea Ashley Dyerman
+
+The version 2.5.2 release was coordinated by Christopher Davis, Helen Rose,
+and Tom Hopkins.
+
+The versions 2.6.2, 2.7 and 2.8 releases were coordinated by Darren Reed.
+
+Contributions for the 2.8 release from the following people:
+Matthew Green <phone@coombs.anu.edu.au>
+Chuck Kane <ckane@ece.uiuc.edu>
+Matt Lyle <matt@oc.com>
+Vesa Ruokonen <ruokonen@lut.fi>
+
+Markku Savela <Markku.Savela@vtt.fi> / April 1990
+Fixed various bugs in 2.2PL1 release server (2.2msa.4) and changed
+sockets to use non-blocking mode (2.2msa.9). [I have absolutely
+nothing to do with clients :-]
+
+Chelsea Ashley Dyerman <chelsea@earth.cchem.berkeley.edu> / April 1990
+Rewrote the Makefiles, restructuring of source tree. Added libIrcd.a to
+the Makefile macros, numerous reformatting of server text messages, and
+added mkversion.sh to keep track of compilation statistics. Numerous
+bug fixes and enhancements, and co-coordinator of the 2.4 release.
+
+jarlek@ifi.uio.no added mail functions to irc.
+
+Armin Gruner <gruner@informatik.tu-muenchen.de> / May, June 1990:
+* Patched KILL-line feature for ircd.conf, works now.
+ Enhancement: Time intervals can be specified in passwd-field.
+ Result: KILL-Line is only active during these intervals
+* Patched PRIVMSG handling, now OPER can specify masks for sending
+ private messages, advantage: msg to all at a specified server or host.
+* Little tests on irc 2.5 alpha, fixed some little typos in client code.
+ Change: common/debug.c has been moved to ircd/s_debug.c, and a
+ irc/c_debug.c has been created, for the benefit that wrong server msg
+ are displayed if client does not recognize them. (strange, if a server
+ sends an 'unknown command', isn't it?)
+
+Tom Hopkins <hoppie@buengf.bu.edu> / September, October 1990:
+* Patched msa's K lines for servers (Q lines).
+* Consolidated several patches, including Stealth's logging patch.
+* Fixed several minor bugs.
+* Has done lots of other stuff that I can't seem to remember, but he
+ always works on code, so he has to have done alot more than three
+ lines worth. :)
+
+Thanks go to those persons not mentioned here who have added their advice,
+opinions, and code to IRC.
+
+Various modifications, bugreports, cleanups and testing by:
+
+Hugo Calendar <hugo@ucscb.ucsc.edu>
+Bo Adler <adler@csvax.cs.caltech.edu>
+Michael Sandrof <ms5n+@andrew.cmu.edu>
+Jon Solomon <jsol@cs.bu.edu>
+Jan Peterson <jlp@hamblin.math.byu.edu>
+Nathan Glasser <nathan@brokaw.lcs.mit.edu>
+Helen Rose <hrose@eff.org>
+Mike Pelletier <stealth@caen.engin.umich.edu>
+Basalat Ali Raja <gwydion@tavi.rice.edu>
+Eric P. Scott <eps@toaster.sfsu.edu>
+Dan Goodwin <fornax@wpi.wpi.edu>
+Noah Friedman <friedman@ai.mit.edu>
--- /dev/null
+
+EFnet Oper Guide
+Last update: 02-21-2002
+Written and maintained by Riedel
+E-Mail: dennisv@vuurwerk.nl
+
+ 1. Commands you should know about
+ 2. The client of your choice
+ 3. Your primary responsibilities
+ 4. Re-routing
+ 4.1 Re-routing other servers and remote connects
+ 5. Kills and klines
+ 6. Kill and K-Line requests
+ 7. Happy birthday!
+ 8. Security
+ 9. Know who your friends are
+10. The TCM bot
+11. Services
+12. G-Lines
+
+
+1. Commands you should know about
+
+ This is no longer covered here. IRCD-hybrid is changing too rapidly, so
+ this section would be outdated in no time ;) For an up-to-date version,
+ please download the latest hybrid at www.ircd-hybrid.org.
+
+
+2. The client of your choice
+
+ There are many IRC clients around for a wide variety of operating systems.
+ Being an IRC Operator doesn't *require* you to use a UNIX client, however
+ I personally prefer UNIX-based clients. If you're familiar with UNIX and
+ use UNIX for opering, I suggest ircII / epic. There are a lot of scripts
+ available for those two clients, and it's not that hard to write scripts
+ yourself to suite your needs. It is important that you know how to operate
+ your client, and familiarize yourself with the options and features. For
+ whatever client you chose this goes for any of them: You should be in
+ control of your client, instead of the client being in control of you.
+
+Resources :
+
+ www.mirc.co.uk - mIRC (MS-Windows)
+ www.irchelp.org - a variety of clients and scripts
+ ftp.blackened.com - several UNIX based clients available
+
+
+3. Your primary responsibilities
+
+ As an IRC Operator, you're responsible for maintaining the server on a
+ real-time basis. You represent your server, and you represent the network.
+ Irresponsible / rude / offensive / stupid behavior may discredit your server
+ and the network. You should focus on the task you were chosen for...
+ maintainance. Sounds simple, no? It means getting rid of users that abuse
+ the service, enforcing the server's policy and keeping the server linked.
+ Users will ask you questions, and expect you to know all the answers.. after
+ all, you're the oper!
+
+ Be prepared for users trying to fool you, sweet talk you into things you
+ don't want, lie and deceive. Most users are handling in good faith...
+ however, the abusers have learned how to manipulate opers. They have studied
+ the alien creature 'oper' for ages like biologists study animals. Be
+ paranoid, be curious and be suspicious. I can't stress the importancy of that
+ often enough.
+
+ Second priority has the network. You were not chosen to maintain the network
+ but you were chosen to maintain the server. However, you may want to be able
+ to reroute servers. If you see something broken, don't be afraid to fix it.
+ If you do, be sure you fix things and don't make it worse. Before you
+ step into routing, be sure you've familiarized yourself with the network's
+ topology, and be confident enough to perform such actions. (re)routing is
+ covered in the next chapter.
+
+ Opers on the network depend on a trusting relationship. You can usually take
+ the word from an oper. Other opers are considered -trusted-, however, there
+ are exceptions. Sometimes even opers lie to opers to get things done. Don't
+ be afraid to ask for proof of a certain statement, such as logs.
+ This doesn't mean you distrust the oper in question, but -you- and you alone
+ are responsible for your actions. You call the shots on your server, unless
+ your admin says otherwise.
+
+
+4. Re-routing
+
+ Re-routing is not hard, and it's not scary but it is important that you do it
+ right. The commands you'll use are SQUIT and CONNECT. First, a very simple
+ example. Let's say your server, irc.yourserver.com is lagged to it's uplink,
+ irc.uplink.com and you want to reroute your server. You have to think about
+ where you want your server to be linked, and you have to time your reroute.
+ An example topology :
+
+irc.yourserver.com ---- irc.uplink.com
+ | | \
+ B C D
+ / \
+ E F
+ / \
+ G H --- O
+ / | \ | \
+ I J K L M
+ \
+ N
+
+ In this case, you're uplinked by irc.uplink.com
+ irc.uplink.com also hubs B, C and D. Server B functions as hub for E and F;
+ F hubs G and H; H hubs L, M and O. G hubs I, J and K. M hubs N.
+ Your server is allowed to connect to server B, F and G. So you consider the
+ servers you're able to connect to. Is the lag caused by a server that uplinks
+ irc.uplink.com ? Use /stats ? irc.uplink.com to determine lag to the other
+ servers. If irc.uplink.com does not respond, the lag is to your uplink. If
+ so, you cannot be sure about the state of the other uplinks, so you'd have to
+ get on a remote server and determine lag by using /stats ? and /trace. For
+ example, you could connect to server N, and /trace yournick. Yournick, being
+ the nick on your server. You'll see which route it takes, and what the
+ problem server is. Example /trace output :
+
+S:[SERVER-N ] V:[2.8/hybrid] U:[SERVER-M ]
+S:[SERVER-M ] V:[2.8/hybrid] U:[SERVER-H ]
+S:[SERVER-H ] V:[2.8/hybrid] U:[SERVER-F ]
+S:[SERVER-F ] V:[2.8/hybrid] U:[SERVER-B ]
+S:[SERVER-B ] V:[2.8/hybrid] U:[irc.uplink.com ]
+S:[irc.uplink.com ] V:[2.8/hybrid] U:[irc.yourserver.com ]
+
+ The trace doesn't complete... server-b announces irc.uplink.com, and
+ irc.uplink.com announces your server. Your server should return something
+ like :
+
+S:[irc.yourserver.] OPER [yournick!user@yourhost]
+
+ If it doesn't, we know the lag is only between yourserver and uplink.
+ Usually if there is lag between your server and your uplink, the send-queue
+ rises. This is not always the case. Sometimes your server can write perfectly
+ to your uplink, but not reverse. That is called one sided lag.
+
+ We pick server B to link to. It means we have to SQUIT and CONNECT.
+ To unlink from irc.uplink.com and connect to SERVER_B we'd type:
+ /quote SQUIT irc.uplink.com :reroute
+ /connect SERVER_B
+
+ we *DON'T* SQUIT irc.yourserver.com... and I'll try to explain why:
+ If we wanted to remove hub M from the network, and with it N, we'd issue
+ a SQUIT M. An SQUIT follows a path, relays the SQUIT request to each server
+ in that path. Finally it reaches server H, which is the hub for M. Server H
+ sees the SQUIT and drops the link to M.
+
+ Now a different situation, we want to separate yourserver, uplink, C and D
+ from the rest of the network, in order to reroute. We'd have to SQUIT server
+ B, since we want the -uplink- of server B (being irc.uplink.com) to drop the
+ link to server B.
+
+ If you'd SQUIT irc.yourserver.com, you ask yourserver.com to drop the link to
+ itself, which is impossible. If you SQUIT irc.uplink.com, you ask yourserver
+ to drop the link to uplink, which is what we want to do.
+
+ After the SQUIT and CONNECT, the new situation looks like this :
+
+ irc.uplink.com
+ | | \
+ irc.yourserver.com -- B C D
+ / \
+ E F
+ / \
+ G H --- O
+ / | \ | \
+ I J K L M
+ \
+ N
+
+ If yourserver is a Hub, it makes the situation more complex, since your
+ actions have more impact.
+
+
+4.1 - Re-routing other servers and remote connects
+
+Example topology :
+
+ irc.uplink.com
+ | | \
+ irc.yourserver.com -- B C D
+ / \
+ E F
+ / \
+ G H --- O
+ / | \ | \
+ I J K L M
+ \
+ N
+
+ Let's say, hub H is way lagged to F, but G to F is fine... we want to reroute
+ H, and stick H to G.
+
+ We'd do :
+
+ /quote SQUIT serverh :re-routing you babe
+ /connect serverh 6667 serverg
+
+ A global wallops will be sent :
+ !serverg! Remote CONNECT serverh 6667 from ItsMe
+
+ When re-routing, always give the server some time to prevent nick collides.
+ When there is lag, people will connect to another server. When you SQUIT and
+ CONNECT to fast, a lot of those clients will be collided. Also, stick to your
+ territory. How enthusiastic you may be, you cannot route the world. If you're
+ an oper on the US side, stick to the US side when re-routing. Needless to
+ say, if you're EU, keep it to EU ;)
+
+
+5. Kills and klines
+
+ As an oper, you're given the incredible power *cough* of KILL and KLINE.
+ /kill nick reason disconnects a client from IRC with the specified reason.
+ A /quote kline *evil@*.dude.org :reason here bans the user from your server.
+ Abusive kills and klines may draw attacks to your server, so always consider
+ if a kline or kill is deserved. If the server gets attacked after a valid
+ kill or kline, well.. tough luck. You should never be 'afraid' to kline
+ anyone on your server. If it's a good reason, make it so. Even if you know
+ it may cause the server to be attacked. Maybe good to think about is this:
+ - if /ignore solves the problem rather than a kick, /ignore
+ - kick if a ban is unneeded
+ - ban if a /kill is unwarranted for
+ - kill rather than kline if that solves the problem
+ - kline when a server ban is really needed.
+
+ You kline a user when you absolutely don't want this user to use the service
+ your server is providing.
+
+ Crosskills (killing users on another server) are another issue. Some admins
+ don't care if users get /kill'ed off their server, for any reason or no
+ reason at all... and other admins are very anal about it. A good way to go
+ (IMO) is to issue a KILL if there is an absolute need for the target user to
+ be disconnected. If there are active opers on that server, let them handle
+ it. They'll be upset if you /kill a user off their server, without
+ contacting them. /stats p irc.server.here shows the active opers on a
+ particular server. Some opers have multiple o-lines and are not watching all
+ sessions. If you can't find an active oper on a server, you can
+ /quote operwall a request for opers from that server.
+
+ Ghost KILLs are another story, an often misunderstood one.
+ When you see a /KILL from an oper with the reason 'ghosted' they usually
+ KILL a client that's about to ping timeout. That is not what a ghost is!
+ To quote Dianora: "a ghost happens because a client misses being killed when
+ it should be. Its a race condition due to nick chasing". In other words,
+ Server X thinks client A has been KILLed, while server Y missed the KILL
+ for that client.
+
+
+6. Kill and K-Line requests
+
+ As previously mentioned, if an oper from another server contacts you and
+ requests a kill or a kline for a local client with a good reason, you can
+ usually trust this request. Opers depend on a trusting relationship. However,
+ since you're responsible for the kill or kline, it is not rude to ask for
+ proof. It depends on the oper making the request how thats interpreted, but
+ the way they respond to asking for proof tells more about them than about
+ you.
+
+ The more and longer you oper, how better you get to know the other opers.
+ You know who is honest, you'll know who are lying and deceiving. Before
+ you acquire this knowledge, you can merely rely on common sense and
+ instincts. You'll probably make mistakes occasionally, and thats nothing to
+ be ashamed of. Opers are - despite contrary believes - human.
+
+ Users occasionally will ask you to kill or kline a user/bot too. Some
+ requests are straight-forward and clear, others require you to be cautious. I
+ recommend to always investigate such requests, and when you're confident the
+ request is valid, issue the kill or kline.
+
+
+7. Happy birthday!
+
+ It is a custom on EFnet to birthday /kill opers of whom it is his/her
+ birthday. Not all opers like this, but typically those opers don't let
+ others know about their birthday. You'll notice that the KILLS say a lot
+ about who likes who and who is friends with who. Whether you want to
+ participate, is entirely up to you.
+
+
+8. Security
+
+ As with any privilege, you have to handle it cautiously and responsibly.
+ Be sure that your o/O line doesn't get compromised! Oper only from secure
+ hosts. You and only you should know your password. Don't share your oper
+ account, and make your oper password a UNIQUE one. If your o/O line gets
+ compromised, nasty things may/will happen. Imagine an oper with crosskill
+ capabilities who's operline gets 'hacked'... the results are often
+ disastrous and you will lose respect and trust from others. It can cause
+ your oper privileges to be revoked, or even the server to be (temporarily)
+ delinked.
+
+
+9. Know who your friends are
+
+ As an oper you will get a lot of users that want to be 'friends' with you.
+ Users offer you free* access to their *nix servers, ops in channels,
+ unlimited leech access to the biggest and fastest warez sites *gasp* and
+ more. They want favors in return. They say they don't but they truly want
+ something in return. They -expect- something in return. You could either
+ don't respond to such offers, or use them. The last option creates an even
+ more distorted image of opers and doesn't do any good for the user <-> oper
+ relationship. Your *real* friends are usually the persons who were your
+ friends _before_ you acquired the extra privileges.
+
+
+10. The TCM Bot
+
+ A TCM bot can be a valuable tool for opers. It keeps record of all connected
+ clients, flags clients with multiple connections and has all sorts of other
+ useful commands. There are three different kind of TCM's in use on EFnet,
+ being OOMon, TCM-Dianora and TCM-Hybrid. Every one of them requires you to
+ log in to be able to access the privileged commands. On OOMon you DCC chat
+ the TCM bot and do '.auth yournick yourpass' where yournick is your oper
+ name in your o/O line. In TCM-Dianora and TCM-Hybrid you register with:
+ '.register yourpass', where yourpass is your password ;)
+ All TCM commands start with a period. If you forget the period, the text goes
+ into the 'partyline', where it is echoed to all connected opers.
+
+ Resources : http://toast.blackened.com/oomon/help
+ http://www.db.net/~db/tcm.html
+
+
+11. Services
+
+ A recent addition to EFNet is Channel Fixer, aka ChanFix. This is an
+ automated service that re-ops clients on opless channels. There are a few
+ restrictions. First, the channel has to be of significant size for ChanFix
+ to store it in its database. Second, it only logs static addresses.
+
+ How does it work? Periodically it stores information about the channel state
+ in its database, for every channel in there. On every 'run', a channel
+ operator gets one point. These scores make a top-5 of 'most frequent opped
+ clients'. When a channel becomes opless, ChanFix will join and op the top-5
+ opped clients CURRENTLY IN THE CHANNEL.
+
+ Chanfix can be invoked manually by server administrators. /msg ChanFix
+ chanfix #channel is the command to do it. ChanFix will join, and treat the
+ channel as if it were opless. It lowers TS by one (resulting in a deop of
+ the entire channel) and re-ops the top-5 clients currently in the channel.
+ The Channel Fixer won't log or actively fix channels when there's a split of
+ significant size. Needless to say, the chanfix command must be used with
+ caution.
+
+
+12. G-Lines
+
+ Oh yes! A G-Line section. Currently, a part of EFNet (EU-EFnet) has G-Lines
+ enabled. This was decided by the EU admin community and is now mandatory
+ within EU-EFnet. In order for a G-Line to be activated, three opers from
+ three different servers need to issue the _exact_ same G-Line. The reason
+ is not counted.
+
+ G-Lines work best when the EU side of EFNet is not fragmented. G-Lines
+ will, however, propogate through a Hybrid 6 hub (but not a CSr hub) even
+ if the hub server has G-Lines disabled. This propogation allows two halves
+ of EU-EFnet to have concurrent G-Lines set even when split by US hub servers.
+
+
+ Questions / Comments / Suggestions are welcome.
+ You can e-mail me: dennisv@vuurwerk.nl
+
+Best regards,
+--
+Dennis "Riedel" Vink ___~___ Email - dennisv@vuurwerk.nl
+Unix System Administrator \ | / Phone - +31 23 5111111
+Vuurwerk Internet '|.|' PGP - 0xD68A7AAB
+
+And on the seventh day, He exited from append mode.
+
+# $Id: operguide.txt 6 2005-09-10 01:02:21Z nenolod $
--- /dev/null
+
+Date: Thu, 30 Jul 1998 16:21:40-0700 (MST)
+To: operlist@the-project.org
+From: rayp@primenet.com (Ray Powers)
+Subject: The myths of opers....
+
+I've always wanted to write something like this.. Its half rant, half
+fact, so bear with it. Hopefully it will be worth reading.
+
+There's a lot of hate for opers for a lot of reasons. Some are directly
+oper related (i.e. 99% of us are colossal assholes), some are directly
+user related (i.e. 99% of you are raving lunatics), and some is just plain
+misconceptions. I'd like to take a minute to talk about part three in
+hopes of clearing a few things up. This will kind of be in a FAQ form,
+maybe you'll like it, maybe not, but its worth a shot.
+
+Q: What can an oper on EFnet do.
+A: This is an EXACT list of what we can do:
+ 1) /squit a server, separating it from the rest of the net
+ 2) /die our server
+ 3) /kill a user, this disconnects them from the server they are on
+ 4) /kline a hostmask, this bans them from our server
+ 5) /dline an ip, this bans them from our server, regardless of
+ hostmask
+ 6) See all invisible users on our server
+ 7) Mass Msg/CTCP/notice a hostmask
+ 8) Mass Msg/CTCP/notice a server
+ 9) See and send Operwall/wallops notices
+
+That's it. We can see more server messages than you, but that's not the
+point.. The point to be shown here is very simple, *none* of these things
+have anything to do with channels. Which leads us to our next question.
+
+Q: What can opers *NOT* do, but keep being asked to anyways?
+A: We can *NOT*:
+ 1) Enter a channel that is +i or +k without being invited or
+ having the key
+ 2) See who is inside a +s channel
+ 3) Op ourselves or op you on a channel (unless of course we are a
+ channel op for that channel)
+ 4) Tell you what XXXX's new nick is since they changed it to hide
+ from you.
+ 5) Deop someone for you on a channel (unless of course we are a
+ channel op for that channel)
+
+Notice a trend, with the exception of 4, all of these are 100% channel
+related. EFnet is made so that opers have *NO* power of channels, for
+better or worse. If we don't help you with these requests, its not because
+we won't, its because we are completely incapable doing so. On the other
+hand....
+
+Q: What can opers do, but won't?
+A: This will be a bit differently done, because I figure I should explain
+ why opers don't do these things, when they may normally make sense.
+ 1) Why won't they kill somebody who has stolen your nick.
+ EFnet has gone on the basis of nicks not being owned, which is
+ why there is no nickserv on EFnet. Of course we see opers kill
+ all the time for nicks, though, so it seems rather hypocrital,
+ doesn't it?
+ An oper who kills for his nick will tell you its because the
+ other person was a bot, was juping his nick, or was imitating an
+ oper. It may be true, but it really comes down to the same
+ feeling you get when your nick is taken "Hey! that's my name! I
+ don't want that person using my name!"
+ I personally, do not kill for nicks. If someone takes my nick,
+ they can have it. Let them get my several hundred messages a day.
+ :P But the problem with the oper is this: How does an oper know
+ that you are really the person that uses that nick, or are you
+ the guy that wants to nick jupe that nick out from the real guy?
+ Unless the oper knows you well, they don't.. And saying that
+ people generally tell the truth means you haven't been on EFnet
+ very long.
+ I would prefer to think I am one of the more well respected
+ people on the net and people still lie to me on a regular basis.
+ So, the oper is stuck refusing to help because he can't tell who
+ is who. Remember this line of reasoning, its going to be coming
+ up a lot. :P
+ 2) Why won't they kill that guy nuking/smurfing/ping -f'ing me?
+ This one is simple. There is no way to prove that somebody is
+ doing any of these things to you from an opers point of view. All
+ logs are fakeable, and the oper has no way to firsthand prove its
+ happening. Your best bet in this situation is to log what you can
+ and complain loud and long to their ISPs.
+ 3) Why won't they help me take my channel back?
+ There's a bunch of answers to this. First, it is popular
+ opinion at EFnet that channels are not owned, and therefore, if
+ you lose a channel, you should go make another one. Notice I
+ say popular instead of official, because EFnet has never had an
+ "official" policy on much of anything.
+ But more and more you see opers killing for takeovers, so why
+ are they helping their channels and not yours.
+ Well, first, let's say your channel was taken over, and is now
+ +smtinlk. How exactly is the oper supposed to find out who is
+ oped in the channel right now to mass kill them? Even if they do get
+ all the nicks, they have to somehow manage to kill them all in
+ one hit, or they'll all just op each other again and it will be
+ fruitless. Or worse, they could have it all set up, and some
+ other oper could kill them halfway through because they don't
+ like mass-kills and it would be all ruined.
+ Or, let's say the mass-kill goes off, then the channel is
+ opless and generally speaking, chaos begins. People start
+ mass-nuking or flooding the channel to clear it out, or just to
+ be annoying. And there's still a 50/50 chance that takeover
+ people will get the channel back on a split and we'll have to try
+ to do it all over again.
+ If you're about to ask why they don't split their server,
+ the answer is very simple: We are not about to screw up roughly
+ 30,000 peoples chatting for your channel. Its rude. This of
+ course is all based on the fact that we can prove its taken over,
+ as per the conversation about nicks, we often can't.
+ 4) But.. its obvious they took it from me! The topic says
+ "Ha ha, we took your channel Rick!" for Pete's sake! And
+ there's only One op, so you can kill him and get the channel
+ back immediately!
+ This one is a bit more complex, but its really a personal
+ call. That one op could be a rampant smurfpup with a penis so
+ tiny he has no choice but to rampantly smurf and synflood anyone
+ that gets in his way. This is popularly known on irc as SPS, or
+ Small Penis Syndrome. In this case, if the oper does help you
+ out, they could end up with their server being downed for a day
+ or two, and it really isn't worth it for your channel, no
+ offense.
+
+Keep in mind that this is all spoken from the perspective of someone who
+*DOES* help with channels when possible, but understands greatly the
+reasons not to, and judges each situation very carefully.
+
+That's the gist of the information I was trying to get across. If you
+were cluefull enough to get on operlist, a lot of this may be common
+knowledge to you, but sometimes its good to step back and see why opers do
+what they do a lot of the time.
+
+Hoping this is of value to SOMEONE....
+
+Ray Powers
+Monkster/MimePunk/PrimeMonk/PacMonk/MtgMonk/Ihavefartoomanynickstonickjupe
+
--- /dev/null
+/* doc/reference.conf - charybdis Example configuration file
+ *
+ * Copyright (C) 2000-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis development team
+ *
+ * Written by ejb, wcampbel, db, leeh and others
+ *
+ * $Id: reference.conf 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+/* IMPORTANT NOTES:
+ *
+ * class {} blocks MUST be specified before anything that uses them. That
+ * means they must be defined before auth {} and before connect {}.
+ *
+ * auth {} blocks MUST be specified in order of precedence. The first one
+ * that matches a user will be used. So place spoofs first, then specials,
+ * then general access, then restricted.
+ *
+ * Both shell style (#) and C style comments are supported.
+ *
+ * Files may be included by either:
+ * .include "filename"
+ * .include <filename>
+ *
+ * Times/durations are written as:
+ * 12 hours 30 minutes 1 second
+ *
+ * Valid units of time:
+ * month, week, day, hour, minute, second
+ *
+ * Valid units of size:
+ * megabyte/mbyte/mb, kilobyte/kbyte/kb, byte
+ *
+ * Sizes and times may be singular or plural.
+ */
+
+/* Extensions:
+ *
+ * Charybdis contains several extensions that are not enabled by default.
+ * To use them, uncomment the lines below.
+ *
+ * Restrict channel creation to logged in users -- createauthonly.so
+ * Account bans (+b $a[:mask]) -- extb_account.so
+ * Banned from another channel (+b $j:mask) -- extb_canjoin.so
+ * Other-channel bans (+b $c:mask) -- extb_channel.so
+ * Extended ban (+b $x:mask) -- extb_extgecos.so
+ * Oper bans (+b $o) -- extb_oper.so
+ * Realname (gecos) bans (+b $r:mask) -- extb_realname.so
+ * Server bans (+b $s:mask) -- extb_server.so
+ * HURT system -- hurt.so
+ * Host mangling (umode +h) -- ip_cloaking.so
+ * Find channel forwards -- m_findforwards.so
+ * /identify support -- m_identify.so
+ * Opers cannot be invisible (umode +i) -- no_oper_invis.so
+ * Far connection notices (snomask +F) -- sno_farconnect.so
+ * Remote k/d/g/x line active notices -- sno_globalkline.so
+ * Remote oper up notices -- sno_globaloper.so
+ */
+#loadmodule "extensions/createauthonly.so";
+#loadmodule "extensions/extb_account.so";
+#loadmodule "extensions/extb_canjoin.so";
+#loadmodule "extensions/extb_channel.so";
+#loadmodule "extensions/extb_extgecos.so";
+#loadmodule "extensions/extb_oper.so";
+#loadmodule "extensions/extb_realname.so";
+#loadmodule "extensions/extb_server.so";
+#loadmodule "extensions/hurt.so";
+#loadmodule "extensions/ip_cloaking.so";
+#loadmodule "extensions/m_findforwards.so";
+#loadmodule "extensions/m_identify.so";
+#loadmodule "extensions/no_oper_invis.so";
+#loadmodule "extensions/sno_farconnect.so";
+#loadmodule "extensions/sno_globalkline.so";
+#loadmodule "extensions/sno_globaloper.so";
+
+/* serverinfo {}: Contains information about the server. (OLD M:) */
+serverinfo {
+ /* name: the name of our server */
+ name = "hades.arpa";
+
+ /* use ts6: whether we want to use the TS6 protocol to other servers
+ * or not.
+ */
+ use_ts6 = yes;
+
+ /* sid: the unique server id of our server. This must be three
+ * characters long. The first character must be a digit [0-9], the
+ * remaining two chars may be letters [A-Z] or digits [0-9].
+ *
+ * This must be specified even if use_ts6 is set to no.
+ */
+ sid = "42X";
+
+ /* description: the description of our server. '[' and ']' may not
+ * be used here for compatibility with older servers.
+ */
+ description = "charybdis test server";
+
+ /* network info: the name and description of the network this server
+ * is on. Shown in the 005 reply and used with serverhiding.
+ */
+ network_name = "MyNet";
+ network_desc = "This is My Network";
+
+ /* hub: allow this server to act as a hub and have multiple servers
+ * connected to it.
+ */
+ hub = no;
+
+ /* vhost: the IP to bind to when we connect outward to ipv4 servers.
+ * This should be an ipv4 IP only.
+ */
+ #vhost = "192.169.0.1";
+
+ /* vhost6: the IP to bind to when we connect outward to ipv6 servers.
+ * This should be an ipv6 IP only.
+ */
+ #vhost6 = "3ffe:80e8:546::2";
+};
+
+/* admin {}: contains admin information about the server. (OLD A:) */
+admin {
+ name = "Smurf target";
+ description = "Main Server Administrator";
+ email = "<syn@packets.r.us>";
+};
+
+/* log {}: contains information about logfiles. */
+log {
+ /* logfiles: the logfiles to use for specific activity. if these
+ * paths are defined, then ircd will log to them, otherwise it wont.
+ *
+ * The confs are, in order:
+ * - userlog: user exits
+ * - fuserlog: failed user connections
+ * - operlog: /oper usage
+ * - foperlog: failed /oper usage
+ * - serverlog: server connects/disconnects
+ * - glinelog: glines
+ * - klinelog: klines, etc
+ * - killlog: kills
+ * - operspylog: operspy usage
+ * - ioerrorlog: IO errors
+ */
+ fname_userlog = "logs/userlog";
+ #fname_fuserlog = "logs/fuserlog";
+ fname_operlog = "logs/operlog";
+ #fname_foperlog = "logs/foperlog";
+ fname_serverlog = "logs/serverlog";
+ fname_glinelog = "logs/glinelog";
+ #fname_klinelog = "logs/klinelog";
+ fname_killlog = "logs/killlog";
+ fname_operspylog = "logs/operspylog";
+ #fname_ioerrorlog = "logs/ioerror";
+};
+
+/* class {}: contain information about classes for users (OLD Y:) */
+class "users" {
+ /* class name must go above */
+
+ /* ping time: how often a client must reply to a PING from the
+ * server before they are dropped.
+ */
+ ping_time = 2 minutes;
+
+ /* number per ident: the number of users per user@host networkwide
+ * allowed to connect. Unidented connections are classified as
+ * the same ident.
+ */
+ number_per_ident = 2;
+
+ /* number per ip: the number of local users per host allowed */
+ number_per_ip = 3;
+
+ /* number per ip global: the number of network wide connections
+ * per host allowed for a user, including connections to the
+ * local server.
+ */
+ number_per_ip_global = 5;
+
+ /* cidr_bitlen: Limits numbers of connections from a subnet size
+ * the following example makes the subnet /64 this is useful
+ * for IPv6 connections in particular
+ * Also note that the way charybdis is written if you have
+ * compiled support for IPv6, IPv4 cidr bitlens need to be modified
+ * Basically to get the approriate length add 96 to the IPv4 length
+ * For example for a /24 do 96+24 = 120
+ *
+ */
+ cidr_bitlen = 64;
+
+ /* number_per_cidr: Number of connections to allow from a subnet of the
+ * size given in cidr_bitlen. 4 seems to be a good default to me.
+ */
+ number_per_cidr = 4;
+
+ /* max number: the maximum number of users allowed in this class */
+ max_number = 100;
+
+ /* sendq: the amount of data allowed in a clients queue before
+ * they are dropped.
+ */
+ sendq = 100 kbytes;
+};
+
+class "restricted" {
+ ping_time = 1 minute 30 seconds;
+ number_per_ip = 1;
+ max_number = 100;
+ sendq = 60kb;
+};
+
+class "opers" {
+ ping_time = 5 minutes;
+ number_per_ip = 10;
+ max_number = 100;
+ sendq = 100kbytes;
+};
+
+class "server" {
+ ping_time = 5 minutes;
+
+ /* connectfreq: only used in server classes. specifies the delay
+ * between autoconnecting to servers.
+ */
+ connectfreq = 5 minutes;
+
+ /* max number: the amount of servers to autoconnect to */
+ max_number = 1;
+
+ /* sendq: servers need a higher sendq as they are sent more data */
+ sendq=2 megabytes;
+};
+
+/* listen {}: contain information about the ports ircd listens on (OLD P:) */
+listen {
+ /* port: the specific port to listen on. if no host is specified
+ * before, it will listen on all available IPs.
+ *
+ * ports are seperated via a comma, a range may be specified using ".."
+ */
+
+ /* port: listen on all available IPs, ports 5000 and 6665 to 6669 */
+ port = 5000, 6665 .. 6669;
+
+ /* host: set a specific IP/host the ports after the line will listen
+ * on. This may be ipv4 or ipv6.
+ */
+ host = "1.2.3.4";
+ port = 7000, 7001;
+
+ host = "3ffe:1234:a:b:c::d";
+ port = 7002;
+};
+
+/* auth {}: allow users to connect to the ircd (OLD I:) */
+auth {
+ /* user: the user@host allowed to connect. multiple IPv4/IPv6 user
+ * lines are permitted per auth block.
+ */
+ user = "*@172.16.0.0/12";
+ user = "*test@123D:B567:*";
+
+ /* password: an optional password that is required to use this block.
+ * By default this is not encrypted, specify the flag "encrypted" in
+ * flags = ...; below if it is.
+ */
+ password = "letmein";
+
+ /* spoof: fake the users user@host to be be this. You may either
+ * specify a host or a user@host to spoof to. This is free-form,
+ * just do everyone a favour and dont abuse it. (OLD I: = flag)
+ */
+ spoof = "I.still.hate.packets";
+
+ /* Possible flags in auth:
+ *
+ * encrypted | password is encrypted with mkpasswd
+ * spoof_notice | give a notice when spoofing hosts
+ * exceed_limit (old > flag) | allow user to exceed class user limits
+ * kline_exempt (old ^ flag) | exempt this user from k/g/xlines&dnsbls
+ * dnsbl_exempt | exempt this user from dnsbls
+ * gline_exempt (old _ flag) | exempt this user from glines
+ * spambot_exempt | exempt this user from spambot checks
+ * shide_exempt | exempt this user from serverhiding
+ * jupe_exempt | exempt this user from generating
+ * warnings joining juped channels
+ * resv_exempt | exempt this user from resvs
+ * flood_exempt | exempt this user from flood limits
+ * USE WITH CAUTION.
+ * no_tilde (old - flag) | don't prefix ~ to username if no ident
+ * need_ident (old + flag) | require ident for user in this class
+ * need_sasl | require SASL id for user in this class
+ */
+ flags = kline_exempt, exceed_limit;
+
+ /* class: the class the user is placed in */
+ class = "opers";
+};
+
+auth {
+ /* redirect: the server and port to redirect a user to. A user does
+ * not have to obey the redirection, the ircd just suggests to them
+ * an alternative server.
+ */
+ redirserv = "irc.some.domain";
+ redirport = 6667;
+
+ user = "*.some.domain";
+
+ /* class: a class is required even though it is not used */
+ class = "users";
+};
+
+auth {
+ user = "*@*";
+ class = "users";
+
+ flags = need_ident;
+};
+
+/* operator {}: defines ircd operators. (OLD O:)
+ * charybdis no longer supports local operators, privileges are
+ * controlled via flags.
+ */
+operator "god" {
+ /* name: the name of the oper must go above */
+
+ /* user: the user@host required for this operator. CIDR *is*
+ * supported now. auth{} spoofs work here, other spoofs do not.
+ * multiple user="" lines are supported.
+ */
+ user = "*god@*";
+ user = "*@127.0.0.1";
+
+ /* password: the password required to oper. Unless ~encrypted is
+ * contained in flags = ...; this will need to be encrypted using
+ * mkpasswd, MD5 is supported
+ */
+ password = "etcnjl8juSU1E";
+
+ /* rsa key: the public key for this oper when using Challenge.
+ * A password should not be defined when this is used, see
+ * doc/challenge.txt for more information.
+ */
+ #rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
+
+ /* umodes: the specific umodes this oper gets when they oper.
+ * If this is specified an oper will not be given oper_umodes
+ * These are described above oper_only_umodes in general {};
+ */
+ #umodes = locops, servnotice, operwall, wallop;
+
+ /* snomask: specific server notice mask on oper up.
+ * If this is specified an oper will not be given oper_snomask.
+ */
+ snomask = "+Zbfkrsuy";
+
+ /* privileges: controls the activities and commands an oper is
+ * allowed to do on the server. You may prefix an option with ~ to
+ * disable it, ie ~operwall
+ *
+ * Default flags are operwall, remoteban and encrypted.
+ *
+ * Available options:
+ *
+ * encrypted: the password above is encrypted [DEFAULT]
+ * local_kill: allows local users to be /KILL'd
+ * global_kill: allows local and remote users to be
+ * /KILL'd (OLD 'O' flag)
+ * remote: allows remote SQUIT and CONNECT (OLD 'R' flag)
+ * kline: allows KILL, KLINE and DLINE (OLD 'K' flag)
+ * unkline: allows UNKLINE and UNDLINE (OLD 'U' flag)
+ * gline: allows GLINE (OLD 'G' flag)
+ * nick_changes: allows oper to see nickchanges (OLD 'N' flag)
+ * via usermode +n
+ * rehash: allows oper to REHASH config (OLD 'H' flag)
+ * die: allows DIE and RESTART (OLD 'D' flag)
+ * admin: gives admin privileges. admins
+ * may (un)load modules and see the
+ * real IPs of servers.
+ * hidden_admin: gives admin privileges except
+ * will not have the admin lines in
+ * stats p and whois.
+ * xline: allows use of /quote xline/unxline
+ * operwall: allows the oper to send operwalls [DEFAULT]
+ * oper_spy: allows 'operspy' features to see through +s
+ * channels etc. see /quote help operspy
+ * hidden_oper: hides the oper from /stats p (OLD UMODE +p)
+ * remoteban: allows remote kline etc [DEFAULT]
+ */
+ flags = global_kill, remote, kline, unkline, gline,
+ die, rehash, admin, xline, operwall;
+};
+
+/* connect {}: controls servers we connect to (OLD C:, N:, H:, L:) */
+connect "irc.uplink.com" {
+ /* the name must go above */
+
+ /* host: the host or IP to connect to. If a hostname is used it
+ * must match the reverse dns of the server.
+ */
+ host = "192.168.0.1";
+
+ /* vhost: the host or IP to bind to for this connection. If this
+ * is not specified, the default vhost (in serverinfo {}) is used.
+ */
+ #vhost = "192.168.0.50";
+
+ /* passwords: the passwords we send (OLD C:) and accept (OLD N:).
+ * The remote server will have these passwords reversed.
+ */
+ send_password = "password";
+ accept_password = "anotherpassword";
+
+ /* port: the port to connect to this server on */
+ port = 6666;
+
+ /* hub mask: the mask of servers that this server may hub. Multiple
+ * entries are permitted
+ */
+ hub_mask = "*";
+
+ /* leaf mask: the mask of servers this server may not hub. Multiple
+ * entries are permitted. Useful for forbidding EU -> US -> EU routes.
+ */
+ #leaf_mask = "*.uk";
+
+ /* class: the class this server is in */
+ class = "server";
+
+ /* flags: controls special options for this server
+ * encrypted - marks the accept_password as being crypt()'d
+ * autoconn - automatically connect to this server
+ * compressed - compress traffic via ziplinks
+ * topicburst - burst topics between servers
+ */
+ flags = compressed, topicburst;
+};
+
+connect "ipv6.some.server" {
+ host = "3ffd:dead:beef::1";
+ send_password = "password";
+ accept_password = "password";
+ port = 6666;
+
+ /* aftype: controls whether the connection uses "ipv4" or "ipv6".
+ * Default is ipv4.
+ */
+ aftype = ipv6;
+ class = "server";
+};
+
+/* cluster {}; servers that we propagate things to automatically.
+ * NOTE: This does NOT grant them privileges to apply anything locally,
+ * you must add a seperate shared block for that. Clustering will
+ * only be done for actions by LOCAL opers, that arent directed
+ * remotely.
+ */
+cluster {
+ /* name: the server to share with, this can be a wildcard and may be
+ * stacked.
+ */
+ /* flags: list of what to share, all the name lines above this (up
+ * until another flags entry) will receive these flags.
+ *
+ * kline - share perm klines
+ * tkline - share temp klines
+ * unkline - share unklines
+ * locops - share locops
+ * xline - share perm xlines
+ * txline - share temp xlines
+ * unxline - share unxlines
+ * resv - share perm resvs
+ * tresv - share temp resvs
+ * unresv - share unresvs
+ * all - share all of the above
+ */
+
+ /* share klines/unklines/xlines with *.lan */
+ name = "*.lan";
+ flags = kline, unkline, xline;
+
+ /* share locops with irc.ircd-ratbox.org and ircd.ircd-ratbox.org */
+ name = "irc.ircd-ratbox.org";
+ name = "ircd.ircd-ratbox.org";
+ flags = locops;
+};
+
+/* service{}: privileged servers (services). These servers have extra
+ * privileges such as setting login names on users and introducing clients
+ * with umode +S (unkickable, hide channels, etc). This does not allow them
+ * to set bans, you need a separate shared{} for that.
+ * Do not place normal servers here.
+ * There may be only one service{} block.
+ */
+service {
+ /* name: the server name. These may be stacked. */
+ name = "services.int";
+};
+
+/* shared {}: users that are allowed to place remote bans on our server.
+ * NOTE: These are ordered top down. The first one the user@host and server
+ * matches will be used. Their access will then be decided on that
+ * block and will not fall back to another block that matches.
+ */
+shared {
+ /* oper: the user@host and server the user must be on to set klines.
+ * The first field must be a user@host, the second field is an
+ * optional server. These may be stacked.
+ */
+ /* flags: list of what to allow them to place, all the oper lines
+ * above this (up until another flags entry) will receive these
+ * flags. This *must* be present.
+ *
+ * kline - allow setting perm/temp klines
+ * tkline - allow setting temp klines
+ * unkline - allow removing klines
+ * xline - allow setting perm/temp xlines
+ * txline - allow setting temp xlines
+ * unxline - allow removing xlines
+ * resv - allow setting perm/temp resvs
+ * tresv - allow setting temp resvs
+ * unresv - allow removing xlines
+ * all - allow oper/server to do all of above.
+ * locops - allow locops - only used for servers who cluster
+ * rehash - allow rehashing
+ * none - disallow everything
+ */
+
+ /* allow flame@*.leeh.co.uk on server irc.ircd-ratbox.org and
+ * allow leeh@*.leeh.co.uk on server ircd.ircd-ratbox.org to kline
+ */
+ oper = "flame@*.leeh.co.uk", "irc.ircd-ratbox.org";
+ oper = "leeh@*.leeh.co.uk", "ircd.ircd-ratbox.org";
+ flags = kline;
+
+ /* you may forbid certain opers/servers from doing anything */
+ oper = "irc@vanity.oper", "*";
+ oper = "*@*", "irc.vanity.server";
+ oper = "irc@another.vanity.oper", "bigger.vanity.server";
+ flags = none;
+
+ /* or allow everyone to place temp klines */
+ oper = "*@*";
+ flags = tkline;
+};
+
+/* exempt {}: IPs that are exempt from Dlines. (OLD d:) */
+exempt {
+ ip = "192.168.0.0/16";
+
+ /* these may be stacked */
+ ip = "127.0.0.1";
+ ip = "10.0.0.0/8";
+};
+
+/* The channel block contains options pertaining to channels */
+channel {
+ /* invex: Enable/disable channel mode +I, a n!u@h list of masks
+ * that can join a +i channel without an invite.
+ */
+ use_invex = yes;
+
+ /* except: Enable/disable channel mode +e, a n!u@h list of masks
+ * that can join a channel through a ban (+b).
+ */
+ use_except = yes;
+
+ /* forward: Enable/disable channel mode +f, a channel to forward
+ * users to if they can't join because of +i etc.
+ */
+ use_forward = yes;
+
+ /* knock: Allows users to request an invite to a channel that
+ * is locked somehow (+ikl). If the channel is +p or you are banned
+ * the knock will not be sent.
+ */
+ use_knock = yes;
+
+ /* invite ops only: Restrict /invite to ops on channels, rather than
+ * allowing unopped users to invite people to a -i channel.
+ */
+ invite_ops_only = yes;
+
+ /* knock delay: The amount of time a user must wait between issuing
+ * the knock command.
+ */
+ knock_delay = 5 minutes;
+
+ /* knock channel delay: How often a knock to any specific channel
+ * is permitted, regardless of the user sending the knock.
+ */
+ knock_delay_channel = 1 minute;
+
+ /* max chans: The maximum number of channels a user can join/be on. */
+ max_chans_per_user = 15;
+
+ /* max bans: maximum number of +b/e/I/q modes in a channel */
+ max_bans = 25;
+
+ /* max bans: maximum number of +b/e/I/q modes in a +L channel */
+ max_bans_large = 500;
+
+ /* splitcode: split users, split servers and either no join on split
+ * or no create on split must be enabled for split checking.
+ * splitmode will be entered on either split users or split servers
+ * dropping below the limit.
+ *
+ * you may force splitmode to be permanent by /quote set splitmode on
+ */
+
+ /* split users: when the usercount is lower than this level, consider
+ * ourselves split. this must be set for automatic splitmode
+ */
+ default_split_user_count = 0;
+
+ /* split servers: when the amount of servers that have acknowledged
+ * theyve finished bursting is lower than this, consider ourselves
+ * split. this must be set for automatic splitmode
+ */
+ default_split_server_count = 0;
+
+ /* split: no create: disallow users creating channels on split */
+ no_create_on_split = no;
+
+ /* split: no join: disallow users joining channels at all on a split */
+ no_join_on_split = no;
+
+ /* burst topicwho: when bursting topics, also burst the topic setter */
+ burst_topicwho = yes;
+
+ /* kick on split riding: kick users riding splits to join +i or +k
+ * channels. more precisely, if a bursting server sends an SJOIN
+ * for a channel with a lower TS with either a +i mode or a +k
+ * mode with a different key, kick all local users.
+ *
+ * note: this does not take +r, +b, +e and +I into account.
+ *
+ * warning: if there are any TS5 servers on the network, this
+ * will cause ban desyncs if they send such an SJOIN and the
+ * splitriders added any bans (our side will lose them, the TS5
+ * side will accept them). we will send a notice to the channel
+ * if this happens. most services do not send such SJOINs but
+ * ratbox-services does.
+ */
+ kick_on_split_riding = no;
+};
+
+
+/* The serverhide block contains the options regarding serverhiding */
+serverhide {
+ /* flatten links: this option will show all servers in /links appear
+ * that they are linked to this current server
+ */
+ flatten_links = no;
+
+ /* links delay: how often to update the links file when it is
+ * flattened.
+ */
+ links_delay = 5 minutes;
+
+ /* hidden: hide this server from a /links output on servers that
+ * support it. this allows hub servers to be hidden etc.
+ */
+ hidden = no;
+
+ /* disable hidden: prevent servers hiding themselves from a
+ * /links ouput.
+ */
+ disable_hidden = no;
+};
+
+/* These are the blacklist settings.
+ * You can have multiple combinations of host and rejection reasons.
+ * They are used in pairs of one host/rejection reason.
+ *
+ * These settings should be adequate for most networks, and are (presently)
+ * required for use on AthemeNet.
+ *
+ * Word to the wise: Do not use blacklists like SPEWS for blocking IRC
+ * connections.
+ *
+ * Note: AHBL (the providers of the below BLs) request that they be
+ * contacted, via email, at admins@2mbit.com before using these BLs.
+ * See <http://www.ahbl.org/services.php> for more information.
+ */
+#blacklist {
+# host = "ircbl.ahbl.org";
+# reject_reason = "You have a host listed in the ircbl.ahbl.org blacklist.";
+#
+# host = "tor.ahbl.org";
+# reject_reason = "You are connecting from a TOR exit node.";
+#};
+
+/*
+ * Alias blocks allow you to define custom commands. (Old m_sshortcut.c)
+ * They send PRIVMSG to the given target. A real command takes
+ * precedence above an alias.
+ */
+alias "NickServ" {
+ /* the name must go above */
+
+ /* target: the target nick (must be a network service) or
+ * user@server (cannot be this server, only opers can use
+ * user starting with "opers" reliably, interpreted on the target
+ * server only so you may need to use nick@server instead)
+ */
+ target = "NickServ";
+};
+
+alias "ChanServ" {
+ target = "ChanServ";
+};
+
+alias "OperServ" {
+ target = "OperServ";
+};
+
+alias "MemoServ" {
+ target = "MemoServ";
+};
+
+alias "NS" {
+ target = "NickServ";
+};
+
+alias "CS" {
+ target = "ChanServ";
+};
+
+alias "OS" {
+ target = "OperServ";
+};
+
+alias "MS" {
+ target = "MemoServ";
+};
+
+/* The general block contains many of the options that were once compiled
+ * in options in config.h. The general block is read at start time.
+ */
+general {
+ /* hide error messages: defines whether error messages from
+ * servers are hidden or not. These can sometimes contain IPs and
+ * can have an adverse effect on server ip hiding. Set to:
+ * yes: hide from opers and admin
+ * opers: hide from opers only
+ * no: do not hide error messages
+ */
+ hide_error_messages = opers;
+
+ /* hide spoof ips: hide the real ips of auth{} spoofed users
+ * If disabled, local opers can see them.
+ * Dynamic spoofs (e.g. set by services) are unaffected by this;
+ * any oper (local and remote) can see the real ip.
+ * Warning: for whowas, this is checked when the client exits,
+ * not when the IP is shown.
+ */
+ hide_spoof_ips = yes;
+
+ /* default umodes: umodes to set upon connection
+ * If you have enabled the ip_cloaking extension, and you wish for
+ * incoming clients to be set +h upon connection, add +h to the umode
+ * string below.
+ */
+ default_umodes = "+i";
+
+ /* default operstring: defines the default oper response
+ * in /whois queries, eg "is an IRC Operator".
+ * After startup use /quote set operstring to change.
+ */
+ default_operstring = "is an IRC Operator";
+
+ /* default adminstring: defines the default admin response
+ * in /whois queries, eg "is a Server Administrator".
+ * After startup use /quote set adminstring to change.
+ */
+ default_adminstring = "is a Server Administrator";
+
+ /* servicestring: defines the response for opered services (+S)
+ * in /whois queries, eg "is a Network Service".
+ * This is updated on rehash.
+ */
+ servicestring = "is a Network Service";
+
+ /* disable fake channels: disable local users joining fake versions
+ * of channels, eg #foo^B^B. Disables bold, mirc colour, reverse,
+ * underline and hard space. (ASCII 2, 3, 22, 31, 160 respectively).
+ */
+ disable_fake_channels = no;
+
+ /* tkline_expire_notices: give a notice to opers when a tkline
+ * expires
+ */
+ tkline_expire_notices = no;
+
+ /* floodcount: the default value of floodcount that is configurable
+ * via /quote set floodcount. This is the amount of lines a user
+ * may send to any other user/channel in one second.
+ */
+ default_floodcount = 10;
+
+ /* failed oper notice: send a notice to all opers on the server when
+ * someone tries to OPER and uses the wrong password, host or ident.
+ */
+ failed_oper_notice = yes;
+
+ /* dots in ident: the amount of '.' characters permitted in an ident
+ * reply before the user is rejected.
+ */
+ dots_in_ident=2;
+
+ /* dot in ipv6: ircd-hybrid-6.0 and earlier will disallow hosts
+ * without a '.' in them. this will add one to the end. only needed
+ * for older servers.
+ */
+ dot_in_ip6_addr = no;
+
+ /* min nonwildcard: the minimum non wildcard characters in k/d/g lines
+ * placed via the server. klines hand placed are exempt from limits.
+ * wildcard chars: '.' '*' '?' '@'
+ */
+ min_nonwildcard = 4;
+
+ /* min nonwildcard simple: the minimum non wildcard characters in
+ * xlines/resvs placed via the server.
+ * wildcard chars: '*' '?'
+ */
+ min_nonwildcard_simple = 3;
+
+ /* max accept: maximum allowed /accept's for +g usermode */
+ max_accept = 20;
+
+ /* max monitor: the maximum amount of nicknames a client may have in
+ * their monitor (server-side notify) list.
+ */
+ max_monitor = 100;
+
+ /* nick flood: enable the nickflood control code */
+ anti_nick_flood = yes;
+
+ /* nick flood: the nick changes allowed in the specified period */
+ max_nick_time = 20 seconds;
+ max_nick_changes = 5;
+
+ /* anti spam time: the minimum time a user must be connected before
+ * custom quit messages are allowed.
+ */
+ anti_spam_exit_message_time = 5 minutes;
+
+ /* ts delta: the time delta allowed between server clocks before
+ * a warning is given, or before the link is dropped. all servers
+ * should run ntpdate/rdate to keep clocks in sync
+ */
+ ts_warn_delta = 30 seconds;
+ ts_max_delta = 5 minutes;
+
+ /* client exit: prepend a users quit message with "Client exit: " */
+ client_exit = yes;
+
+ /* collision fnc: change user's nick to their UID instead of
+ * killing them, if possible. This setting only applies to nick
+ * collisions detected on this server. Only enable this if
+ * all servers on the network allow remote nicks to start with
+ * a digit.
+ */
+ collision_fnc = yes;
+
+ /* global snotices: send out certain snotices (most +b, +f, +y,
+ * some +s) to other servers via ENCAP SNOTE. Received SNOTEs are
+ * displayed unconditionally.
+ */
+ global_snotices = yes;
+
+ /* dline reason: show the user the dline reason when they connect
+ * and are dlined.
+ */
+ dline_with_reason = yes;
+
+ /* kline delay: delay the checking of klines until a specified time.
+ * Useful if large kline lists are applied often to prevent the
+ * server eating CPU.
+ */
+ kline_delay = 0 seconds;
+
+ /* kline reason: show the user the reason why they are k/d/glined
+ * on exit. may give away who set k/dline when set via tcm.
+ */
+ kline_with_reason = yes;
+
+ /* kline reason: make the users quit message on channels this
+ * reason instead of the oper's reason.
+ */
+ kline_reason = "Connection closed";
+
+ /* identify to services via server password
+ * if auth{} block had no password but the user specified a
+ * server password anyway, send a PRIVMSG to <identify_service>
+ * with as text <identify_command> <password>.
+ */
+ identify_service = "NickServ@services.int";
+ identify_command = "IDENTIFY";
+
+ /* non redundant klines: flag and ignore redundant klines */
+ non_redundant_klines = yes;
+
+ /* warn no nline: warn opers about servers that try to connect but
+ * we dont have a connect {} block for. Twits with misconfigured
+ * servers can get really annoying with this enabled.
+ */
+ warn_no_nline = yes;
+
+ /* stats e disabled: disable stats e. useful if server ips are
+ * exempted and you dont want them listing on irc.
+ */
+ stats_e_disabled = no;
+
+ /* stats c oper only: make stats c (connect {}) oper only */
+ stats_c_oper_only=no;
+
+ /* stats h oper only: make stats h (hub_mask/leaf_mask) oper only */
+ stats_h_oper_only=no;
+
+ /* stats y oper only: make stats y (class {}) oper only */
+ stats_y_oper_only=no;
+
+ /* stats o oper only: make stats o (opers) oper only */
+ stats_o_oper_only=yes;
+
+ /* stats P oper only: make stats P (ports) oper only
+ * NOTE: users doing stats P will never be given the ips that the
+ * server listens on, simply the ports.
+ */
+ stats_P_oper_only=no;
+
+ /* stats i oper only: make stats i (auth {}) oper only. set to:
+ * yes: show users no auth blocks, made oper only.
+ * masked: show users first matching auth block
+ * no: show users all auth blocks.
+ */
+ stats_i_oper_only=masked;
+
+ /* stats k/K oper only: make stats k/K (klines) oper only. set to:
+ * yes: show users no auth blocks, made oper only
+ * masked: show users first matching auth block
+ * no: show users all auth blocks.
+ */
+ stats_k_oper_only=masked;
+
+ /* map oper only: make /map oper only */
+ map_oper_only = no;
+
+ /* operspy admin only: make operspy notices to +Z admin only */
+ operspy_admin_only = no;
+
+ /* operspy dont care user info: treat /who mask as if there was
+ * an '!' always; do not log or server notice about operspy
+ * /who mask, /masktrace and /scan. channel information is still
+ * protected. */
+ operspy_dont_care_user_info = no;
+
+ /* caller id wait: time between notifying a +g user that somebody
+ * is messaging them.
+ */
+ caller_id_wait = 1 minute;
+
+ /* pace wait simple: time between use of less intensive commands
+ * (HELP, remote WHOIS, WHOWAS)
+ */
+ pace_wait_simple = 1 second;
+
+ /* pace wait: time between more intensive commands
+ * (ADMIN, INFO, LIST, LUSERS, MOTD, STATS, VERSION)
+ */
+ pace_wait = 10 seconds;
+
+ /* short motd: send clients a notice telling them to read the motd
+ * instead of forcing a motd to clients who may simply ignore it.
+ */
+ short_motd = no;
+
+ /* ping cookies: require clients to respond exactly to a ping command,
+ * can help block certain types of drones and FTP PASV mode spoofing.
+ */
+ ping_cookie = no;
+
+ /* connect timeout: sets how long we should wait for a connection
+ * request to succeed
+ */
+ connect_timeout = 30 seconds;
+
+ /* disable auth: disables identd checking */
+ disable_auth = no;
+
+ /* no oper flood: increase flood limits for opers. */
+ no_oper_flood = yes;
+
+ /* glines: enable glines, network wide temp klines */
+ glines = no;
+
+ /* gline time: the amount of time a gline will remain before expiring */
+ gline_time = 1 day;
+
+ /* gline_min_cidr: If using a CIDR gline, the minimum length the
+ * mask must be
+ */
+ gline_min_cidr = 16;
+
+ /* idletime: the maximum amount of time a user may idle before
+ * they are disconnected
+ */
+ idletime = 0;
+
+ /* REMOVE ME. The following line checks you've been reading. */
+ havent_read_conf = yes;
+
+ /* max targets: the maximum amount of targets in a single
+ * PRIVMSG/NOTICE. set to 999 NOT 0 for unlimited.
+ */
+ max_targets = 4;
+
+ /* client flood: maximum number of lines in a clients queue before
+ * they are dropped for flooding.
+ */
+ client_flood = 20;
+
+ /* use_whois_actually: send clients requesting a whois a numeric
+ * giving the real IP of non-spoofed clients to prevent DNS abuse.
+ */
+ use_whois_actually = yes;
+
+ /* usermodes configurable: a list of usermodes for the options below
+ *
+ * +g - callerid - Server Side Ignore
+ * +D - deaf - Don't see channel messages
+ * +i - invisible - Not shown in NAMES or WHO unless you share a
+ * a channel
+ * +l - locops - See LOCOPS messages
+ * +Q - noforward - Unaffected by channel forwarding
+ * +R - regonlymsg - No messages from unindentified
+ * +s - servnotice - See server notices
+ * +w - wallop - See oper and server generated WALLOPS
+ * +z - operwall - See operwalls
+ */
+
+ /* oper only umodes: usermodes only opers may set */
+ oper_only_umodes = operwall, locops, servnotice;
+
+ /* oper umodes: default usermodes opers get when they /oper */
+ oper_umodes = locops, servnotice, operwall, wallop;
+
+ /* oper snomask: default snomask opers get when they /oper,
+ * provided they have umode +s set */
+ oper_snomask = "+s";
+
+ /* servlink path: path to 'servlink' program used by ircd to handle
+ * encrypted/compressed server <-> server links.
+ *
+ * only define if servlink is not in same directory as ircd itself.
+ */
+ #servlink_path = "/usr/local/ircd/bin/servlink";
+
+ /* use egd: if your system does not have *random devices yet you
+ * want to use OpenSSL and encrypted links, enable this. Beware -
+ * EGD is *very* CPU intensive when gathering data for its pool
+ */
+ #use_egd = yes;
+
+ /* egdpool path: path to EGD pool. Not necessary for OpenSSL >= 0.9.7
+ * which automatically finds the path.
+ */
+ #egdpool_path = "/var/run/egd-pool";
+
+
+ /* compression level: level of compression for compressed links between
+ * servers.
+ *
+ * values are between: 1 (least compression, fastest)
+ * and: 9 (most compression, slowest).
+ */
+ #compression_level = 6;
+
+ /* burst_away: This enables bursting away messages to servers.
+ * With this disabled, we will only propogate AWAY messages
+ * as users send them, but never burst them. Be warned though
+ * enabling this could increase the size of a burst significantly
+ * for a large network, like EFnet.
+ */
+ burst_away = yes;
+
+ /* nick delay: This locks nicks of split clients for the given time
+ * or until a remote client uses the nick. This significantly
+ * reduces nick collisions on short splits but it can be annoying.
+ * To make things as fair as possible, this should be the same on
+ * all servers. If you enable this, the suggested value is 15 minutes.
+ */
+ nick_delay = 0 seconds;
+
+ /* reject time: the amount of rejections through klines/dlines etc
+ * allowed in the given time before the rejection is cached and
+ * a pseudo temp dline is placed
+ */
+ reject_ban_time = 1 minute;
+ reject_after_count = 3;
+
+ /* reject duration: the amount of time to cache the rejection */
+ reject_duration = 5 minutes;
+};
+
+modules {
+ /* module path: paths to search for modules specified below and
+ * in /modload.
+ */
+ path = "/usr/local/ircd/modules";
+ path = "/usr/local/ircd/modules/autoload";
+
+ /* module: the name of a module to load on startup/rehash */
+ #module = "some_module.so";
+};
--- /dev/null
+ Server VERSION Info
+
+ $Id: server-version-info 1851 2006-08-24 17:16:53Z jilles $
+
+ Copyright (c) 2001 by ircd-hybrid team
+ Copyright (c) 2002 ircd-ratbox development team
+
+ ----------------------------------------------------------------------
+
+ When you type /version, you will often see something like this:
+
+ ircd-ratbox-1.0rc7(20021120_0). embers.lan egGHIKMpZ6 TS5ow
+
+ Ever wondered what those funny chars mean after the version number? Well
+ here they are:
+
+ +----------------------------+
+ | 'e' | USE_EXCEPT |
+ |------+---------------------|
+ | 'g' | NO_FAKE_GLINES |
+ |------+---------------------|
+ | 'G' | GLINES |
+ |------+---------------------|
+ | 'H' | HUB |
+ |------+---------------------|
+ | 'I' | USE_INVEX |
+ |------+---------------------|
+ | 'K' | USE_KNOCK |
+ |------+---------------------|
+ | 'M' | IDLE_FROM_MSG |
+ |------+---------------------|
+ | 'p' | CRYPT_OPER_PASSWORD |
+ |------+---------------------|
+ | 'S' | OPERS_SEE_ALL_USERS |
+ |------+---------------------|
+ | 'T' | IGNORE_BOGUS_TS |
+ |------+---------------------|
+ | 'Z' | ZIPLINKS |
+ |------+---------------------|
+ | '6' | IPv6 |
+ |------+---------------------|
+ | | |
+ |------+---------------------|
+ | 'TS' | Supports TS |
+ |------+---------------------|
+ | '5' | TS Version 5 |
+ |------+---------------------|
+ | 'o' | TS Only |
+ |------+---------------------|
+ | 'w' | TS Warnings |
+ +----------------------------+
--- /dev/null
+ratbox-services compatibility documentation - Lee H <lee -at- leeh.co.uk>
+-------------------------------------------------------------------------
+
+Compatibility with ratbox-services can be enabled by passing the
+'--enable-services' flag to configure. It will add the following features
+to ircd:
+
+1. Channel mode +r
+
+ A simple mode taking no parameters, will require users are logged in
+ with user services before they may join the channel.
+
+ Gives numeric 477 to users who arent logged in:
+ :<server> 477 <nick> <channel> :Cannot join channel (+r)
+
+2. service block to ircd.conf
+
+ Ability to specify the names of services servers in ircd.conf:
+ service {
+ name = "services.ircd-ratbox.org";
+ name = "backup-services.ircd-ratbox.org";
+ };
+
+ These must be specified for certain features to work. You may specify as
+ many name entries as you wish, however you must define only one service
+ block.
+
+ Entries will be listed in stats U with the flag 's'.
+
+3. Services protection
+
+ Services will be protected from being deopped or kicked from a channel.
+
+4. Username tracking through netsplits
+
+ When users are logged in, the username they are logged in with will be
+ preserved on a netsplit, so users will not have to relogin when the
+ network merges together.
+
+5. Username given on WHOIS
+
+ When users are logged in, WHOIS will also give numeric 330:
+ :<server> 330 <yournick> <targetnick> <loginname> :is logged in as
+
+ Note this needs to be a remote whois to work when the target is
+ on a different server.
+
+6. Forced nick change
+
+ When using nickname services and a client requests they regain a
+ nickname, services can perform a forced nick change on the client.
+ This forcibly changes the clients nickname to the one they requested
+ they regain, ensuring they can always regain their nickname.
+
+# $Id: services.txt 6 2005-09-10 01:02:21Z nenolod $
--- /dev/null
+<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
+<!ENTITY intro SYSTEM "intro.sgml">
+<!ENTITY oprivs SYSTEM "oprivs.sgml">
+<!ENTITY umodes SYSTEM "umodes.sgml">
+<!ENTITY cmodes SYSTEM "cmodes.sgml">
+<!ENTITY ucommands SYSTEM "ucommands.sgml">
+<!ENTITY commands SYSTEM "commands.sgml">
+<!ENTITY config SYSTEM "config.sgml">
+]>
+<book id="charybdis-oper-guide">
+ <bookinfo>
+ <date>24 November 2005</date>
+ <title>Operators guide for the charybdis IRC server</title>
+ <author>
+ <firstname>William</firstname>
+ <surname>Pitcock</surname>
+ </author>
+ <address><email>nenolod@nenolod.net</email></address>
+ <copyright>
+ <year>2005-2007</year>
+ <holder>William Pitcock and Jilles Tjoelker</holder>
+ </copyright>
+ <legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this document under the terms of the GNU
+ General Public License, Version 2 or any later version published by the Free Software Foundation
+ </para>
+ </legalnotice>
+ </bookinfo>
+ <toc>
+ </toc>
+ &intro;
+ &umodes;
+ &cmodes;
+ &ucommands;
+ &commands;
+ &oprivs;
+ &config;
+</book>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:("/usr/lib/sgml/catalog")
+sgml-local-ecat-files:nil
+fill-column: 105
+End:
+-->
--- /dev/null
+ <chapter id="cmodes">
+ <title>Cmodes</title>
+ <sect1>
+ <title>Meanings of channel modes</title>
+ <sect2>
+ <title>+b, channel ban</title>
+ <para>
+ Bans take one parameter which can take several forms.
+ The most common form is +b nick!user@host.
+ The wildcards * and ? are allowed, matching zero-or-more, and
+ exactly-one characters respectively. The masks will be trimmed to fit the maximum allowable
+ length for the relevant element.
+ Bans are also checked against the IP address, even if it resolved or
+ is spoofed.
+ CIDR is supported, like *!*@10.0.0.0/8. This is most useful with
+ IPv6.
+ Bans are not checked against the real hostname behind any kind
+ of spoof, except if host mangling is in use (e.g.
+ <filename>extensions/ip_cloaking.so</filename>):
+ if the user's host is mangled, their real hostname is checked
+ additionally, and if a user has no spoof but could enable mangling,
+ the mangled form of their hostname is checked additionally.
+ Hence, it is not possible to evade bans by toggling
+ host mangling.
+ </para>
+ <para>
+ The second form (extban) is +b $type or +b $type:data.
+ type is a single character (case insensitive) indicating the
+ type of match, optionally preceded by a tilde (~) to negate the
+ comparison. data depends on type. Each type is loaded as a module.
+ The available types (if any)
+ are listed in the EXTBAN token of the 005 (RPL_ISUPPORT) numeric.
+ See <filename>doc/extban.txt</filename> in the source distribution
+ for more information.
+ </para>
+ <para>
+ If no parameter is given, the list of bans is returned. All users
+ can use this form. The plus sign should also be omitted.
+ </para>
+ <para>
+ Matching users will not be allowed to join the channel or knock
+ on it. If they are already on the channel, they may not send to
+ it or change their nick.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+c, colour filter</title>
+ <para>
+ This cmode activates the colour filter for the channel. This filters out bold, underline,
+ reverse video, beeps, mIRC colour codes, and ANSI escapes. Note that escape sequences will
+ usually leave cruft sent to the channel, just without the escape characters themselves.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+e, ban exemption</title>
+ <para>
+ This mode takes one parameter of the same form as bans, which
+ overrides +b and +q bans for all clients it matches.
+ </para>
+ <para>
+ Only channel operators can see +e changes or request the list.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+f, channel forwarding</title>
+ <para>
+ This mode takes one parameter, the name of a channel (+f #channel). If the channel also has the
+ +i cmode set, and somebody attempts to join without either being expliticly invited, or having
+ an invex (+I), then they will instead join the channel named in the mode parameter. The client
+ will also be sent a 470 numeric giving the original and target channels.
+ </para>
+ <para>
+ Users are similarly forwarded if the +j cmode is set and their attempt to join is throttled,
+ if +l is set and there are already too many users in the channel
+ or if +r is set and they are not identified.
+ </para>
+ <para>
+ Forwards may only be set to +F channels, or to channels the setter
+ has ops in.
+ </para>
+ <para>
+ Without parameter (/mode #channel f or /mode #channel +f) the
+ forward channel is returned. This form also works off channel.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+F, allow anybody to forward to this</title>
+ <para>
+ When this mode is set, anybody may set a forward from a channel
+ they have ops in to this channel. Otherwise they have to have ops
+ in this channel.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+g, allow anybody to invite</title>
+ <para>
+ When this mode is set, anybody may use the INVITE command on the channel in question. When it
+ is unset, only channel operators may use the INVITE command
+ (unless the invite_ops_only option is disabled and +i is
+ not set).
+ </para>
+ <para>
+ When this mode is set together with +i, all channel members can influence who can join.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+i, invite only</title>
+ <para>
+ When this cmode is set, no client can join the channel unless they have an invex (+I) or are
+ invited with the INVITE command.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+I, invite exception (invex)</title>
+ <para>
+ This mode takes one parameter of the same form as bans. Matching
+ clients do not need to be invited to join the channel when it is invite-only (+i).
+ </para>
+ <para>
+ Only channel operators can see +I changes or request the list.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+j, join throttling</title>
+ <para>
+ This mode takes one parameter of the form <replaceable>n</replaceable>:<replaceable>t</replaceable>, where <replaceable>n</replaceable> and <replaceable>t</replaceable> are positive integers. Only <replaceable>n</replaceable> users may join in each period of <replaceable>t</replaceable> seconds.
+ </para>
+ <para>
+ Due to propagation delays between servers, more users may be
+ able to join (by racing for the last slot on each server).
+ </para>
+ </sect2>
+ <sect2>
+ <title>+k, key (channel password)</title>
+ <para>
+ Taking one parameter, when set, this mode requires a user to supply the key in order to join
+ the channel: /JOIN #channel key.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+l, channel member limit</title>
+ <para>
+ Takes one numeric parameter, the number of users which are allowed to be in the channel before
+ further joins are blocked.
+ </para>
+ <para>
+ Due to propagation delays between servers, more users may be
+ able to join (by racing for the last slot on each server).
+ </para>
+ </sect2>
+ <sect2>
+ <title>+L, large ban list</title>
+ <para>
+ Channels with this mode will be allowed larger banlists (by default,
+ 500 instead of 50 entries for +b, +q, +e and +I together).
+ Only network operators may set this mode.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+m, moderated</title>
+ <para>
+ When a channel is set +m, only users with +o or +v on the channel can send to it.
+ </para>
+ <para>
+ Users can still knock on the channel or change their nick.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+n, no external messages</title>
+ <para>
+ When set, this mode prevents users from sending to the channel without being in it themselves.
+ This is recommended.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+o, channel operator</title>
+ <para>
+ This mode takes one parameter, a nick, and grants or removes channel
+ operator privilege to that user. Channel operators have full control
+ over the channel, having the ability to set all channel modes except
+ +L and +P, and kick users.
+ Like voiced users, channel operators can always
+ send to the channel, overriding +b, +m and +q modes and the
+ per-channel flood limit.
+ In most clients channel operators are marked with an '@' sign.
+ </para>
+ <para>
+ The privilege is lost if the user leaves the channel or server
+ in any way.
+ </para>
+ <para>
+ Most networks will run channel registration services (e.g. ChanServ)
+ which ensure the founder (and users designated by the founder) can
+ always gain channel operator privileges and provide some features
+ to manage the channel.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+p, paranoid channel</title>
+ <para>
+ When set, the KNOCK command cannot be used on the channel
+ to request an invite, and users will not be shown the
+ channel in WHOIS replies unless they are on it.
+ Unlike in traditional IRC, +p and +s can be set together.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+P, permanent channel</title>
+ <para>
+ Channels with this mode (which is accessible only to network operators) set will not be destroyed
+ when the last user leaves.
+ </para>
+ <para>
+ This makes it less likely modes, bans and the topic will be lost and
+ makes it harder to abuse network splits, but also causes more
+ unwanted restoring of old modes, bans and topics after long splits.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+q, quiet</title>
+ <para>
+ This mode behaves exactly like +b (ban), except that the user may still join
+ the channel. The net effect is that they cannot knock on the channel,
+ send to the channel or change their nick while on channel.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+Q, block forwarded users</title>
+ <para>
+ Channels with this mode set are not valid targets for forwarding. Any attempt to forward to
+ this channel will be ignored, and the user will be handled as if the attempt was never made (by
+ sending them the relevant error message).
+ </para>
+ <para>
+ This does not affect the ability to set +f.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+r, block unidentified</title>
+ <para>
+ When set, this mode prevents unidentified users from joining.
+ </para>
+ </sect2>
+ <!-- not planned (jilles)
+ <sect2>
+ <title>+R, quiet unidentified</title>
+ <para>
+ When set, this mode prevents unidentified users from sending to the channel, although they can
+ still join.
+ </para>
+ <para>
+ Please note that this mode is not implemented in Charybdis 1.0.x, and is documented in
+ expectation for upcoming Charybdis 1.1.
+ </para>
+ </sect2>
+ -->
+ <sect2>
+ <title>+s, secret channel</title>
+ <para>
+ When set, this mode prevents the channel from appearing in the
+ output of the LIST, WHO and WHOIS command by users who are not on
+ it. Also, the server will refuse to answer WHO, NAMES, TOPIC and
+ LIST queries from users not on the channel.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+t, topic limit</title>
+ <para>
+ When set, this mode prevents users who are not channel operators
+ from changing the topic.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+v, voice</title>
+ <para>
+ This mode takes one parameter, a nick, and grants or removes voice
+ privilege to that user. Voiced users can always send to the channel,
+ overriding +b, +m and +q modes and the per-channel flood limit.
+ In most clients voiced users are marked with a plus sign.
+ </para>
+ <para>
+ The privilege is lost if the user leaves the channel or server
+ in any way.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+z, reduced moderation</title>
+ <para>
+ When +z is set, the effects of +m are relaxed. For each message, if that message
+ would normally be blocked by moderation, it is instead sent to all channel operators. This is intended for use in moderated debates.
+ </para>
+ <para>
+ Note that +n and channel bans/quiets are unaffected by this. To silence a given user completely,
+ remove them from the channel.
+ </para>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+fill-column:105
+End:
+-->
--- /dev/null
+ <chapter id="commands">
+ <title>Operator Commands</title>
+ <sect1>
+ <title>Network management commands</title>
+ <note>
+ <para>
+ Except STATS letters, all commands and names are case insensitive.
+ </para>
+ </note>
+ <sect2>
+ <title>CONNECT</title>
+ <cmdsynopsis><command>CONNECT</command>
+ <arg choice=plain><replaceable>target</replaceable></arg>
+ <arg><replaceable>port</replaceable></arg>
+ <arg><replaceable>source</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Initiate a connection attempt to server <replaceable class=parameter>target</replaceable>. If a port is
+ given, connect to that port on the target, otherwise use the one given in <filename>ircd.conf</filename>. If
+ <replaceable class=parameter>source</replaceable> is given, tell that server to initiate the connection
+ attempt, otherwise it will be made from the server you are attached to.
+ </para>
+ </sect2>
+ <sect2>
+ <title>SQUIT</title>
+ <cmdsynopsis>
+ <command>SQUIT</command>
+ <arg choice=plain><replaceable>server</replaceable></arg>
+ <arg><replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Closes down the link to <replaceable>server</replaceable> from this side of the network. If a reason is
+ given, it will be sent out in the server notices on both sides of the link.
+ </para>
+ </sect2>
+ <sect2>
+ <title>REHASH</title>
+ <cmdsynopsis>
+ <command>REHASH</command>
+ <group>
+ <arg>BANS</arg>
+ <arg>DNS</arg>
+ <arg>MOTD</arg>
+ <arg>OMOTD</arg>
+ <arg>GLINES</arg>
+ <arg>PGLINES</arg>
+ <arg>TKLINES</arg>
+ <arg>TDLINES</arg>
+ <arg>TXLINES</arg>
+ <arg>TRESVS</arg>
+ <arg>REJECTCACHE</arg>
+ <arg>HELP</arg>
+ </group>
+ <arg><replaceable>server</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ With no parameter given, <filename>ircd.conf</filename> will be reread and parsed.
+ The server argument is a wildcard match of server names.
+ </para>
+ <variablelist>
+ <title>Parameters</title>
+ <varlistentry>
+ <term>BANS</term>
+ <listitem>
+ <para>Rereads <filename>kline.conf</filename>, <filename>dline.conf</filename>, <filename>xline.conf</filename>, <filename>resv.conf</filename> and their .perm variants</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DNS</term>
+ <listitem>
+ <para>Reread <filename>/etc/resolv.conf</filename>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>MOTD</term>
+ <listitem>
+ <para>Reload the MOTD file</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>OMOTD</term>
+ <listitem>
+ <para>Reload the operator MOTD file</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>GLINES</term>
+ <listitem>
+ <para>Clears G:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PGLINES</term>
+ <listitem>
+ <para>Clears pending G:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TKLINES</term>
+ <listitem>
+ <para>Clears temporary K:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TDLINES</term>
+ <listitem>
+ <para>Clears temporary D:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TXLINES</term>
+ <listitem>
+ <para>Clears temporary X:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TRESVS</term>
+ <listitem>
+ <para>Clears temporary reservations.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>REJECTCACHE</term>
+ <listitem>
+ <para>Clears the client rejection cache.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>HELP</term>
+ <listitem>
+ <para>Refreshes the help system cache.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>RESTART</title>
+ <cmdsynopsis>
+ <command>RESTART</command>
+ <arg choice=plain><replaceable>server</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Cause an immediate total shutdown of the IRC server, and restart from scratch as if it had just been executed.
+ </para>
+ <para>
+ This reexecutes the ircd using the compiled-in path, visible
+ as SPATH in INFO.
+ </para>
+ <note>
+ <para>This command cannot be used remotely. The server name is used only as a safety measure.</para>
+ </note>
+ </sect2>
+ <sect2>
+ <title>DIE</title>
+ <cmdsynopsis>
+ <command>DIE</command>
+ <arg choice=plain><replaceable>server</replaceable></arg>
+ </cmdsynopsis>
+ <para>Immediately terminate the IRC server, after sending notices to all connected clients and servers</para>
+ <note>
+ <para>This command cannot be used remotely. The server name is used only as a safety measure.</para>
+ </note>
+ </sect2>
+ <sect2>
+ <title>SET</title>
+ <cmdsynopsis>
+ <command>SET</command>
+ <group>
+ <arg>LOG</arg>
+ <arg>MAX</arg>
+ <arg>SPLITDELAY</arg>
+ <arg>SMALLNET</arg>
+ <arg>SPAMNUM</arg>
+ <arg>SPAMTIME</arg>
+ </group>
+ <arg choice=plain><replaceable>value</replaceable></arg>
+ </cmdsynopsis>
+ <para>The SET command sets a runtime-configurable value</para>
+ <variablelist>
+ <varlistentry>
+ <term>LOG</term>
+ <listitem>
+ <para>Logging level for ircd.log and syslog</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <varlistentry>
+ <term>MAX</term>
+ <listitem>
+ <para>Set the maximum connections allowed (may not exceed the compiled-in value HARD_FDLIMIT)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRONETIME</term>
+ <listitem>
+ <para>Number of seconds in which DRONECOUNT messages must occur to trip the drone alarm</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRONECOUNT</term>
+ <listitem>
+ <para>Number of messages which constitutes a drone flood. 0 disables drone flood checking.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>SPLITDELAY</term>
+ <listitem>
+ <para>Number of minutes after a connect burst begins until joining an empty channel will give you ops</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>SMALLNET</term>
+ <listitem>
+ <para>Sets the number of servers which are needed to constitute <quote>attached to the network</quote>, as opposed to <quote>split</quote></para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>SPAMNUM</term>
+ <listitem>
+ <para>Sets the number of JOINs/PARTs which constitutes a possible spambot</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>SPAMTIME</term>
+ <listitem>
+ <para>Staying on a channel for less than this length of time adds to the SPAMNUM count</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+ <sect1 id="usercommands">
+ <title>User management commands</title>
+ <sect2>
+ <title>KILL</title>
+ <cmdsynopsis>
+ <command>KILL</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg><replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Disconnects the user with the given nick from the server they are connected to,
+ with the reason given, if present, and broadcast a server notice announcing this.
+ </para>
+ <para>
+ Your nick and the reason will appear on channels.
+ </para>
+ </sect2>
+ <sect2>
+ <title>CLOSE</title>
+ <para>
+ Closes all connections from and to clients and servers who have not completed registering.
+ </para>
+ </sect2>
+ <sect2>
+ <title>KLINE</title>
+ <cmdsynopsis>
+ <command>KLINE</command>
+ <arg><replaceable>length</replaceable></arg>
+ <group>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>host</replaceable></arg>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>a</replaceable>.<replaceable>b</replaceable>.<replaceable>c</replaceable>.<replaceable>d</replaceable></arg>
+ </group>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ <arg>:<replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Adds a K:line to <filename>kline.conf</filename> to ban the given user@host from using that
+ server.
+ </para>
+ <para>
+ If the optional parameter <replaceable>length</replaceable> is given, the K:line will
+ be temporary (i.e. it will not be stored on disk) and last that
+ long in minutes.
+ </para>
+ <para>
+ If an IP address is given, the ban will be against all hosts matching that IP regardless
+ of DNS. The IP address can be given as a full address (192.168.0.1), as a CIDR mask
+ (192.168.0.0/24), or as a glob (192.168.0.*).
+ </para>
+ <para>
+ All clients matching the K:line will be disconnected from the server immediately.
+ </para>
+ <para>
+ If a reason is specified, it will be sent to the client when they are disconnected, and
+ whenever a connection is attempted which is banned.
+ </para>
+ <para>
+ If the ON part is specified, the K:line is set on servers matching
+ the given mask (provided a matching shared{} block exists there).
+ Otherwise, if specified in a cluster{} block, the K:Line will be
+ propagated across the network accordingly.
+ </para>
+ </sect2>
+ <sect2>
+ <title>UNKLINE</title>
+ <cmdsynopsis>
+ <command>UNKLINE</command>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>host</replaceable></arg>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Will attempt to remove a K:line matching user@host from <filename>kline.conf</filename>, and will flush
+ a temporary K:line.
+ </para>
+ </sect2>
+ <sect2>
+ <title>XLINE</title>
+ <cmdsynopsis>
+ <command>XLINE</command>
+ <arg><replaceable>length</replaceable></arg>
+ <arg choice=plain><replaceable>mask</replaceable></arg>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ <arg>:<replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Works similarly to KLINE, but matches against the real name field.
+ The wildcards are * (any sequence), ? (any character),
+ # (a digit) and @ (a letter); wildcard characters can be
+ escaped with a backslash.
+ </para>
+ <para>
+ Use \s for a space; this currently interferes with the
+ check whether the mask is already xlined and UNXLINE.
+ </para>
+ <para>
+ All clients matching the X:line will be disconnected from the server immediately.
+ </para>
+ <para>
+ The reason is never sent to users. Instead, they will be exited
+ with <quote>Bad user info</quote>.
+ </para>
+ <para>
+ If the ON part is specified, the X:line is set on servers matching
+ the given mask (provided a matching shared{} block exists there).
+ Otherwise, if specified in a cluster{} block, the X:line will be
+ propagated across the network accordingly.
+ </para>
+ </sect2>
+ <sect2>
+ <title>UNXLINE</title>
+ <cmdsynopsis>
+ <command>UNXLINE</command>
+ <arg choice=plain><replaceable>mask</replaceable></arg>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Will attempt to remove an X:line from <filename>xline.conf</filename>, and will flush
+ a temporary X:line.
+ </para>
+ </sect2>
+ <sect2>
+ <title>RESV</title>
+ <cmdsynopsis>
+ <command>RESV</command>
+ <arg><replaceable>length</replaceable></arg>
+ <group>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ <arg choice=plain><replaceable>mask</replaceable></arg>
+ </group>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ <arg>:<replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ If used on a channel, <quote>jupes</quote> the channel locally. Joins to the
+ channel will be disallowed and generate a server notice on +y, and
+ users will not be able to send to the channel. Channel jupes cannot
+ contain wildcards.
+ </para>
+ <para>
+ If used on a nickname mask, prevents local users from using a nick
+ matching the mask (the same wildcard characters as xlines). There
+ is no way to exempt the initial nick from this.
+ </para>
+ <para>
+ In neither case will current users of the nick or channel be
+ kicked or disconnected.
+ </para>
+ <para>
+ This facility is not designed to make certain nicks
+ or channels oper-only.
+ </para>
+ <para>
+ The reason is never sent to users.
+ </para>
+ <para>
+ If the ON part is specified, the resv is set on servers matching
+ the given mask (provided a matching shared{} block exists there).
+ Otherwise, if specified in a cluster{} block, the resv will be
+ propagated across the network accordingly.
+ </para>
+ </sect2>
+ <sect2>
+ <title>UNRESV</title>
+ <cmdsynopsis>
+ <command>UNRESV</command>
+ <group>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ <arg choice=plain><replaceable>mask</replaceable></arg>
+ </group>
+ <arg>ON <replaceable>servername</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Will attempt to remove a resv from <filename>resv.conf</filename>, and will flush
+ a temporary resv.
+ </para>
+ </sect2>
+ <sect2>
+ <title>DLINE</title>
+ <cmdsynopsis>
+ <command>DLINE</command>
+ <arg><replaceable>length</replaceable></arg>
+ <arg choice=plain><replaceable>a</replaceable>.<replaceable>b</replaceable>.<replaceable>c</replaceable>.<replaceable>d</replaceable></arg>
+ <arg>:<replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Adds a D:line to <filename>dline.conf</filename>, which will deny any connections
+ from the given IP address.
+ </para>
+ <para>
+ If the optional parameter <replaceable>length</replaceable> is given, the D:line will
+ be temporary (i.e. it will not be stored on disk) and last that
+ long in minutes.
+ </para>
+ <para>
+ If a reason is specified, it will be sent to the client when they are disconnected, and,
+ if dline_reason is enabled,
+ whenever a connection is attempted which is banned.
+ </para>
+ <para>
+ D:lines are less load on a server, and may be more appropriate if somebody is flooding
+ connections.
+ </para>
+ <para>
+ D:lines cannot be set remotely on other servers.
+ </para>
+ <para>
+ Only exempt{} blocks exempt from D:lines on initial connection.
+ Being a server or having kline_exempt in auth{} does
+ <emphasis>not</emphasis> exempt (different from K/G/X:lines).
+ </para>
+ </sect2>
+ <sect2>
+ <title>UNDLINE</title>
+ <cmdsynopsis>
+ <command>UNDLINE</command>
+ <arg choice=plain><replaceable>a.b.c.d</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Will attempt to remove a D:line from <filename>dline.conf</filename>, and will flush
+ a temporary D:line.
+ </para>
+ </sect2>
+ <sect2>
+ <title>GLINE</title>
+ <cmdsynopsis>
+ <command>GLINE</command>
+ <group>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>host</replaceable></arg>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>a</replaceable>.<replaceable>b</replaceable>.<replaceable>c</replaceable>.<replaceable>d</replaceable></arg>
+ </group>
+ <arg choice=plain>:<replaceable>reason</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Attempts to add a network-wide ban for the given mask.
+ It takes three different opers on three different servers
+ requesting the same G:line to have it triggered for a configured
+ time.
+ </para>
+ <para>
+ Once triggered, a G:line is similar to a temporary K:line on
+ each server. No further propagation or on-disk storage is done.
+ </para>
+ <note><para>
+ This command can be enabled or disabled in the configuration file.
+ If it is disabled, no oper on the server can issue a G:line and no
+ G:lined user is banned, but G:lines are still propagated to other
+ servers which may have G:lines enabled.
+ </para></note>
+ </sect2>
+ <sect2>
+ <title>UNGLINE</title>
+ <cmdsynopsis>
+ <command>UNGLINE</command>
+ <group>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>host</replaceable></arg>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>a</replaceable>.<replaceable>b</replaceable>.<replaceable>c</replaceable>.<replaceable>d</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Removes the given G:line on this server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>TESTGECOS</title>
+ <cmdsynopsis>
+ <command>TESTGECOS</command>
+ <arg choice=plain><replaceable>gecos</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Looks up X:Lines matching the given gecos.
+ </para>
+ </sect2>
+ <sect2>
+ <title>TESTLINE</title>
+ <cmdsynopsis>
+ <command>TESTLINE</command>
+ <arg><replaceable>nick</replaceable>!</arg>
+ <group>
+ <arg choice=plain><replaceable>user</replaceable>@<replaceable>host</replaceable></arg>
+ <arg choice=plain><replaceable>a</replaceable>.<replaceable>b</replaceable>.<replaceable>c</replaceable>.<replaceable>d</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Looks up the given hostmask or IP address and reports back on any auth{} blocks, D:, G:, or K: lines found.
+ If <replaceable>nick</replaceable> is given, also searches for
+ nick resvs.
+ </para>
+ <para>
+ For temporary items the number of minutes until the item expires
+ is shown (as opposed to the hit count in STATS q/Q/x/X).
+ </para>
+ <para>
+ This command will not perform DNS lookups; for best
+ results you must testline a host and its IP form.
+ </para>
+ <para>
+ The given username should begin with a tilde (~) if identd is not
+ in use. As of charybdis 2.1.1, no_tilde and username truncation will
+ be taken into account like in the normal client access check.
+ </para>
+ </sect2>
+ <sect2>
+ <title>TESTMASK</title>
+ <cmdsynopsis>
+ <command>TESTMASK</command>
+ <arg choice=plain><replaceable>hostmask</replaceable></arg>
+ <arg><replaceable>gecos</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Searches the network for users that match the hostmask and gecos given,
+ returning the number of matching users on this server and other servers.
+ </para>
+ <para>
+ The <replaceable>hostmask</replaceable> is of the form user@host
+ or user@ip/cidr with * and ? wildcards, optionally preceded by
+ nick!.
+ </para>
+ <para>
+ The <replaceable>gecos</replaceable> field accepts the same wildcards
+ as xlines.
+ </para>
+ <para>
+ The IP address checked against is 255.255.255.255 if the IP address
+ is unknown (remote client on a TS5 server) or 0 if the IP address
+ is hidden (auth{} spoof).
+ </para>
+ </sect2>
+ <sect2>
+ <title>LUSERS</title>
+ <cmdsynopsis>
+ <command>LUSERS</command>
+ <arg><replaceable>mask</replaceable></arg>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Shows various user and channel counts.
+ </para>
+ <para>
+ The <replaceable>mask</replaceable> parameter is obsolete
+ but must be used when querying a remote server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>TRACE</title>
+ <cmdsynopsis>
+ <command>TRACE</command>
+ <group>
+ <arg><replaceable>server</replaceable></arg>
+ <arg><replaceable>nick</replaceable></arg>
+ </group>
+ <arg><replaceable>location</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ With no argument or one argument which is the current server,
+ TRACE gives a list of all connections to the current server
+ and a summary of connection classes.
+ </para>
+ <para>
+ With one argument which is another server, TRACE displays the path
+ to the specified server, and all servers, opers and -i users
+ on that server, along with a summary of connection classes.
+ </para>
+ <para>
+ With one argument which is a client, TRACE displays the
+ path to that client, and that client's information.
+ </para>
+ <para>
+ If location is given, the command is executed on that server;
+ no path is displayed.
+ </para>
+ <para>
+ When listing connections, type, name and class is shown
+ in addition to information depending on the type:
+ </para>
+ <variablelist>
+ <title>TRACE types</title>
+ <varlistentry>
+ <term>Try.</term>
+ <listitem><para>
+ A server we are trying to make a TCP connection to.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>H.S.</term>
+ <listitem><para>
+ A server we have established a TCP connection to, but is not
+ yet registered.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>????</term>
+ <listitem><para>
+ An incoming connection that has not yet registered as
+ a user or a server (<quote>unknown</quote>).
+ Shows the username, hostname, IP address
+ and the time the connection has been open. It is possible
+ that the ident or DNS lookups have not completed yet, and in
+ any case no tildes are shown here.
+ Unknown connections may not have a name yet.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>User</term>
+ <listitem><para>
+ A registered unopered user.
+ Shows the username, hostname, IP address, the time the client
+ has not sent anything (as in STATS l) and the time the user has
+ been idle (from PRIVMSG only, as in WHOIS).
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Oper</term>
+ <listitem><para>
+ Like User, but opered.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Serv</term>
+ <listitem><para>
+ A registered server.
+ Shows the number of servers and users reached via this link,
+ who made this connection and the time the server has not sent
+ anything.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>ETRACE</title>
+ <cmdsynopsis>
+ <command>ETRACE</command>
+ <arg><replaceable>nick</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Shows client information about the given target, or about all local clients if
+ no target is specified.
+ </para>
+ </sect2>
+ <sect2>
+ <title>MASKTRACE</title>
+ <cmdsynopsis>
+ <command>MASKTRACE</command>
+ <arg choice=plain><replaceable>hostmask</replaceable></arg>
+ <arg><replaceable>gecos</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Searches the local server or network for users that match the hostmask and gecos given.
+ Network searches require the oper_spy privilege and an '!'
+ before the hostmask.
+ The matching works the same way as TESTMASK.
+ </para>
+ <para>
+ The <replaceable>hostmask</replaceable> is of the form user@host
+ or user@ip/cidr with * and ? wildcards, optionally preceded by
+ nick!.
+ </para>
+ <para>
+ The <replaceable>gecos</replaceable> field accepts the same wildcards
+ as xlines.
+ </para>
+ <para>
+ The IP address field contains 255.255.255.255 if the IP address
+ is unknown (remote client on a TS5 server) or 0 if the IP address
+ is hidden (auth{} spoof).
+ </para>
+ </sect2>
+ <sect2>
+ <title>CHANTRACE</title>
+ <cmdsynopsis>
+ <command>CHANTRACE</command>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Displays information about users in a channel.
+ Opers with the oper_spy privilege
+ can get the information without being on the channel,
+ by prefixing the channel name with an '!'.
+ </para>
+ <para>
+ The IP address field contains 255.255.255.255 if the IP address
+ is unknown (remote client on a TS5 server) or 0 if the IP address
+ is hidden (auth{} spoof).
+ </para>
+ </sect2>
+ <sect2>
+ <title>SCAN</title>
+ <cmdsynopsis>
+ <command>SCAN UMODES</command>
+ <arg choice=plain>+<replaceable>modes</replaceable>-<replaceable>modes</replaceable></arg>
+ <arg>no-list</arg>
+ <arg>list</arg>
+ <arg>global</arg>
+ <arg>list-max <replaceable>number</replaceable></arg>
+ <arg>mask <replaceable>nick!user@host</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Searches the local server or network for users that have the umodes given with + and do not have the umodes given with -.
+ no-list disables the listing of matching users and only shows the count.
+ list enables the listing (default).
+ global extends the search to the entire network instead of local users only.
+ list-max limits the listing of matching users to the given amount.
+ mask causes only users matching the given nick!user@host mask
+ to be selected. Only the displayed host is considered, not the
+ IP address or real host behind dynamic spoofs.
+ </para>
+ <para>
+ The IP address field contains 255.255.255.255 if the IP address
+ is unknown (remote client on a TS5 server) or 0 if the IP address
+ is hidden (auth{} spoof).
+ </para>
+ <para>
+ Network searches where a listing is given or the mask option is used
+ are operspy commands.
+ </para>
+ </sect2>
+ <sect2>
+ <title>CHGHOST</title>
+ <cmdsynopsis>
+ <command>CHGHOST</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg choice=plain><replaceable>value</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Set the hostname associated with a particular nick for the duration of this session.
+ This command is disabled by default because of the abuse potential
+ and little practical use.
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="misccommands">
+ <title>Miscellaneous commands</title>
+ <sect2>
+ <title>ADMIN</title>
+ <cmdsynopsis>
+ <command>ADMIN</command>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Shows the information in the admin{} block.
+ </para>
+ </sect2>
+ <sect2>
+ <title>INFO</title>
+ <cmdsynopsis>
+ <command>INFO</command>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Shows information about the authors of the IRC server, and
+ some information about this server instance.
+ Opers also get a list of configuration options.
+ </para>
+ </sect2>
+ <sect2>
+ <title>TIME</title>
+ <cmdsynopsis>
+ <command>TIME</command>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Shows the local time on the given server, in a human-readable format.
+ </para>
+ </sect2>
+ <sect2>
+ <title>VERSION</title>
+ <cmdsynopsis>
+ <command>VERSION</command>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Shows version information, a few compile/config options,
+ the SID and the 005 numerics.
+ The 005 numeric will be remapped to 105 for remote requests.
+ </para>
+ </sect2>
+ <sect2>
+ <title>STATS</title>
+ <cmdsynopsis>
+ <command>STATS</command>
+ <arg><replaceable>type</replaceable></arg>
+ <group>
+ <arg><replaceable>nick</replaceable></arg>
+ <arg><replaceable>server</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ <para>
+ Display various statistics and configuration information.
+ </para>
+ <variablelist>
+ <title>Values for <replaceable>type</replaceable></title>
+ <varlistentry>
+ <term>A</term>
+ <listitem>
+ <para>Show DNS servers</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>b</term>
+ <listitem>
+ <para>Show active nick delays</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>B</term>
+ <listitem>
+ <para>Show hash statistics</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>c</term>
+ <listitem>
+ <para>Show connect blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>d</term>
+ <listitem>
+ <para>Show temporary D:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>D</term>
+ <listitem>
+ <para>Show permanent D:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>e</term>
+ <listitem>
+ <para>Show exempt blocks (exceptions to D:lines)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>E</term>
+ <listitem>
+ <para>Show events</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>f</term>
+ <listitem>
+ <para>Show file descriptors</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>g</term>
+ <listitem>
+ <para>Show pending glines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>G</term>
+ <listitem>
+ <para>Show active glines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>h</term>
+ <listitem>
+ <para>Show hub_mask/leaf_mask</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>i</term>
+ <listitem>
+ <para>Show auth blocks, or matched auth blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>k</term>
+ <listitem>
+ <para>Show temporary K:lines, or matched temporary K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>K</term>
+ <listitem>
+ <para>Show permanent K:lines, or matched permanent K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>l</term>
+ <listitem>
+ <para>
+ Show hostname and link information about the given nick.
+ With a server name, show information about opers and servers
+ on that server; opers also get information about all local users
+ if they query their own server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>L</term>
+ <listitem>
+ <para>Like l, but show IP address instead of hostname</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>m</term>
+ <listitem>
+ <para>Show commands and their usage statistics (total counts, total bytes, counts from server connections)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>n</term>
+ <listitem>
+ <para>Show blacklist blocks (DNS blacklists) with hit counts.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>o</term>
+ <listitem>
+ <para>Show operator blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>p</term>
+ <listitem>
+ <para>Show logged on network operators which are not set AWAY.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>P</term>
+ <listitem>
+ <para>Show listen blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>q</term>
+ <listitem>
+ <para>Show temporarily resv'ed nicks and channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Q</term>
+ <listitem>
+ <para>Show permanently resv'ed nicks and channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>r</term>
+ <listitem>
+ <para>Show resource usage by the ircd</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>t</term>
+ <listitem>
+ <para>Show generic server statistics</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>u</term>
+ <listitem>
+ <para>Show server uptime</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>U</term>
+ <listitem>
+ <para>Show shared (c), cluster (C) and service (s) blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>v</term>
+ <listitem>
+ <para>Show connected servers and brief status</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>x</term>
+ <listitem>
+ <para>Show temporary X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>X</term>
+ <listitem>
+ <para>Show permanent X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>y</term>
+ <listitem>
+ <para>Show class blocks</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>z</term>
+ <listitem>
+ <para>Show memory usage statistics</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Z</term>
+ <listitem>
+ <para>Show ziplinks statistics</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>?</term>
+ <listitem>
+ <para>Show connected servers and sendq information about them</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>WALLOPS</title>
+ <cmdsynopsis>
+ <command>WALLOPS</command>
+ <arg choice=plain>:<replaceable>message</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Sends a WALLOPS message to all users who have the +w umode set. This is for
+ things you don't mind the whole network knowing about.
+ </para>
+ </sect2>
+ <sect2>
+ <title>OPERWALL</title>
+ <cmdsynopsis>
+ <command>OPERWALL</command>
+ <arg choice=plain>:<replaceable>message</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Sends an OPERWALL message to all opers who have the +z umode set. +z is restricted,
+ OPERWALL should be considered private communications.
+ </para>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+sgml-local-ecat-files:nil
+fill-column:105
+End:
+-->
--- /dev/null
+ <chapter id="config">
+ <title>Server config file format</title>
+ <sect1>
+ <title>General format</title>
+ <para>
+ The config file consists of a series of BIND-style blocks. Each block consists of a series
+ of values inside it which pertain to configuration settings that apply to the given block.
+ </para>
+ <para>
+ Several values take lists of values and have defaults preset inside
+ them. Prefix a keyword with a tilde (~) to override the default and
+ disable it.
+ </para>
+ <para>
+ A line may also be a .include directive, which is of the form <synopsis>.include "<replaceable>file</replaceable>"</synopsis>
+ and causes <replaceable>file</replaceable> to be read in at that point, before the rest of the current file is
+ processed.
+ Relative paths are first tried relative to PREFIX and then relative
+ to ETCPATH (normally PREFIX/etc).
+ </para>
+ <para>
+ Anything from a # to the end of a line is a comment. Blank lines are ignored. C-style comments are also supported.
+ </para>
+ </sect1>
+ <sect1 id="configlines">
+ <title>Specific blocks and directives</title>
+ <para>
+ Not all configuration blocks and directives are listed here, only the most common ones. More blocks and directives will
+ be documented in later revisions of this manual.
+ </para>
+ <sect2>
+ <title>loadmodule directive</title>
+ <synopsis>
+loadmodule "<replaceable>text</replaceable>";</synopsis>
+ <para>
+ Loads a module into the IRCd. In charybdis 1.1, most modules are automatically loaded in. In future versions, it is
+ intended to remove this behaviour as to allow for easy customization of the IRCd's featureset.
+ </para>
+ </sect2>
+ <sect2>
+ <title>serverinfo {} block</title>
+ <synopsis>
+serverinfo {
+ name = "<replaceable>text</replaceable>";
+ use_ts6 = <replaceable>boolean</replaceable>;
+ sid = "<replaceable>text</replaceable>";
+ description = "<replaceable>text</replaceable>";
+ network_name = "<replaceable>text</replaceable>";
+ network_desc = "<replaceable>text</replaceable>";
+ hub = <replaceable>boolean</replaceable>;
+ vhost = "<replaceable>text</replaceable>";
+ vhost6 = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ The serverinfo {} block defines the core operational parameters of the IRC server.
+ </para>
+ <variablelist>
+ <title>serverinfo {} variables</title>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>
+ The name of the IRC server that you are configuring. This
+ must contain at least one dot. It is not necessarily equal
+ to any DNS name. This must be unique on the IRC network.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>use_ts6</term>
+ <listitem>
+ <para>
+ A boolean which defines whether or not you want to use the new TS6 protocol, which provides
+ many improvements over the old protocol, TS5, which is used in Hyperion.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>sid</term>
+ <listitem>
+ <para>
+ A unique ID which describes the server. This is required regardless of whether you are using
+ TS6 or not.
+ This consists of one digit and two characters which can be
+ digits or letters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>description</term>
+ <listitem>
+ <para>
+ A user-defined field of text which describes the IRC server. This information is used in
+ /links and /whois requests. Geographical location information could be a useful use of
+ this field, but most administrators put a witty saying inside it instead.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>network_name</term>
+ <listitem>
+ <para>
+ The name of the IRC network that this server will be a member of.
+ This is used in the welcome message and NETWORK= in 005.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>network_desc</term>
+ <listitem>
+ <para>
+ A description of the IRC network that this server will be a member of.
+ This is currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>hub</term>
+ <listitem>
+ <para>
+ A boolean which defines whether or not this IRC server will be serving as a hub, i.e. have multiple servers connected to it.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>vhost</term>
+ <listitem>
+ <para>
+ An optional text field which defines an IP from which to connect outward to other IRC servers.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>vhost6</term>
+ <listitem>
+ <para>
+ An optional text field which defines an IPv6 IP from which to connect outward to other IRC servers.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>admin {} block</title>
+ <synopsis>
+admin {
+ name = "<replaceable>text</replaceable>";
+ description = "<replaceable>text</replaceable>";
+ email = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ This block provides the information which is returned by the ADMIN command.
+ </para>
+ <variablelist>
+ <title>admin {} variables</title>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The name of the administrator running this service.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>description</term>
+ <listitem>
+ <para>The description of the administrator's position in the network.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>email</term>
+ <listitem>
+ <para>A point of contact for the administrator, usually an e-mail address.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>class {} block</title>
+ <synopsis>
+class "<replaceable>name</replaceable>" {
+ ping_time = <replaceable>duration</replaceable>;
+ number_per_ident = <replaceable>number</replaceable>;
+ number_per_ip = <replaceable>number</replaceable>;
+ number_per_ip_global = <replaceable>number</replaceable>;
+ cidr_bitlen = <replaceable>number</replaceable>;
+ number_per_cidr = <replaceable>number</replaceable>;
+ max_number = <replaceable>number</replaceable>;
+ sendq = <replaceable>size</replaceable>;
+};</synopsis>
+ <synopsis>
+class "<replaceable>name</replaceable>" {
+ ping_time = <replaceable>duration</replaceable>;
+ connectfreq = <replaceable>duration</replaceable>;
+ max_number = <replaceable>number</replaceable>;
+ sendq = <replaceable>size</replaceable>;
+};</synopsis>
+ <para>
+ Class blocks define classes of connections for later use.
+ The class name is used to connect them to
+ other blocks in the config file (auth{} and connect{}).
+ They must be defined before they are used.
+ </para>
+ <para>
+ Classes are used both for client and server connections,
+ but most variables are different.
+ </para>
+ <variablelist>
+ <title>class {} variables: client classes</title>
+ <varlistentry>
+ <term>ping_time</term>
+ <listitem>
+ <para>The amount of time between checking pings for clients, e.g.: 2 minutes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>number_per_ident</term>
+ <listitem>
+ <para>The amount of clients which may be connected from a single identd username on a per-IP basis, globally. Unidented clients all count as the same username.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>number_per_ip</term>
+ <listitem>
+ <para>The amount of clients which may be connected from a single IP address.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>number_per_ip_global</term>
+ <listitem>
+ <para>The amount of clients which may be connected globally from a single IP address.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>cidr_bitlen</term>
+ <listitem>
+ <para>The netblock length to use with CIDR-based client limiting for this class.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>number_per_cidr</term>
+ <listitem>
+ <para>The amount of clients which may be connected from a single netblock.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>max_number</term>
+ <listitem>
+ <para>The maximum amount of clients which may use this class at any given time.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>sendq</term>
+ <listitem>
+ <para>The maximum size of the queue of data to be sent to a client before it is dropped.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <title>class {} variables: server classes</title>
+ <varlistentry>
+ <term>ping_time</term>
+ <listitem>
+ <para>The amount of time between checking pings for servers, e.g.: 2 minutes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>connectfreq</term>
+ <listitem>
+ <para>The amount of time between autoconnects. This must at least be one minute, as autoconnects are evaluated with that granularity.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>max_number</term>
+ <listitem>
+ <para>The amount of servers to autoconnect to in this class. More precisely, no autoconnects are done if the number of servers in this class is greater than or equal max_number</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>sendq</term>
+ <listitem>
+ <para>The maximum size of the queue of data to be sent to a server before it is dropped.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>auth {} block</title>
+ <synopsis>
+auth {
+ user = "<replaceable>hostmask</replaceable>";
+ password = "<replaceable>text</replaceable>";
+ spoof = "<replaceable>text</replaceable>";
+ flags = <replaceable>list</replaceable>;
+ class = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ auth {} blocks allow client connections to the server, and set various properties concerning those connections.
+ </para>
+ <para>
+ Auth blocks are evaluated from top to bottom in priority, so put special blocks first.
+ </para>
+ <variablelist>
+ <title>auth {} variables</title>
+ <varlistentry>
+ <term>user</term>
+ <listitem>
+ <para>A hostmask (user@host) that the auth{} block is matched against. You can have multiple user entries.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>password</term>
+ <listitem>
+ <para>
+ An optional password to use for authenticating into this auth{}
+ block. If the password is wrong the user will not be able to
+ connect (will not fall back on another auth{} block).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>spoof</term>
+ <listitem>
+ <para>An optional fake hostname (or user@host) to apply to users authenticated to this auth{} block.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flags</term>
+ <listitem>
+ <para>A list of flags to apply to this auth{} block. They are listed below.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>class</term>
+ <listitem>
+ <para>A name of a class to put users matching this auth{} block into.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <title>auth {} flags</title>
+ <varlistentry>
+ <term>encrypted</term>
+ <listitem>
+ <para>The password used has been encrypted.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>spoof_notice</term>
+ <listitem>
+ <para>Causes the IRCd to send out a server notice when activating a spoof provided by this auth{} block.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>exceed_limit</term>
+ <listitem>
+ <para>Users in this auth{} block can exceed class-wide limitations.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>dnsbl_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block are exempted from DNS blacklist checks. However, they will still be warned if they are listed.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>kline_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block are exempted from DNS blacklists, k:lines, g:lines and x:lines, and will not be disconnected because of d:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>gline_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block are exempted from g:lines.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>spambot_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block are exempted from spambot checks.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>shide_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block are exempted from some serverhiding effects.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>jupe_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block do not trigger an alarm when joining juped channels.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>resv_exempt</term>
+ <listitem>
+ <para>Users in this auth{} block may use reserved nicknames and channels.</para>
+ <note><para>The initial nickname may still not be reserved.</para></note>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flood_exempt</term>
+ <listitem>
+ <para>
+ Users in this auth{} block may send arbitrary amounts of
+ commands per time unit to the server. This does not exempt
+ them from any other flood limits.
+ You should use this setting with caution.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>no_tilde</term>
+ <listitem>
+ <para>Users in this auth{} block will not have a tilde added to their username if they do not run identd.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>need_ident</term>
+ <listitem>
+ <para>Users in this auth{} block must have identd, otherwise they will be rejected.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>need_sasl</term>
+ <listitem>
+ <para>Users in this auth{} block must identify via SASL, otherwise they will be rejected.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>exempt {} block</title>
+ <synopsis>
+exempt {
+ ip = "<replaceable>ip</replaceable>";
+};</synopsis>
+ <para>
+ An exempt block specifies IP addresses which are exempt from D:lines.
+ Multiple addresses can be specified in one block.
+ Clients coming from these addresses can still be K/G/X:lined or
+ banned by a DNS blacklist unless
+ they also have appropriate flags in their auth{} block.
+ </para>
+ <variablelist>
+ <title>exempt {} variables</title>
+ <varlistentry>
+ <term>ip</term>
+ <listitem>
+ <para>The IP address or CIDR range to exempt.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>operator {} block</title>
+ <synopsis>
+operator "<replaceable>name</replaceable>" {
+ user = "<replaceable>hostmask</replaceable>";
+ password = "<replaceable>text</replaceable>";
+ rsa_public_key_file = "<replaceable>text</replaceable>";
+ umodes = <replaceable>list</replaceable>;
+ snomask = "<replaceable>text</replaceable>";
+ flags = <replaceable>list</replaceable>;
+};</synopsis>
+ <para>
+ Operator blocks define who may use the OPER command to gain extended privileges.
+ </para>
+ <variablelist>
+ <title>operator {} variables</title>
+ <varlistentry>
+ <term>user</term>
+ <listitem>
+ <para>
+ A hostmask that users trying to use this operator {} block
+ must match. This is checked against the original host and IP
+ address; CIDR is also supported. So auth {} spoofs work in
+ operator {} blocks; the real host behind them is not checked.
+ Other kind of spoofs do not work in operator {} blocks; the
+ real host behind them is checked.
+ </para>
+ <para>
+ Note that this is different from charybdis 1.x where all
+ kinds of spoofs worked in operator {} blocks.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>password</term>
+ <listitem>
+ <para>
+ A password used with the OPER command to use this operator {} block.
+ Passwords are encrypted by default, but may be unencrypted if ~encrypted is present
+ in the flags list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>rsa_public_key_file</term>
+ <listitem>
+ <para>
+ An optional path to a RSA public key file associated with the operator {} block.
+ This information is used by the CHALLENGE command, which is an alternative authentication
+ scheme to the traditional OPER command.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>umodes</term>
+ <listitem>
+ <para>A list of usermodes to apply to successfully opered clients.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>snomask</term>
+ <listitem>
+ <para>
+ An snomask to apply to successfully opered clients.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flags</term>
+ <listitem>
+ <para>
+ A listing of privileges granted to operators using this block.
+ By default, the operwall and remoteban privileges are granted;
+ use ~operwall and ~remoteban to disable them if necessary.
+ </para>
+ <para>
+ In addition, a flag designating if the password is encrypted is here.
+ Privileges are documented elsewhere in this guide.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>connect {} block</title>
+ <synopsis>
+connect "<replaceable>name</replaceable>" {
+ host = "<replaceable>text</replaceable>";
+ send_password = "<replaceable>text</replaceable>";
+ accept_password = "<replaceable>text</replaceable>";
+ port = <replaceable>number</replaceable>;
+ hub_mask = "<replaceable>mask</replaceable>";
+ leaf_mask = "<replaceable>mask</replaceable>";
+ class = "<replaceable>text</replaceable>";
+ flags = <replaceable>list</replaceable>;
+ aftype = <replaceable>protocol</replaceable>;
+};</synopsis>
+ <para>
+ Connect blocks define what servers may connect or be connected to.
+ </para>
+ <variablelist>
+ <title>connect {} variables</title>
+ <varlistentry>
+ <term>host</term>
+ <listitem>
+ <para>The hostname or IP to connect to.</para>
+ <note><para>
+ Charybdis uses solely DNS for all hostname/address lookups
+ (no <filename>/etc/hosts</filename> or anything else).
+ Furthermore, if a hostname is used, it must have an A or AAAA
+ record (no CNAME) and it must be the primary
+ hostname for inbound connections to work.
+ </para></note>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>send_password</term>
+ <listitem>
+ <para>The password to send to the other server.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>accept_password</term>
+ <listitem>
+ <para>The password that should be accepted from the other server.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>port</term>
+ <listitem>
+ <para>The port on the other server to connect to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>hub_mask</term>
+ <listitem>
+ <para>
+ An optional domain mask of servers allowed to be introduced
+ by this link. Usually, "*" is fine. Multiple hub_masks may be
+ specified, and any of them may be introduced.
+ Violation of hub_mask and leaf_mask restrictions will
+ cause the local link to be closed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>leaf_mask</term>
+ <listitem>
+ <para>
+ An optional domain mask of servers not allowed to be
+ introduced by this link. Multiple leaf_masks may be specified,
+ and none of them may be introduced. leaf_mask has priority
+ over hub_mask.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>class</term>
+ <listitem>
+ <para>The name of the class this server should be placed into.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flags</term>
+ <listitem>
+ <para>A list of flags concerning the connect block. They are listed below.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>aftype</term>
+ <listitem>
+ <para>The protocol that should be used to connect with, either ipv4 or ipv6. This defaults to ipv4 unless host is a numeric IPv6 address.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <title>connect {} flags</title>
+ <varlistentry>
+ <term>encrypted</term>
+ <listitem>
+ <para>The value for accept_password has been encrypted.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>autoconn</term>
+ <listitem>
+ <para>
+ The server should automatically try to connect to the server defined in this
+ connect {} block if it's not connected already and max_number
+ in the class is not reached yet.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>compressed</term>
+ <listitem>
+ <para>Ziplinks should be used with this server connection.
+ This compresses traffic using zlib, saving some bandwidth
+ and speeding up netbursts.</para>
+ <para>If you have trouble setting up a link, you should
+ turn this off as it often hides error messages.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>topicburst</term>
+ <listitem>
+ <para>Topics should be bursted to this server.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>listen {} block</title>
+ <synopsis>
+listen {
+ host = "<replaceable>text</replaceable>";
+ port = <replaceable>number</replaceable>;
+};</synopsis>
+ <para>
+ A listen block specifies what ports a server should listen on.
+ </para>
+ <variablelist>
+ <title>listen {} variables</title>
+ <varlistentry>
+ <term>host</term>
+ <listitem>
+ <para>An optional host to bind to. Otherwise, the ircd will listen on all available hosts.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>port</term>
+ <listitem>
+ <para>
+ A port to listen on. You can specify multiple ports via commas, and define a range by seperating
+ the start and end ports with two dots (..).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>modules {} block</title>
+ <synopsis>
+modules {
+ path = "<replaceable>text</replaceable>";
+ module = <replaceable>text</replaceable>;
+};</synopsis>
+ <para>
+ The modules block specifies information for loadable modules.
+ </para>
+ <variablelist>
+ <title>modules {} variables</title>
+ <varlistentry>
+ <term>path</term>
+ <listitem>
+ <para>Specifies a path to search for loadable modules.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>module</term>
+ <listitem>
+ <para>
+ Specifies a module to load, similar to loadmodule.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>general {} block</title>
+ <synopsis>
+modules {
+ <replaceable>values</replaceable>
+};</synopsis>
+ <para>
+ The general block specifies a variety of options, many of which
+ were in <filename>config.h</filename> in older daemons.
+ The options are documented in <filename>reference.conf</filename>.
+ </para>
+ </sect2>
+ <sect2>
+ <title>channel {} block</title>
+ <synopsis>
+modules {
+ <replaceable>values</replaceable>
+};</synopsis>
+ <para>
+ The channel block specifies a variety of channel-related options,
+ many of which were in <filename>config.h</filename> in older daemons.
+ The options are documented in <filename>reference.conf</filename>.
+ </para>
+ </sect2>
+ <sect2>
+ <title>serverhide {} block</title>
+ <synopsis>
+modules {
+ <replaceable>values</replaceable>
+};</synopsis>
+ <para>
+ The serverhide block specifies options related to server hiding.
+ The options are documented in <filename>reference.conf</filename>.
+ </para>
+ </sect2>
+ <sect2>
+ <title>blacklist {} block</title>
+ <synopsis>
+blacklist {
+ host = "<replaceable>text</replaceable>";
+ reject_reason = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ The blacklist block specifies DNS blacklists to check.
+ Listed clients will not be allowed to connect.
+ IPv6 clients are not checked against these.
+ </para>
+ <para>
+ Multiple blacklists can be specified, in pairs with first host
+ then reject_reason.
+ </para>
+ <variablelist>
+ <title>blacklist {} variables</title>
+ <varlistentry>
+ <term>host</term>
+ <listitem>
+ <para>The DNSBL to use.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>reject_reason</term>
+ <listitem>
+ <para>The reason to send to listed clients when disconnecting them.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>alias {} block</title>
+ <synopsis>
+alias "<replaceable>name</replaceable>" {
+ target = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ Alias blocks allow the definition of custom commands.
+ These commands send PRIVMSG to the given target. A real
+ command takes precedence above an alias.
+ </para>
+ <variablelist>
+ <title>alias {} variables</title>
+ <varlistentry>
+ <term>target</term>
+ <listitem>
+ <para>
+ The target nick (must be a network service (umode +S)) or
+ user@server.
+ In the latter case, the server cannot be this server,
+ only opers can use user starting with "opers" reliably and
+ the user is interpreted on the target server only
+ so you may need to use nick@server instead).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>cluster {} block</title>
+ <synopsis>
+cluster {
+ name = "<replaceable>text</replaceable>";
+ flags = <replaceable>list</replaceable>;
+};</synopsis>
+ <para>
+ The cluster block specifies servers we propagate things to
+ automatically.
+ This does not allow them to set bans, you need a separate shared{}
+ block for that.
+ </para>
+ <para>
+ Having overlapping cluster{} items will cause the command to
+ be executed twice on the target servers. This is particularly
+ undesirable for ban removals.
+ </para>
+ <para>
+ The letters in parentheses denote the flags in /stats U.
+ </para>
+ <variablelist>
+ <title>cluster {} variables</title>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The server name to share with, this may contain wildcards
+ and may be stacked.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flags</term>
+ <listitem>
+ <para>The list of what to share, all the name lines above this
+ (up to another flags entry) will receive these flags.
+ They are listed below.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <title>cluster {} flags</title>
+ <varlistentry>
+ <term>kline (K)</term>
+ <listitem>
+ <para>Permanent K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tkline (k)</term>
+ <listitem>
+ <para>Temporary K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unkline (U)</term>
+ <listitem>
+ <para>K:line removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>xline (X)</term>
+ <listitem>
+ <para>Permanent X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>txline (x)</term>
+ <listitem>
+ <para>Temporary X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unxline (Y)</term>
+ <listitem>
+ <para>X:line removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>resv (Q)</term>
+ <listitem>
+ <para>Permanently reserved nicks/channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tresv (q)</term>
+ <listitem>
+ <para>Temporarily reserved nicks/channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unresv (R)</term>
+ <listitem>
+ <para>RESV removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>locops (L)</term>
+ <listitem>
+ <para>LOCOPS messages (sharing this with * makes LOCOPS rather
+ similar to OPERWALL which is not useful)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>all</term>
+ <listitem>
+ <para>All of the above</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>shared {} block</title>
+ <synopsis>
+shared {
+ oper = "<replaceable>user@host</replaceable>", "<replaceable>server</replaceable>";
+ flags = <replaceable>list</replaceable>;
+};</synopsis>
+ <para>
+ The shared block specifies opers allowed to perform certain actions
+ on our server remotely.
+ These are ordered top down. The first one matching will determine
+ the oper's access.
+ If access is denied, the command will be silently ignored.
+ </para>
+ <para>
+ The letters in parentheses denote the flags in /stats U.
+ </para>
+ <variablelist>
+ <title>shared {} variables</title>
+ <varlistentry>
+ <term>oper</term>
+ <listitem>
+ <para>The user@host the oper must have, and the server they must
+ be on. This may contain wildcards.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>flags</term>
+ <listitem>
+ <para>The list of what to allow, all the oper lines above this
+ (up to another flags entry) will receive these flags.
+ They are listed below.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <note><para>
+ While they have the same names, the flags have subtly different
+ meanings from those in the cluster{} block.
+ </para></note>
+ <variablelist>
+ <title>shared {} flags</title>
+ <varlistentry>
+ <term>kline (K)</term>
+ <listitem>
+ <para>Permanent and temporary K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tkline (k)</term>
+ <listitem>
+ <para>Temporary K:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unkline (U)</term>
+ <listitem>
+ <para>K:line removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>xline (X)</term>
+ <listitem>
+ <para>Permanent and temporary X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>txline (x)</term>
+ <listitem>
+ <para>Temporary X:lines</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unxline (Y)</term>
+ <listitem>
+ <para>X:line removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>resv (Q)</term>
+ <listitem>
+ <para>Permanently and temporarily reserved nicks/channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>tresv (q)</term>
+ <listitem>
+ <para>Temporarily reserved nicks/channels</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>unresv (R)</term>
+ <listitem>
+ <para>RESV removals</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>all</term>
+ <listitem>
+ <para>All of the above; this does not include locops or rehash</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>locops (L)</term>
+ <listitem>
+ <para>LOCOPS messages (accepting this from * makes LOCOPS rather
+ similar to OPERWALL which is not useful); unlike the other flags,
+ this can only be accepted from *@* although it can be
+ restricted based on source server.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>rehash (H)</term>
+ <listitem>
+ <para>REHASH commands; all options can be used</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>none</term>
+ <listitem>
+ <para>Allow nothing to be done</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>service {} block</title>
+ <synopsis>
+service {
+ name = "<replaceable>text</replaceable>";
+};</synopsis>
+ <para>
+ The service block specifies privileged servers (services). These
+ servers have extra privileges such as setting login names on users
+ and introducing clients with umode +S (unkickable, hide channels, etc).
+ This does not allow them to set bans, you need a separate shared{}
+ block for that.
+ </para>
+ <para>
+ Do not place normal servers here.
+ </para>
+ <para>
+ Multiple names may be specified but there may be only one service{}
+ block.
+ </para>
+ <variablelist>
+ <title>service {} variables</title>
+ <varlistentry>
+ <term>name</term>
+ <listitem>
+ <para>The server name to grant special privileges. This may not
+ contain wildcards.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("dancer-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+fill-column:105
+sgml-validate-command: "nsgmls -e -g -s -u dancer-oper-guide.sgml"
+End:
+-->
--- /dev/null
+ <chapter id="intro">
+ <title>Introduction</title>
+ <sect1>
+ <title>Scope of this document</title>
+ <para>
+ This document describes the commands and functions available to operators in
+ the charybdis ircd, as used on <ulink url="http://www.atheme.net">AthemeNet</ulink>.
+ </para>
+ <para>
+ This document, and various ideas for features of charybdis, have
+ been taken from dancer-ircd/hyperion, the ircd used on freenode,
+ mainly written by Andrew Suffield and Jilles Tjoelker.
+ </para>
+ <para>
+ While this document may be of some interest to the users of charybdis servers,
+ it is intended as a reference for network staff.
+ </para>
+ <para>
+ Charybdis is based on ircd-ratbox 2.1.4, although much has changed.
+ <ulink url="http://www.ircd-ratbox.org">ircd-ratbox</ulink> is commonly used
+ on efnet, and some other networks.
+ </para>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+fill-column:105
+sgml-validate-command: "nsgmls -e -g -s -u charybdis-oper-guide.sgml"
+End:
+-->
--- /dev/null
+ <chapter id="oprivs">
+ <title>Oper privileges</title>
+ <sect1 id="oprivlist">
+ <title>Meanings of oper privileges</title>
+ <para>
+ These are flags in operator{}.
+ The letter appears after opering up and in /stats o; an uppercase
+ letter means the privilege is possessed, lowercase means it is not.
+ </para>
+ <sect2>
+ <title>admin (A), server administrator</title>
+ <para>
+ Various privileges intended for server administrators.
+ Among other things, this automatically sets umode +a and allows
+ loading modules.
+ </para>
+ </sect2>
+ <sect2>
+ <title>remoteban (B), set remote bans</title>
+ <para>
+ This grants the ability to use the ON argument on KLINE/XLINE/RESV
+ and UNKLINE/UNXLINE/UNRESV to set and unset bans on other servers,
+ and the server argument on REHASH.
+ This is only allowed if the oper may perform the action locally,
+ and if the remote server has a shared{} block.
+ </para>
+ <note><para>
+ If a cluster{} block is present, bans are sent remotely even
+ if the oper does not have remoteban privilege.
+ </para></note>
+ </sect2>
+ <sect2>
+ <title>local_kill (C), kill local users</title>
+ <para>
+ This grants permission to use KILL on users on the same server,
+ disconnecting them from the network.
+ </para>
+ </sect2>
+ <sect2>
+ <title>die (D), die and restart</title>
+ <para>
+ This grants permission to use DIE and RESTART, shutting down
+ or restarting the server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>gline (G), gline</title>
+ <para>
+ This allows using GLINE (network wide temp bans if 3 opers agree).
+ If unkline privilege is also possessed, allow UNGLINE (remove gline
+ locally).
+ </para>
+ </sect2>
+ <sect2>
+ <title>rehash (H), rehash</title>
+ <para>
+ Allows using the REHASH command, to rehash various configuration
+ files or clear certain lists.
+ </para>
+ </sect2>
+ <sect2>
+ <title>kline (K), kline and dline</title>
+ <para>
+ Allows using KLINE and DLINE, to ban users by user@host mask
+ or IP address.
+ </para>
+ </sect2>
+ <sect2>
+ <title>operwall (L), send/receive operwall</title>
+ <para>
+ Allows using the OPERWALL command and umode +z to send and
+ receive operwalls.
+ </para>
+ </sect2>
+ <sect2>
+ <title>nick_changes (N), see nick changes</title>
+ <para>
+ Allows using snomask +n to see local client nick changes.
+ This is designed for monitor bots.
+ </para>
+ </sect2>
+ <sect2>
+ <title>global_kill (O), global kill</title>
+ <para>
+ Allows using KILL on users on any server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>hidden_oper (P), hide from /stats p</title>
+ <para>
+ This privilege currently does nothing, but was designed
+ to hide bots from /stats p so users will not message them
+ for help.
+ </para>
+ </sect2>
+ <sect2>
+ <title>remote (R), remote routing</title>
+ <para>
+ This allows using the third argument of the CONNECT command, to
+ instruct another server to connect somewhere, and using SQUIT
+ with an argument that is not locally connected.
+ (In both cases all opers with +w set will be notified.)
+ </para>
+ </sect2>
+ <sect2>
+ <title>oper_spy (S), use operspy</title>
+ <para>
+ This allows using /mode !#channel, /whois !nick, /who !#channel,
+ /chantrace !#channel, /who !mask, /masktrace !user@host :gecos
+ and /scan umodes +modes-modes global list to see through secret
+ channels, invisible users, etc.
+ </para>
+ <para>
+ All operspy usage is broadcasted to opers with snomask +Z set
+ (on the entire network) and optionally logged.
+ If you grant this to anyone, it is a good idea to establish
+ concrete policies describing what it is to be used for, and
+ what not.
+ </para>
+ <para>
+ If operspy_dont_care_user_info is enabled, /who mask is operspy
+ also, and /who !mask, /who mask, /masktrace !user@host :gecos
+ and /scan umodes +modes-modes global list do not generate +Z notices
+ or logs.
+ </para>
+ </sect2>
+ <sect2>
+ <title>unkline (U), unkline</title>
+ <para>
+ Allows using UNKLINE and UNDLINE, and if gline privilege is also
+ possessed, UNGLINE.
+ </para>
+ </sect2>
+ <sect2>
+ <title>xline (X), xline and unxline</title>
+ <para>
+ Allows using XLINE and UNXLINE, to ban/unban users by realname.
+ </para>
+ </sect2>
+ <sect2>
+ <title>hidden_admin, hidden administrator</title>
+ <para>
+ This grants everything granted to the admin privilege,
+ except the ability to set umode +a. If both admin and hidden_admin
+ are possessed, umode +a can still not be used.
+ </para>
+ <note><para>
+ This privilege does not appear in /stats o or oper up notices.
+ </para></note>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+fill-column: 105
+sgml-validate-command: "nsgmls -e -g -s -u charybdis-oper-guide.sgml"
+End:
+-->
--- /dev/null
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+<!ENTITY docbook-html.dsl PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
+<!ENTITY docbook-print.dsl PUBLIC "-//Norman Walsh//DOCUMENT DocBook Print Stylesheet//EN" CDATA DSSSL>
+]>
+
+<style-sheet>
+<style-specification id="print" use="print-stylesheet">
+<style-specification-body>
+
+(define %generate-book-titlepage% #t)
+(define %generate-book-titlepage-on-separate-page% #t)
+(define %generate-book-toc% #t)
+(define %generate-book-toc-on-titlepage% #f)
+
+</style-specification-body>
+</style-specification>
+
+<style-specification id="html" use="html-stylesheet">
+<style-specification-body>
+
+(define %header-navigation% #t)
+(define %section-autolabel% #t)
+(define %root-filename% "index")
+(define %use-id-as-filename% #t)
+(define %css-decoration% #t)
+(define %example-rules% #t)
+
+</style-specification-body>
+</style-specification>
+
+<external-specification id="print-stylesheet" document="docbook-print.dsl">
+<external-specification id="html-stylesheet" document="docbook-html.dsl">
+</style-sheet>
--- /dev/null
+ <chapter id="ucommands">
+ <title>User Commands</title>
+ <sect1>
+ <title>User commands</title>
+ <para>
+ Standard IRC commands are not listed here.
+ Several of the commands in the operator commands chapter
+ can also be used by normal users.
+ </para>
+ <sect2>
+ <title>ACCEPT</title>
+ <cmdsynopsis><command>ACCEPT</command>
+ <arg choice=plain><replaceable>nick</replaceable>,</arg>
+ <arg choice=plain>-<replaceable>nick</replaceable>,</arg>
+ <arg choice=plain><replaceable>...</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Adds or removes users from your accept list for umode +g and +R.
+ Users are automatically removed when they quit, split or change
+ nick.
+ </para>
+ <cmdsynopsis><command>ACCEPT</command>
+ <arg choice=plain>*</arg>
+ </cmdsynopsis>
+ <para>
+ Lists all users on your accept list.
+ </para>
+ <para>
+ Support of this command is indicated by the CALLERID token in
+ RPL_ISUPPORT (005); the optional parameter indicates the letter
+ of the <quote>only allow accept users to send private messages</quote>
+ umode, otherwise +g. In charybdis this is always +g.
+ </para>
+ </sect2>
+ <sect2>
+ <title>CNOTICE</title>
+ <cmdsynopsis><command>CNOTICE</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ <arg choice=plain>:<replaceable>text</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Providing you are opped (+o) or voiced (+v) in
+ <replaceable>channel</replaceable>, and <replaceable>nick</replaceable>
+ is a member of <replaceable>channel</replaceable>, CNOTICE generates a NOTICE towards
+ <replaceable>nick</replaceable>.
+ </para>
+ <para>
+ CNOTICE bypasses any anti-spam measures in place.
+ If you get <quote>Targets changing too fast, message dropped</quote>,
+ you should probably use this command, for example sending a
+ notice to every user joining a certain channel.
+ </para>
+ <para>
+ Support of this command is indicated by the CNOTICE token in
+ RPL_ISUPPORT (005).
+ </para>
+ </sect2>
+ <sect2>
+ <title>CPRIVMSG</title>
+ <cmdsynopsis><command>CPRIVMSG</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ <arg choice=plain>:<replaceable>text</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Providing you are opped (+o) or voiced (+v) in
+ <replaceable>channel</replaceable>, and <replaceable>nick</replaceable>
+ is a member of <replaceable>channel</replaceable>, CPRIVMSG generates a PRIVMSG towards
+ <replaceable>nick</replaceable>.
+ </para>
+ <para>
+ CPRIVMSG bypasses any anti-spam measures in place.
+ If you get <quote>Targets changing too fast, message dropped</quote>,
+ you should probably use this command.
+ </para>
+ <para>
+ Support of this command is indicated by the CPRIVMSG token in
+ RPL_ISUPPORT (005).
+ </para>
+ </sect2>
+ <sect2>
+ <title>HELP</title>
+ <cmdsynopsis><command>HELP</command>
+ <arg><replaceable>topic</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Displays help information. <replaceable>topic</replaceable> can
+ be INDEX, CREDITS, UMODE, CMODE, SNOMASK or a command name.
+ </para>
+ <para>
+ There are separate help files for users and opers. Opers can use
+ UHELP to query the user help files.
+ </para>
+ </sect2>
+ <sect2>
+ <title>KNOCK</title>
+ <cmdsynopsis><command>KNOCK</command>
+ <arg choice=plain><replaceable>channel</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Requests an invite to the given channel. The channel must be
+ locked somehow (+ikl), must not be +p and you may not be banned
+ or quieted. Also, this command is rate limited.
+ </para>
+ <para>
+ If successful, all channel operators will receive a 710 numeric.
+ The recipient field of this numeric is the channel.
+ </para>
+ <para>
+ Support of this command is indicated by the KNOCK token in
+ RPL_ISUPPORT (005).
+ </para>
+ </sect2>
+ <sect2>
+ <title>MONITOR</title>
+ <para>
+ Server side notify list. This list contains nicks. When a user
+ connects, quits with a listed nick or changes to or from a listed
+ nick, you will receive a 730 numeric if the nick went online and
+ a 731 numeric if the nick went offline.
+ </para>
+ <para>
+ Support of this command is indicated by the MONITOR token in
+ RPL_ISUPPORT (005); the parameter indicates the maximum number
+ of nicknames you may have in your monitor list.
+ </para>
+ <para>
+ You may only use this command once per second.
+ </para>
+ <para>
+ More details can be found in <filename>doc/monitor.txt</filename>
+ in the source distribution.
+ </para>
+ <cmdsynopsis><command>MONITOR +</command>
+ <arg choice=plain><replaceable>nick</replaceable>,</arg>
+ <arg choice=plain><replaceable>...</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Adds nicks to your monitor list. You will receive 730 and 731
+ numerics for the nicks.
+ </para>
+ <cmdsynopsis><command>MONITOR -</command>
+ <arg choice=plain><replaceable>nick</replaceable>,</arg>
+ <arg choice=plain><replaceable>...</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ Removes nicks from your monitor list. No output is generated for
+ this command.
+ </para>
+ <cmdsynopsis><command>MONITOR C</command>
+ </cmdsynopsis>
+ <para>
+ Clears your monitor list. No output is generated for
+ this command.
+ </para>
+ <cmdsynopsis><command>MONITOR L</command>
+ </cmdsynopsis>
+ <para>
+ Lists all nicks on your monitor list, using 732 numerics and
+ ending with a 733 numeric.
+ </para>
+ <cmdsynopsis><command>MONITOR S</command>
+ </cmdsynopsis>
+ <para>
+ Shows status for all nicks on your monitor list, using 730 and 731
+ numerics.
+ </para>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+sgml-local-ecat-files:nil
+fill-column:105
+End:
+-->
--- /dev/null
+ <chapter id="umodes">
+ <title>Umodes</title>
+ <sect1 id="umodelist">
+ <title>Meanings of user modes</title>
+ <sect2>
+ <title>+a, server administrator</title>
+ <para>
+ This vanity usermode is used to denote a server administrator in WHOIS output.
+ All local <quote>admin</quote> privileges are independent of it, though services
+ packages may grant extra privileges to +a users.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+D, deaf</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ Users with the +D umode set will not receive messages sent to
+ channels. Joins, parts, topic changes, mode changes, etc are
+ received as normal, as are private messages.
+ </para>
+ <para>
+ Support of this umode is indicated by the DEAF token in
+ RPL_ISUPPORT (005); the parameter indicates the letter
+ of the umode. Note that several common IRCD implementations have
+ an umode like this (typically +d) but do not have the token in 005.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+g, Caller ID</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ Users with the +g umode set will only receive private messages from users on a
+ session-defined whitelist, defined by the /accept command. If a user who is not
+ on the whitelist attempts to send a private message, the target user will receive a rate-limited notice saying that the user
+ wishes to speak to them.
+ </para>
+ <para>
+ Network operators are not affected by the callerid whitelist system in the event
+ that they need to speak to users who have it enabled.
+ </para>
+ <para>
+ Support of this umode is indicated by the CALLERID token in
+ RPL_ISUPPORT (005); the optional parameter indicates the letter
+ of the umode, otherwise +g.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+i, invisible</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ Invisible users do not show up in WHO and NAMES unless you can see them.
+ </para>
+ </sect2>
+ <!-- not planned (jilles)
+ <sect2>
+ <title>+I, refuse invite</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ If you have the +I umode set, nobody will be able to issue an INVITE to let you
+ in to a channel.
+ </para>
+ <para>
+ This mode is not yet implemented. It will be implemented in Charybdis 1.1.
+ </para>
+ </sect2>
+ -->
+ <sect2>
+ <title>+l, receive locops</title>
+ <para>
+ LOCOPS is a version of OPERWALL that is sent to opers on a single
+ server only. With cluster{} and shared{} blocks they can optionally
+ be propagated further.
+ </para>
+ <para>
+ Unlike OPERWALL, any oper can send and receive LOCOPS.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+o, operator</title>
+ <para>
+ This indicates global operator status.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+Q, disable forwarding</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ This umode prevents you from being affected by any of the channel forwarding mechanisms. In
+ any event where you would normally be forwarded, instead you will get the usual error message
+ as if no forwarding was in effect.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+R, reject messages from unauthenticated users</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ If a user has the +R umode set, then any users who are not authenticated
+ will receive an error message if they attempt to send a private
+ message or notice to the +R user.
+ </para>
+ <para>
+ Opers and accepted users (like in +g) are exempt.
+ Unlike +g, the target user is not notified of failed messages.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+s, receive server notices</title>
+ <para>
+ This umode allows an oper to receive server notices.
+ The requested types of server notices are specified as a
+ parameter (<quote>snomask</quote>) to this umode.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+S, network service</title>
+ <para>
+ <note>
+ <para>
+ This umode can only be set by servers named in a service{}
+ block.
+ </para>
+ </note>
+ This umode grants various features useful for services. For example,
+ clients with this umode cannot be kicked or deopped on channels,
+ do not show channels the querying user is not on in WHOIS,
+ and do not appear in /stats p.
+ </para>
+ <para>
+ The exact effects of this umode are variable; no user or oper on
+ an actual charybdis server can set it.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+w, receive wallops</title>
+ <para>
+ <note>
+ <para>
+ This is a user umode, which anybody can set. It is not specific to operators.
+ </para>
+ </note>
+ Users with the +w umode set will receive WALLOPS messages sent by opers.
+ Opers with +w additionally receive WALLOPS sent by servers (e.g.
+ remote CONNECT, remote SQUIT, many services packages).
+ </para>
+ </sect2>
+ <sect2>
+ <title>+z, receive operwall</title>
+ <para>
+ OPERWALL differs from WALLOPS in that the ability to receive such messages is
+ restricted. Opers with +z set will receive OPERWALL messages.
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="snomaskusage">
+ <title>Snomask usage</title>
+ <para>
+ Usage is as follows:
+ </para>
+ <cmdsynopsis><command>MODE</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg choice=plain>+s</arg>
+ <arg choice=plain><replaceable>+/-flags</replaceable></arg>
+ </cmdsynopsis>
+ <para>
+ To set snomasks.
+ </para>
+ <cmdsynopsis><command>MODE</command>
+ <arg choice=plain><replaceable>nick</replaceable></arg>
+ <arg choice=plain>-s</arg>
+ </cmdsynopsis>
+ <para>
+ To clear all snomasks.
+ </para>
+ <para>
+ Umode +s will be set if at least one snomask is set.
+ </para>
+ <para>
+ Umode +s is oper only by default, but even if you allow nonopers to
+ set it, they will not get any server notices.
+ </para>
+ </sect1>
+ <sect1 id="snomasklist">
+ <title>Meanings of server notice masks</title>
+ <sect2>
+ <title>+b, bot warnings</title>
+ <para>
+ Opers with the +b snomask set will receive warning messages from the server when potential
+ flooders and spambots are detected.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+c, client connections</title>
+ <para>
+ Opers who have the +c snomask set will receive server notices when clients attach to the
+ local server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+C, extended client connection notices</title>
+ <para>
+ Opers who have the +C snomask set will receive server notices when clients attach to the
+ local server. Unlike the +c snomask, the information is displayed in a format intended
+ to be parsed by scripts, and includes the two unused fields of the USER command.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+d, debug</title>
+ <para>
+ The +d snomask provides opers extra information which may be of interest to debuggers.
+ It will also cause the user to receive server notices if certain assertions fail inside the
+ server. Its precise meaning is variable. Do not depend on the
+ effects of this snomask as they can and will change without notice in later revisions.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+f, full warning</title>
+ <para>
+ Opers with the +f snomask set will receive notices when a user
+ connection is denied because a connection limit is exceeded
+ (one of the limits in a class{} block, or the total per-server
+ limit settable with /quote set max).
+ </para>
+ </sect2>
+ <sect2>
+ <title>+k, server kill notices</title>
+ <para>
+ Opers with the +k snomask set will receive server notices when
+ services kill users and when
+ other servers kill and save (forced nick change to UID) users.
+ Kills and saves by this server are on +d or +s.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+n, nick change notices</title>
+ <para>
+ An oper with +n set will receive a server notice every time a local user changes their nick,
+ giving the old and new nicks.
+ This is mostly useful for bots that track all users on a single server.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+r, notices on name rejections</title>
+ <para>
+ Opers with this snomask set will receive a server notice when somebody tries to use an
+ invalid username, or if a dumb HTTP proxy tries to connect.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+s, generic server notices</title>
+ <para>
+ This snomask allows an oper to receive generic server notices.
+ This includes kills from opers (except services).
+ </para>
+ </sect2>
+ <sect2>
+ <title>+u, unauthorized connections</title>
+ <para>
+ This snomask allows an oper to see when users try to connect who do not have an
+ available auth{} block.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+x, extra routing notices</title>
+ <para>
+ Opers who have the +x snomask set will get notices about servers
+ connecting and disconnecting on the whole network. This includes
+ all servers connected behind the affected link. This can get
+ rather noisy but is useful for keeping track of all linked
+ servers.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+y, spy</title>
+ <para>
+ Opers with +y receive notices when users try to join RESV'ed (<quote>juped</quote>) channels.
+ Additionally, if certain extension modules are loaded, they will
+ receive notices when special commands are used and/or when they
+ are whoised.
+ </para>
+ </sect2>
+ <sect2>
+ <title>+Z, operspy notices</title>
+ <para>
+ Opers with +Z receive notices whenever an oper anywhere on the
+ network uses operspy.
+ </para>
+ <para>
+ This snomask can be configured to be only effective for admins.
+ </para>
+ </sect2>
+ </sect1>
+ </chapter>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document: ("charybdis-oper-guide.sgml" "book")
+sgml-exposed-tags:nil
+fill-column: 105
+sgml-validate-command: "nsgmls -e -g -s -u charybdis-oper-guide.sgml"
+End:
+-->
--- /dev/null
+ Protocol changes for +TSora
+ ---------------------------
+
+
+Note:
+
+The protocols described here implement TimeStamps on IRC channels and
+nicks. The idea of IRC TimeStamps was started on Undernet, and first
+implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here
+are not exactly the same as the ones used on Undernet; the nick-kill
+handling is very similar and must be credited to Run, while the
+"TimeStamped channel description" protocol is quite different.
+
+
+
+TSora servers keep track of which version of the TS protocol (if any)
+their neighboring servers are using, and take it into account when
+sending messages to them. This allows for seamless integration of TS
+servers into a non-TS net, and for upgrades of the protocol.
+
+Each server knows which is the lowest and the highest version of the
+TS protocol it can interact with; currently both of these are set to 1:
+
+#define TS_CURRENT 1 /* the highest TS ver we can do */
+#define TS_MIN 1 /* the lowest TS ver we can do */
+
+
+Timings and TS versions:
+========================
+
+. Keep a 'delta' value to be added to the result of all calls to time(),
+ initially 0.
+
+. Send a second argument to the PASS command, ending in the 'TS' string.
+
+. Send a
+
+ SVINFO <TS_CURRENT> <TS_MIN> <STANDALONE> :<UTC-TIME>
+
+ just after "SERVER", where <STANDALONE> is 1 if we're connected to
+ more TSora servers, and 0 if not, and <UTC-TIME> is our idea of the
+ current UTC time, fixed with the delta.
+
+. When we receive a "SVINFO <x> <y> <z> :<t>" line from a connecting
+ server, we ignore it if TS_CURRENT<y or x<TS_MIN, otherwise we
+ set a flag remembering that that server is TS-aware, remember the TS
+ version to use with it (min(TS_CURRENT, x)). Additionally, if this is
+ our first connected TS server, we set our delta to t-<OUR_UTC> if
+ z==0, and to (t-<OUR_UTC>)/2 if z!=0. The SVINFO data is kept around
+ until the server has effectively registered with SERVER, and used
+ *after* sending our own SVINFO to that server.
+
+
+Explanations:
+
+ Servers will always know which of their directly-linked servers can do
+ TS, and will use the TS protocol only with servers that do understand
+ it. This makes it possible to switch to full TS in just one
+ code-replacement step, without incompatibilities.
+
+ As long as not all servers are TS-aware, the net will be divided into
+ "zones" of linked TS-aware servers. Channel modes will be kept
+ synchronized at least within the zone in which the channel was
+ created, and nick collisions between servers in the same zone will
+ result in only one client being killed.
+
+ Time synchronization ensures that servers have the same idea of the
+ current time, and achieves this purpose as long as TS servers are
+ introduced one by one within the same 'zone'. The merging of two zones
+ cannot synchronize them completely, but it is to be expected that
+ within each zone the effective time will be very close to the real
+ time.
+
+ By sending TSINFO after SERVER rather than before, we avoid the extra
+ lag created by the identd check on the server. To be able to send
+ immediately a connect burst of either type (TS or not), we need to
+ know before that if the server does TS or not, so we send that
+ information with PASS as an extra argument. And to avoid being
+ incompatible with 2.9 servers, which check that this second argument
+ begins with "2.9", we check that it *ends* with "TS".
+
+ The current time is only used when setting a TS on a new channel or
+ nick, and once such a TS is set, it is never modified because of
+ synchronization, as it is much more important that the TS for a
+ channel or nick stays the same across all servers than that it is
+ accurate to the second.
+
+ Note that Undernet's 2.8.x servers have no time synchronization at
+ all, and have had no problems because of it - all of this is more to
+ catch the occasional server with a way-off clock than anything.
+
+
+NICK handling patches (anti-nick-collide + shorter connect burst):
+==================================================================
+
+. For each nick, store a TS value = the TS value received if any, or our
+ UTC+delta at the time we first heard of the nick. TS's are propagated
+ to TS-aware servers whenever sending a NICK command.
+
+. Nick changes reset the TS to the current time.
+
+. When sending a connect burst to another TS server, replace the
+ NICK/USER pair with only one NICK command containing the nick, the
+ hopcount, the TS, the umode, and all the USER information.
+
+ The format for a full NICK line is:
+ NICK <nick> <hops> <TS> <umode> <user> <host> <server> :<ircname>
+
+ The umode is a + followed by any applying usermodes.
+
+ The format for a nick-change NICK line is:
+ :<oldnick> NICK <newnick> :<TS>
+
+. When a NICK is received from a TS server, that conflicts with an
+ existing nick:
+ + if the userhosts differ or one is not known:
+ * if the timestamps are equal, kill ours and the old one if it
+ was a nick change
+ * if the incoming timestamp is older than ours, kill ours and
+ propagate the new one
+ * if the incoming timestamp is younger, ignore the line, but kill
+ the old nick if it was a nick change
+ + if the userhosts are the same:
+ * if the timestamps are equal, kill ours and the old one if it
+ was a nick change
+ * if the incoming timestamp is younger, kill ours and propagate
+ the new one
+ * if the incoming timestamp is older, ignore the line but kill
+ the old nick if it was a nick change
+
+. When a NICK is received from a non-TS server that conflicts with
+ an existing nick, kill both.
+
+. Do not send "Fake Prefix" kills in response to lines coming from TS
+ servers; the sanitization works anyway, and this allows the "newer
+ nick overruled" case to work.
+
+Explanations:
+
+ The modified nick-introduction syntax allows for a slightly shorter
+ connect-burst, and most importantly lets the server compare
+ user@host's when determining which nick to kill: if the user@host
+ is the same, then the older nick must be killed rather than the
+ newer.
+
+ When talking to a non-TS server, we need to behave exactly like one
+ because it expects us to. When talkign to a TS server, we don't kill
+ the nicks it's introducing, as we know it'll be smart enough to do it
+ itself when seeing our own introduced nick.
+
+ When we see a nick arriving from a non-TS server, it won't have a TS,
+ but it's safe enough to give it the current time rather than keeping
+ it 0; such TS's won't be the same all across the network (as long as
+ there is more than one TS zone), and when there's a collision, the TS
+ used will be the one in the zone the collision occurs in.
+
+ Also, it is important to note that by the time a server sees (and
+ chooses to ignore) a nick introduction, the introducing server has
+ also had the time to put umode changes for that nick on its queue, so
+ we must ignore them too... so we need to ignore fake-prefix lines
+ rather than sending kills for them. This is safe enough, as the rest
+ of the protocol ensures that they'll get killed anyway (and the
+ Undernet does it too, so it's been more than enough tested). Just for
+ an extra bit of compatibility, we still kill fake prefixes coming from
+ non-TS servers.
+
+ This part of the TS protocol is almost exactly the same as the
+ Undernet's .anc (anti-nick-collide) patches, except that Undernet
+ servers don't add usermodes to the NICK line.
+
+
+TimeStamped channel descriptions (avoiding hacked ops and desynchs):
+====================================================================
+
+. For each channel, keep a timestamp, set to the current time when the
+ channel is created by a client on the local server, or to the received
+ value if the channel has been propagated from a TS server, or to 0
+ otherwise. This value will have the semantics of "the time of creation
+ of the current ops on the channel", and 0 will mean that the channel
+ is in non-TS mode.
+
+ A new server protocol command is introduced, SJOIN, which introduces
+ a full channel description: a timestamp, all the modes (except bans),
+ and the list of channel members with their ops and voices. This
+ command will be used instead of JOIN and of (most) MODEs both in
+ connect bursts and when propagating channel creations among TS
+ servers. SJOIN will never be accepted from or sent to users.
+
+ The syntax for the command is:
+
+ SJOIN <TS> #<channel> <modes> :[@][+]<nick_1> ... [@][+]<nick_n>
+
+ The fields have the following meanings:
+
+ * <TS> is the timestamp for the channel
+
+ * <modes> is the list of global channel modes, starting with a +
+ and a letter for each of the active modes (spmntkil), followed
+ by an argument for +l if there is a limit, and an argument for
+ +k if there's a key (in the same order they were mentioned in
+ the string of letters).
+
+ A channel with no modes will have a "+" in that field.
+
+ A special value of "0" means that the server does not specify the
+ modes, and will be used when more than one SJOIN line is needed
+ to completely describe a channel, or when propagating a SJOIN
+ the modes of which were rejected.
+
+ * Each nick is preceded by a "@" if the user has ops, and a "+" if
+ the user has a voice. For mode +ov, both flags are used.
+
+ SJOINs will be propagated (when appropriate) to neighboring TS
+ servers, and converted to JOINs and MODEs for neighboring non-TS
+ servers.
+
+ To propagate channels for which not all users fit in one
+ SJOIN line, several SJOINs will be sent consecutively, only the first
+ one including actual information in the <mode> field.
+
+ An extra ad-hoc restriction is imposed on SJOIN messages, to simplify
+ processing: if a channel has ops, then the first <nick> of the first
+ SJOIN sent to propagate that channel must be one of the ops.
+
+ Servers will never attempt to reconstruct a SJOIN from JOIN/MODE
+ information being received at the moment from other servers.
+
+. For each user on a channel, keep an extra flag (like ops and voice)
+ that is set when the user has received channel ops from another
+ server (in a SJOIN channel description), which we rejected (ignored).
+ Mode changes (but NOT kicks) coming from a TS server and from someone
+ with this flag set will be ignored. The flag will be reset when the
+ user gets ops from another user or server.
+
+. On deops done by non-local users, coming from TS servers, on channels
+ with a non-zero TS, do not check that the user has ops but check that
+ their 'deopped' flag is not set. For kicks coming from a TS server, do
+ not check either. This will avoid desynchs, and 'bad' modechanges are
+ avoided anyway. Other mode changes will still only be taken into
+ account and propagated when done by users that are seen as having ops.
+
+. When a MODE change that ops someone is received from a server for a
+ channel, that channel's TS is set to 0, and the mode change is
+ propagated.
+
+. When a SJOIN is received for a channel, deal with it in this way:
+ * received-TS = 0:
+ + if we have ops or the SJOIN doesn't op anyone, SJOIN propagated
+ with our own TS.
+ + otherwise, TS set to 0 and SJOIN propagated with 0.
+ * received-TS > 0, own-TS = 0:
+ + if the SJOIN ops someone or we don't have ops, set our TS to the
+ received TS and propagate.
+ + otherwise, propagate with TS = 0.
+ * received-TS = own-TS: propagate.
+ * received-TS < own-TS:
+ + if the SJOIN ops someone, remove *all* modes (except bans) from
+ the channel and propagate these mode changes to all neighboring
+ non-TS servers, and copy the received TS and propagate the SJOIN.
+ + if the SJOIN does not op anyone and we have ops, propagate
+ with our own TS.
+ + otherwise, copy the received TS and propagate the SJOIN.
+ * received-TS > own-TS:
+ + if the SJOIN does not introduce any ops, process and propagate
+ with our own TS.
+ + if we have ops: for each person the mode change would op, set the
+ 'deopped' flag; process all the JOINs ignoring the '@' and '+'
+ flags; propagate without the flags and with our TS.
+ + if we don't have ops: set our TS to the received one, propagate
+ with the flags.
+
+
+Explanations:
+
+ This part of the protocol is the one that is most different (and
+ incompatible) with the Undernet's: we never timestamp MODE changes,
+ but instead we introduce the concept of time-stamped channel
+ descriptions. This way each server can determine, based on its state
+ and the received description, what the correct modes for a channel
+ are, and deop its own users if necessary. With this protocol, there is
+ *never* the need to reverse and bounce back a mode change. This is
+ both faster and more bandwith-effective.
+
+ The end goal is to have a protocol will eventually protect channels
+ against hacked ops, while minimizing the impact on a mixed-server net.
+ In order to do this, whenever there is a conflict between a TS server
+ and a non-TS one, the non-TS one's idea of the whole situation
+ prevails. This means that channels will only have a TS when they have
+ been created on a TS-aware server, and will lose it whenever a server
+ op comes from a non-TS server. Also, at most one 'zone' will have a TS
+ for any given channel at any given time, ensuring that there won't be
+ any deops when zones are merged. However, when TS zones are merged, if
+ the side that has a TS also has ops, then the TS is kept across the
+ whole new zone. Effective protection will only be ensured once all
+ servers run TS patches and channels have been re-created, as there is
+ no way servers can assign a TS to a channel they are not creating
+ (like they do with nicks) without having unwanted deops later.
+
+ The visible effects of this timestamped channel-description protocol
+ are that when a split rejoins, and one side has hacked ops, the other
+ side doesn't see any server mode changes (just like with Undernet's
+ TS), but the side that has hacked ops sees:
+
+ * first the first server on the other side deopping and devoicing
+ everyone, and fixing the +spmntkli modes
+ * then other users joining, and getting server ops and voices
+
+ The less obvious part of this protocol is its behavior in the case
+ that the younger side of a rejoin has servers that are lagged with
+ each other. In such a situation, a SJOIN that clears all modes and
+ sets the legitimate ones is being propagated from one server, and
+ lagged illegitimate mode changes and kicks are being propagated in the
+ opposite direction. In this case, a kick done by someone who is being
+ deopped by the SJOIN must be taken into account to keep the name list
+ in sync (and since it can only be kicking someone who also was on the
+ younger side), while a deop does not matter (and will be ignored by
+ the first server on the other side), and an opping *needs* to be
+ discareded to avoid hacked ops.
+
+ The main property of timestamped channel descriptions that makes them
+ a very stable protocol even with lag and splits, is that they leave a
+ server in the same final state, independently of the order in which
+ channel descriptions coming from different servers are received. Even
+ when SJOINs and MODEs for the same channel are being propagated in
+ different direction because of several splits rejoining, the final
+ state will be the same, independently of the exact order in which each
+ server received the SJOINs, and will be the same across all the
+ servers in the same zone.
+
+
--- /dev/null
+Server capabilities
+William Pitcock <nenolod -at- nenolod.net>
+-------------------
+
+Not all TSora IRCd's support these.
+
+QS - supports Quit Storm (SQUIT does not have to send recursive quits)
+EX - supports ban exceptions (+e)
+CHW - supports messages directed to channel operators only i.e. @#channel
+IE - supports invite exceptions (+I)
+EOB - supports end of burst notification (EOB token)
+KLN - supports remote KLINE
+UNKLN - supports remote UNKLINE
+GLN - supports hybrid7-style GLINE (:oper GLINE user host :reason)
+HOPS - supports halfops (+h -- %<nick>)
+HUB - denotes that the target server is a HUB
+AOPS - supports anonymous ops (+a, op hiding/op status hiding)
+KNOCK - supports KNOCK extension (request invite to +ikl channel)
+TBURST - supports old TBURST command [broken, don't use.]
+TB - supports new TB command [do use.]
+PARA - supports sending invite notices via INVITE from server
+ENCAP - supports message encapsulation
+SERVICES - supports ratbox's services extensions
+SAVE - supports SAVE extension (friendlier alternative to KILL on nick collide)
+RSFNC - supports RSFNC extension (forcenick)
+CLUSTER - supports remote XLINE, UNXLINE, RESV, UNRESV and LOCOPS
+EUID - supports EUID, non-ENCAP CHGHOST and NICKDELAY
+ZIP - supports ziplinks
+ENC - supports encryption (cryptlinks)
+
+The KLN, UNKLN and CLUSTER capabilities do not apply to klines, xlines
+and resvs sent over ENCAP.
+
+Disabling ban/invite exceptions in ircd.conf does not remove the EX/IE capabs.
--- /dev/null
+$Id: cluster.txt 6 2005-09-10 01:02:21Z nenolod $
+
+Short description of how remote kline and friends are propagated under
+the old hyb7 style (CAP_KLN etc) and under the new style over ENCAP.
+
+CAP_KLN:
+:<source> KLINE <target> <time> <user> <host> :<reason>
+:<source> ENCAP <target> KLINE <time> <user> <host> :<reason>
+
+CAP_UNKLN:
+:<source> UNKLINE <target> <user> <host>
+:<source> ENCAP <target> UNKLINE <user> <host>
+
+CAP_CLUSTER:
+:<source> XLINE <target> <gecos> <type> :<reason>
+:<source> ENCAP <target> XLINE <time> <gecos> <type> :<reason>
+
+:<source> UNXLINE <target> <gecos>
+:<source> ENCAP <target> UNXLINE <gecos>
+
+:<source> RESV <target> <name> :<reason>
+:<source> ENCAP <target> RESV <time> <name> 0 :<reason>
+
+:<source> UNRESV <target> <name>
+:<source> ENCAP <target> UNRESV <name>
+
--- /dev/null
+$Id: euid.txt 1863 2006-08-27 13:40:37Z jilles $
+
+Extended UID command proposal
+Jilles Tjoelker <jilles@stack.nl>
+
+Introduction
+------------
+
+The current protocol to deal with real and visible hosts, with UID, ENCAP
+REALHOST and ENCAP CHGHOST commands has several problems.
+
+In some cases (MONITOR) real hosts are used inappropriately because the UID
+command contains the real host for new users. In other cases (atheme
+akills), the visible host is used inappropriately because the UID command
+contains the visible host for burst users. In both cases nothing is sent
+after the UID command if real and visible hosts are equal. In the latter
+case this problem can be worked around with end-of-burst detection but in
+the former case that is not possible.
+
+This can be fixed by sending both real and visible host in the same command.
+
+This command can also include the data that is currently sent with ENCAP
+LOGIN.
+
+Another problem is that CHGHOST is an ENCAP command although it is important
+for synchronization. One of the problems is that the target often remains
+a UID even if sent to a TS5 server (various old services packages).
+
+This can be fixed by making it a regular command.
+
+Current commands
+----------------
+
+(TS6 form only)
+
+:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
+
+Introduces a user, see Lee Hardy's ts6.txt.
+
+:<UID> ENCAP * REALHOST <REALHOST>
+
+Sets the real host of a user (the hostname in UID is the visible host).
+
+:<SID> ENCAP * CHGHOST <UID> <VHOST>
+
+Sets/changes the visible host of a user (the hostname in UID is the real host).
+
+:<UID> ENCAP * LOGIN <ACCOUNT>
+
+Sets the login name of a user.
+
+New commands
+------------
+
+:<SID> EUID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <VHOST> <IP> <UID> <REALHOST> <ACCOUNT> :<GECOS>
+
+Introduces a user. The hostname field is now always the visible host.
+The realhost field is * if the real host is equal to the visible host.
+The account field is * if the login is not set.
+Note that even if both new fields are *, an EUID command still carries more
+information than a UID command (namely that real host is visible host and the
+user is not logged in with services). Hence a NICK or UID command received
+from a remote server should not be sent in EUID form to other servers.
+
+:<SID> CHGHOST <UID> <VHOST>
+
+Changes the visible host of a user.
+
+A new server capab named EUID will be sent if these commands are supported.
+If the capab is not present, the old commands must be used.
+EUID can (in principle) also be used with TS5.
--- /dev/null
+Overview of the event subsystem
+Adrian Chadd <adrian@creative.net.au>
+
+$Id: event.txt 6 2005-09-10 01:02:21Z nenolod $
+
+
+One of the things that immediately struck me whilst first looking at the
+code was that the ircd periodically scheduled things in io_loop() but
+it did them manually. This is very wasteful and very tedious.
+
+Therefore, an event system was added to hybrid. src/event.c contains an
+event system ported from the squid web cache. It is pretty self contained,
+and only a few things (debugging, time resolution) needed changing.
+
+An event is scheduled through eventAdd() or eventAddIsh() :
+
+eventAdd(const char *name, EVH * func, void *arg, time_t when, int weight)
+eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish,
+ int weight)
+
+after 'when' (or delta_ish) seconds has elapsed from the time the above
+functions are called, the 'func' is called with the given data 'arg'. The
+event is then deleted.
+
+To delete an event, use eventDelete() :
+
+eventDelete(EVH * func, void *arg)
+
+An event is identified by its callback function and data pair.
+
+Events are run through eventRun(). This is designed to be called *BEFORE*
+your IO handlers, to let events scheduled immediately (ie a time of 0)
+to initiate IO before the IO handlers are called.
+
+(Believe me, its useful.)
+
+
+
+Example:
+
+Say you have something which must be called every 15 seconds.
+
+* You would first define the callback in your module:
+
+static EVH foo_periodic_event;
+static int initialised = 0;
+
+* You would then add the event in your initialization function:
+
+void foo_init(void)
+{
+ if (!initialised) {
+ eventAdd("foo_periodic_event", foo_periodic_event, NULL, 0, 0);
+ initialised = 1;
+ }
+}
+
+ This will force the event to be called the next time eventRun() is called,
+ rather than waiting 15 seconds.
+
+* You then define your event callback:
+
+static void
+foo_periodic_event(void *data)
+{
+ /* We'd do our work here */
+
+ /* Then we'd finish */
+ eventAdd("foo_periodic_event", foo_periodic_event, NULL, 15, 0);
+}
+
+
+Notes:
+
+* I really should change the timeout value to be in milliseconds. Squid used
+ a double, but Dianora had something against floating point code in the main
+ loop (which is understandable). If someone wants a fun task .. :-)
+
+* Note that the 'name' parameter to eventAdd() / eventAddIsh() is a const
+ char *, and is *not copied* but *referenced*. Therefore, it is in your
+ best interest to use string constants.
+
+* /stats E for an oper shows pending events. Thanks Diane!
+
--- /dev/null
+Overview of the filedescriptor subsystem
+Adrian Chadd <adrian@creative.net.au>
+
+$Id: fd-management.txt 6 2005-09-10 01:02:21Z nenolod $
+
+
+Filedescriptor lists
+--------------------
+
+The filedescriptor list is managed through the routines in fdlist.c .
+These include:
+
+fd_open() - tag an FD as "open" and active
+fd_close() - tag an FD as "closed" and close() the filedescriptor
+fd_note() - update the filedescriptor tag
+
+You can get the current list of open filedescriptors through /stats F as
+an oper.
+
+
+
+FD lists
+--------
+
+The FD list support is very alpha. There are a few lists defined:
+
+typedef enum fdlist_t {
+ FDLIST_NONE,
+ FDLIST_SERVICE,
+ FDLIST_SERVER,
+ FDLIST_IDLECLIENT,
+ FDLIST_BUSYCLIENT,
+ FDLIST_MAX
+} fdlist_t;
+
+FDLIST_NONE Not on any list (ie close()d)
+FDLIST_SERVICE A service - listen() sockets, resolver, etc
+FDLIST_SERVER Server connections
+FDLIST_IDLECLIENT An idle client
+FDLIST_BUSYCLIENT A busy client
+FDLIST_MAX Used for bounds checking
+
+The idea is that the SERVICE sockets need polling frequently, the SERVER
+sockets also need polling frequently, BUSYCLIENT is for busy clients
+which need frequent polling (eg we're trying to write to them), and
+IDLECLIENT is for clients which we don't need to poll frequently.
+THIS hasn't been decided upon yet.
+
+
+
+File operations
+---------------
+
+The file operations are also wrapped through file_open() and file_close()
+which handle calling fd_open() / fd_close() and tracking the filedescriptors
+correctly. fbopen() / fbclose() use file_open() / file_close() too.
+
+fileio.c defines the functions:
+
+int
+file_open(const char *filename, int mode, int fmode)
+
+A wrapper around open(filename, flags, mode). Read the open manpage for
+information. file_open() enforces filedescriptor limits and tags the FD
+through fd_open().
+
+void
+file_close(int fd)
+
+A wrapper around close() for files. close() handles fd_close()ing the fd.
+
+
+FBFILE *
+fbopen(const char *filename, const char *mode)
+
+void
+fbclose(FBFILE *fb)
+
+These are the 'buffered disk IO' routines. You can read the code yourself.
+Note that these routines use file_open() and file_close().
+
--- /dev/null
+Overview of the file management subsystem
+Adrian Chadd <adrian@creative.net.au>
+
+$Id: file-management.txt 6 2005-09-10 01:02:21Z nenolod $
+
+
+File operations
+---------------
+
+The file operations are also wrapped through file_open() and file_close()
+which handle calling fd_open() / fd_close() and tracking the filedescriptors
+correctly. fbopen() / fbclose() use file_open() / file_close() too.
+
+fileio.c defines the functions:
+
+int
+file_open(const char *filename, int mode, int fmode)
+
+A wrapper around open(filename, flags, mode). Read the open manpage for
+information. file_open() enforces filedescriptor limits and tags the FD
+through fd_open().
+
+void
+file_close(int fd)
+
+A wrapper around close() for files. close() handles fd_close()ing the fd.
+
+
+FBFILE *
+fbopen(const char *filename, const char *mode)
+
+void
+fbclose(FBFILE *fb)
+
+These are the 'buffered disk IO' routines. You can read the code yourself.
+Note that these routines use file_open() and file_close().
+
--- /dev/null
+The hostmask/netmask system.
+Copyright(C) 2001 by Andrew Miller(A1kmm)<a1kmm@mware.virtualave.net>
+$Id: hostmask.txt 6 2005-09-10 01:02:21Z nenolod $
+
+Contents
+========
+* Section 1: Motivation
+* Section 2: Underlying mechanism
+ - 2.1: General overview.
+ - 2.2: IPv4 netmasks.
+ - 2.3: IPv6 netmasks.
+ - 2.4: Hostmasks.
+* Section 3: Exposed abstraction layer
+ - 3.1: Parsing masks.
+ - 3.2: Adding configuration items.
+ - 3.3: Initialising or rehashing.
+ - 3.4: Finding IP/host confs.
+ - 3.5: Deleting entries.
+ - 3.6: Reporting entries.
+
+Section 1: Motivation
+=====================
+Looking up config hostnames and IP addresses(such as for I-lines and
+K-lines) needs to be implemented efficiently. It turns out a hash
+based algorithm like that employed here performs well on the average
+case, which is what we should be the most concerned about. A profiling
+comparison with the mtrie code using data from a real network confirmed
+that this algorithm performs much better.
+
+Section 2: Underlying mechanism
+===============================
+2.1: General overview
+---------------------
+In short, a hash-table with linked lists for buckets is used to locate
+the correct hostname/netmask entries. In order to support CIDR IPs and
+wildcard masks, the entire key cannot be hashed, and there is a need to
+rehash. The means for deciding how much to hash differs between hostmasks
+and IPv4/6 netmasks.
+
+2.2: IPv4 netmasks
+------------------
+In order to hash IPv4 netmasks for addition to the hash, the mask is first
+processed to a 32 bit address and a number of bits used. All unused bits
+are set to 0. The mask could be in the forms:
+1.2.3.4 => 1.2.3.4 32
+1.2.3.* => 1.2.3.0 24
+1.2 => 1.2.0.0 16
+1.2.3.64/26 => 1.2.3.64 26
+The number of whole bytes is then calculated, and only those bytes are
+hashed. (e.g. 1.2.3.64/26 and 1.2.3.0/24 hash the same).
+When a complete IPv4 address is given so that an IPv4 match can be found,
+the entire IP address is first hashed, and looked up in the table. Then
+the most significant three bytes are hashed, followed by the most
+significant two, the most significant one, and finally the 'identity hash'
+bucket is searched(to match masks like 192/7).
+
+2.3: IPv6 netmasks
+------------------
+As per IPv4 netmasks, except that instead of rehashing with a one byte
+granularity, a 16 bit(two byte) granularity is used, as 16 rehashes is
+considered too great a fixed offset to be justified for a (possible)
+slight reduction in hash collisions.
+
+2.4: Hostmasks
+--------------
+On adding a hostmask to the hash, all of the hostmask right of the next
+dot after the last wildcard character in the string is hashed, or in the
+case that there are no wildcards in the hostmask, the entire string is
+hashed.
+On searching for a hostmask match, the entire hostname is hashed, followed
+by the entire hostmask after the first dot, followed by the entire
+hostmask after the second dot, and so on. Finally, the 'identity' hash
+bucket is checked, to catch hostnames like *test*.
+
+Section 3: Exposed abstraction layer
+====================================
+Section 3.1: Parsing masks
+--------------------------
+Call "parse_netmask()" with the netmask and a pointer to an irc_inaddr
+structure to be filled in, as well as a pointer to an integer where the
+number of bits will be placed.
+Always check the return value. If it returns HM_HOST, it means that the
+mask is probably a hostname mask. If it returns HM_IPV4, it means it was
+an IPv4 address. If it returns HM_IPV6, it means it was an IPv6 address.
+If parse_netmask returns HM_HOST, no change is made to the irc_inaddr
+structure or the number of bits.
+
+Section 3.2: Adding configuration items
+---------------------------------------
+Call "add_conf_by_address" with the hostname or IP mask, the username,
+and the ConfItem* to associate with this mask.
+
+Section 3.3: Initialising and rehashing
+----------------------------------------
+To initialise, call init_host_hash(). This only needs to be done once on
+startup.
+On rehash, to wipe out the old unwanted conf, and free them if there are
+no references to them, call clear_out_address_conf().
+
+Section 3.4: Finding IP/host confs
+----------------------------------
+Call find_address_conf() with the hostname, the username, the address,
+and the address family.
+To find a d-line, call find_dline() with the address and address family.
+
+Section 3.5: Deletiing entries
+------------------------------
+Call delete_one_address_conf() with the hostname and the ConfItem*.
+
+Section 3.6: Reporting entries
+------------------------------
+Call report_dlines, report_exemptlines, report_Klines() or report_Ilines()
+with the client pointer to report to. Note these walk the hash, which is
+inefficient, but these are not called often enough to justify the memory
+and maintenance clockcycles to for more efficient data structure.
--- /dev/null
+Technical Documentation for ircd-hybrid-7
+
+Persistent_Clients.txt - A global UID and Persistent client (with cookies)
+ proposal
+README.TSora - Description of the TS3 protocol
+README.openssl - Information for users who have problems with
+ Hybrid, OpenSSL, and their operating system
+cryptlink.txt - Outline of CRYPTLINK protocol
+event.txt - Outline of the event system
+fd-management.txt - Outline of the file descriptor management system
+file-management.txt - Outline of the disk file management system
+hostmask.txt - Outline of hostmask handling
+linebuf.txt - Outline of the linebuf system (dbuf replacement)
+network.txt - Outline of the network traffic subsystem
+rfc1459.txt - The IRC RFC
+send.txt - Document on all of the send_to functions
+whats-new-code.txt - Whats changed in the code
+
+# $Id: index.txt 6 2005-09-10 01:02:21Z nenolod $
--- /dev/null
+
+linebuf - a dbuf replacement for the New World Order(tm)
+
+By Adrian Chadd <adrian@creative.net.au>
+
+$Id: linebuf.txt 6 2005-09-10 01:02:21Z nenolod $
+
+
+History
+-------
+
+I could probably learn the dbuf history, but basically its evil. The
+general idea is that a dbuf holds incoming and outgoing data streams.
+The trouble is that well.. it was evil. You can check it out by getting
+the old src/dbuf.c and include/dbuf.h files if you really want.
+
+
+Replacement
+-----------
+
+The linebuf system is a replacement for the dbuf code. The general idea here
+is that the data should be buffered in "lines" rather than just linearly
+like in the dbuf code. This lends to easier manipulation at a later date
+(think flushing data lines to a socket, and even "sharing" linebufs to
+reduce the copying required for one to many delivery.)
+
+The linebuf system is broken into two structures, the buf_head and buf_line .
+buf_head contains the buffer information (queue head/tail, length, allocated
+length and the write offset for flushing), and buf_line contains the
+line buffer information (buffer and various flags.)
+
+linebuf->terminated is *only* set when a CR/LF combination is received.
+
+linebuf->overflow is set if we get more data than we should, and we simply
+ truncate the incoming data.
+
+linebuf->flushing is set when we are currently writing the buffer. We should
+ _NEVER_ be appending to a buffer which we're flushing!
+
+When you get a buffer through linebuf_get() or write one through
+linebuf_flush(), it will *always* be terminated with a CR/LF (and a NUL if
+its a linebuf_get()).
+
+
+Linebuf manipulation
+--------------------
+
+To use a linebuf, you simply stick a buf_head_t in your structure somewhere.
+You then use the following routines:
+
+int
+linebuf_parse(buf_head_t *bufhead, char *buf, int len)
+
+Parse the given buf. This routine does some complex manipulation:
+
+- if there is an incomplete buffer at the tail, buf is parsed to try and
+ fill that incomplete buffer
+- a buffer is completed by a CR/LF/CRLF/LFCR. It accepts everything purely
+ because I wanted to be "liberal in what you accept" ..
+- If a buffer is terminated, the linebuf is flagged terminated
+- If more data is trying to be squeezed into the buffer than space LEFT
+ in the buffer, we skip to the next "CRLF", and tag the buffer terminated
+ _and_ overflowed.
+- We treat multiple runs of CR/LF/CRLF/LFCR as a single CRLF. This is just
+ a little extra goody to stop people sending hundreds of "CRLF"s and creating
+ unnecessary buffers.
+- The number of lines parsed is returned (so you can implement per-line flood
+ protection ..)
+
+
+void
+linebuf_put(buf_head_t *bufhead, char *buf, int len)
+
+Parse the given buf, ASSUMING it is a single buffer line. This is useful
+for server-generated messages where you know you have a single line, and
+you don't want to go through the overhead of parsing the data just for
+this.
+
+
+int
+linebuf_get(buf_head_t *bufhead, char *buf, int maxlen)
+
+Get a single line from the buffer. This removes data from the head of the
+buffer. If the first buffer is empty or is not terminated, 0 is returned
+which indicates that there is no data to parse. Terminated buffers are
+returned (CR/LF/NUL), and the length INCLUDING the CR/LF/NUL is returned.
+The buffer is copied and the linebuf is then deallocated.
+
+
+int
+linebuf_flush(int fd, buf_head_t *bufhead)
+
+Attempt to flush some data to the given socket. bufhead->writeofs tracks
+where in the head buffer we currently are. If the buffer is not terminated,
+-1 is returned with errno == EWOULDBLOCK to simulate a "retry me" condition.
+(See TODO..)
+
+linebuf_flush() returns whatever write() returns, and sets (ie doesn't touch
+after write()) errno accordingly.
+
+
+int
+linebuf_len(buf_head_t *bufhead)
+
+Return the length of the buffer, in bytes. This should be used when calculating
+how big a buffer is for statistics.
+
+
+int
+linebuf_alloclen(buf_head_t *bufhead)
+
+Return how big the *allocated* space is. This is much more suitable for
+anti-flood checking, as someone might be sending a whole bunch of 1-byte
+linebufs which might not trigger a recvq / sendq limit but might chew up
+way too much memory.
+
+
+
+Notes
+-----
+
+* Remember that the trailing NUL isn't covered in the string length.
+
+
+Limitations
+-----------
+
+* all the buffers are a fixed size - here they are current 513 bytes
+ (510 bytes + CR/LF/NUL)
+
+
+TODO
+----
+
+* linebuf_flush() should be changed a little so if the buffer isn't
+ terminated, we *dont* retry flushing a buffer until we get more data.
+
+* Implement a reference-friendly linebuf to reduce copies ..
+
--- /dev/null
+Overview of the network subsystem
+Adrian Chadd <adrian@creative.net.au>
+
+$Id: network.txt 6 2005-09-10 01:02:21Z nenolod $
+
+
+This document is an overview of the new and hopefully improved network
+subsystem.
+
+The code is based loosely upon the network core found in the Squid web cache
+server, with some optimizations for ircd-specific IO patterns.
+
+
+
+Filedescriptor IO
+-----------------
+
+Filedescriptor IO is initiated using comm_setselect(). comm_setselect()
+registers interest in reading from or writing to a file descriptor.
+When a filedescriptor is ready for the required IO a callback is called
+from the IO loop.
+
+The comm_setselect() usage is:
+
+void
+comm_setselect(int fd, fdlist_t list, int type, PF *callback, void *cbdata,
+ int timeout)
+
+where:
+ fd filedescriptor
+ list Which list the FD should be put on
+ type IO type. Can currently include:
+ COMM_SELECT_READ - register for read
+ COMM_SELECT_WRITE - register for write
+ callback Function to call when the FD is ready
+ cbdata Data to be passed to above function
+ timeout Update the timeout value. 0 is "don't update".
+
+
+A typical use is:
+
+..
+
+/* Register interest in the FD for a read event */
+comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, read_data,
+ 0);
+
+..
+
+(FD becomes ready for read in the IO loop)
+
+void
+read_callback(int fd, void *data)
+{
+ /* called when the FD becomes ready for read */
+ retval = read(fd, buf, len);
+
+ ..
+ /* Ok, we need to read some more when its ready */
+ comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, data,
+ 0);
+}
+
+
+
+
+Socket timeouts
+---------------
+
+A "socket timeout" is a callback registered to be called when a certain
+amount of time has elapsed. Think of it as an event, but against a FD.
+
+A good example of socket timeouts is in the comm_connect_tcp() code.
+When the connect() begins, comm_settimeout() is called to call
+comm_connect_timeout() if the timeout occurs. Once the connect() completes,
+comm_settimeout() is called with a timeout of 0 and callback of NULL
+to deregister the timeout. If the timeout occurs, comm_connect_timeout()
+is called and the connection attempt is aborted.
+
+
+
+
+Functions
+---------
+
+comm_open() - a socket() wrapper, enforcing fd limitations and tagging the
+ file descriptor with a note
+
+comm_accept() - an accept() wrapper, enforcing fd limitations and tagging
+ the file descriptor with a note
+
+comm_connect_tcp() - attempt an async connect(). Handles DNS lookups if
+ required, and will call the given callback at completion or error
+
+comm_settimeout() - set a callback to be called after a given time period.
+ This is good to implement things like PING checks and connect() timeouts.
+
+Notes:
+
+* All socket creation should go through comm_open() / comm_accept().
+* All socket closing should go through fd_close(). comm_close() isn't
+ implemented yet.
+* comm_connect_tcp() is your best friend. :-)
+* *ALL* network sockets should be non-blocking. If your OS doesn't support
+ non-blocking sockets, you shouldn't be here.
--- /dev/null
+
+
+
+
+
+
+Network Working Group J. Oikarinen
+Request for Comments: 1459 D. Reed
+ May 1993
+
+
+ Internet Relay Chat Protocol
+
+Status of This Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. Discussion and suggestions for improvement are requested.
+ Please refer to the current edition of the "IAB Official Protocol
+ Standards" for the standardization state and status of this protocol.
+ Distribution of this memo is unlimited.
+
+Abstract
+
+ The IRC protocol was developed over the last 4 years since it was
+ first implemented as a means for users on a BBS to chat amongst
+ themselves. Now it supports a world-wide network of servers and
+ clients, and is stringing to cope with growth. Over the past 2 years,
+ the average number of users connected to the main IRC network has
+ grown by a factor of 10.
+
+ The IRC protocol is a text-based protocol, with the simplest client
+ being any socket program capable of connecting to the server.
+
+Table of Contents
+
+ 1. INTRODUCTION ............................................... 4
+ 1.1 Servers ................................................ 4
+ 1.2 Clients ................................................ 5
+ 1.2.1 Operators .......................................... 5
+ 1.3 Channels ................................................ 5
+ 1.3.1 Channel Operators .................................... 6
+ 2. THE IRC SPECIFICATION ....................................... 7
+ 2.1 Overview ................................................ 7
+ 2.2 Character codes ......................................... 7
+ 2.3 Messages ................................................ 7
+ 2.3.1 Message format in 'pseudo' BNF .................... 8
+ 2.4 Numeric replies ......................................... 10
+ 3. IRC Concepts ................................................ 10
+ 3.1 One-to-one communication ................................ 10
+ 3.2 One-to-many ............................................. 11
+ 3.2.1 To a list .......................................... 11
+ 3.2.2 To a group (channel) ............................... 11
+ 3.2.3 To a host/server mask .............................. 12
+ 3.3 One to all .............................................. 12
+
+
+
+Oikarinen & Reed [Page 1]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 3.3.1 Client to Client ................................... 12
+ 3.3.2 Clients to Server .................................. 12
+ 3.3.3 Server to Server ................................... 12
+ 4. MESSAGE DETAILS ............................................. 13
+ 4.1 Connection Registration ................................. 13
+ 4.1.1 Password message ................................... 14
+ 4.1.2 Nickname message ................................... 14
+ 4.1.3 User message ....................................... 15
+ 4.1.4 Server message ..................................... 16
+ 4.1.5 Operator message ................................... 17
+ 4.1.6 Quit message ....................................... 17
+ 4.1.7 Server Quit message ................................ 18
+ 4.2 Channel operations ...................................... 19
+ 4.2.1 Join message ....................................... 19
+ 4.2.2 Part message ....................................... 20
+ 4.2.3 Mode message ....................................... 21
+ 4.2.3.1 Channel modes ................................. 21
+ 4.2.3.2 User modes .................................... 22
+ 4.2.4 Topic message ...................................... 23
+ 4.2.5 Names message ...................................... 24
+ 4.2.6 List message ....................................... 24
+ 4.2.7 Invite message ..................................... 25
+ 4.2.8 Kick message ....................................... 25
+ 4.3 Server queries and commands ............................. 26
+ 4.3.1 Version message .................................... 26
+ 4.3.2 Stats message ...................................... 27
+ 4.3.3 Links message ...................................... 28
+ 4.3.4 Time message ....................................... 29
+ 4.3.5 Connect message .................................... 29
+ 4.3.6 Trace message ...................................... 30
+ 4.3.7 Admin message ...................................... 31
+ 4.3.8 Info message ....................................... 31
+ 4.4 Sending messages ........................................ 32
+ 4.4.1 Private messages ................................... 32
+ 4.4.2 Notice messages .................................... 33
+ 4.5 User-based queries ...................................... 33
+ 4.5.1 Who query .......................................... 33
+ 4.5.2 Whois query ........................................ 34
+ 4.5.3 Whowas message ..................................... 35
+ 4.6 Miscellaneous messages .................................. 35
+ 4.6.1 Kill message ....................................... 36
+ 4.6.2 Ping message ....................................... 37
+ 4.6.3 Pong message ....................................... 37
+ 4.6.4 Error message ...................................... 38
+ 5. OPTIONAL MESSAGES ........................................... 38
+ 5.1 Away message ............................................ 38
+ 5.2 Rehash command .......................................... 39
+ 5.3 Restart command ......................................... 39
+
+
+
+Oikarinen & Reed [Page 2]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 5.4 Summon message .......................................... 40
+ 5.5 Users message ........................................... 40
+ 5.6 Operwall command ........................................ 41
+ 5.7 Userhost message ........................................ 42
+ 5.8 Ison message ............................................ 42
+ 6. REPLIES ..................................................... 43
+ 6.1 Error Replies ........................................... 43
+ 6.2 Command responses ....................................... 48
+ 6.3 Reserved numerics ....................................... 56
+ 7. Client and server authentication ............................ 56
+ 8. Current Implementations Details ............................. 56
+ 8.1 Network protocol: TCP ................................... 57
+ 8.1.1 Support of Unix sockets ............................ 57
+ 8.2 Command Parsing ......................................... 57
+ 8.3 Message delivery ........................................ 57
+ 8.4 Connection 'Liveness' ................................... 58
+ 8.5 Establishing a server-client connection ................. 58
+ 8.6 Establishing a server-server connection ................. 58
+ 8.6.1 State information exchange when connecting ......... 59
+ 8.7 Terminating server-client connections ................... 59
+ 8.8 Terminating server-server connections ................... 59
+ 8.9 Tracking nickname changes ............................... 60
+ 8.10 Flood control of clients ............................... 60
+ 8.11 Non-blocking lookups ................................... 61
+ 8.11.1 Hostname (DNS) lookups ............................ 61
+ 8.11.2 Username (Ident) lookups .......................... 61
+ 8.12 Configuration file ..................................... 61
+ 8.12.1 Allowing clients to connect ....................... 62
+ 8.12.2 Operators ......................................... 62
+ 8.12.3 Allowing servers to connect ....................... 62
+ 8.12.4 Administrivia ..................................... 63
+ 8.13 Channel membership ..................................... 63
+ 9. Current problems ............................................ 63
+ 9.1 Scalability ............................................. 63
+ 9.2 Labels .................................................. 63
+ 9.2.1 Nicknames .......................................... 63
+ 9.2.2 Channels ........................................... 64
+ 9.2.3 Servers ............................................ 64
+ 9.3 Algorithms .............................................. 64
+ 10. Support and availability ................................... 64
+ 11. Security Considerations .................................... 65
+ 12. Authors' Addresses ......................................... 65
+
+
+
+
+
+
+
+
+
+Oikarinen & Reed [Page 3]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+1. INTRODUCTION
+
+ The IRC (Internet Relay Chat) protocol has been designed over a
+ number of years for use with text based conferencing. This document
+ describes the current IRC protocol.
+
+ The IRC protocol has been developed on systems using the TCP/IP
+ network protocol, although there is no requirement that this remain
+ the only sphere in which it operates.
+
+ IRC itself is a teleconferencing system, which (through the use of
+ the client-server model) is well-suited to running on many machines
+ in a distributed fashion. A typical setup involves a single process
+ (the server) forming a central point for clients (or other servers)
+ to connect to, performing the required message delivery/multiplexing
+ and other functions.
+
+1.1 Servers
+
+ The server forms the backbone of IRC, providing a point to which
+ clients may connect to to talk to each other, and a point for other
+ servers to connect to, forming an IRC network. The only network
+ configuration allowed for IRC servers is that of a spanning tree [see
+ Fig. 1] where each server acts as a central node for the rest of the
+ net it sees.
+
+
+ [ Server 15 ] [ Server 13 ] [ Server 14]
+ / \ /
+ / \ /
+ [ Server 11 ] ------ [ Server 1 ] [ Server 12]
+ / \ /
+ / \ /
+ [ Server 2 ] [ Server 3 ]
+ / \ \
+ / \ \
+ [ Server 4 ] [ Server 5 ] [ Server 6 ]
+ / | \ /
+ / | \ /
+ / | \____ /
+ / | \ /
+ [ Server 7 ] [ Server 8 ] [ Server 9 ] [ Server 10 ]
+
+ :
+ [ etc. ]
+ :
+
+ [ Fig. 1. Format of IRC server network ]
+
+
+
+Oikarinen & Reed [Page 4]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+1.2 Clients
+
+ A client is anything connecting to a server that is not another
+ server. Each client is distinguished from other clients by a unique
+ nickname having a maximum length of nine (9) characters. See the
+ protocol grammar rules for what may and may not be used in a
+ nickname. In addition to the nickname, all servers must have the
+ following information about all clients: the real name of the host
+ that the client is running on, the username of the client on that
+ host, and the server to which the client is connected.
+
+1.2.1 Operators
+
+ To allow a reasonable amount of order to be kept within the IRC
+ network, a special class of clients (operators) is allowed to perform
+ general maintenance functions on the network. Although the powers
+ granted to an operator can be considered as 'dangerous', they are
+ nonetheless required. Operators should be able to perform basic
+ network tasks such as disconnecting and reconnecting servers as
+ needed to prevent long-term use of bad network routing. In
+ recognition of this need, the protocol discussed herein provides for
+ operators only to be able to perform such functions. See sections
+ 4.1.7 (SQUIT) and 4.3.5 (CONNECT).
+
+ A more controversial power of operators is the ability to remove a
+ user from the connected network by 'force', i.e. operators are able
+ to close the connection between any client and server. The
+ justification for this is delicate since its abuse is both
+ destructive and annoying. For further details on this type of
+ action, see section 4.6.1 (KILL).
+
+1.3 Channels
+
+ A channel is a named group of one or more clients which will all
+ receive messages addressed to that channel. The channel is created
+ implicitly when the first client joins it, and the channel ceases to
+ exist when the last client leaves it. While channel exists, any
+ client can reference the channel using the name of the channel.
+
+ Channels names are strings (beginning with a '&' or '#' character) of
+ length up to 200 characters. Apart from the the requirement that the
+ first character being either '&' or '#'; the only restriction on a
+ channel name is that it may not contain any spaces (' '), a control G
+ (^G or ASCII 7), or a comma (',' which is used as a list item
+ separator by the protocol).
+
+ There are two types of channels allowed by this protocol. One is a
+ distributed channel which is known to all the servers that are
+
+
+
+Oikarinen & Reed [Page 5]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ connected to the network. These channels are marked by the first
+ character being a only clients on the server where it exists may join
+ it. These are distinguished by a leading '&' character. On top of
+ these two types, there are the various channel modes available to
+ alter the characteristics of individual channels. See section 4.2.3
+ (MODE command) for more details on this.
+
+ To create a new channel or become part of an existing channel, a user
+ is required to JOIN the channel. If the channel doesn't exist prior
+ to joining, the channel is created and the creating user becomes a
+ channel operator. If the channel already exists, whether or not your
+ request to JOIN that channel is honoured depends on the current modes
+ of the channel. For example, if the channel is invite-only, (+i),
+ then you may only join if invited. As part of the protocol, a user
+ may be a part of several channels at once, but a limit of ten (10)
+ channels is recommended as being ample for both experienced and
+ novice users. See section 8.13 for more information on this.
+
+ If the IRC network becomes disjoint because of a split between two
+ servers, the channel on each side is only composed of those clients
+ which are connected to servers on the respective sides of the split,
+ possibly ceasing to exist on one side of the split. When the split
+ is healed, the connecting servers announce to each other who they
+ think is in each channel and the mode of that channel. If the
+ channel exists on both sides, the JOINs and MODEs are interpreted in
+ an inclusive manner so that both sides of the new connection will
+ agree about which clients are in the channel and what modes the
+ channel has.
+
+1.3.1 Channel Operators
+
+ The channel operator (also referred to as a "chop" or "chanop") on a
+ given channel is considered to 'own' that channel. In recognition of
+ this status, channel operators are endowed with certain powers which
+ enable them to keep control and some sort of sanity in their channel.
+ As an owner of a channel, a channel operator is not required to have
+ reasons for their actions, although if their actions are generally
+ antisocial or otherwise abusive, it might be reasonable to ask an IRC
+ operator to intervene, or for the usersjust leave and go elsewhere
+ and form their own channel.
+
+ The commands which may only be used by channel operators are:
+
+ KICK - Eject a client from the channel
+ MODE - Change the channel's mode
+ INVITE - Invite a client to an invite-only channel (mode +i)
+ TOPIC - Change the channel topic in a mode +t channel
+
+
+
+
+Oikarinen & Reed [Page 6]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ A channel operator is identified by the '@' symbol next to their
+ nickname whenever it is associated with a channel (ie replies to the
+ NAMES, WHO and WHOIS commands).
+
+2. The IRC Specification
+
+2.1 Overview
+
+ The protocol as described herein is for use both with server to
+ server and client to server connections. There are, however, more
+ restrictions on client connections (which are considered to be
+ untrustworthy) than on server connections.
+
+2.2 Character codes
+
+ No specific character set is specified. The protocol is based on a a
+ set of codes which are composed of eight (8) bits, making up an
+ octet. Each message may be composed of any number of these octets;
+ however, some octet values are used for control codes which act as
+ message delimiters.
+
+ Regardless of being an 8-bit protocol, the delimiters and keywords
+ are such that protocol is mostly usable from USASCII terminal and a
+ telnet connection.
+
+ Because of IRC's scandanavian origin, the characters {}| are
+ considered to be the lower case equivalents of the characters []\,
+ respectively. This is a critical issue when determining the
+ equivalence of two nicknames.
+
+2.3 Messages
+
+ Servers and clients send eachother messages which may or may not
+ generate a reply. If the message contains a valid command, as
+ described in later sections, the client should expect a reply as
+ specified but it is not advised to wait forever for the reply; client
+ to server and server to server communication is essentially
+ asynchronous in nature.
+
+ Each IRC message may consist of up to three main parts: the prefix
+ (optional), the command, and the command parameters (of which there
+ may be up to 15). The prefix, command, and all parameters are
+ separated by one (or more) ASCII space character(s) (0x20).
+
+ The presence of a prefix is indicated with a single leading ASCII
+ colon character (':', 0x3b), which must be the first character of the
+ message itself. There must be no gap (whitespace) between the colon
+ and the prefix. The prefix is used by servers to indicate the true
+
+
+
+Oikarinen & Reed [Page 7]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ origin of the message. If the prefix is missing from the message, it
+ is assumed to have originated from the connection from which it was
+ received. Clients should not use prefix when sending a message from
+ themselves; if they use a prefix, the only valid prefix is the
+ registered nickname associated with the client. If the source
+ identified by the prefix cannot be found from the server's internal
+ database, or if the source is registered from a different link than
+ from which the message arrived, the server must ignore the message
+ silently.
+
+ The command must either be a valid IRC command or a three (3) digit
+ number represented in ASCII text.
+
+ IRC messages are always lines of characters terminated with a CR-LF
+ (Carriage Return - Line Feed) pair, and these messages shall not
+ exceed 512 characters in length, counting all characters including
+ the trailing CR-LF. Thus, there are 510 characters maximum allowed
+ for the command and its parameters. There is no provision for
+ continuation message lines. See section 7 for more details about
+ current implementations.
+
+2.3.1 Message format in 'pseudo' BNF
+
+ The protocol messages must be extracted from the contiguous stream of
+ octets. The current solution is to designate two characters, CR and
+ LF, as message separators. Empty messages are silently ignored,
+ which permits use of the sequence CR-LF between messages
+ without extra problems.
+
+ The extracted message is parsed into the components <prefix>,
+ <command> and list of parameters matched either by <middle> or
+ <trailing> components.
+
+ The BNF representation for this is:
+
+
+<message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
+<prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
+<command> ::= <letter> { <letter> } | <number> <number> <number>
+<SPACE> ::= ' ' { ' ' }
+<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
+
+<middle> ::= <Any *non-empty* sequence of octets not including SPACE
+ or NUL or CR or LF, the first of which may not be ':'>
+<trailing> ::= <Any, possibly *empty*, sequence of octets not including
+ NUL or CR or LF>
+
+<crlf> ::= CR LF
+
+
+
+Oikarinen & Reed [Page 8]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+NOTES:
+
+ 1) <SPACE> is consists only of SPACE character(s) (0x20).
+ Specially notice that TABULATION, and all other control
+ characters are considered NON-WHITE-SPACE.
+
+ 2) After extracting the parameter list, all parameters are equal,
+ whether matched by <middle> or <trailing>. <Trailing> is just
+ a syntactic trick to allow SPACE within parameter.
+
+ 3) The fact that CR and LF cannot appear in parameter strings is
+ just artifact of the message framing. This might change later.
+
+ 4) The NUL character is not special in message framing, and
+ basically could end up inside a parameter, but as it would
+ cause extra complexities in normal C string handling. Therefore
+ NUL is not allowed within messages.
+
+ 5) The last parameter may be an empty string.
+
+ 6) Use of the extended prefix (['!' <user> ] ['@' <host> ]) must
+ not be used in server to server communications and is only
+ intended for server to client messages in order to provide
+ clients with more useful information about who a message is
+ from without the need for additional queries.
+
+ Most protocol messages specify additional semantics and syntax for
+ the extracted parameter strings dictated by their position in the
+ list. For example, many server commands will assume that the first
+ parameter after the command is the list of targets, which can be
+ described with:
+
+ <target> ::= <to> [ "," <target> ]
+ <to> ::= <channel> | <user> '@' <servername> | <nick> | <mask>
+ <channel> ::= ('#' | '&') <chstring>
+ <servername> ::= <host>
+ <host> ::= see RFC 952 [DNS:4] for details on allowed hostnames
+ <nick> ::= <letter> { <letter> | <number> | <special> }
+ <mask> ::= ('#' | '$') <chstring>
+ <chstring> ::= <any 8bit code except SPACE, BELL, NUL, CR, LF and
+ comma (',')>
+
+ Other parameter syntaxes are:
+
+ <user> ::= <nonwhite> { <nonwhite> }
+ <letter> ::= 'a' ... 'z' | 'A' ... 'Z'
+ <number> ::= '0' ... '9'
+ <special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}'
+
+
+
+Oikarinen & Reed [Page 9]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ <nonwhite> ::= <any 8bit code except SPACE (0x20), NUL (0x0), CR
+ (0xd), and LF (0xa)>
+
+2.4 Numeric replies
+
+ Most of the messages sent to the server generate a reply of some
+ sort. The most common reply is the numeric reply, used for both
+ errors and normal replies. The numeric reply must be sent as one
+ message consisting of the sender prefix, the three digit numeric, and
+ the target of the reply. A numeric reply is not allowed to originate
+ from a client; any such messages received by a server are silently
+ dropped. In all other respects, a numeric reply is just like a normal
+ message, except that the keyword is made up of 3 numeric digits
+ rather than a string of letters. A list of different replies is
+ supplied in section 6.
+
+3. IRC Concepts.
+
+ This section is devoted to describing the actual concepts behind the
+ organization of the IRC protocol and how the current
+ implementations deliver different classes of messages.
+
+
+
+ 1--\
+ A D---4
+ 2--/ \ /
+ B----C
+ / \
+ 3 E
+
+ Servers: A, B, C, D, E Clients: 1, 2, 3, 4
+
+ [ Fig. 2. Sample small IRC network ]
+
+3.1 One-to-one communication
+
+ Communication on a one-to-one basis is usually only performed by
+ clients, since most server-server traffic is not a result of servers
+ talking only to each other. To provide a secure means for clients to
+ talk to each other, it is required that all servers be able to send a
+ message in exactly one direction along the spanning tree in order to
+ reach any client. The path of a message being delivered is the
+ shortest path between any two points on the spanning tree.
+
+ The following examples all refer to Figure 2 above.
+
+
+
+
+
+Oikarinen & Reed [Page 10]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+Example 1:
+ A message between clients 1 and 2 is only seen by server A, which
+ sends it straight to client 2.
+
+Example 2:
+ A message between clients 1 and 3 is seen by servers A & B, and
+ client 3. No other clients or servers are allowed see the message.
+
+Example 3:
+ A message between clients 2 and 4 is seen by servers A, B, C & D
+ and client 4 only.
+
+3.2 One-to-many
+
+ The main goal of IRC is to provide a forum which allows easy and
+ efficient conferencing (one to many conversations). IRC offers
+ several means to achieve this, each serving its own purpose.
+
+3.2.1 To a list
+
+ The least efficient style of one-to-many conversation is through
+ clients talking to a 'list' of users. How this is done is almost
+ self explanatory: the client gives a list of destinations to which
+ the message is to be delivered and the server breaks it up and
+ dispatches a separate copy of the message to each given destination.
+ This isn't as efficient as using a group since the destination list
+ is broken up and the dispatch sent without checking to make sure
+ duplicates aren't sent down each path.
+
+3.2.2 To a group (channel)
+
+ In IRC the channel has a role equivalent to that of the multicast
+ group; their existence is dynamic (coming and going as people join
+ and leave channels) and the actual conversation carried out on a
+ channel is only sent to servers which are supporting users on a given
+ channel. If there are multiple users on a server in the same
+ channel, the message text is sent only once to that server and then
+ sent to each client on the channel. This action is then repeated for
+ each client-server combination until the original message has fanned
+ out and reached each member of the channel.
+
+ The following examples all refer to Figure 2.
+
+Example 4:
+ Any channel with 1 client in it. Messages to the channel go to the
+ server and then nowhere else.
+
+
+
+
+
+Oikarinen & Reed [Page 11]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+Example 5:
+ 2 clients in a channel. All messages traverse a path as if they
+ were private messages between the two clients outside a channel.
+
+Example 6:
+ Clients 1, 2 and 3 in a channel. All messages to the channel are
+ sent to all clients and only those servers which must be traversed
+ by the message if it were a private message to a single client. If
+ client 1 sends a message, it goes back to client 2 and then via
+ server B to client 3.
+
+3.2.3 To a host/server mask
+
+ To provide IRC operators with some mechanism to send messages to a
+ large body of related users, host and server mask messages are
+ provided. These messages are sent to users whose host or server
+ information match that of the mask. The messages are only sent to
+ locations where users are, in a fashion similar to that of channels.
+
+3.3 One-to-all
+
+ The one-to-all type of message is better described as a broadcast
+ message, sent to all clients or servers or both. On a large network
+ of users and servers, a single message can result in a lot of traffic
+ being sent over the network in an effort to reach all of the desired
+ destinations.
+
+ For some messages, there is no option but to broadcast it to all
+ servers so that the state information held by each server is
+ reasonably consistent between servers.
+
+3.3.1 Client-to-Client
+
+ There is no class of message which, from a single message, results in
+ a message being sent to every other client.
+
+3.3.2 Client-to-Server
+
+ Most of the commands which result in a change of state information
+ (such as channel membership, channel mode, user status, etc) must be
+ sent to all servers by default, and this distribution may not be
+ changed by the client.
+
+3.3.3 Server-to-Server.
+
+ While most messages between servers are distributed to all 'other'
+ servers, this is only required for any message that affects either a
+ user, channel or server. Since these are the basic items found in
+
+
+
+Oikarinen & Reed [Page 12]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ IRC, nearly all messages originating from a server are broadcast to
+ all other connected servers.
+
+4. Message details
+
+ On the following pages are descriptions of each message recognized by
+ the IRC server and client. All commands described in this section
+ must be implemented by any server for this protocol.
+
+ Where the reply ERR_NOSUCHSERVER is listed, it means that the
+ <server> parameter could not be found. The server must not send any
+ other replies after this for that command.
+
+ The server to which a client is connected is required to parse the
+ complete message, returning any appropriate errors. If the server
+ encounters a fatal error while parsing a message, an error must be
+ sent back to the client and the parsing terminated. A fatal error
+ may be considered to be incorrect command, a destination which is
+ otherwise unknown to the server (server, nick or channel names fit
+ this category), not enough parameters or incorrect privileges.
+
+ If a full set of parameters is presented, then each must be checked
+ for validity and appropriate responses sent back to the client. In
+ the case of messages which use parameter lists using the comma as an
+ item separator, a reply must be sent for each item.
+
+ In the examples below, some messages appear using the full format:
+
+ :Name COMMAND parameter list
+
+ Such examples represent a message from "Name" in transit between
+ servers, where it is essential to include the name of the original
+ sender of the message so remote servers may send back a reply along
+ the correct path.
+
+4.1 Connection Registration
+
+ The commands described here are used to register a connection with an
+ IRC server as either a user or a server as well as correctly
+ disconnect.
+
+ A "PASS" command is not required for either client or server
+ connection to be registered, but it must precede the server message
+ or the latter of the NICK/USER combination. It is strongly
+ recommended that all server connections have a password in order to
+ give some level of security to the actual connections. The
+ recommended order for a client to register is as follows:
+
+
+
+
+Oikarinen & Reed [Page 13]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 1. Pass message
+ 2. Nick message
+ 3. User message
+
+4.1.1 Password message
+
+
+ Command: PASS
+ Parameters: <password>
+
+ The PASS command is used to set a 'connection password'. The
+ password can and must be set before any attempt to register the
+ connection is made. Currently this requires that clients send a PASS
+ command before sending the NICK/USER combination and servers *must*
+ send a PASS command before any SERVER command. The password supplied
+ must match the one contained in the C/N lines (for servers) or I
+ lines (for clients). It is possible to send multiple PASS commands
+ before registering but only the last one sent is used for
+ verification and it may not be changed once registered. Numeric
+ Replies:
+
+ ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED
+
+ Example:
+
+ PASS secretpasswordhere
+
+4.1.2 Nick message
+
+ Command: NICK
+ Parameters: <nickname> [ <hopcount> ]
+
+ NICK message is used to give user a nickname or change the previous
+ one. The <hopcount> parameter is only used by servers to indicate
+ how far away a nick is from its home server. A local connection has
+ a hopcount of 0. If supplied by a client, it must be ignored.
+
+ If a NICK message arrives at a server which already knows about an
+ identical nickname for another client, a nickname collision occurs.
+ As a result of a nickname collision, all instances of the nickname
+ are removed from the server's database, and a KILL command is issued
+ to remove the nickname from all other server's database. If the NICK
+ message causing the collision was a nickname change, then the
+ original (old) nick must be removed as well.
+
+ If the server recieves an identical NICK from a client which is
+ directly connected, it may issue an ERR_NICKCOLLISION to the local
+ client, drop the NICK command, and not generate any kills.
+
+
+
+Oikarinen & Reed [Page 14]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ Numeric Replies:
+
+ ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME
+ ERR_NICKNAMEINUSE ERR_NICKCOLLISION
+
+ Example:
+
+ NICK Wiz ; Introducing new nick "Wiz".
+
+ :WiZ NICK Kilroy ; WiZ changed his nickname to Kilroy.
+
+4.1.3 User message
+
+ Command: USER
+ Parameters: <username> <hostname> <servername> <realname>
+
+ The USER message is used at the beginning of connection to specify
+ the username, hostname, servername and realname of s new user. It is
+ also used in communication between servers to indicate new user
+ arriving on IRC, since only after both USER and NICK have been
+ received from a client does a user become registered.
+
+ Between servers USER must to be prefixed with client's NICKname.
+ Note that hostname and servername are normally ignored by the IRC
+ server when the USER command comes from a directly connected client
+ (for security reasons), but they are used in server to server
+ communication. This means that a NICK must always be sent to a
+ remote server when a new user is being introduced to the rest of the
+ network before the accompanying USER is sent.
+
+ It must be noted that realname parameter must be the last parameter,
+ because it may contain space characters and must be prefixed with a
+ colon (':') to make sure this is recognised as such.
+
+ Since it is easy for a client to lie about its username by relying
+ solely on the USER message, the use of an "Identity Server" is
+ recommended. If the host which a user connects from has such a
+ server enabled the username is set to that as in the reply from the
+ "Identity Server".
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED
+
+ Examples:
+
+
+ USER guest tolmoon tolsun :Ronnie Reagan
+
+
+
+Oikarinen & Reed [Page 15]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ ; User registering themselves with a
+ username of "guest" and real name
+ "Ronnie Reagan".
+
+
+ :testnick USER guest tolmoon tolsun :Ronnie Reagan
+ ; message between servers with the
+ nickname for which the USER command
+ belongs to
+
+4.1.4 Server message
+
+ Command: SERVER
+ Parameters: <servername> <hopcount> <info>
+
+ The server message is used to tell a server that the other end of a
+ new connection is a server. This message is also used to pass server
+ data over whole net. When a new server is connected to net,
+ information about it be broadcast to the whole network. <hopcount>
+ is used to give all servers some internal information on how far away
+ all servers are. With a full server list, it would be possible to
+ construct a map of the entire server tree, but hostmasks prevent this
+ from being done.
+
+ The SERVER message must only be accepted from either (a) a connection
+ which is yet to be registered and is attempting to register as a
+ server, or (b) an existing connection to another server, in which
+ case the SERVER message is introducing a new server behind that
+ server.
+
+ Most errors that occur with the receipt of a SERVER command result in
+ the connection being terminated by the destination host (target
+ SERVER). Error replies are usually sent using the "ERROR" command
+ rather than the numeric since the ERROR command has several useful
+ properties which make it useful here.
+
+ If a SERVER message is parsed and attempts to introduce a server
+ which is already known to the receiving server, the connection from
+ which that message must be closed (following the correct procedures),
+ since a duplicate route to a server has formed and the acyclic nature
+ of the IRC tree broken.
+
+ Numeric Replies:
+
+ ERR_ALREADYREGISTRED
+
+ Example:
+
+
+
+
+Oikarinen & Reed [Page 16]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+SERVER test.oulu.fi 1 :[tolsun.oulu.fi] Experimental server
+ ; New server test.oulu.fi introducing
+ itself and attempting to register. The
+ name in []'s is the hostname for the
+ host running test.oulu.fi.
+
+
+:tolsun.oulu.fi SERVER csd.bu.edu 5 :BU Central Server
+ ; Server tolsun.oulu.fi is our uplink
+ for csd.bu.edu which is 5 hops away.
+
+4.1.5 Oper
+
+ Command: OPER
+ Parameters: <user> <password>
+
+ OPER message is used by a normal user to obtain operator privileges.
+ The combination of <user> and <password> are required to gain
+ Operator privileges.
+
+ If the client sending the OPER command supplies the correct password
+ for the given user, the server then informs the rest of the network
+ of the new operator by issuing a "MODE +o" for the clients nickname.
+
+ The OPER message is client-server only.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS RPL_YOUREOPER
+ ERR_NOOPERHOST ERR_PASSWDMISMATCH
+
+ Example:
+
+ OPER foo bar ; Attempt to register as an operator
+ using a username of "foo" and "bar" as
+ the password.
+
+4.1.6 Quit
+
+ Command: QUIT
+ Parameters: [<Quit message>]
+
+ A client session is ended with a quit message. The server must close
+ the connection to a client which sends a QUIT message. If a "Quit
+ Message" is given, this will be sent instead of the default message,
+ the nickname.
+
+ When netsplits (disconnecting of two servers) occur, the quit message
+
+
+
+Oikarinen & Reed [Page 17]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ is composed of the names of two servers involved, separated by a
+ space. The first name is that of the server which is still connected
+ and the second name is that of the server that has become
+ disconnected.
+
+ If, for some other reason, a client connection is closed without the
+ client issuing a QUIT command (e.g. client dies and EOF occurs
+ on socket), the server is required to fill in the quit message with
+ some sort of message reflecting the nature of the event which
+ caused it to happen.
+
+ Numeric Replies:
+
+ None.
+
+ Examples:
+
+ QUIT :Gone to have lunch ; Preferred message format.
+
+4.1.7 Server quit message
+
+ Command: SQUIT
+ Parameters: <server> <comment>
+
+ The SQUIT message is needed to tell about quitting or dead servers.
+ If a server wishes to break the connection to another server it must
+ send a SQUIT message to the other server, using the the name of the
+ other server as the server parameter, which then closes its
+ connection to the quitting server.
+
+ This command is also available operators to help keep a network of
+ IRC servers connected in an orderly fashion. Operators may also
+ issue an SQUIT message for a remote server connection. In this case,
+ the SQUIT must be parsed by each server inbetween the operator and
+ the remote server, updating the view of the network held by each
+ server as explained below.
+
+ The <comment> should be supplied by all operators who execute a SQUIT
+ for a remote server (that is not connected to the server they are
+ currently on) so that other operators are aware for the reason of
+ this action. The <comment> is also filled in by servers which may
+ place an error or similar message here.
+
+ Both of the servers which are on either side of the connection being
+ closed are required to to send out a SQUIT message (to all its other
+ server connections) for all other servers which are considered to be
+ behind that link.
+
+
+
+
+Oikarinen & Reed [Page 18]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ Similarly, a QUIT message must be sent to the other connected servers
+ rest of the network on behalf of all clients behind that link. In
+ addition to this, all channel members of a channel which lost a
+ member due to the split must be sent a QUIT message.
+
+ If a server connection is terminated prematurely (e.g. the server on
+ the other end of the link died), the server which detects
+ this disconnection is required to inform the rest of the network
+ that the connection has closed and fill in the comment field
+ with something appropriate.
+
+ Numeric replies:
+
+ ERR_NOPRIVILEGES ERR_NOSUCHSERVER
+
+ Example:
+
+ SQUIT tolsun.oulu.fi :Bad Link ? ; the server link tolson.oulu.fi has
+ been terminated because of "Bad Link".
+
+ :Trillian SQUIT cm22.eng.umd.edu :Server out of control
+ ; message from Trillian to disconnect
+ "cm22.eng.umd.edu" from the net
+ because "Server out of control".
+
+4.2 Channel operations
+
+ This group of messages is concerned with manipulating channels, their
+ properties (channel modes), and their contents (typically clients).
+ In implementing these, a number of race conditions are inevitable
+ when clients at opposing ends of a network send commands which will
+ ultimately clash. It is also required that servers keep a nickname
+ history to ensure that wherever a <nick> parameter is given, the
+ server check its history in case it has recently been changed.
+
+4.2.1 Join message
+
+ Command: JOIN
+ Parameters: <channel>{,<channel>} [<key>{,<key>}]
+
+ The JOIN command is used by client to start listening a specific
+ channel. Whether or not a client is allowed to join a channel is
+ checked only by the server the client is connected to; all other
+ servers automatically add the user to the channel when it is received
+ from other servers. The conditions which affect this are as follows:
+
+ 1. the user must be invited if the channel is invite-only;
+
+
+
+
+Oikarinen & Reed [Page 19]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 2. the user's nick/username/hostname must not match any
+ active bans;
+
+ 3. the correct key (password) must be given if it is set.
+
+ These are discussed in more detail under the MODE command (see
+ section 4.2.3 for more details).
+
+ Once a user has joined a channel, they receive notice about all
+ commands their server receives which affect the channel. This
+ includes MODE, KICK, PART, QUIT and of course PRIVMSG/NOTICE. The
+ JOIN command needs to be broadcast to all servers so that each server
+ knows where to find the users who are on the channel. This allows
+ optimal delivery of PRIVMSG/NOTICE messages to the channel.
+
+ If a JOIN is successful, the user is then sent the channel's topic
+ (using RPL_TOPIC) and the list of users who are on the channel (using
+ RPL_NAMREPLY), which must include the user joining.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN
+ ERR_INVITEONLYCHAN ERR_BADCHANNELKEY
+ ERR_CHANNELISFULL ERR_BADCHANMASK
+ ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS
+ RPL_TOPIC
+
+ Examples:
+
+ JOIN #foobar ; join channel #foobar.
+
+ JOIN &foo fubar ; join channel &foo using key "fubar".
+
+ JOIN #foo,&bar fubar ; join channel #foo using key "fubar"
+ and &bar using no key.
+
+ JOIN #foo,#bar fubar,foobar ; join channel #foo using key "fubar".
+ and channel #bar using key "foobar".
+
+ JOIN #foo,#bar ; join channels #foo and #bar.
+
+ :WiZ JOIN #Twilight_zone ; JOIN message from WiZ
+
+4.2.2 Part message
+
+ Command: PART
+ Parameters: <channel>{,<channel>}
+
+
+
+
+Oikarinen & Reed [Page 20]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ The PART message causes the client sending the message to be removed
+ from the list of active users for all given channels listed in the
+ parameter string.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL
+ ERR_NOTONCHANNEL
+
+ Examples:
+
+ PART #twilight_zone ; leave channel "#twilight_zone"
+
+ PART #oz-ops,&group5 ; leave both channels "&group5" and
+ "#oz-ops".
+
+4.2.3 Mode message
+
+ Command: MODE
+
+ The MODE command is a dual-purpose command in IRC. It allows both
+ usernames and channels to have their mode changed. The rationale for
+ this choice is that one day nicknames will be obsolete and the
+ equivalent property will be the channel.
+
+ When parsing MODE messages, it is recommended that the entire message
+ be parsed first and then the changes which resulted then passed on.
+
+4.2.3.1 Channel modes
+
+ Parameters: <channel> {[+|-]|o|p|s|i|t|n|b|v} [<limit>] [<user>]
+ [<ban mask>]
+
+ The MODE command is provided so that channel operators may change the
+ characteristics of `their' channel. It is also required that servers
+ be able to change channel modes so that channel operators may be
+ created.
+
+ The various modes available for channels are as follows:
+
+ o - give/take channel operator privileges;
+ p - private channel flag;
+ s - secret channel flag;
+ i - invite-only channel flag;
+ t - topic settable by channel operator only flag;
+ n - no messages to channel from clients on the outside;
+ m - moderated channel;
+ l - set the user limit to channel;
+
+
+
+Oikarinen & Reed [Page 21]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ b - set a ban mask to keep users out;
+ v - give/take the ability to speak on a moderated channel;
+ k - set a channel key (password).
+
+ When using the 'o' and 'b' options, a restriction on a total of three
+ per mode command has been imposed. That is, any combination of 'o'
+ and
+
+4.2.3.2 User modes
+
+ Parameters: <nickname> {[+|-]|i|w|s|o}
+
+ The user MODEs are typically changes which affect either how the
+ client is seen by others or what 'extra' messages the client is sent.
+ A user MODE command may only be accepted if both the sender of the
+ message and the nickname given as a parameter are both the same.
+
+ The available modes are as follows:
+
+ i - marks a users as invisible;
+ s - marks a user for receipt of server notices;
+ w - user receives wallops;
+ o - operator flag.
+
+ Additional modes may be available later on.
+
+ If a user attempts to make themselves an operator using the "+o"
+ flag, the attempt should be ignored. There is no restriction,
+ however, on anyone `deopping' themselves (using "-o"). Numeric
+ Replies:
+
+ ERR_NEEDMOREPARAMS RPL_CHANNELMODEIS
+ ERR_CHANOPRIVSNEEDED ERR_NOSUCHNICK
+ ERR_NOTONCHANNEL ERR_KEYSET
+ RPL_BANLIST RPL_ENDOFBANLIST
+ ERR_UNKNOWNMODE ERR_NOSUCHCHANNEL
+
+ ERR_USERSDONTMATCH RPL_UMODEIS
+ ERR_UMODEUNKNOWNFLAG
+
+ Examples:
+
+ Use of Channel Modes:
+
+MODE #Finnish +im ; Makes #Finnish channel moderated and
+ 'invite-only'.
+
+MODE #Finnish +o Kilroy ; Gives 'chanop' privileges to Kilroy on
+
+
+
+Oikarinen & Reed [Page 22]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ channel #Finnish.
+
+MODE #Finnish +v Wiz ; Allow WiZ to speak on #Finnish.
+
+MODE #Fins -s ; Removes 'secret' flag from channel
+ #Fins.
+
+MODE #42 +k oulu ; Set the channel key to "oulu".
+
+MODE #eu-opers +l 10 ; Set the limit for the number of users
+ on channel to 10.
+
+MODE &oulu +b ; list ban masks set for channel.
+
+MODE &oulu +b *!*@* ; prevent all users from joining.
+
+MODE &oulu +b *!*@*.edu ; prevent any user from a hostname
+ matching *.edu from joining.
+
+ Use of user Modes:
+
+:MODE WiZ -w ; turns reception of WALLOPS messages
+ off for WiZ.
+
+:Angel MODE Angel +i ; Message from Angel to make themselves
+ invisible.
+
+MODE WiZ -o ; WiZ 'deopping' (removing operator
+ status). The plain reverse of this
+ command ("MODE WiZ +o") must not be
+ allowed from users since would bypass
+ the OPER command.
+
+4.2.4 Topic message
+
+ Command: TOPIC
+ Parameters: <channel> [<topic>]
+
+ The TOPIC message is used to change or view the topic of a channel.
+ The topic for channel <channel> is returned if there is no <topic>
+ given. If the <topic> parameter is present, the topic for that
+ channel will be changed, if the channel modes permit this action.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_NOTONCHANNEL
+ RPL_NOTOPIC RPL_TOPIC
+ ERR_CHANOPRIVSNEEDED
+
+
+
+Oikarinen & Reed [Page 23]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ Examples:
+
+ :Wiz TOPIC #test :New topic ;User Wiz setting the topic.
+
+ TOPIC #test :another topic ;set the topic on #test to "another
+ topic".
+
+ TOPIC #test ; check the topic for #test.
+
+4.2.5 Names message
+
+ Command: NAMES
+ Parameters: [<channel>{,<channel>}]
+
+ By using the NAMES command, a user can list all nicknames that are
+ visible to them on any channel that they can see. Channel names
+ which they can see are those which aren't private (+p) or secret (+s)
+ or those which they are actually on. The <channel> parameter
+ specifies which channel(s) to return information about if valid.
+ There is no error reply for bad channel names.
+
+ If no <channel> parameter is given, a list of all channels and their
+ occupants is returned. At the end of this list, a list of users who
+ are visible but either not on any channel or not on a visible channel
+ are listed as being on `channel' "*".
+
+ Numerics:
+
+ RPL_NAMREPLY RPL_ENDOFNAMES
+
+ Examples:
+
+ NAMES #twilight_zone,#42 ; list visible users on #twilight_zone
+ and #42 if the channels are visible to
+ you.
+
+ NAMES ; list all visible channels and users
+
+4.2.6 List message
+
+ Command: LIST
+ Parameters: [<channel>{,<channel>} [<server>]]
+
+ The list message is used to list channels and their topics. If the
+ <channel> parameter is used, only the status of that channel
+ is displayed. Private channels are listed (without their
+ topics) as channel "Prv" unless the client generating the query is
+ actually on that channel. Likewise, secret channels are not listed
+
+
+
+Oikarinen & Reed [Page 24]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ at all unless the client is a member of the channel in question.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER RPL_LISTSTART
+ RPL_LIST RPL_LISTEND
+
+ Examples:
+
+ LIST ; List all channels.
+
+ LIST #twilight_zone,#42 ; List channels #twilight_zone and #42
+
+4.2.7 Invite message
+
+ Command: INVITE
+ Parameters: <nickname> <channel>
+
+ The INVITE message is used to invite users to a channel. The
+ parameter <nickname> is the nickname of the person to be invited to
+ the target channel <channel>. There is no requirement that the
+ channel the target user is being invited to must exist or be a valid
+ channel. To invite a user to a channel which is invite only (MODE
+ +i), the client sending the invite must be recognised as being a
+ channel operator on the given channel.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_NOSUCHNICK
+ ERR_NOTONCHANNEL ERR_USERONCHANNEL
+ ERR_CHANOPRIVSNEEDED
+ RPL_INVITING RPL_AWAY
+
+ Examples:
+
+ :Angel INVITE Wiz #Dust ; User Angel inviting WiZ to channel
+ #Dust
+
+ INVITE Wiz #Twilight_Zone ; Command to invite WiZ to
+ #Twilight_zone
+
+4.2.8 Kick command
+
+ Command: KICK
+ Parameters: <channel> <user> [<comment>]
+
+ The KICK command can be used to forcibly remove a user from a
+ channel. It 'kicks them out' of the channel (forced PART).
+
+
+
+Oikarinen & Reed [Page 25]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ Only a channel operator may kick another user out of a channel.
+ Each server that receives a KICK message checks that it is valid
+ (ie the sender is actually a channel operator) before removing
+ the victim from the channel.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL
+ ERR_BADCHANMASK ERR_CHANOPRIVSNEEDED
+ ERR_NOTONCHANNEL
+
+ Examples:
+
+KICK &Melbourne Matthew ; Kick Matthew from &Melbourne
+
+KICK #Finnish John :Speaking English
+ ; Kick John from #Finnish using
+ "Speaking English" as the reason
+ (comment).
+
+:WiZ KICK #Finnish John ; KICK message from WiZ to remove John
+ from channel #Finnish
+
+NOTE:
+ It is possible to extend the KICK command parameters to the
+following:
+
+<channel>{,<channel>} <user>{,<user>} [<comment>]
+
+4.3 Server queries and commands
+
+ The server query group of commands has been designed to return
+ information about any server which is connected to the network. All
+ servers connected must respond to these queries and respond
+ correctly. Any invalid response (or lack thereof) must be considered
+ a sign of a broken server and it must be disconnected/disabled as
+ soon as possible until the situation is remedied.
+
+ In these queries, where a parameter appears as "<server>", it will
+ usually mean it can be a nickname or a server or a wildcard name of
+ some sort. For each parameter, however, only one query and set of
+ replies is to be generated.
+
+4.3.1 Version message
+
+ Command: VERSION
+ Parameters: [<server>]
+
+
+
+
+Oikarinen & Reed [Page 26]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ The VERSION message is used to query the version of the server
+ program. An optional parameter <server> is used to query the version
+ of the server program which a client is not directly connected to.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER RPL_VERSION
+
+ Examples:
+
+ :Wiz VERSION *.se ; message from Wiz to check the version
+ of a server matching "*.se"
+
+ VERSION tolsun.oulu.fi ; check the version of server
+ "tolsun.oulu.fi".
+
+4.3.2 Stats message
+
+ Command: STATS
+ Parameters: [<query> [<server>]]
+
+ The stats message is used to query statistics of certain server. If
+ <server> parameter is omitted, only the end of stats reply is sent
+ back. The implementation of this command is highly dependent on the
+ server which replies, although the server must be able to supply
+ information as described by the queries below (or similar).
+
+ A query may be given by any single letter which is only checked by
+ the destination server (if given as the <server> parameter) and is
+ otherwise passed on by intermediate servers, ignored and unaltered.
+ The following queries are those found in the current IRC
+ implementation and provide a large portion of the setup information
+ for that server. Although these may not be supported in the same way
+ by other versions, all servers should be able to supply a valid reply
+ to a STATS query which is consistent with the reply formats currently
+ used and the purpose of the query.
+
+ The currently supported queries are:
+
+ c - returns a list of servers which the server may connect
+ to or allow connections from;
+ h - returns a list of servers which are either forced to be
+ treated as leaves or allowed to act as hubs;
+ i - returns a list of hosts which the server allows a client
+ to connect from;
+ k - returns a list of banned username/hostname combinations
+ for that server;
+ l - returns a list of the server's connections, showing how
+
+
+
+Oikarinen & Reed [Page 27]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ long each connection has been established and the traffic
+ over that connection in bytes and messages for each
+ direction;
+ m - returns a list of commands supported by the server and
+ the usage count for each if the usage count is non zero;
+ o - returns a list of hosts from which normal clients may
+ become operators;
+ y - show Y (Class) lines from server's configuration file;
+ u - returns a string showing how long the server has been up.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+ RPL_STATSCLINE RPL_STATSNLINE
+ RPL_STATSILINE RPL_STATSKLINE
+ RPL_STATSQLINE RPL_STATSLLINE
+ RPL_STATSLINKINFO RPL_STATSUPTIME
+ RPL_STATSCOMMANDS RPL_STATSOLINE
+ RPL_STATSHLINE RPL_ENDOFSTATS
+
+ Examples:
+
+STATS m ; check the command usage for the server
+ you are connected to
+
+:Wiz STATS c eff.org ; request by WiZ for C/N line
+ information from server eff.org
+
+4.3.3 Links message
+
+ Command: LINKS
+ Parameters: [[<remote server>] <server mask>]
+
+ With LINKS, a user can list all servers which are known by the server
+ answering the query. The returned list of servers must match the
+ mask, or if no mask is given, the full list is returned.
+
+ If <remote server> is given in addition to <server mask>, the LINKS
+ command is forwarded to the first server found that matches that name
+ (if any), and that server is then required to answer the query.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+ RPL_LINKS RPL_ENDOFLINKS
+
+ Examples:
+
+
+
+
+Oikarinen & Reed [Page 28]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+LINKS *.au ; list all servers which have a name
+ that matches *.au;
+
+:WiZ LINKS *.bu.edu *.edu ; LINKS message from WiZ to the first
+ server matching *.edu for a list of
+ servers matching *.bu.edu.
+
+4.3.4 Time message
+
+ Command: TIME
+ Parameters: [<server>]
+
+ The time message is used to query local time from the specified
+ server. If the server parameter is not given, the server handling the
+ command must reply to the query.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER RPL_TIME
+
+ Examples:
+
+ TIME tolsun.oulu.fi ; check the time on the server
+ "tolson.oulu.fi"
+
+ Angel TIME *.au ; user angel checking the time on a
+ server matching "*.au"
+
+4.3.5 Connect message
+
+ Command: CONNECT
+ Parameters: <target server> [<port> [<remote server>]]
+
+ The CONNECT command can be used to force a server to try to establish
+ a new connection to another server immediately. CONNECT is a
+ privileged command and is to be available only to IRC Operators. If
+ a remote server is given then the CONNECT attempt is made by that
+ server to <target server> and <port>.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER ERR_NOPRIVILEGES
+ ERR_NEEDMOREPARAMS
+
+ Examples:
+
+CONNECT tolsun.oulu.fi ; Attempt to connect a server to
+ tolsun.oulu.fi
+
+
+
+Oikarinen & Reed [Page 29]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+:WiZ CONNECT eff.org 6667 csd.bu.edu
+ ; CONNECT attempt by WiZ to get servers
+ eff.org and csd.bu.edu connected on port
+ 6667.
+
+4.3.6 Trace message
+
+ Command: TRACE
+ Parameters: [<server>]
+
+ TRACE command is used to find the route to specific server. Each
+ server that processes this message must tell the sender about it by
+ sending a reply indicating it is a pass-through link, forming a chain
+ of replies similar to that gained from using "traceroute". After
+ sending this reply back, it must then send the TRACE message to the
+ next server until given server is reached. If the <server> parameter
+ is omitted, it is recommended that TRACE command send a message to
+ the sender telling which servers the current server has direct
+ connection to.
+
+ If the destination given by "<server>" is an actual server, then the
+ destination server is required to report all servers and users which
+ are connected to it, although only operators are permitted to see
+ users present. If the destination given by <server> is a nickname,
+ they only a reply for that nickname is given.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+
+ If the TRACE message is destined for another server, all intermediate
+ servers must return a RPL_TRACELINK reply to indicate that the TRACE
+ passed through it and where its going next.
+
+ RPL_TRACELINK
+ A TRACE reply may be composed of any number of the following numeric
+ replies.
+
+ RPL_TRACECONNECTING RPL_TRACEHANDSHAKE
+ RPL_TRACEUNKNOWN RPL_TRACEOPERATOR
+ RPL_TRACEUSER RPL_TRACESERVER
+ RPL_TRACESERVICE RPL_TRACENEWTYPE
+ RPL_TRACECLASS
+
+ Examples:
+
+TRACE *.oulu.fi ; TRACE to a server matching *.oulu.fi
+
+
+
+
+Oikarinen & Reed [Page 30]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+:WiZ TRACE AngelDust ; TRACE issued by WiZ to nick AngelDust
+
+4.3.7 Admin command
+
+ Command: ADMIN
+ Parameters: [<server>]
+
+ The admin message is used to find the name of the administrator of
+ the given server, or current server if <server> parameter is omitted.
+ Each server must have the ability to forward ADMIN messages to other
+ servers.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+ RPL_ADMINME RPL_ADMINLOC1
+ RPL_ADMINLOC2 RPL_ADMINEMAIL
+
+ Examples:
+
+ ADMIN tolsun.oulu.fi ; request an ADMIN reply from
+ tolsun.oulu.fi
+
+ :WiZ ADMIN *.edu ; ADMIN request from WiZ for first
+ server found to match *.edu.
+
+4.3.8 Info command
+
+ Command: INFO
+ Parameters: [<server>]
+
+ The INFO command is required to return information which describes
+ the server: its version, when it was compiled, the patchlevel, when
+ it was started, and any other miscellaneous information which may be
+ considered to be relevant.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+ RPL_INFO RPL_ENDOFINFO
+
+ Examples:
+
+ INFO csd.bu.edu ; request an INFO reply from
+ csd.bu.edu
+
+ :Avalon INFO *.fi ; INFO request from Avalon for first
+ server found to match *.fi.
+
+
+
+Oikarinen & Reed [Page 31]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ INFO Angel ; request info from the server that
+ Angel is connected to.
+
+4.4 Sending messages
+
+ The main purpose of the IRC protocol is to provide a base for clients
+ to communicate with each other. PRIVMSG and NOTICE are the only
+ messages available which actually perform delivery of a text message
+ from one client to another - the rest just make it possible and try
+ to ensure it happens in a reliable and structured manner.
+
+4.4.1 Private messages
+
+ Command: PRIVMSG
+ Parameters: <receiver>{,<receiver>} <text to be sent>
+
+ PRIVMSG is used to send private messages between users. <receiver>
+ is the nickname of the receiver of the message. <receiver> can also
+ be a list of names or channels separated with commas.
+
+ The <receiver> parameter may also me a host mask (#mask) or server
+ mask ($mask). In both cases the server will only send the PRIVMSG
+ to those who have a server or host matching the mask. The mask must
+ have at least 1 (one) "." in it and no wildcards following the
+ last ".". This requirement exists to prevent people sending messages
+ to "#*" or "$*", which would broadcast to all users; from
+ experience, this is abused more than used responsibly and properly.
+ Wildcards are the '*' and '?' characters. This extension to
+ the PRIVMSG command is only available to Operators.
+
+ Numeric Replies:
+
+ ERR_NORECIPIENT ERR_NOTEXTTOSEND
+ ERR_CANNOTSENDTOCHAN ERR_NOTOPLEVEL
+ ERR_WILDTOPLEVEL ERR_TOOMANYTARGETS
+ ERR_NOSUCHNICK
+ RPL_AWAY
+
+ Examples:
+
+:Angel PRIVMSG Wiz :Hello are you receiving this message ?
+ ; Message from Angel to Wiz.
+
+PRIVMSG Angel :yes I'm receiving it !receiving it !'u>(768u+1n) .br ;
+ Message to Angel.
+
+PRIVMSG jto@tolsun.oulu.fi :Hello !
+ ; Message to a client on server
+
+
+
+Oikarinen & Reed [Page 32]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ tolsun.oulu.fi with username of "jto".
+
+PRIVMSG $*.fi :Server tolsun.oulu.fi rebooting.
+ ; Message to everyone on a server which
+ has a name matching *.fi.
+
+PRIVMSG #*.edu :NSFNet is undergoing work, expect interruptions
+ ; Message to all users who come from a
+ host which has a name matching *.edu.
+
+4.4.2 Notice
+
+ Command: NOTICE
+ Parameters: <nickname> <text>
+
+ The NOTICE message is used similarly to PRIVMSG. The difference
+ between NOTICE and PRIVMSG is that automatic replies must never be
+ sent in response to a NOTICE message. This rule applies to servers
+ too - they must not send any error reply back to the client on
+ receipt of a notice. The object of this rule is to avoid loops
+ between a client automatically sending something in response to
+ something it received. This is typically used by automatons (clients
+ with either an AI or other interactive program controlling their
+ actions) which are always seen to be replying lest they end up in a
+ loop with another automaton.
+
+ See PRIVMSG for more details on replies and examples.
+
+4.5 User based queries
+
+ User queries are a group of commands which are primarily concerned
+ with finding details on a particular user or group users. When using
+ wildcards with any of these commands, if they match, they will only
+ return information on users who are 'visible' to you. The visibility
+ of a user is determined as a combination of the user's mode and the
+ common set of channels you are both on.
+
+4.5.1 Who query
+
+ Command: WHO
+ Parameters: [<name> [<o>]]
+
+ The WHO message is used by a client to generate a query which returns
+ a list of information which 'matches' the <name> parameter given by
+ the client. In the absence of the <name> parameter, all visible
+ (users who aren't invisible (user mode +i) and who don't have a
+ common channel with the requesting client) are listed. The same
+ result can be achieved by using a <name> of "0" or any wildcard which
+
+
+
+Oikarinen & Reed [Page 33]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ will end up matching every entry possible.
+
+ The <name> passed to WHO is matched against users' host, server, real
+ name and nickname if the channel <name> cannot be found.
+
+ If the "o" parameter is passed only operators are returned according
+ to the name mask supplied.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER
+ RPL_WHOREPLY RPL_ENDOFWHO
+
+ Examples:
+
+ WHO *.fi ; List all users who match against
+ "*.fi".
+
+ WHO jto* o ; List all users with a match against
+ "jto*" if they are an operator.
+
+4.5.2 Whois query
+
+ Command: WHOIS
+ Parameters: [<server>] <nickmask>[,<nickmask>[,...]]
+
+ This message is used to query information about particular user. The
+ server will answer this message with several numeric messages
+ indicating different statuses of each user which matches the nickmask
+ (if you are entitled to see them). If no wildcard is present in the
+ <nickmask>, any information about that nick which you are allowed to
+ see is presented. A comma (',') separated list of nicknames may be
+ given.
+
+ The latter version sends the query to a specific server. It is
+ useful if you want to know how long the user in question has been
+ idle as only local server (ie. the server the user is directly
+ connected to) knows that information, while everything else is
+ globally known.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER ERR_NONICKNAMEGIVEN
+ RPL_WHOISUSER RPL_WHOISCHANNELS
+ RPL_WHOISCHANNELS RPL_WHOISSERVER
+ RPL_AWAY RPL_WHOISOPERATOR
+ RPL_WHOISIDLE ERR_NOSUCHNICK
+ RPL_ENDOFWHOIS
+
+
+
+Oikarinen & Reed [Page 34]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ Examples:
+
+ WHOIS wiz ; return available user information
+ about nick WiZ
+
+ WHOIS eff.org trillian ; ask server eff.org for user
+ information about trillian
+
+4.5.3 Whowas
+
+ Command: WHOWAS
+ Parameters: <nickname> [<count> [<server>]]
+
+ Whowas asks for information about a nickname which no longer exists.
+ This may either be due to a nickname change or the user leaving IRC.
+ In response to this query, the server searches through its nickname
+ history, looking for any nicks which are lexically the same (no wild
+ card matching here). The history is searched backward, returning the
+ most recent entry first. If there are multiple entries, up to
+ <count> replies will be returned (or all of them if no <count>
+ parameter is given). If a non-positive number is passed as being
+ <count>, then a full search is done.
+
+ Numeric Replies:
+
+ ERR_NONICKNAMEGIVEN ERR_WASNOSUCHNICK
+ RPL_WHOWASUSER RPL_WHOISSERVER
+ RPL_ENDOFWHOWAS
+
+ Examples:
+
+ WHOWAS Wiz ; return all information in the nick
+ history about nick "WiZ";
+
+ WHOWAS Mermaid 9 ; return at most, the 9 most recent
+ entries in the nick history for
+ "Mermaid";
+
+ WHOWAS Trillian 1 *.edu ; return the most recent history for
+ "Trillian" from the first server found
+ to match "*.edu".
+
+4.6 Miscellaneous messages
+
+ Messages in this category do not fit into any of the above categories
+ but are nonetheless still a part of and required by the protocol.
+
+
+
+
+
+Oikarinen & Reed [Page 35]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+4.6.1 Kill message
+
+ Command: KILL
+ Parameters: <nickname> <comment>
+
+ The KILL message is used to cause a client-server connection to be
+ closed by the server which has the actual connection. KILL is used
+ by servers when they encounter a duplicate entry in the list of valid
+ nicknames and is used to remove both entries. It is also available
+ to operators.
+
+ Clients which have automatic reconnect algorithms effectively make
+ this command useless since the disconnection is only brief. It does
+ however break the flow of data and can be used to stop large amounts
+ of being abused, any user may elect to receive KILL messages
+ generated for others to keep an 'eye' on would be trouble spots.
+
+ In an arena where nicknames are required to be globally unique at all
+ times, KILL messages are sent whenever 'duplicates' are detected
+ (that is an attempt to register two users with the same nickname) in
+ the hope that both of them will disappear and only 1 reappear.
+
+ The comment given must reflect the actual reason for the KILL. For
+ server-generated KILLs it usually is made up of details concerning
+ the origins of the two conflicting nicknames. For users it is left
+ up to them to provide an adequate reason to satisfy others who see
+ it. To prevent/discourage fake KILLs from being generated to hide
+ the identify of the KILLer, the comment also shows a 'kill-path'
+ which is updated by each server it passes through, each prepending
+ its name to the path.
+
+ Numeric Replies:
+
+ ERR_NOPRIVILEGES ERR_NEEDMOREPARAMS
+ ERR_NOSUCHNICK ERR_CANTKILLSERVER
+
+
+ KILL David (csd.bu.edu <- tolsun.oulu.fi)
+ ; Nickname collision between csd.bu.edu
+ and tolson.oulu.fi
+
+
+ NOTE:
+ It is recommended that only Operators be allowed to kill other users
+ with KILL message. In an ideal world not even operators would need
+ to do this and it would be left to servers to deal with.
+
+
+
+
+
+Oikarinen & Reed [Page 36]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+4.6.2 Ping message
+
+ Command: PING
+ Parameters: <server1> [<server2>]
+
+ The PING message is used to test the presence of an active client at
+ the other end of the connection. A PING message is sent at regular
+ intervals if no other activity detected coming from a connection. If
+ a connection fails to respond to a PING command within a set amount
+ of time, that connection is closed.
+
+ Any client which receives a PING message must respond to <server1>
+ (server which sent the PING message out) as quickly as possible with
+ an appropriate PONG message to indicate it is still there and alive.
+ Servers should not respond to PING commands but rely on PINGs from
+ the other end of the connection to indicate the connection is alive.
+ If the <server2> parameter is specified, the PING message gets
+ forwarded there.
+
+ Numeric Replies:
+
+ ERR_NOORIGIN ERR_NOSUCHSERVER
+
+ Examples:
+
+ PING tolsun.oulu.fi ; server sending a PING message to
+ another server to indicate it is still
+ alive.
+
+ PING WiZ ; PING message being sent to nick WiZ
+
+4.6.3 Pong message
+
+ Command: PONG
+ Parameters: <daemon> [<daemon2>]
+
+ PONG message is a reply to ping message. If parameter <daemon2> is
+ given this message must be forwarded to given daemon. The <daemon>
+ parameter is the name of the daemon who has responded to PING message
+ and generated this message.
+
+ Numeric Replies:
+
+ ERR_NOORIGIN ERR_NOSUCHSERVER
+
+ Examples:
+
+ PONG csd.bu.edu tolsun.oulu.fi ; PONG message from csd.bu.edu to
+
+
+
+Oikarinen & Reed [Page 37]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ tolsun.oulu.fi
+
+4.6.4 Error
+
+ Command: ERROR
+ Parameters: <error message>
+
+ The ERROR command is for use by servers when reporting a serious or
+ fatal error to its operators. It may also be sent from one server to
+ another but must not be accepted from any normal unknown clients.
+
+ An ERROR message is for use for reporting errors which occur with a
+ server-to-server link only. An ERROR message is sent to the server
+ at the other end (which sends it to all of its connected operators)
+ and to all operators currently connected. It is not to be passed
+ onto any other servers by a server if it is received from a server.
+
+ When a server sends a received ERROR message to its operators, the
+ message should be encapsulated inside a NOTICE message, indicating
+ that the client was not responsible for the error.
+
+ Numerics:
+
+ None.
+
+ Examples:
+
+ ERROR :Server *.fi already exists; ERROR message to the other server
+ which caused this error.
+
+ NOTICE WiZ :ERROR from csd.bu.edu -- Server *.fi already exists
+ ; Same ERROR message as above but sent
+ to user WiZ on the other server.
+
+5. OPTIONALS
+
+ This section describes OPTIONAL messages. They are not required in a
+ working server implementation of the protocol described herein. In
+ the absence of the option, an error reply message must be generated
+ or an unknown command error. If the message is destined for another
+ server to answer then it must be passed on (elementary parsing
+ required) The allocated numerics for this are listed with the
+ messages below.
+
+5.1 Away
+
+ Command: AWAY
+ Parameters: [message]
+
+
+
+Oikarinen & Reed [Page 38]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ With the AWAY message, clients can set an automatic reply string for
+ any PRIVMSG commands directed at them (not to a channel they are on).
+ The automatic reply is sent by the server to client sending the
+ PRIVMSG command. The only replying server is the one to which the
+ sending client is connected to.
+
+ The AWAY message is used either with one parameter (to set an AWAY
+ message) or with no parameters (to remove the AWAY message).
+
+ Numeric Replies:
+
+ RPL_UNAWAY RPL_NOWAWAY
+
+ Examples:
+
+ AWAY :Gone to lunch. Back in 5 ; set away message to "Gone to lunch.
+ Back in 5".
+
+ :WiZ AWAY ; unmark WiZ as being away.
+
+
+5.2 Rehash message
+
+ Command: REHASH
+ Parameters: None
+
+ The rehash message can be used by the operator to force the server to
+ re-read and process its configuration file.
+
+ Numeric Replies:
+
+ RPL_REHASHING ERR_NOPRIVILEGES
+
+Examples:
+
+REHASH ; message from client with operator
+ status to server asking it to reread its
+ configuration file.
+
+5.3 Restart message
+
+ Command: RESTART
+ Parameters: None
+
+ The restart message can only be used by an operator to force a server
+ restart itself. This message is optional since it may be viewed as a
+ risk to allow arbitrary people to connect to a server as an operator
+ and execute this command, causing (at least) a disruption to service.
+
+
+
+Oikarinen & Reed [Page 39]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ The RESTART command must always be fully processed by the server to
+ which the sending client is connected and not be passed onto other
+ connected servers.
+
+ Numeric Replies:
+
+ ERR_NOPRIVILEGES
+
+ Examples:
+
+ RESTART ; no parameters required.
+
+5.4 Summon message
+
+ Command: SUMMON
+ Parameters: <user> [<server>]
+
+ The SUMMON command can be used to give users who are on a host
+ running an IRC server a message asking them to please join IRC. This
+ message is only sent if the target server (a) has SUMMON enabled, (b)
+ the user is logged in and (c) the server process can write to the
+ user's tty (or similar).
+
+ If no <server> parameter is given it tries to summon <user> from the
+ server the client is connected to is assumed as the target.
+
+ If summon is not enabled in a server, it must return the
+ ERR_SUMMONDISABLED numeric and pass the summon message onwards.
+
+ Numeric Replies:
+
+ ERR_NORECIPIENT ERR_FILEERROR
+ ERR_NOLOGIN ERR_NOSUCHSERVER
+ RPL_SUMMONING
+
+ Examples:
+
+ SUMMON jto ; summon user jto on the server's host
+
+ SUMMON jto tolsun.oulu.fi ; summon user jto on the host which a
+ server named "tolsun.oulu.fi" is
+ running.
+
+
+5.5 Users
+
+ Command: USERS
+ Parameters: [<server>]
+
+
+
+Oikarinen & Reed [Page 40]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ The USERS command returns a list of users logged into the server in a
+ similar format to who(1), rusers(1) and finger(1). Some people
+ may disable this command on their server for security related
+ reasons. If disabled, the correct numeric must be returned to
+ indicate this.
+
+ Numeric Replies:
+
+ ERR_NOSUCHSERVER ERR_FILEERROR
+ RPL_USERSSTART RPL_USERS
+ RPL_NOUSERS RPL_ENDOFUSERS
+ ERR_USERSDISABLED
+
+ Disabled Reply:
+
+ ERR_USERSDISABLED
+
+ Examples:
+
+USERS eff.org ; request a list of users logged in on
+ server eff.org
+
+:John USERS tolsun.oulu.fi ; request from John for a list of users
+ logged in on server tolsun.oulu.fi
+
+5.6 Operwall message
+
+ Command: WALLOPS
+ Parameters: Text to be sent to all operators currently online
+
+ Sends a message to all operators currently online. After
+ implementing WALLOPS as a user command it was found that it was
+ often and commonly abused as a means of sending a message to a lot
+ of people (much similar to WALL). Due to this it is recommended
+ that the current implementation of WALLOPS be used as an
+ example by allowing and recognising only servers as the senders of
+ WALLOPS.
+
+ Numeric Replies:
+
+ ERR_NEEDMOREPARAMS
+
+ Examples:
+
+ :csd.bu.edu WALLOPS :Connect '*.uiuc.edu 6667' from Joshua; WALLOPS
+ message from csd.bu.edu announcing a
+ CONNECT message it received and acted
+ upon from Joshua.
+
+
+
+Oikarinen & Reed [Page 41]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+5.7 Userhost message
+
+ Command: USERHOST
+ Parameters: <nickname>{<space><nickname>}
+
+ The USERHOST command takes a list of up to 5 nicknames, each
+ separated by a space character and returns a list of information
+ about each nickname that it found. The returned list has each reply
+ separated by a space.
+
+ Numeric Replies:
+
+ RPL_USERHOST ERR_NEEDMOREPARAMS
+
+ Examples:
+
+ USERHOST Wiz Michael Marty p ;USERHOST request for information on
+ nicks "Wiz", "Michael", "Marty" and "p"
+
+5.8 Ison message
+
+ Command: ISON
+ Parameters: <nickname>{<space><nickname>}
+
+ The ISON command was implemented to provide a quick and efficient
+ means to get a response about whether a given nickname was currently
+ on IRC. ISON only takes one (1) parameter: a space-separated list of
+ nicks. For each nickname in the list that is present, the server
+ adds that to its reply string. Thus the reply string may return
+ empty (none of the given nicks are present), an exact copy of the
+ parameter string (all of them present) or as any other subset of the
+ set of nicks given in the parameter. The only limit on the number
+ of nicks that may be checked is that the combined length must not be
+ too large as to cause the server to chop it off so it fits in 512
+ characters.
+
+ ISON is only be processed by the server local to the client sending
+ the command and thus not passed onto other servers for further
+ processing.
+
+ Numeric Replies:
+
+ RPL_ISON ERR_NEEDMOREPARAMS
+
+ Examples:
+
+ ISON phone trillian WiZ jarlek Avalon Angel Monstah
+ ; Sample ISON request for 7 nicks.
+
+
+
+Oikarinen & Reed [Page 42]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+6. REPLIES
+
+ The following is a list of numeric replies which are generated in
+ response to the commands given above. Each numeric is given with its
+ number, name and reply string.
+
+6.1 Error Replies.
+
+ 401 ERR_NOSUCHNICK
+ "<nickname> :No such nick/channel"
+
+ - Used to indicate the nickname parameter supplied to a
+ command is currently unused.
+
+ 402 ERR_NOSUCHSERVER
+ "<server name> :No such server"
+
+ - Used to indicate the server name given currently
+ doesn't exist.
+
+ 403 ERR_NOSUCHCHANNEL
+ "<channel name> :No such channel"
+
+ - Used to indicate the given channel name is invalid.
+
+ 404 ERR_CANNOTSENDTOCHAN
+ "<channel name> :Cannot send to channel"
+
+ - Sent to a user who is either (a) not on a channel
+ which is mode +n or (b) not a chanop (or mode +v) on
+ a channel which has mode +m set and is trying to send
+ a PRIVMSG message to that channel.
+
+ 405 ERR_TOOMANYCHANNELS
+ "<channel name> :You have joined too many \
+ channels"
+ - Sent to a user when they have joined the maximum
+ number of allowed channels and they try to join
+ another channel.
+
+ 406 ERR_WASNOSUCHNICK
+ "<nickname> :There was no such nickname"
+
+ - Returned by WHOWAS to indicate there is no history
+ information for that nickname.
+
+ 407 ERR_TOOMANYTARGETS
+ "<target> :Duplicate recipients. No message \
+
+
+
+Oikarinen & Reed [Page 43]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ delivered"
+
+ - Returned to a client which is attempting to send a
+ PRIVMSG/NOTICE using the user@host destination format
+ and for a user@host which has several occurrences.
+
+ 409 ERR_NOORIGIN
+ ":No origin specified"
+
+ - PING or PONG message missing the originator parameter
+ which is required since these commands must work
+ without valid prefixes.
+
+ 411 ERR_NORECIPIENT
+ ":No recipient given (<command>)"
+ 412 ERR_NOTEXTTOSEND
+ ":No text to send"
+ 413 ERR_NOTOPLEVEL
+ "<mask> :No toplevel domain specified"
+ 414 ERR_WILDTOPLEVEL
+ "<mask> :Wildcard in toplevel domain"
+
+ - 412 - 414 are returned by PRIVMSG to indicate that
+ the message wasn't delivered for some reason.
+ ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
+ are returned when an invalid use of
+ "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted.
+
+ 421 ERR_UNKNOWNCOMMAND
+ "<command> :Unknown command"
+
+ - Returned to a registered client to indicate that the
+ command sent is unknown by the server.
+
+ 422 ERR_NOMOTD
+ ":MOTD File is missing"
+
+ - Server's MOTD file could not be opened by the server.
+
+ 423 ERR_NOADMININFO
+ "<server> :No administrative info available"
+
+ - Returned by a server in response to an ADMIN message
+ when there is an error in finding the appropriate
+ information.
+
+ 424 ERR_FILEERROR
+ ":File error doing <file op> on <file>"
+
+
+
+Oikarinen & Reed [Page 44]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ - Generic error message used to report a failed file
+ operation during the processing of a message.
+
+ 431 ERR_NONICKNAMEGIVEN
+ ":No nickname given"
+
+ - Returned when a nickname parameter expected for a
+ command and isn't found.
+
+ 432 ERR_ERRONEUSNICKNAME
+ "<nick> :Erroneus nickname"
+
+ - Returned after receiving a NICK message which contains
+ characters which do not fall in the defined set. See
+ section x.x.x for details on valid nicknames.
+
+ 433 ERR_NICKNAMEINUSE
+ "<nick> :Nickname is already in use"
+
+ - Returned when a NICK message is processed that results
+ in an attempt to change to a currently existing
+ nickname.
+
+ 436 ERR_NICKCOLLISION
+ "<nick> :Nickname collision KILL"
+
+ - Returned by a server to a client when it detects a
+ nickname collision (registered of a NICK that
+ already exists by another server).
+
+ 441 ERR_USERNOTINCHANNEL
+ "<nick> <channel> :They aren't on that channel"
+
+ - Returned by the server to indicate that the target
+ user of the command is not on the given channel.
+
+ 442 ERR_NOTONCHANNEL
+ "<channel> :You're not on that channel"
+
+ - Returned by the server whenever a client tries to
+ perform a channel effecting command for which the
+ client isn't a member.
+
+ 443 ERR_USERONCHANNEL
+ "<user> <channel> :is already on channel"
+
+ - Returned when a client tries to invite a user to a
+ channel they are already on.
+
+
+
+Oikarinen & Reed [Page 45]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 444 ERR_NOLOGIN
+ "<user> :User not logged in"
+
+ - Returned by the summon after a SUMMON command for a
+ user was unable to be performed since they were not
+ logged in.
+
+ 445 ERR_SUMMONDISABLED
+ ":SUMMON has been disabled"
+
+ - Returned as a response to the SUMMON command. Must be
+ returned by any server which does not implement it.
+
+ 446 ERR_USERSDISABLED
+ ":USERS has been disabled"
+
+ - Returned as a response to the USERS command. Must be
+ returned by any server which does not implement it.
+
+ 451 ERR_NOTREGISTERED
+ ":You have not registered"
+
+ - Returned by the server to indicate that the client
+ must be registered before the server will allow it
+ to be parsed in detail.
+
+ 461 ERR_NEEDMOREPARAMS
+ "<command> :Not enough parameters"
+
+ - Returned by the server by numerous commands to
+ indicate to the client that it didn't supply enough
+ parameters.
+
+ 462 ERR_ALREADYREGISTRED
+ ":You may not reregister"
+
+ - Returned by the server to any link which tries to
+ change part of the registered details (such as
+ password or user details from second USER message).
+
+
+ 463 ERR_NOPERMFORHOST
+ ":Your host isn't among the privileged"
+
+ - Returned to a client which attempts to register with
+ a server which does not been setup to allow
+ connections from the host the attempted connection
+ is tried.
+
+
+
+Oikarinen & Reed [Page 46]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 464 ERR_PASSWDMISMATCH
+ ":Password incorrect"
+
+ - Returned to indicate a failed attempt at registering
+ a connection for which a password was required and
+ was either not given or incorrect.
+
+ 465 ERR_YOUREBANNEDCREEP
+ ":You are banned from this server"
+
+ - Returned after an attempt to connect and register
+ yourself with a server which has been setup to
+ explicitly deny connections to you.
+
+ 467 ERR_KEYSET
+ "<channel> :Channel key already set"
+ 471 ERR_CHANNELISFULL
+ "<channel> :Cannot join channel (+l)"
+ 472 ERR_UNKNOWNMODE
+ "<char> :is unknown mode char to me"
+ 473 ERR_INVITEONLYCHAN
+ "<channel> :Cannot join channel (+i)"
+ 474 ERR_BANNEDFROMCHAN
+ "<channel> :Cannot join channel (+b)"
+ 475 ERR_BADCHANNELKEY
+ "<channel> :Cannot join channel (+k)"
+ 481 ERR_NOPRIVILEGES
+ ":Permission Denied- You're not an IRC operator"
+
+ - Any command requiring operator privileges to operate
+ must return this error to indicate the attempt was
+ unsuccessful.
+
+ 482 ERR_CHANOPRIVSNEEDED
+ "<channel> :You're not channel operator"
+
+ - Any command requiring 'chanop' privileges (such as
+ MODE messages) must return this error if the client
+ making the attempt is not a chanop on the specified
+ channel.
+
+ 483 ERR_CANTKILLSERVER
+ ":You cant kill a server!"
+
+ - Any attempts to use the KILL command on a server
+ are to be refused and this error returned directly
+ to the client.
+
+
+
+
+Oikarinen & Reed [Page 47]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 491 ERR_NOOPERHOST
+ ":No O-lines for your host"
+
+ - If a client sends an OPER message and the server has
+ not been configured to allow connections from the
+ client's host as an operator, this error must be
+ returned.
+
+ 501 ERR_UMODEUNKNOWNFLAG
+ ":Unknown MODE flag"
+
+ - Returned by the server to indicate that a MODE
+ message was sent with a nickname parameter and that
+ the a mode flag sent was not recognized.
+
+ 502 ERR_USERSDONTMATCH
+ ":Cant change mode for other users"
+
+ - Error sent to any user trying to view or change the
+ user mode for a user other than themselves.
+
+6.2 Command responses.
+
+ 300 RPL_NONE
+ Dummy reply number. Not used.
+
+ 302 RPL_USERHOST
+ ":[<reply>{<space><reply>}]"
+
+ - Reply format used by USERHOST to list replies to
+ the query list. The reply string is composed as
+ follows:
+
+ <reply> ::= <nick>['*'] '=' <'+'|'-'><hostname>
+
+ The '*' indicates whether the client has registered
+ as an Operator. The '-' or '+' characters represent
+ whether the client has set an AWAY message or not
+ respectively.
+
+ 303 RPL_ISON
+ ":[<nick> {<space><nick>}]"
+
+ - Reply format used by ISON to list replies to the
+ query list.
+
+ 301 RPL_AWAY
+ "<nick> :<away message>"
+
+
+
+Oikarinen & Reed [Page 48]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ 305 RPL_UNAWAY
+ ":You are no longer marked as being away"
+ 306 RPL_NOWAWAY
+ ":You have been marked as being away"
+
+ - These replies are used with the AWAY command (if
+ allowed). RPL_AWAY is sent to any client sending a
+ PRIVMSG to a client which is away. RPL_AWAY is only
+ sent by the server to which the client is connected.
+ Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the
+ client removes and sets an AWAY message.
+
+ 311 RPL_WHOISUSER
+ "<nick> <user> <host> * :<real name>"
+ 312 RPL_WHOISSERVER
+ "<nick> <server> :<server info>"
+ 313 RPL_WHOISOPERATOR
+ "<nick> :is an IRC operator"
+ 317 RPL_WHOISIDLE
+ "<nick> <integer> :seconds idle"
+ 318 RPL_ENDOFWHOIS
+ "<nick> :End of /WHOIS list"
+ 319 RPL_WHOISCHANNELS
+ "<nick> :{[@|+]<channel><space>}"
+
+ - Replies 311 - 313, 317 - 319 are all replies
+ generated in response to a WHOIS message. Given that
+ there are enough parameters present, the answering
+ server must either formulate a reply out of the above
+ numerics (if the query nick is found) or return an
+ error reply. The '*' in RPL_WHOISUSER is there as
+ the literal character and not as a wild card. For
+ each reply set, only RPL_WHOISCHANNELS may appear
+ more than once (for long lists of channel names).
+ The '@' and '+' characters next to the channel name
+ indicate whether a client is a channel operator or
+ has been granted permission to speak on a moderated
+ channel. The RPL_ENDOFWHOIS reply is used to mark
+ the end of processing a WHOIS message.
+
+ 314 RPL_WHOWASUSER
+ "<nick> <user> <host> * :<real name>"
+ 369 RPL_ENDOFWHOWAS
+ "<nick> :End of WHOWAS"
+
+ - When replying to a WHOWAS message, a server must use
+ the replies RPL_WHOWASUSER, RPL_WHOISSERVER or
+ ERR_WASNOSUCHNICK for each nickname in the presented
+
+
+
+Oikarinen & Reed [Page 49]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ list. At the end of all reply batches, there must
+ be RPL_ENDOFWHOWAS (even if there was only one reply
+ and it was an error).
+
+ 321 RPL_LISTSTART
+ "Channel :Users Name"
+ 322 RPL_LIST
+ "<channel> <# visible> :<topic>"
+ 323 RPL_LISTEND
+ ":End of /LIST"
+
+ - Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark
+ the start, actual replies with data and end of the
+ server's response to a LIST command. If there are
+ no channels available to return, only the start
+ and end reply must be sent.
+
+ 324 RPL_CHANNELMODEIS
+ "<channel> <mode> <mode params>"
+
+ 331 RPL_NOTOPIC
+ "<channel> :No topic is set"
+ 332 RPL_TOPIC
+ "<channel> :<topic>"
+
+ - When sending a TOPIC message to determine the
+ channel topic, one of two replies is sent. If
+ the topic is set, RPL_TOPIC is sent back else
+ RPL_NOTOPIC.
+
+ 341 RPL_INVITING
+ "<channel> <nick>"
+
+ - Returned by the server to indicate that the
+ attempted INVITE message was successful and is
+ being passed onto the end client.
+
+ 342 RPL_SUMMONING
+ "<user> :Summoning user to IRC"
+
+ - Returned by a server answering a SUMMON message to
+ indicate that it is summoning that user.
+
+ 351 RPL_VERSION
+ "<version>.<debuglevel> <server> :<comments>"
+
+ - Reply by the server showing its version details.
+ The <version> is the version of the software being
+
+
+
+Oikarinen & Reed [Page 50]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ used (including any patchlevel revisions) and the
+ <debuglevel> is used to indicate if the server is
+ running in "debug mode".
+
+ The "comments" field may contain any comments about
+ the version or further version details.
+
+ 352 RPL_WHOREPLY
+ "<channel> <user> <host> <server> <nick> \
+ <H|G>[*][@|+] :<hopcount> <real name>"
+ 315 RPL_ENDOFWHO
+ "<name> :End of /WHO list"
+
+ - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
+ to answer a WHO message. The RPL_WHOREPLY is only
+ sent if there is an appropriate match to the WHO
+ query. If there is a list of parameters supplied
+ with a WHO message, a RPL_ENDOFWHO must be sent
+ after processing each list item with <name> being
+ the item.
+
+ 353 RPL_NAMREPLY
+ "<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]"
+ 366 RPL_ENDOFNAMES
+ "<channel> :End of /NAMES list"
+
+ - To reply to a NAMES message, a reply pair consisting
+ of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
+ server back to the client. If there is no channel
+ found as in the query, then only RPL_ENDOFNAMES is
+ returned. The exception to this is when a NAMES
+ message is sent with no parameters and all visible
+ channels and contents are sent back in a series of
+ RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
+ the end.
+
+ 364 RPL_LINKS
+ "<mask> <server> :<hopcount> <server info>"
+ 365 RPL_ENDOFLINKS
+ "<mask> :End of /LINKS list"
+
+ - In replying to the LINKS message, a server must send
+ replies back using the RPL_LINKS numeric and mark the
+ end of the list using an RPL_ENDOFLINKS reply.
+
+ 367 RPL_BANLIST
+ "<channel> <banid>"
+ 368 RPL_ENDOFBANLIST
+
+
+
+Oikarinen & Reed [Page 51]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ "<channel> :End of channel ban list"
+
+ - When listing the active 'bans' for a given channel,
+ a server is required to send the list back using the
+ RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate
+ RPL_BANLIST is sent for each active banid. After the
+ banids have been listed (or if none present) a
+ RPL_ENDOFBANLIST must be sent.
+
+ 371 RPL_INFO
+ ":<string>"
+ 374 RPL_ENDOFINFO
+ ":End of /INFO list"
+
+ - A server responding to an INFO message is required to
+ send all its 'info' in a series of RPL_INFO messages
+ with a RPL_ENDOFINFO reply to indicate the end of the
+ replies.
+
+ 375 RPL_MOTDSTART
+ ":- <server> Message of the day - "
+ 372 RPL_MOTD
+ ":- <text>"
+ 376 RPL_ENDOFMOTD
+ ":End of /MOTD command"
+
+ - When responding to the MOTD message and the MOTD file
+ is found, the file is displayed line by line, with
+ each line no longer than 80 characters, using
+ RPL_MOTD format replies. These should be surrounded
+ by a RPL_MOTDSTART (before the RPL_MOTDs) and an
+ RPL_ENDOFMOTD (after).
+
+ 381 RPL_YOUREOPER
+ ":You are now an IRC operator"
+
+ - RPL_YOUREOPER is sent back to a client which has
+ just successfully issued an OPER message and gained
+ operator status.
+
+ 382 RPL_REHASHING
+ "<config file> :Rehashing"
+
+ - If the REHASH option is used and an operator sends
+ a REHASH message, an RPL_REHASHING is sent back to
+ the operator.
+
+ 391 RPL_TIME
+
+
+
+Oikarinen & Reed [Page 52]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ "<server> :<string showing server's local time>"
+
+ - When replying to the TIME message, a server must send
+ the reply using the RPL_TIME format above. The string
+ showing the time need only contain the correct day and
+ time there. There is no further requirement for the
+ time string.
+
+ 392 RPL_USERSSTART
+ ":UserID Terminal Host"
+ 393 RPL_USERS
+ ":%-8s %-9s %-8s"
+ 394 RPL_ENDOFUSERS
+ ":End of users"
+ 395 RPL_NOUSERS
+ ":Nobody logged in"
+
+ - If the USERS message is handled by a server, the
+ replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
+ RPL_NOUSERS are used. RPL_USERSSTART must be sent
+ first, following by either a sequence of RPL_USERS
+ or a single RPL_NOUSER. Following this is
+ RPL_ENDOFUSERS.
+
+ 200 RPL_TRACELINK
+ "Link <version & debug level> <destination> \
+ <next server>"
+ 201 RPL_TRACECONNECTING
+ "Try. <class> <server>"
+ 202 RPL_TRACEHANDSHAKE
+ "H.S. <class> <server>"
+ 203 RPL_TRACEUNKNOWN
+ "???? <class> [<client IP address in dot form>]"
+ 204 RPL_TRACEOPERATOR
+ "Oper <class> <nick>"
+ 205 RPL_TRACEUSER
+ "User <class> <nick>"
+ 206 RPL_TRACESERVER
+ "Serv <class> <int>S <int>C <server> \
+ <nick!user|*!*>@<host|server>"
+ 208 RPL_TRACENEWTYPE
+ "<newtype> 0 <client name>"
+ 261 RPL_TRACELOG
+ "File <logfile> <debug level>"
+
+ - The RPL_TRACE* are all returned by the server in
+ response to the TRACE message. How many are
+ returned is dependent on the the TRACE message and
+
+
+
+Oikarinen & Reed [Page 53]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ whether it was sent by an operator or not. There
+ is no predefined order for which occurs first.
+ Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+ RPL_TRACEHANDSHAKE are all used for connections
+ which have not been fully established and are either
+ unknown, still attempting to connect or in the
+ process of completing the 'server handshake'.
+ RPL_TRACELINK is sent by any server which handles
+ a TRACE message and has to pass it on to another
+ server. The list of RPL_TRACELINKs sent in
+ response to a TRACE command traversing the IRC
+ network should reflect the actual connectivity of
+ the servers themselves along that path.
+ RPL_TRACENEWTYPE is to be used for any connection
+ which does not fit in the other categories but is
+ being displayed anyway.
+
+ 211 RPL_STATSLINKINFO
+ "<linkname> <sendq> <sent messages> \
+ <sent bytes> <received messages> \
+ <received bytes> <time open>"
+ 212 RPL_STATSCOMMANDS
+ "<command> <count>"
+ 213 RPL_STATSCLINE
+ "C <host> * <name> <port> <class>"
+ 214 RPL_STATSNLINE
+ "N <host> * <name> <port> <class>"
+ 215 RPL_STATSILINE
+ "I <host> * <host> <port> <class>"
+ 216 RPL_STATSKLINE
+ "K <host> * <username> <port> <class>"
+ 218 RPL_STATSYLINE
+ "Y <class> <ping frequency> <connect \
+ frequency> <max sendq>"
+ 219 RPL_ENDOFSTATS
+ "<stats letter> :End of /STATS report"
+ 241 RPL_STATSLLINE
+ "L <hostmask> * <servername> <maxdepth>"
+ 242 RPL_STATSUPTIME
+ ":Server Up %d days %d:%02d:%02d"
+ 243 RPL_STATSOLINE
+ "O <hostmask> * <name>"
+ 244 RPL_STATSHLINE
+ "H <hostmask> * <servername>"
+
+ 221 RPL_UMODEIS
+ "<user mode string>"
+
+
+
+
+Oikarinen & Reed [Page 54]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ - To answer a query about a client's own mode,
+ RPL_UMODEIS is sent back.
+
+ 251 RPL_LUSERCLIENT
+ ":There are <integer> users and <integer> \
+ invisible on <integer> servers"
+ 252 RPL_LUSEROP
+ "<integer> :operator(s) online"
+ 253 RPL_LUSERUNKNOWN
+ "<integer> :unknown connection(s)"
+ 254 RPL_LUSERCHANNELS
+ "<integer> :channels formed"
+ 255 RPL_LUSERME
+ ":I have <integer> clients and <integer> \
+ servers"
+
+ - In processing an LUSERS message, the server
+ sends a set of replies from RPL_LUSERCLIENT,
+ RPL_LUSEROP, RPL_USERUNKNOWN,
+ RPL_LUSERCHANNELS and RPL_LUSERME. When
+ replying, a server must send back
+ RPL_LUSERCLIENT and RPL_LUSERME. The other
+ replies are only sent back if a non-zero count
+ is found for them.
+
+ 256 RPL_ADMINME
+ "<server> :Administrative info"
+ 257 RPL_ADMINLOC1
+ ":<admin info>"
+ 258 RPL_ADMINLOC2
+ ":<admin info>"
+ 259 RPL_ADMINEMAIL
+ ":<admin info>"
+
+ - When replying to an ADMIN message, a server
+ is expected to use replies RLP_ADMINME
+ through to RPL_ADMINEMAIL and provide a text
+ message with each. For RPL_ADMINLOC1 a
+ description of what city, state and country
+ the server is in is expected, followed by
+ details of the university and department
+ (RPL_ADMINLOC2) and finally the administrative
+ contact for the server (an email address here
+ is required) in RPL_ADMINEMAIL.
+
+
+
+
+
+
+
+Oikarinen & Reed [Page 55]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+6.3 Reserved numerics.
+
+ These numerics are not described above since they fall into one of
+ the following categories:
+
+ 1. no longer in use;
+
+ 2. reserved for future planned use;
+
+ 3. in current use but are part of a non-generic 'feature' of
+ the current IRC server.
+
+ 209 RPL_TRACECLASS 217 RPL_STATSQLINE
+ 231 RPL_SERVICEINFO 232 RPL_ENDOFSERVICES
+ 233 RPL_SERVICE 234 RPL_SERVLIST
+ 235 RPL_SERVLISTEND
+ 316 RPL_WHOISCHANOP 361 RPL_KILLDONE
+ 362 RPL_CLOSING 363 RPL_CLOSEEND
+ 373 RPL_INFOSTART 384 RPL_MYPORTIS
+ 466 ERR_YOUWILLBEBANNED 476 ERR_BADCHANMASK
+ 492 ERR_NOSERVICEHOST
+
+7. Client and server authentication
+
+ Clients and servers are both subject to the same level of
+ authentication. For both, an IP number to hostname lookup (and
+ reverse check on this) is performed for all connections made to the
+ server. Both connections are then subject to a password check (if
+ there is a password set for that connection). These checks are
+ possible on all connections although the password check is only
+ commonly used with servers.
+
+ An additional check that is becoming of more and more common is that
+ of the username responsible for making the connection. Finding the
+ username of the other end of the connection typically involves
+ connecting to an authentication server such as IDENT as described in
+ RFC 1413.
+
+ Given that without passwords it is not easy to reliably determine who
+ is on the other end of a network connection, use of passwords is
+ strongly recommended on inter-server connections in addition to any
+ other measures such as using an ident server.
+
+8. Current implementations
+
+ The only current implementation of this protocol is the IRC server,
+ version 2.8. Earlier versions may implement some or all of the
+ commands described by this document with NOTICE messages replacing
+
+
+
+Oikarinen & Reed [Page 56]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ many of the numeric replies. Unfortunately, due to backward
+ compatibility requirements, the implementation of some parts of this
+ document varies with what is laid out. On notable difference is:
+
+ * recognition that any LF or CR anywhere in a message marks the
+ end of that message (instead of requiring CR-LF);
+
+ The rest of this section deals with issues that are mostly of
+ importance to those who wish to implement a server but some parts
+ also apply directly to clients as well.
+
+8.1 Network protocol: TCP - why it is best used here.
+
+ IRC has been implemented on top of TCP since TCP supplies a reliable
+ network protocol which is well suited to this scale of conferencing.
+ The use of multicast IP is an alternative, but it is not widely
+ available or supported at the present time.
+
+8.1.1 Support of Unix sockets
+
+ Given that Unix domain sockets allow listen/connect operations, the
+ current implementation can be configured to listen and accept both
+ client and server connections on a Unix domain socket. These are
+ recognized as sockets where the hostname starts with a '/'.
+
+ When providing any information about the connections on a Unix domain
+ socket, the server is required to supplant the actual hostname in
+ place of the pathname unless the actual socket name is being asked
+ for.
+
+8.2 Command Parsing
+
+ To provide useful 'non-buffered' network IO for clients and servers,
+ each connection is given its own private 'input buffer' in which the
+ results of the most recent read and parsing are kept. A buffer size
+ of 512 bytes is used so as to hold 1 full message, although, this
+ will usually hold several commands. The private buffer is parsed
+ after every read operation for valid messages. When dealing with
+ multiple messages from one client in the buffer, care should be taken
+ in case one happens to cause the client to be 'removed'.
+
+8.3 Message delivery
+
+ It is common to find network links saturated or hosts to which you
+ are sending data unable to send data. Although Unix typically
+ handles this through the TCP window and internal buffers, the server
+ often has large amounts of data to send (especially when a new
+ server-server link forms) and the small buffers provided in the
+
+
+
+Oikarinen & Reed [Page 57]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ kernel are not enough for the outgoing queue. To alleviate this
+ problem, a "send queue" is used as a FIFO queue for data to be sent.
+ A typical "send queue" may grow to 200 Kbytes on a large IRC network
+ with a slow network connection when a new server connects.
+
+ When polling its connections, a server will first read and parse all
+ incoming data, queuing any data to be sent out. When all available
+ input is processed, the queued data is sent. This reduces the number
+ of write() system calls and helps TCP make bigger packets.
+
+8.4 Connection 'Liveness'
+
+ To detect when a connection has died or become unresponsive, the
+ server must ping each of its connections that it doesn't get a
+ response from in a given amount of time.
+
+ If a connection doesn't respond in time, its connection is closed
+ using the appropriate procedures. A connection is also dropped if
+ its sendq grows beyond the maximum allowed, because it is better to
+ close a slow connection than have a server process block.
+
+8.5 Establishing a server to client connection
+
+ Upon connecting to an IRC server, a client is sent the MOTD (if
+ present) as well as the current user/server count (as per the LUSER
+ command). The server is also required to give an unambiguous message
+ to the client which states its name and version as well as any other
+ introductory messages which may be deemed appropriate.
+
+ After dealing with this, the server must then send out the new user's
+ nickname and other information as supplied by itself (USER command)
+ and as the server could discover (from DNS/authentication servers).
+ The server must send this information out with NICK first followed by
+ USER.
+
+8.6 Establishing a server-server connection.
+
+ The process of establishing of a server-to-server connection is
+ fraught with danger since there are many possible areas where
+ problems can occur - the least of which are race conditions.
+
+ After a server has received a connection following by a PASS/SERVER
+ pair which were recognised as being valid, the server should then
+ reply with its own PASS/SERVER information for that connection as
+ well as all of the other state information it knows about as
+ described below.
+
+ When the initiating server receives a PASS/SERVER pair, it too then
+
+
+
+Oikarinen & Reed [Page 58]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ checks that the server responding is authenticated properly before
+ accepting the connection to be that server.
+
+8.6.1 Server exchange of state information when connecting
+
+ The order of state information being exchanged between servers is
+ essential. The required order is as follows:
+
+ * all known other servers;
+
+ * all known user information;
+
+ * all known channel information.
+
+ Information regarding servers is sent via extra SERVER messages, user
+ information with NICK/USER/MODE/JOIN messages and channels with MODE
+ messages.
+
+ NOTE: channel topics are *NOT* exchanged here because the TOPIC
+ command overwrites any old topic information, so at best, the two
+ sides of the connection would exchange topics.
+
+ By passing the state information about servers first, any collisions
+ with servers that already exist occur before nickname collisions due
+ to a second server introducing a particular nickname. Due to the IRC
+ network only being able to exist as an acyclic graph, it may be
+ possible that the network has already reconnected in another
+ location, the place where the collision occurs indicating where the
+ net needs to split.
+
+8.7 Terminating server-client connections
+
+ When a client connection closes, a QUIT message is generated on
+ behalf of the client by the server to which the client connected. No
+ other message is to be generated or used.
+
+8.8 Terminating server-server connections
+
+ If a server-server connection is closed, either via a remotely
+ generated SQUIT or 'natural' causes, the rest of the connected IRC
+ network must have its information updated with by the server which
+ detected the closure. The server then sends a list of SQUITs (one
+ for each server behind that connection) and a list of QUITs (again,
+ one for each client behind that connection).
+
+
+
+
+
+
+
+Oikarinen & Reed [Page 59]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+8.9 Tracking nickname changes
+
+ All IRC servers are required to keep a history of recent nickname
+ changes. This is required to allow the server to have a chance of
+ keeping in touch of things when nick-change race conditions occur
+ with commands which manipulate them. Commands which must trace nick
+ changes are:
+
+ * KILL (the nick being killed)
+
+ * MODE (+/- o,v)
+
+ * KICK (the nick being kicked)
+
+ No other commands are to have nick changes checked for.
+
+ In the above cases, the server is required to first check for the
+ existence of the nickname, then check its history to see who that
+ nick currently belongs to (if anyone!). This reduces the chances of
+ race conditions but they can still occur with the server ending up
+ affecting the wrong client. When performing a change trace for an
+ above command it is recommended that a time range be given and
+ entries which are too old ignored.
+
+ For a reasonable history, a server should be able to keep previous
+ nickname for every client it knows about if they all decided to
+ change. This size is limited by other factors (such as memory, etc).
+
+8.10 Flood control of clients
+
+ With a large network of interconnected IRC servers, it is quite easy
+ for any single client attached to the network to supply a continuous
+ stream of messages that result in not only flooding the network, but
+ also degrading the level of service provided to others. Rather than
+ require every 'victim' to be provide their own protection, flood
+ protection was written into the server and is applied to all clients
+ except services. The current algorithm is as follows:
+
+ * check to see if client's `message timer' is less than
+ current time (set to be equal if it is);
+
+ * read any data present from the client;
+
+ * while the timer is less than ten seconds ahead of the current
+ time, parse any present messages and penalize the client by
+ 2 seconds for each message;
+
+ which in essence means that the client may send 1 message every 2
+
+
+
+Oikarinen & Reed [Page 60]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ seconds without being adversely affected.
+
+8.11 Non-blocking lookups
+
+ In a real-time environment, it is essential that a server process do
+ as little waiting as possible so that all the clients are serviced
+ fairly. Obviously this requires non-blocking IO on all network
+ read/write operations. For normal server connections, this was not
+ difficult, but there are other support operations that may cause the
+ server to block (such as disk reads). Where possible, such activity
+ should be performed with a short timeout.
+
+8.11.1 Hostname (DNS) lookups
+
+ Using the standard resolver libraries from Berkeley and others has
+ meant large delays in some cases where replies have timed out. To
+ avoid this, a separate set of DNS routines were written which were
+ setup for non-blocking IO operations and then polled from within the
+ main server IO loop.
+
+8.11.2 Username (Ident) lookups
+
+ Although there are numerous ident libraries for use and inclusion
+ into other programs, these caused problems since they operated in a
+ synchronous manner and resulted in frequent delays. Again the
+ solution was to write a set of routines which would cooperate with
+ the rest of the server and work using non-blocking IO.
+
+8.12 Configuration File
+
+ To provide a flexible way of setting up and running the server, it is
+ recommended that a configuration file be used which contains
+ instructions to the server on the following:
+
+ * which hosts to accept client connections from;
+
+ * which hosts to allow to connect as servers;
+
+ * which hosts to connect to (both actively and
+ passively);
+
+ * information about where the server is (university,
+ city/state, company are examples of this);
+
+ * who is responsible for the server and an email address
+ at which they can be contacted;
+
+ * hostnames and passwords for clients which wish to be given
+
+
+
+Oikarinen & Reed [Page 61]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ access to restricted operator commands.
+
+ In specifying hostnames, both domain names and use of the 'dot'
+ notation (127.0.0.1) should both be accepted. It must be possible to
+ specify the password to be used/accepted for all outgoing and
+ incoming connections (although the only outgoing connections are
+ those to other servers).
+
+ The above list is the minimum requirement for any server which wishes
+ to make a connection with another server. Other items which may be
+ of use are:
+
+ * specifying which servers other server may introduce;
+
+ * how deep a server branch is allowed to become;
+
+ * hours during which clients may connect.
+
+8.12.1 Allowing clients to connect
+
+ A server should use some sort of 'access control list' (either in the
+ configuration file or elsewhere) that is read at startup and used to
+ decide what hosts clients may use to connect to it.
+
+ Both 'deny' and 'allow' should be implemented to provide the required
+ flexibility for host access control.
+
+8.12.2 Operators
+
+ The granting of operator privileges to a disruptive person can have
+ dire consequences for the well-being of the IRC net in general due to
+ the powers given to them. Thus, the acquisition of such powers
+ should not be very easy. The current setup requires two 'passwords'
+ to be used although one of them is usually easy guessed. Storage of
+ oper passwords in configuration files is preferable to hard coding
+ them in and should be stored in a crypted format (ie using crypt(3)
+ from Unix) to prevent easy theft.
+
+8.12.3 Allowing servers to connect
+
+ The interconnection of server is not a trivial matter: a bad
+ connection can have a large impact on the usefulness of IRC. Thus,
+ each server should have a list of servers to which it may connect and
+ which servers may connect to it. Under no circumstances should a
+ server allow an arbitrary host to connect as a server. In addition
+ to which servers may and may not connect, the configuration file
+ should also store the password and other characteristics of that
+ link.
+
+
+
+Oikarinen & Reed [Page 62]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+8.12.4 Administrivia
+
+ To provide accurate and valid replies to the ADMIN command (see
+ section 4.3.7), the server should find the relevant details in the
+ configuration.
+
+8.13 Channel membership
+
+ The current server allows any registered local user to join upto 10
+ different channels. There is no limit imposed on non-local users so
+ that the server remains (reasonably) consistant with all others on a
+ channel membership basis
+
+9. Current problems
+
+ There are a number of recognized problems with this protocol, all of
+ which hope to be solved sometime in the near future during its
+ rewrite. Currently, work is underway to find working solutions to
+ these problems.
+
+9.1 Scalability
+
+ It is widely recognized that this protocol does not scale
+ sufficiently well when used in a large arena. The main problem comes
+ from the requirement that all servers know about all other servers
+ and users and that information regarding them be updated as soon as
+ it changes. It is also desirable to keep the number of servers low
+ so that the path length between any two points is kept minimal and
+ the spanning tree as strongly branched as possible.
+
+9.2 Labels
+
+ The current IRC protocol has 3 types of labels: the nickname, the
+ channel name and the server name. Each of the three types has its
+ own domain and no duplicates are allowed inside that domain.
+ Currently, it is possible for users to pick the label for any of the
+ three, resulting in collisions. It is widely recognized that this
+ needs reworking, with a plan for unique names for channels and nicks
+ that don't collide being desirable as well as a solution allowing a
+ cyclic tree.
+
+9.2.1 Nicknames
+
+ The idea of the nickname on IRC is very convenient for users to use
+ when talking to each other outside of a channel, but there is only a
+ finite nickname space and being what they are, its not uncommon for
+ several people to want to use the same nick. If a nickname is chosen
+ by two people using this protocol, either one will not succeed or
+
+
+
+Oikarinen & Reed [Page 63]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+ both will removed by use of KILL (4.6.1).
+
+9.2.2 Channels
+
+ The current channel layout requires that all servers know about all
+ channels, their inhabitants and properties. Besides not scaling
+ well, the issue of privacy is also a concern. A collision of
+ channels is treated as an inclusive event (both people who create the
+ new channel are considered to be members of it) rather than an
+ exclusive one such as used to solve nickname collisions.
+
+9.2.3 Servers
+
+ Although the number of servers is usually small relative to the
+ number of users and channels, they two currently required to be known
+ globally, either each one separately or hidden behind a mask.
+
+9.3 Algorithms
+
+ In some places within the server code, it has not been possible to
+ avoid N^2 algorithms such as checking the channel list of a set
+ of clients.
+
+ In current server versions, there are no database consistency checks,
+ each server assumes that a neighbouring server is correct. This
+ opens the door to large problems if a connecting server is buggy or
+ otherwise tries to introduce contradictions to the existing net.
+
+ Currently, because of the lack of unique internal and global labels,
+ there are a multitude of race conditions that exist. These race
+ conditions generally arise from the problem of it taking time for
+ messages to traverse and effect the IRC network. Even by changing to
+ unique labels, there are problems with channel-related commands being
+ disrupted.
+
+10. Current support and availability
+
+ Mailing lists for IRC related discussion:
+ Future protocol: ircd-three-request@eff.org
+ General discussion: operlist-request@eff.org
+
+ Software implemenations
+ cs.bu.edu:/irc
+ nic.funet.fi:/pub/irc
+ coombs.anu.edu.au:/pub/irc
+
+ Newsgroup: alt.irc
+
+
+
+
+Oikarinen & Reed [Page 64]
+\f
+RFC 1459 Internet Relay Chat Protocol May 1993
+
+
+Security Considerations
+
+ Security issues are discussed in sections 4.1, 4.1.1, 4.1.3, 5.5, and
+ 7.
+
+12. Authors' Addresses
+
+ Jarkko Oikarinen
+ Tuirantie 17 as 9
+ 90500 OULU
+ FINLAND
+
+ Email: jto@tolsun.oulu.fi
+
+
+ Darren Reed
+ 4 Pateman Street
+ Watsonia, Victoria 3087
+ Australia
+
+ Email: avalon@coombs.anu.edu.au
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Oikarinen & Reed [Page 65]
+\f
\ No newline at end of file
--- /dev/null
+
+send.c re-work
+
+PREFIXES
+========
+
+ Server prefixes are the ":%s" strings at the beginning of messages.
+They are used by servers to route the message properly and by servers to
+local clients to update their idea of who is whom.
+
+":nick!user@host" is a prefix ":name" where name is either a nick
+or name of a server is another valid prefix.
+
+Typical prefix for a local client to a channel:
+
+":Dianora!db@irc.db.net"
+
+for a prefix to a remote server:
+":Dianora"
+
+e.g. as seen locally on a channel:
+
+":Dianora!db@irc.db.net PRIVMSG #us-opers :ON TOP OF ...\r\n"
+
+e.g. as seen sent to a remote server:
+":Dianora PRIVMSG #us-opers :ON TOP OF ...\r\n"
+
+ It has been argued that full prefixes sent locally are a waste of bandwidth
+(Isomer from Undernet has argued this). i.e. instead of sending:
+":nick!user@host" for a local prefix, one could just send ":nick"..
+Unfortunately, this breaks many clients badly. Personally I feel that
+until clients are updated to understand that a full prefix isn't always
+going to be sent, that this should be held off on.
+
+ As much as possible, prefix generation is now moved "upstairs" as
+much as possible. i.e. if its known its a local client only, then the
+onus of the prefix generation, is the users, not hidden in send.c
+This allows somewhat faster code to be written, as the prefix doesn't
+have to be regenerated over and over again.
+
+ Prefixes aren't sent in all cases, such as a new user using NICK
+A prefix is needed when it must be routed.
+
+i.e.
+
+NICK newnick
+
+ There is obviously no prefix needed from a locally connected client.
+
+
+
+FUNCTIONS
+=========
+
+sendto_one() - Should be used for _local_ clients only
+ it expects the prefix to be pre-built by user.
+
+ usage - sendto_one(struct Client *to, char *pattern, ...);
+
+ typical use:
+
+ sendto_one(acptr,":%s NOTICE %s :I'm tired", me.name,
+ acptr->name);
+ Note: This was from a server "me" hence only one
+ name in prefix.
+
+ This would be an example of a client sptr, noticing
+ acptr IF acptr is known to be a local client:
+
+ sendto_one(acptr,":%s!%s@%s NOTICE %s :You there?",
+ sptr->name,
+ sptr->username,
+ sptr->host,
+ acptr->name);
+
+sendto_one_prefix()
+ - Sends a message to a remote client, with proper
+ prefix and target (name or UID).
+ usage - sendto_one_prefix(struct Client *target_p,
+ struct Client *source_p,
+ const char *command,
+ const char *pattern, ...)
+
+ typical use:
+
+ sendto_one_prefix(target_p, source_p, "INVITE", ":%s",
+ chptr->chname);
+
+
+sendto_one_notice()
+ - Sends a notice from this server to target. Target may
+ be a local or remote client.
+ Prefix and target are chosen based on TS6 capability.
+
+ typical use:
+
+ sendto_one_notice(source_p, ":You suck. Yes, really.");
+
+sendto_one_numeric()
+ - Sends a numeric from this server to target. Target may
+ be a local or remote client.
+ Prefix and target are chosen based on TS6 capability.
+
+ typical use:
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "p :%u staff members", count);
+
+sendto_channel_flags()
+ - This function sends a var args message to a channel globally,
+ except to the client specified as "one", the prefix
+ is built by this function on the fly as it has to
+ be sent both to local clients on this server and to
+ remote servers.
+ For type use one of:
+ ONLY_SERVERS ALL_MEMBERS ONLY_CHANOPS ONLY_CHANOPSVOICED
+ If type is not ALL_MEMBERS it's not sent to not-CHW-capable
+ servers.
+ Deaf (umode +D) clients are always skipped.
+
+ usage - sendto_channel_flags(struct Client *one,
+ int type,
+ struct Client *from,
+ struct Channel *chptr,
+ const char *pattern, ... );
+
+ sendto_channel_butone(cptr, ALL_MEMBERS, sptr, chptr
+ "PRIVMSG %s :HI!",
+ chptr->chname);
+
+ e.g. if channel message is coming from "cptr"
+ it must not be sent back to cptr.
+
+
+sendto_server()
+ - This function sends specified var args message
+ to all connected servers except the client "one"
+ which have all of "caps" capabilities but none
+ of "nocaps" capabilities.
+
+ If "chptr" is not NULL and is a local channel,
+ nothing is sent.
+
+ usage - sendto_server(struct Client *one,
+ struct Channel *chptr,
+ unsigned long caps,
+ unsigned long nocaps,
+ const char *format, ... );
+
+sendto_common_channels_local()
+ - This function is used only by m_nick and exit_one_client
+ its used to propagate nick changes to all channels user
+ is in, and QUIT messages to all channels user is in.
+ As it only sends to local clients, prefix generation
+ is left to the user. It also sends the message to the
+ user if the user isn't on any channels.
+
+ usage - sendto_common_channels_local(struct Client *user,
+ const char *pattern,
+ ...);
+
+sendto_channel_local()
+ - This function is used to send only locally, never
+ to remote servers. This is useful when removing
+ local chanops, or adding a local chanop. MODE/SJOIN
+ sent to remote server allows that server to propagate
+ mode changes to its clients locally.
+ The message is also sent to deaf (umode +D) clients.
+
+ usage - sendto_channel_local(int type,
+ struct Channel *chptr,
+ const char *pattern, ... );
+
+ prefix must be pre-built. type is a flag
+ denoting ONE of
+ ALL_MEMBERS - all members locally are sent to
+ ONLY_CHANOPS_VOICED - only chanops and voiced see this
+ ONLY_CHANOPS - only chanops see this
+
+
+sendto_match_butone()
+ - only used for the old style oper masking
+ i.e. /msg #hostmask which in hyb7 is /msg $#hostmask
+ or /msg $servermask in hyb7 /msg $$servermask
+
+ usage - sendto_match_butone(struct Client *one,
+ struct Client *source_p,
+ char *mask,
+ int what,
+ const char *pattern, ... );
+
+ one is the client not to send to
+ mask is the actual mask
+ what is either MATCH_HOST or MATCH_SERVER
+
+sendto_match_servs()
+ - Allows sending a message to servers whose names match
+ the given mask. A message is also sent to non-matching
+ servers which have matching servers behind them.
+ Used for ENCAP, remote kline, etc.
+ No message is sent to source_p->from.
+
+ usage - sendto_match_servs(struct Client *source_p,
+ const char *mask,
+ int cap, int nocap,
+ const char *pattern, ...);
+
+sendto_anywhere()
+ - Allows the sending of a message to any client on the net
+ without knowing whether its local or remote. The penalty
+ is the calculation of a run-time prefix.
+ It is less efficient then sendto_one()
+
+ usage - sendto_anywhere(struct Client *to,
+ struct Client *from,
+ const char *command,
+ const char *pattern, ...);
+
+ e.g.
+ sendto_anywhere(target_p, source_p,
+ "PRIVMSG", ":Hi, Where ever you are");
+
+sendto_realops_flags()
+ - combines old sendto_realops and sendto_realops_flags
+ sends specified message to opers locally only
+ depending on umodes. UMODE_ALL is UMODE_SERVNOTICE.
+ the message is sent as a server notice, prefixed with
+ "*** Notice -- ".
+
+ usage - sendto_realops_flags(int flags,
+ const char *pattern, ... );
+
+ e.g.
+ sendto_realops_flags(UMODE_ALL,
+ "Don't eat the yellow snow");
+
+sendto_wallops_flags()
+ - sends specified message to opers/users locally,
+ depending on umodes. used for messages that need
+ to be in wallops form
+ - some policy decisions about who gets what live in here
+
+ usage - sendto_wallops_flags(int flags,
+ struct Client *, const char *patterm ...);
+
+ e.g.
+ sendto_wallops_flags(UMODE_LOCOPS,
+ sptr, "Message");
+
+-- Diane Bruce
+Updated Jan 2006 by jilles with ratbox and late hybrid7 changes
+
+$Id: send.txt 587 2006-01-27 19:45:11Z jilles $
--- /dev/null
+ Overview of the TS5 system
+ Lee H <lee@leeh.co.uk>
+
+$Id: ts5.txt 6 2005-09-10 01:02:21Z nenolod $
+
+For the purposes of this document, ircd versions:
+ hybrid6.0
+ ircd-comstud-1.12
+ CSr31pl4
+
+and prior, are TS3.
+
+ircd-hybrid-6.2 and later support TS5.
+
+
+Whats TS5?
+----------
+
+The difference between TS5 and TS3 is what happened on opless channels. TS
+works by establishing which server has the oldest version of the channel,
+the version that is oldest, keeps its modes and ops, the version that is
+youngest, removes their modes and ops, and accepts the older version.
+
+There was an exception to this rule with opless channels, if a channel was
+opless, TS3 would allow anybody to keep their ops and modes on the channel.
+TS5 aims to stop this, by removing this exception.
+
+Example1:
+
+An irc network, with server A (every server is ts3)
+
+UserA is on ServerA, in channel #broken. This channel is opless, and has a
+TS of 800000000. ServerA splits, and whilst it is split, UserA cycles
+channel #broken, recreates the channel and is given ops. On ServerA #broken
+now has a TS of 900000000 and has ops. ServerA rejoins with the network,
+via HubB. HubB realises #broken is opless, so allows UserA to retain ops.
+The TS is moved forward to 900000000.
+
+The network now sees #broken as having a TS of 900000000, with UserA being
+opped.
+
+Example2:
+
+An irc network, with server C (every server is ts5)
+
+Same scenario as above. ServerC splits and UserC cycles channel #broken,
+recreating it with a TS of 900000000. ServerC rejoins with the network via
+HubD. HubD realises #broken has a TS of 800000000 locally, and ServerC is
+showing a TS of 900000000, it ignores ServerC's modes and ops. The channel
+remains opless. ServerC receives HubD's modes, and it notices HubD has a
+lower TS of channel #broken. It removes UserC's ops, removes the channel
+modes on #broken, and accepts HubD's status.
+
+The network version of #broken hasnt changed. It is still opless, with a TS
+of 800000000.
+
+
+As you can see, TS5 makes splitting a server to regain ops useless, as it
+cannot be abused to give ops after a netsplit.
+
+The problem with TS5 however, is what happens on a mixed TS5/TS3 network.
+Channels where the older TS has ops will behave the same way on TS5 and TS3,
+however an opless channel will behave differently, as you can see above.
+
+The result of TS5/TS3 mixed can be a desync:
+
+Example1:
+
+As per Example1 above, except the rest of the network is TS5, ServerA is
+TS3. ServerA would keep its modes and ops, whilst the rest of the network
+would remove them. This means only ServerA would see UserA as opped. The
+desync can be abused, as UserA can send modes. Hybrid6.0 servers will
+accept these modes from the unopped client, so if UserA ops UserB, who then
+ops UserA, the channel will be the same across all Hybrid6.0 and Hybrid6.1
+servers.
+
+Example2:
+
+As per Example2 above, except the rest of the network is TS3. ServerC is
+TS5. ServerC would remove its modes and ops, therefore UserC would not be
+opped on ServerC, therefore it could not send any mode changes to the
+channel. Although it is opped elsewhere, it isnt opped locally, so the
+desync cannot be abused.
+
+As you can see, the desync's that can occur can either be resynced, or are
+useless to the user, so a mixed TS5/TS3 network is not a huge problem,
+although a desync is NOT a good thing to have.
+
+
+Why TS5?
+--------
+
+We have jumped to TS5 from TS3, because there was a version of ircd that was
+TS4, so it was thought better to avoid a clash with an existing version.
+
+
+Advantages
+----------
+
+Its a realistic event that a server will be attacked so it splits off a
+network, then used to regain ops in a channel. TS5 makes this pointless,
+the server will never give ops on a netsplit. TS5 is network wide, so it
+leaves individual servers free to choose options like NO_JOIN_ON_SPLIT,
+whilst keeping splits useless to users.
+
+
+Disadvantages
+-------------
+
+Its virtually impossible for a user to actively regain ops themselves (some
+regard this as an advantage..) because on a large sized channel, its
+impossible to get people to leave so it can be recreated, therefore if a
+network did not have some form of services, it could possibly end up
+requiring oper intervention, as you cant get everybody to leave, and you
+cant use splits to regain ops, therefore if the channel is open (an
+invite-only channel would gradually destroy itself as noone new can join) it
+could be impossible for a user to regain ops.
+
+On a network that has some form of services, The effect of TS5 would be
+minimal, however the services must be of sufficient quality to fix opless
+channels, as TS5 renders netsplits for ops worthless.
+
+
+Recommendations
+---------------
+
+If your network has good stable services, we recommend TS5 is enabled, as
+people have no reason to abuse netsplits anyway.
+
+If your network has no services at all, then TS5 may cause problems with
+users being left with a permanently opless channel.
+
+If your network occupies the middle ground, then its a choice between users
+needing to be able to use splits to regain ops, or making netsplits that are
+caused to regain ops worthless.
+
+If TS5 is chosen, the FULL network must upgrade and this should be done in a
+relatively short space of time to minimise the possible desync effects.
+
+
+Alternatives
+------------
+
+There is also NO_JOIN_ON_SPLIT and NO_OP_ON_SPLIT, however these use the
+configuration of minimum servers and users, and sometimes a split that is
+above these limits is enough to be abused to regain ops, whereas if the
+limits are too high, clients will never be able to join anything or be opped
+when they create a channel.
+
+
+EOF
--- /dev/null
+$Id: ts6.txt 6 2005-09-10 01:02:21Z nenolod $
+
+TS6 Proposal (v7)
+Written by Lee H <lee@leeh.co.uk>
+Ideas borrowed heavily from ircnet (Beeth, jv, Q)
+
+Introduction
+------------
+
+This document aims to fix some of the flaws that are still present in the
+current TS system.
+
+Whilst only one person may use a nickname at any one time, they are not
+a reliable method of directing commands between servers. Clients can change
+their nicknames, which can create desyncs. A reliable method of directing
+messages between servers is required so that a message will always reach the
+intended destination, even if the client changes nicks in between.
+
+UID solves this problem by ensuring that a client has a unique ID for the
+duration of his connection.
+
+This document also aims to solve the lack of TS rules to channel 'bans' on
+a netburst. Bans from both sides of a TS war (losing/winning) are kept.
+Bursting the bans with a TS solves this problem.
+
+There is also a race condition in the current TS system, where a user can
+issue a mode during a netburst and the mode will be set on the server
+we are bursting to.
+
+
+Definitions
+-----------
+
+Throughout this document, the following terms are used:
+
+SID - A servers unique ID. This is three characters long and must be in
+ the form [0-9][A-Z0-9][A-Z0-9]
+ID - A clients unique ID. This is six characters long and must be in
+ the form [A-Z][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]. The
+ numbers [0-9] at the beginning of an ID are legal characters, but
+ reserved for future use.
+UID - An ID concateneted to a SID. This forms the clients UID.
+TS6 - The TS version 6.
+
+
+Support
+-------
+
+Support for this document is given by the TS version 6.
+
+Wherever a destination parameter or source parameter is used, it must use
+the SID or UID if the server/client has one. A TS6 capable server must
+translate any SIDs/UIDs back into the server/clients name when communicating
+with a server that does not support TS6.
+
+A TS6 server must also support the QS (quitstorm) system, and the encap
+specification found here:
+http://www.leeh.co.uk/ircd/encap.txt
+
+The TS6 protocol does not supports masked entities.
+
+
+Nick TS rules
+-------------
+
+A server receiving a command that requires nick TS rules must check for a
+collision between an existing user, and the nick in the received message.
+(the "new user"). The collisions must obey the rules specified in Nick TS
+collisions.
+
+If the TS received is lower than the TS of the existing user the server will
+collide the existing user if the clients user@host are different, if the
+clients user@hosts are identical it will collide the new user.
+
+If the TS received is equal to the TS of the existing user both clients are
+collided.
+
+If the TS received is higher than the TS of the existing user, the server
+will collide the existing user if the user@hosts are identical, if the
+clients user@host are different it will collide the new user and drop the
+message.
+
+
+Nick TS collisions
+------------------
+
+If both users are to be collided, we must issue a KILL for the existing
+user to all servers. If the new user has a UID then we must also issue a
+KILL for that UID back to the server sending us data causing the collision.
+
+If only the existing user is being collided, we must issue a KILL for the
+existing user to all servers except the server sending us data. If the
+existing user has a UID and the server sending us data supports TS6 then
+we must also issue a KILL for the existing users UID to the server sending
+us data.
+
+If only the new user is being collided, we must issue a KILL for the new user
+back to the server sending us data if the new user has a UID.
+
+
+Channel TS rules
+----------------
+
+A server receiving a command that requires normal channel TS rules must
+apply the following rules to the command.
+
+If the TS received is lower than our TS of the channel a TS6 server must
+remove status modes (+ov etc) and channel modes (+nt etc). If the
+originating server is TS6 capable (ie, it has a SID), the server must
+also remove any ban modes (+b etc). The new modes and statuses are then
+accepted.
+
+If any bans are removed, the server must send to non-TS6, directly connected
+servers mode changes removing the bans after the command is propagated.
+This prevents desync with banlists, and has to be sent after as clients are
+still able to send mode changes before the triggering command arrives.
+
+If the TS received is equal to our TS of the channel the server should keep
+its current modes and accept the received modes and statuses.
+
+If the TS received is higher than our TS of the channel the server should keep
+its current modes and ignore the received modes and statuses. Any statuses
+given in the received message will be removed. A server must mark clients
+losing their op (+o) status who do not have a UID as 'deopped'. A server must
+ignore any "MODE" commands from a user marked as 'deopped'.
+
+
+Simple channel TS rules
+-----------------------
+
+A server receiving a command that requires simple channel TS rules must
+apply the following rules to the command.
+
+If the TS received is lower, or equal to our TS of the channel the modes are
+accepted. If the TS received is higher than our TS of the channel the modes
+are ignored and dropped.
+
+Simple channel TS rules do not affect current modes in the channel except
+for the modes we are accepting.
+
+
+The following commands are defined here as the TS6 protocol
+-----------------------------------------------------------
+
+PASS:
+PASS <PASSWORD> TS <TS_CURRENT> :<SID>
+
+This command is used for password verification with the server we are
+connecting to.
+
+Due to the burst being sent on verification of the "SERVER" command, and
+"SVINFO" being sent after "SERVER", we need to be aware of the TS version
+earlier to decide whether to send a TS6 burst or not.
+
+The <PASSWORD> field is the password we have stored for this server,
+<TS_CURRENT> is our current TS version. If this field is not present then
+the server does not support TS6. <SID> is the SID of the server.
+
+UID:
+:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
+
+This command is used for introducing clients to the network.
+
+The <SID> field is the SID of the server the client is connected to.
+The <NICK> field is the nick of the client being introduced. The <HOPS>
+field is the amount of server hops between the server being burst to and
+the server the client is on. The <TS> field is the TS of the client, either
+the time they connected or the time they last changed nick. The <UMODE>
+field contains the clients usermodes that need to be transmitted between
+servers. The <USERNAME> field contains the clients username/ident. The
+<HOSTNAME> field contains the clients host.
+
+The <IP> field contains the clients IP. If the IP is not to be sent
+(due to a spoof etc), the field must be sent as "0". The <UID> field is the
+clients UID. The <GECOS> field is the clients gecos.
+
+A server receiving a UID command must apply nick TS rules to the nick.
+
+SID:
+:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
+
+This command is used for introducing servers to the network.
+
+The first <SID> field is the SID of the new servers uplink. The
+<SERVERNAME> field is the new servers name. The <HOPS> field is the hops
+between the server being introduced nd the server being burst to.
+
+The second <SID> field is the SID of the new server. The <GECOS> field i
+is the new servers gecos.
+
+Upon receiving the SID command servers must check for a SID collision.
+Two servers must not be allowed to link to the network with the same SID.
+If a server detects a SID collision it must drop the link to the directly
+connected server through which the command was received.
+
+Client and servers which do not have a UID/SID must be introduced by old
+methods.
+
+SJOIN:
+:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
+
+This command is used for introducing users to channels.
+
+The <SID> field is the SID of the server introducing users to the channel.
+The <TS> field is the channels current TS, <CHANNAME> is the channels
+current name, <CHANMODES> are the channels current modes. <UIDS> is a
+space delimited list of clients UIDs to join to the channel. Each clients
+UID is prefixed with their status on the channel, ie "@UID" for an opped
+user. Multiple prefixes are allowed, "peons" (clients without a status) are
+not prefixed.
+
+A server receiving an SJOIN must apply normal channel TS rules to the SJOIN.
+
+A TS6 server must not use the SJOIN command outside of a netburst
+to introduce a single user to an existing channel. It must instead
+use the "JOIN" command defined in this specification. A TS6 server must
+still use SJOIN for creating channels.
+
+JOIN:
+:<UID> JOIN <TS> <CHANNAME> +<CHANMODES>
+
+This command is used for introducing one user unopped to an existing channel.
+
+The <UID> field is the UID of the client joining the channel. The
+<TS> field is the channels current TS, <CHANNAME> is the channels
+current name, <CHANMODES> are the channels current modes.
+
+A server receiving a JOIN must apply normal channel TS rules to the JOIN.
+
+It should be noted that whilst JOIN would not normally create a
+channel, during specific race conditions it can. This can create
+a ban desync that this specification does not rectify.
+
+BMASK:
+:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
+
+This command is used for bursting channel bans to a network.
+
+The <SID> field is the SID of the server bursting the bans. The
+<TS> field is the channels current TS, <CHANNAME> is the channels
+name. <TYPE> is a single character identifying the mode type (ie,
+for a ban 'b'). <MASKS> is a space delimited list of masks of the
+given mode,limited only in length to the size of the buffer as defined
+by RFC1459.
+
+A server receiving a BMASK must apply simple channel TS rules to the BMASK.
+
+A TS6 server must translate BMASKs into raw modes for non-TS6
+capable servers. This command must be used only after SJOIN has
+been sent for the given channel.
+
+It should be noted however, that a BMASK with a lower TS should
+not be possible without a desync, due to it being sent after
+SJOIN.
+
+TMODE:
+:<UID> TMODE <TS> <CHANNAME> <MODESTRING>
+
+This command is used for clients issuing modes on a channel.
+
+<UID> is the UID of the client setting the mode. <TS> is the
+current TS of the channel, <CHANNAME> is the channels name.
+<MODESTRING> is the raw mode the client is setting.
+
+A server receiving a TMODE must apply simple channel TS rules to the TMODE.
+
+A TS6 server must translate MODEs issued by a local client into TMODE
+to send to other TS6 capable servers.
+
--- /dev/null
+Target Change for Messages
+Lee H <lee -at- leeh.co.uk>
+---------------------------
+
+If the server you are using uses the target change mechanism, then
+restrictions are placed on how many different users you can message in a set
+timeframe.
+
+Target change does not apply to channels, ctcp replies or messages to
+yourself.
+
+You will have a set number of 'slots', each different client you message
+will take up one slot. A client doing a nick change will not use a new slot,
+however a client leaving the network and reconnecting will. You will
+receive 1 new slot roughly every minute.
+
+When all slots are filled, messages to new clients will not be accepted.
+Messages to clients already filling a slot will be accepted. If all slots
+are full, you will receive the ERR_TARGCHANGE numeric, number 707 in the
+form:
+:<server> 707 <yournick> <targetnick> :Targets changing too fast, message dropped
+
+The slots are operated as a FIFO (first in, first out), so the first person
+you message will be the first person removed from a slot, even if you are
+still talking to this person.
+
+The number of slots in use will be kept through a reconnection, though the
+information in those slots will be dropped. However, you will always
+receive one free slot on a reconnection. Other servers using this mechanism
+will also be made aware of details about slots.
+
+Target change can be avoided via the CNOTICE and CPRIVMSG commands, when you
+are opped or voiced in a channel, and you are messaging a client within that
+channel. See /quote help cnotice and /quote help cprivmsg for more
+information.
+
+--
+$Id: tgchange.txt 6 2005-09-10 01:02:21Z nenolod $
--- /dev/null
+$Id: whats-new-2.0.txt 6 2005-09-10 01:02:21Z nenolod $
+
+The following is a list of major changes between ircd-ratbox-1.x and
+ircd-ratbox-2.0
+
+Config File
+-----------
+- name="foo"; is no longer supported in connect {}; operator {}; and
+ class {};. You must now use connect "irc.foo.com" { ... }; etc.
+- operator {}; no longer contains a class
+- kline_with_connection_closed is gone, replaced with
+ kline_reason = "Connection closed";
+- logging {}; is gone, replaced with more advanced log system - see
+ example.conf log {}; for more info. Note, by default only very basic
+ information will be logged.
+- support for a specific opers initial umodes on /oper, by umodes = ...;
+ in operator {};
+- added stats_e_disabled = yes|no; to general {};, controlling whether stats
+ e (which can contain server ips) is never shown to anyone
+- support for compressed|encrypted|topicburst|autoconn = yes|no; is gone,
+ replaced with flags = compressed, encrypted, topicburst, autoconn;
+- support for individual auth flags "kline_exempt = yes"; etc removed, now
+ must use flags = ...; method
+- support for individual oper flags "kline = yes;" etc removed, now must use
+ flags = ...; method.
+- extended flags = ...; method to allow negation, so you may prefix a flag
+ with '~' to negate it. Default oper flags are operwall, remoteban and
+ encrypted (indicates password is encrypted with mkpasswd)
+- new flags in shared {};, tkline, txline and tresv, allowing temp only of
+ kline, xline and resv respectively.
+- new flags in cluster {}; tkline, txline and tresv which will cluster
+ only the temp of each type. kline, xline and resv will now only
+ cluster the permanent ones of each type.
+- cluster {}; no longer allows a server to place klines etc locally, it
+ simply dictates who we send to.
+- shared {}; is now ordered top-down and the first one that matches the
+ user@host and server will be used, and the flags taken from this. This
+ means if a remote oper matches a shared block without kline privs, even
+ though there is a shared {}; block they match under it with kline privs
+ they will not be able to place klines.
+- added invite_ops_only to channel {}; which will restrict the use of INVITE
+ to chanops on that channel always, rather than just to +i chans.
+
+Client
+------
+- /help is now available for all users, as its now cached in memory.
+ removes config option use_help from general {};
+- default CHANNELLEN for local clients is now 50
+- AWAYLEN added to 005, default is 90
+- kick/part/quit now use REASONLEN (120) rather than TOPICLEN
+- umode +g now exempts users messaging themselves
+
+Oper
+----
+- kline/dline <nick> is no longer supported
+- oper reasons are now more fully supported
+- opers can now be hidden from stats p, by flag "invisible"
+- XLINEs no longer contain a type field, theyll now all just silently reject
+- xlines are now 'tracked' - stats X shows how many times each xline has
+ rejected a client
+- temp xlines and resvs
+- klines set against spoofed users will now take effect when the user
+ connects as well, if the user is not kline_exempt
+- trace spy now contains target param if its against a single user
+- the old "you need xline=yes;" notices have been replaced by ERR_NOPRIVS
+ (numeric 723)
+- umode +C, machine parsable client connect/exit notices which includes the
+ two unused fields sent in the USER command
+
+Channels
+--------
+- persistent channels have been removed
+- quiet_on_ban now uses a cache, which should speed it up
+
+Server <-> Server Protocol
+--------------------------
+- support for bursting away messages on connect, controlled by
+ burst_away = yes|no; in general {};
+- TS6, the new server <-> server protocol. As part of this you *must*
+ specify a "sid" in serverinfo {}; that is three alphanumeric characters,
+ and must start with a digit. use_ts6 = yes|no; in general controls
+ whether it is actually used or not. For more information, see:
+ http://www.ircd-ratbox.org/TS6.txt
+- fakename in connect {}; is gone, you can no longer mask servers.
+- support for encrypted links are gone
+- global capabilities. The server will now inform the rest of the network
+ over ENCAP about the capabilities of other servers.
+
+Misc
+----
+- support for message translation has been removed. If you want these,
+ modify messages.tab and distribute that.
+- most of server hiding is gone, only thing that is left is flattened links
+- flattened links cache is now stored in memory instead of a file
+- nick delay. any client which splits will have their nick 'locked', until
+ a remote client uses this nick, or until it expires after the time nick_delay
+ in general {}. This prevents the masses of kills from clients 'regaining'
+ nicknames on a short split.
+- support for disabling bold chars etc in channel names for local users, to
+ prevent faking channels. disable_fake_channels = <yes|no>; in general {};
+
+Code cleanups
+-------------
+- remove mapped ipv4 in ipv6 sockets, the correct native socket will now be
+ used for each.
+- module API has been rewritten, 1.x modules will no longer work.
+- hook API has been rewritten
+- proper handlers for ENCAP commands
+- support for vms ast i/o
+- connect {}; and operator {}; are now in their own structs, saving memory
+ in ConfItem
+- shared/cluster now use the same struct and flags
+- various other code cleanups thatd take all year to list ;)
--- /dev/null
+# $Id: whats-new-2.1.txt 6 2005-09-10 01:02:21Z nenolod $
+
+The following is a list of the major changes between ircd-ratbox-2.0 and
+ircd-ratbox-2.1.
+
+Config file
+-----------
+- IP entries within exempt {}; can now be stacked, eg:
+ exempt { ip = "127.0.0.1"; ip = "192.168.0.0/24"; };
+- shared {}; has been completely reworked so that it allows stacking.
+ shared {}; blocks for 2.0 and earlier will no longer work.
+ See example.conf for the new format.
+- cluster {}; has been reworked to allow stacking.
+ cluster {}; blocks for 2.0 and earlier will no longer work.
+ See example.conf for the new format.
+- New auth flag, jupe_exempt. When set on a client, that client will not
+ generate jupe warning notices when they try to join juped channels.
+- You may no longer specify klines, dlines, xlines and resvs in ircd.conf.
+ Instead, there is no support for banconfigs with a ".perm" extension,
+ eg kline.conf.perm. Anything within a .perm file will be read, but
+ cannot be removed via the ircd. The format of these files is the same
+ format as their normal non-permanent counterpart. So kline.conf.perm
+ takes the same format as kline.conf, and so on.
+- rehash and kill -HUP no longer reread the ban configs kline.conf etc.
+ You must now use /rehash bans, or kill -USR2
+- New config option to general {};, dline_with_reason = yes|no;. Default no.
+ Traditionally, when a client connects and is dlined, the reason is never
+ shown. Enabling this will output the reason to clients.
+
+
+Client
+------
+- Support for "deaf", umode +D. When a client is 'deaf', they will not
+ receive any messages sent towards channels. They will still receive joins
+ etc, but normal channel chat will not be sent. Any private messages
+ will still be sent.
+- Target change anti-spam system. Restrictions are now placed upon how many
+ different clients (not channels) can be messaged within a specific time
+ period.
+- Server-side notify lists. These allow a client to request a server
+ notifies them when a nickname comes online or goesoffline. See
+ doc/monitor.txt for more information.
+- Client capabilities. These allow clients to negotiate capabilities with
+ the server. Currently supports:
+ - multi-prefix: A +ov client will have "@+" shown in names/who replies.
+
+Oper
+----
+- RESVs are now tracked. Stats q/Q have been modified so that the first
+ field of the output is now a number indicating how many times the RESV
+ has been hit.
+
+ratbox-services support (non-efnet)
+-----------------------------------
+- For those of you using ratbox-services, there is now compatibility code
+ within ircd, enabled by passing '--enable-services' to configure.
+ See doc/services.txt for more information.
+
+Code cleanups
+-------------
+- Removed the custom file implementation, use the system one instead.
+- The hook system has been redesigned, theres now a more thorough set of
+ hooks that may be used. See docs/hooks.txt
+- Removed support for VMS. It hasnt worked for a long time.
+- Cleanups to the expiry of temp klines/dlines.
+- Various other things ;-).
+- Better splitcode, it now works on how many servers have notified
+ us of burst finishing, rather than how many servers are linked to the
+ network.
--- /dev/null
+-i8 -bli0 -cs -ut -nsai -nsaw -nsaf -npcs -nprs -l100
--- /dev/null
+#
+# Makefile.in for ircd/contrib
+#
+# $Id: Makefile.in 1849 2006-08-23 12:40:21Z jilles $
+#
+CC = @CC@
+RM = @RM@
+SED = @SED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+PICFLAGS = @PICFLAGS@
+MKDEP = @MKDEP@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+SHELL = /bin/sh
+AUTOMODULEDIR = @moduledir@/extensions
+
+SSL_LIBS = @SSL_LIBS@
+SSL_INCLUDES = @SSL_INCLUDES@
+
+IRCDLIBS = @LIBS@ $(SSL_LIBS)
+
+INCLUDES = -I. -I../include -I../libcharybdis -I../adns $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+SRCS = \
+ createauthonly.c \
+ extb_account.c \
+ extb_canjoin.c \
+ extb_channel.c \
+ extb_oper.c \
+ extb_server.c \
+ extb_realname.c \
+ extb_extgecos.c \
+ hurt.c \
+ ip_cloaking.c \
+ sno_farconnect.c \
+ sno_globalkline.c \
+ sno_globaloper.c \
+ m_42.c \
+ m_findforwards.c \
+ m_identify.c \
+ m_mkpasswd.c \
+ m_ojoin.c \
+ m_olist.c \
+ m_okick.c \
+ m_omode.c \
+ m_opme.c \
+ m_webirc.c \
+ no_oper_invis.c \
+ spy_admin_notice.c \
+ spy_info_notice.c \
+ spy_links_notice.c \
+ spy_motd_notice.c \
+ spy_stats_notice.c \
+ spy_stats_p_notice.c \
+ spy_trace_notice.c \
+ spy_whois_notice.c \
+ spy_whois_notice_global.c \
+ example_module.c
+
+OBJS = ${SRCS:.c=.so}
+
+default: build
+build: all
+all: $(OBJS)
+
+install: all
+ -@if test ! -d $(DESTDIR)$(AUTOMODULEDIR); then \
+ mkdir $(DESTDIR)$(AUTOMODULEDIR); \
+ fi
+ @echo "Installing modules into $(DESTDIR)$(AUTOMODULEDIR) .."
+ @for file in $(OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(AUTOMODULEDIR); \
+ done
+
+.SUFFIXES: .so
+
+.c.so:
+ ${CC} ${PICFLAGS} ${CPPFLAGS} ${CFLAGS} $< -o $@
+
+.PHONY: depend clean distclean
+depend:
+ @${MKDEP} ${CPPFLAGS} ${SRCS} > .depend
+ @sed s/\\\.o/\\\.so/ < .depend > .depend.tmp
+ @sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
+ @echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
+ @echo '# make depend needs it.' >>Makefile.depend
+ @cat .depend.tmp >>Makefile.depend
+ @mv Makefile.depend Makefile
+ @rm -f .depend.tmp .depend
+
+clean:
+ ${RM} -f *.so *~
+
+distclean: clean
+ ${RM} -f Makefile
+
--- /dev/null
+$Id: README 1622 2006-06-04 03:01:05Z beu $
+
+This directory contains extensions (modules) to charybdis ircd that
+have been contributed by other people, or written by our development
+team. Unsupported extensions live under unsupported/.
+
+
+Modules
+-------
+
+createauthonly.c - Only allow authenticated (identified) users to create
+ channels.
+
+ip_cloaking.c - Cloak (spoof) the host for users that have umode +h.
+
+m_42.c - The Answer to Life, the Universe, and Everything.
+ Syntax: 42
+
+m_findforwards.c - Find channels that forward (+f) to a given channel.
+ Syntax: FINDFORWARDS <channel>
+
+m_mkpasswd.c - MKPASSWD - generate a DES or MD5 encryption of a password
+ Syntax: MKPASSWD <plaintext> [MD5|DES]
+
+m_ojoin.c - OJOIN - Join a channel through any modes or limits with
+ an optional status (@%+)
+ Syntax: OJOIN [status]<channel>
+
+m_olist.c - OLIST - Lists channels like LIST, but shows hidden
+ channels. Oper only of course.
+
+m_opme.c - OPME - Allows an admin to op themselves in an opless channel
+ Syntax: OPME <channel>
+
+m_omode.c - OMODE - Allows an admin to do all sorts of evil upon a
+ channel, sets modes with extreme prejudice
+
+no_oper_invis.c - Disallow opers setting marking themselves as invisible
+ (+i) unless they have the hidden_oper flag.
+
+example_module.c - An example module to be used for creating your own.
+ Syntax: TEST
+
+
+Spy Modules
+-----------
+
+The following are the 'spy' parts, accessible via the +y usermode
+
+spy_admin_notice.c - Spy on clients doing ADMIN
+spy_info_notice.c - Spy on clients doing INFO
+spy_links_notice.c - Spy on clients doing LINKS
+spy_motd_notice.c - Spy on clients doing MOTD
+spy_stats_notice.c - Spy on clients doing all STATS
+spy_stats_p_notice.c - Spy on clients doing STATS p only
+spy_trace_notice.c - Spy on clients doing TRACE/LTRACE
+spy_whois_notice.c - Spy on local clients who WHOIS you.
+spy_whois_notice_global.c - Spy on remote clients who WHOIS you.
+
+Note: if you have both spy_stats_notice.c and spy_stats_p_notice.c loaded
+you will get two messages.
+
+Snomask Modules
+---------------
+
+sno_farconnect.c - Remote client connect/exit notices (snomask +F)
+sno_globalkline.c - Global K/D/X-line activation notices
+sno_globaloper.c - Global oper-up notices
--- /dev/null
+/*
+ * This module restricts channel creation to authenticated users
+ * only. This module could be useful for running private chat
+ * systems, or if a network gets droneflood problems. It will
+ * return ERR_NEEDREGGEDNICK on failure.
+ * -- nenolod
+ *
+ * $Id: createauthonly.c 833 2006-02-15 00:27:59Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+#include "snomask.h"
+#include "numeric.h"
+
+static void h_can_create_channel_authenticated(hook_data_client_approval *);
+
+mapi_hfn_list_av1 restrict_hfnlist[] = {
+ { "can_create_channel", (hookfn) h_can_create_channel_authenticated },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(createauthonly, NULL, NULL, NULL, NULL, restrict_hfnlist, "$Revision: 833 $");
+
+static void
+h_can_create_channel_authenticated(hook_data_client_approval *data)
+{
+ struct Client *source_p = data->client;
+
+ if (*source_p->user->suser == '\0')
+ data->approved = ERR_NEEDREGGEDNICK;
+}
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, doc/example_module.c
+ * Copyright (C) 2001 Hybrid 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 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.
+ *
+ * $Id: example_module.c 494 2006-01-15 16:08:28Z jilles $
+ */
+
+/* List of ircd includes from ../include/ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+/* Declare the void's initially up here, as modules dont have an
+ * include file, we will normally have client_p, source_p, parc
+ * and parv[] where:
+ *
+ * client_p == client issuing command
+ * source_p == where the command came from
+ * parc == the number of parameters
+ * parv == an array of the parameters
+ */
+
+static int munreg_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int mclient_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int mserver_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int mrclient_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int moper_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+/* Show the commands this module can handle in a msgtab
+ * and give the msgtab a name, here its test_msgtab
+ */
+
+struct Message test_msgtab = {
+ "TEST", /* the /COMMAND you want */
+ 0, /* SET TO ZERO -- number of times command used by clients */
+ 0, /* SET TO ZERO -- number of times command used by clients */
+ 0, /* SET TO ZERO -- number of times command used by clients */
+ MFLG_SLOW, /* ALWAYS SET TO MFLG_SLOW */
+
+ /* the functions to call for each handler. If not using the generic
+ * handlers, the first param is the function to call, the second is the
+ * required number of parameters. NOTE: If you specify a min para of 2,
+ * then parv[1] must *also* be non-empty.
+ */
+ {
+ {munreg_test, 0}, /* function call for unregistered clients, 0 parms required */
+ {mclient_test, 0}, /* function call for local clients, 0 parms required */
+ {mrclient_test, 0}, /* function call for remote clients, 0 parms required */
+ {mserver_test, 0}, /* function call for servers, 0 parms required */
+ mg_ignore, /* function call for ENCAP, unused in this test */
+ {moper_test, 0} /* function call for operators, 0 parms required */
+ }
+};
+/*
+ * There are also some macros for the above function calls and parameter counts.
+ * Here's a list:
+ *
+ * mg_ignore: ignore the command when it comes from certain types
+ * mg_not_oper: tell the client it requires being an operator
+ * mg_reg: prevent the client using this if registered
+ * mg_unreg: prevent the client using this if unregistered
+ *
+ * These macros assume a parameter count of zero; you do not set it.
+ * For further details, see include/msg.h
+ */
+
+
+/* The mapi_clist_av1 indicates which commands (struct Message)
+ * should be loaded from the module. The list should be terminated
+ * by a NULL.
+ */
+mapi_clist_av1 test_clist[] = { &test_msgtab, NULL };
+
+/* The mapi_hlist_av1 indicates which hook functions we need to be able to
+ * call. We need to declare an integer, then add the name of the hook
+ * function to call and a pointer to this integer. The list should be
+ * terminated with NULLs.
+ */
+int doing_example_hook;
+mapi_hlist_av1 test_hlist[] = {
+ { "doing_example_hook", &doing_example_hook, },
+ { NULL, NULL }
+};
+
+/* The mapi_hfn_list_av1 declares the hook functions which other modules can
+ * call. The first parameter is the name of the hook, the second is a void
+ * returning function, with arbitrary parameters casted to (hookfn). This
+ * list must be terminated with NULLs.
+ */
+static void show_example_hook(void *unused);
+
+mapi_hfn_list_av1 test_hfnlist[] = {
+ { "doing_example_hook", (hookfn) show_example_hook },
+ { NULL, NULL }
+};
+
+/* Here we tell it what to do when the module is loaded */
+static int
+modinit(void)
+{
+ /* Nothing to do for the example module. */
+ /* The init function should return -1 on failure,
+ which will cause the module to be unloaded,
+ otherwise 0 to indicate success. */
+ return 0;
+}
+
+/* here we tell it what to do when the module is unloaded */
+static void
+moddeinit(void)
+{
+ /* Again, nothing to do. */
+}
+
+/* DECLARE_MODULE_AV1() actually declare the MAPI header. */
+DECLARE_MODULE_AV1(
+ /* The first argument is the name */
+ example,
+ /* The second argument is the function to call on load */
+ modinit,
+ /* And the function to call on unload */
+ moddeinit,
+ /* Then the MAPI command list */
+ test_clist,
+ /* Next the hook list, if we have one. */
+ test_hlist,
+ /* Then the hook function list, if we have one */
+ test_hfnlist,
+ /* And finally the version number of this module. */
+ "$Revision: 494 $");
+
+/* Any of the above arguments can be NULL to indicate they aren't used. */
+
+
+/*
+ * mr_test
+ * parv[0] = sender prefix
+ * parv[1] = parameter
+ */
+
+/* Here we have the functions themselves that we declared above,
+ * and the fairly normal C coding
+ */
+static int
+munreg_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc < 2)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent no parameters",
+ me.name, source_p->name);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You are unregistered and sent parameter: %s",
+ me.name, source_p->name, parv[1]);
+ }
+
+ /* illustration of how to call a hook function */
+ call_hook(doing_example_hook, NULL);
+
+ return 0;
+}
+
+/*
+ * mclient_test
+ * parv[0] = sender prefix
+ * parv[1] = parameter
+ */
+static int
+mclient_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc < 2)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You are a normal user, and sent no parameters",
+ me.name, source_p->name);
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You are a normal user, and send parameters: %s", me.name,
+ source_p->name, parv[1]);
+ }
+
+ /* illustration of how to call a hook function */
+ call_hook(doing_example_hook, NULL);
+
+ return 0;
+}
+
+/*
+ * mrclient_test
+ * parv[0] = sender prefix
+ * parv[1] = parameter
+ */
+static int
+mrclient_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc < 2)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You are a remote client, and sent no parameters",
+ me.name, source_p->name);
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You are a remote client, and sent parameters: %s",
+ me.name, source_p->name, parv[1]);
+ }
+ return 0;
+}
+
+/*
+ * mserver_test
+ * parv[0] = sender prefix
+ * parv[1] = parameter
+ */
+static int
+mserver_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc < 2)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You are a server, and sent no parameters",
+ me.name, source_p->name);
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You are a server, and sent parameters: %s",
+ me.name, source_p->name, parv[1]);
+ }
+ return 0;
+}
+
+/*
+ * moper_test
+ * parv[0] = sender prefix
+ * parv[1] = parameter
+ */
+static int
+moper_test(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc < 2)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent no parameters",
+ me.name, source_p->name);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You are an operator, and sent parameters: %s",
+ me.name, source_p->name, parv[1]);
+ }
+ return 0;
+}
+
+static void
+show_example_hook(void *unused)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Called example hook!");
+}
+
+/* END OF EXAMPLE MODULE */
--- /dev/null
+/*
+ * Account extban type: bans all users with any/matching account
+ * -- jilles
+ *
+ * $Id: extb_account.c 1299 2006-05-11 15:43:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_account(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_account, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1299 $");
+
+static int
+_modinit(void)
+{
+ extban_table['a'] = eb_account;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['a'] = NULL;
+}
+
+static int eb_account(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+
+ (void)chptr;
+ /* $a alone matches any logged in user */
+ if (data == NULL)
+ return EmptyString(client_p->user->suser) ? EXTBAN_NOMATCH : EXTBAN_MATCH;
+ /* $a:MASK matches users logged in under matching account */
+ return match(data, client_p->user->suser) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+}
--- /dev/null
+/*
+ * Canjoin extban type: matches users who are or are not banned from a
+ * specified channel.
+ * -- nenolod/jilles
+ *
+ * $Id: extb_canjoin.c 1841 2006-08-22 17:30:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "channel.h"
+#include "hash.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_canjoin(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_canjoin, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1841 $");
+
+static int
+_modinit(void)
+{
+ extban_table['j'] = eb_canjoin;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['j'] = NULL;
+}
+
+static int eb_canjoin(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+ struct Channel *chptr2;
+ int ret;
+ static int recurse = 0;
+
+ (void)mode_type;
+ /* don't process a $j in a $j'ed list */
+ if (recurse)
+ return EXTBAN_INVALID;
+ if (data == NULL)
+ return EXTBAN_INVALID;
+ chptr2 = find_channel(data);
+ /* must exist, and no point doing this with the same channel */
+ if (chptr2 == NULL || chptr2 == chptr)
+ return EXTBAN_INVALID;
+ /* require consistent target */
+ if (chptr->chname[0] == '#' && data[0] == '&')
+ return EXTBAN_INVALID;
+ /* this allows getting some information about ban exceptions
+ * but +s/+p doesn't seem the right criterion */
+#if 0
+ /* privacy! don't allow +s/+p channels to influence another channel */
+ if (!PubChannel(chptr2))
+ return EXTBAN_INVALID;
+#endif
+ recurse = 1;
+ ret = is_banned(chptr2, client_p, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+ recurse = 0;
+ return ret;
+}
--- /dev/null
+/*
+ * Channel extban type: matches users who are in a certain public channel
+ * -- jilles
+ *
+ * $Id: extb_channel.c 1723 2006-07-06 15:23:58Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "channel.h"
+#include "hash.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_channel(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_channel, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1723 $");
+
+static int
+_modinit(void)
+{
+ extban_table['c'] = eb_channel;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['c'] = NULL;
+}
+
+static int eb_channel(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+ struct Channel *chptr2;
+
+ (void)chptr;
+ (void)mode_type;
+ if (data == NULL)
+ return EXTBAN_INVALID;
+ chptr2 = find_channel(data);
+ if (chptr2 == NULL)
+ return EXTBAN_INVALID;
+ /* require consistent target */
+ if (chptr->chname[0] == '#' && data[0] == '&')
+ return EXTBAN_INVALID;
+ /* privacy! don't allow +s/+p channels to influence another channel */
+ if (!PubChannel(chptr2))
+ return EXTBAN_INVALID;
+ return IsMember(client_p, chptr2) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+}
--- /dev/null
+/*
+ * Extended extban type: bans all users with matching nick!user@host#gecos.
+ * Requested by Lockwood.
+ * - nenolod
+ *
+ * $Id: extb_realname.c 1339 2006-05-17 00:45:40Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_extended(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_extended, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1339 $");
+
+static int
+_modinit(void)
+{
+ extban_table['x'] = eb_extended;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['x'] = NULL;
+}
+
+static int eb_extended(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+ char buf[BUFSIZE];
+ int ret;
+
+ (void)chptr;
+
+ if (data == NULL)
+ return EXTBAN_INVALID;
+
+ ircsnprintf(buf, BUFSIZE, "%s!%s@%s#%s",
+ client_p->name, client_p->username, client_p->host, client_p->info);
+
+ ret = match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+
+ if (ret == EXTBAN_NOMATCH && IsDynSpoof(client_p))
+ {
+ ircsnprintf(buf, BUFSIZE, "%s!%s@%s#%s",
+ client_p->name, client_p->username, client_p->orighost, client_p->info);
+
+ ret = match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Oper extban type: matches opers
+ * -- jilles
+ *
+ * $Id: extb_oper.c 1299 2006-05-11 15:43:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_oper(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_oper, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1299 $");
+
+static int
+_modinit(void)
+{
+ extban_table['o'] = eb_oper;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['o'] = NULL;
+}
+
+static int eb_oper(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+
+ (void)chptr;
+ (void)data;
+ (void)mode_type;
+ /* perhaps use data somehow? (opernick/flags?) */
+ return IsOper(client_p) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+}
--- /dev/null
+/*
+ * Realname extban type: bans all users with matching gecos
+ * -- jilles
+ *
+ * $Id: extb_realname.c 1299 2006-05-11 15:43:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_realname(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_realname, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1299 $");
+
+static int
+_modinit(void)
+{
+ extban_table['r'] = eb_realname;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['r'] = NULL;
+}
+
+static int eb_realname(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+
+ (void)chptr;
+ /* This type is not safe for exceptions */
+ if (mode_type == CHFL_EXCEPTION || mode_type == CHFL_INVEX)
+ return EXTBAN_INVALID;
+ if (data == NULL)
+ return EXTBAN_INVALID;
+ return match(data, client_p->info) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+}
--- /dev/null
+/*
+ * Server name extban type: bans all users using a certain server
+ * -- jilles
+ *
+ * $Id: extb_server.c 1299 2006-05-11 15:43:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static int eb_server(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
+
+DECLARE_MODULE_AV1(extb_server, _modinit, _moddeinit, NULL, NULL, NULL, "$Revision: 1299 $");
+
+static int
+_modinit(void)
+{
+ extban_table['s'] = eb_server;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ extban_table['s'] = NULL;
+}
+
+static int eb_server(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type)
+{
+
+ (void)chptr;
+ /* This type is not safe for exceptions */
+ if (mode_type == CHFL_EXCEPTION || mode_type == CHFL_INVEX)
+ return EXTBAN_INVALID;
+ if (data == NULL)
+ return EXTBAN_INVALID;
+ return match(data, me.name) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
+}
--- /dev/null
+/*
+ * charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ *
+ * Copyright (C) 2006 charybdis development team
+ * All rights reserved
+ *
+ * $Id: hurt.c 1905 2006-08-29 14:51:31Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+#include "numeric.h"
+#include "hostmask.h"
+#include "event.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "hash.h"
+
+/* {{{ Structures */
+#define HURT_CUTOFF (10) /* protocol messages. */
+#define HURT_DEFAULT_EXPIRE (7 * 24 * 60) /* minutes. */
+#define HURT_EXIT_REASON "Hurt: Failed to identify to services"
+
+enum {
+ HEAL_NICK = 0,
+ HEAL_IP
+};
+
+typedef struct _hurt_state {
+ time_t start_time;
+ uint32_t n_hurts;
+ dlink_list hurt_clients;
+ uint16_t cutoff;
+ time_t default_expire;
+ const char *exit_reason;
+} hurt_state_t;
+
+typedef struct _hurt {
+ const char *ip;
+ struct sockaddr *saddr;
+ int saddr_bits;
+ const char *reason;
+ time_t expire;
+} hurt_t;
+/* }}} */
+
+/* {{{ Prototypes */
+static int mo_hurt(struct Client *, struct Client *, int, const char **);
+static int me_hurt(struct Client *, struct Client *, int, const char **);
+static int mo_heal(struct Client *, struct Client *, int, const char **);
+static int me_heal(struct Client *, struct Client *, int, const char **);
+
+static int modinit(void);
+static void modfini(void);
+
+static void client_exit_hook(hook_data_client_exit *);
+static void new_local_user_hook(struct Client *);
+static void doing_stats_hook(hook_data_int *hdata);
+
+static void hurt_check_event(void *);
+static void hurt_expire_event(void *);
+
+static hurt_t *hurt_new(time_t, const char *, const char *);
+static void hurt_add(hurt_t *);
+static void hurt_propagate(struct Client *, struct Client *, hurt_t *);
+static hurt_t *hurt_find(const char *ip);
+static hurt_t *hurt_find_exact(const char *ip);
+static void hurt_remove(const char *ip);
+static void hurt_destroy(void *hurt);
+
+static int heal_nick(struct Client *, struct Client *);
+
+static int nick_is_valid(const char *);
+/* }}} */
+
+/* {{{ State containers */
+
+dlink_list hurt_confs = { NULL, NULL, 0 };
+
+/* }}} */
+
+/* {{{ Messages */
+struct Message hurt_msgtab = {
+ "HURT", 0, 0, 0, MFLG_SLOW, {
+ mg_ignore, mg_ignore, mg_ignore,
+ mg_ignore, {me_hurt, 0}, {mo_hurt, 3}
+ }
+};
+
+struct Message heal_msgtab = {
+ "HEAL", 0, 0, 0, MFLG_SLOW, {
+ mg_ignore, mg_ignore, mg_ignore,
+ mg_ignore, {me_heal, 0}, {mo_heal, 2}
+ }
+};
+/* }}} */
+
+/* {{{ Misc module stuff */
+mapi_hfn_list_av1 hurt_hfnlist[] = {
+ {"client_exit", (hookfn) client_exit_hook},
+ {"new_local_user", (hookfn) new_local_user_hook},
+ {"doing_stats", (hookfn) doing_stats_hook},
+ {NULL, NULL},
+};
+
+mapi_clist_av1 hurt_clist[] = { &hurt_msgtab, &heal_msgtab, NULL };
+
+DECLARE_MODULE_AV1(
+ hurt,
+ modinit,
+ modfini,
+ hurt_clist,
+ NULL,
+ hurt_hfnlist,
+ "$Revision: 1905 $"
+);
+/* }}} */
+
+hurt_state_t hurt_state = {
+ .cutoff = HURT_CUTOFF,
+ .default_expire = HURT_DEFAULT_EXPIRE,
+ .exit_reason = HURT_EXIT_REASON,
+};
+
+/*
+ * Module constructor/destructor.
+ */
+
+/* {{{ static int modinit() */
+static int
+modinit(void)
+{
+ /* set-up hurt_state. */
+ hurt_state.start_time = CurrentTime;
+
+ /* add our event handlers. */
+ eventAdd("hurt_expire", hurt_expire_event, NULL, 60);
+ eventAdd("hurt_check", hurt_check_event, NULL, 5);
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ static void modfini() */
+static void
+modfini(void)
+{
+ dlink_node *ptr, *next_ptr;
+
+ /* and delete our events. */
+ eventDelete(hurt_expire_event, NULL);
+ eventDelete(hurt_check_event, NULL);
+
+ DLINK_FOREACH_SAFE (ptr, next_ptr, hurt_state.hurt_clients.head)
+ {
+ dlinkDestroy(ptr, &hurt_state.hurt_clients);
+ }
+}
+/* }}} */
+
+/*
+ * Message handlers.
+ */
+
+/* {{{ static int mo_hurt()
+ *
+ * HURT [<expire>] <ip> <reason>
+ *
+ * parv[1] - expire or ip
+ * parv[2] - ip or reason
+ * parv[3] - reason or NULL
+ */
+static int
+mo_hurt(struct Client *client_p, struct Client *source_p,
+ int parc, const char **parv)
+{
+ const char *ip, *expire, *reason;
+ int expire_time;
+ hurt_t *hurt;
+ struct Client *target_p;
+
+ if (!IsOperK(source_p)) {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name,
+ source_p->name, "kline");
+ return 0;
+ }
+
+ if (parc == 3)
+ expire = NULL, ip = parv[1], reason = parv[2];
+ else
+ expire = parv[1], ip = parv[2], reason = parv[3];
+
+ if (!expire)
+ expire_time = HURT_DEFAULT_EXPIRE;
+ if (expire && (expire_time = valid_temp_time(expire)) < 1) {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Permanent HURTs are not supported",
+ me.name, source_p->name);
+ return 0;
+ }
+ if (EmptyString(reason)) {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Empty HURT reasons are bad for business",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ /* Is this a client? */
+ if (strchr(ip, '.') == NULL && strchr(ip, ':') == NULL)
+ {
+ target_p = find_named_person(ip);
+ if (target_p == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), ip);
+ return 0;
+ }
+ ip = target_p->orighost;
+ }
+ else
+ {
+ if (!strncmp(ip, "*@", 2))
+ ip += 2;
+ if (strchr(ip, '!') || strchr(ip, '@'))
+ {
+ sendto_one_notice(source_p, ":Invalid HURT mask [%s]",
+ ip);
+ return 0;
+ }
+ }
+
+ if (hurt_find(ip) != NULL) {
+ sendto_one(source_p,
+ ":%s NOTICE %s :[%s] already HURT",
+ me.name, source_p->name, ip);
+ return 0;
+ }
+
+ /*
+ * okay, we've got this far, now it's time to add the the HURT locally
+ * and propagate it to other servers on the network.
+ */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added HURT on [%s] for %ld minutes with reason [%s]",
+ get_oper_name(source_p), ip, (long) expire_time / 60, reason);
+
+ hurt = hurt_new(expire_time, ip, reason);
+ hurt_add(hurt);
+ hurt_propagate(NULL, source_p, hurt);
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ static int me_hurt()
+ *
+ * [ENCAP mask] HURT <target> <expire> <ip> <reason>
+ *
+ * parv[1] - expire
+ * parv[2] - ip
+ * parv[3] - reason
+ */
+static int
+me_hurt(struct Client *client_p, struct Client *source_p,
+ int parc, const char **parv)
+{
+ time_t expire_time;
+ hurt_t *hurt;
+
+ /*
+ * right... if we don't get enough arguments, or if we get any invalid
+ * arguments, just ignore this request - shit happens, and it's not worth
+ * dropping a server over.
+ */
+ if (parc < 4 || !IsPerson(source_p))
+ return 0;
+ if ((expire_time = atoi(parv[1])) < 1)
+ return 0;
+ if (hurt_find(parv[2]) != NULL)
+ return 0;
+ if (EmptyString(parv[3]))
+ return 0;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added HURT on [%s] for %ld minutes with reason [%s]",
+ get_oper_name(source_p), parv[2], (long) expire_time / 60, parv[3]);
+ hurt = hurt_new(expire_time, parv[2], parv[3]);
+ hurt_add(hurt);
+
+ return 0;
+}
+/* }}} */
+
+/* {{{ static int mo_heal()
+ *
+ * HURT <nick>|<ip>
+ *
+ * parv[1] - nick or ip
+ */
+static int
+mo_heal(struct Client *client_p, struct Client *source_p,
+ int parc, const char **parv)
+{
+ struct Client *target_p;
+
+ if (!IsOperUnkline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "unkline");
+ return 0;
+ }
+
+ if (nick_is_valid(parv[1]))
+ {
+ target_p = find_named_person(parv[1]);
+ if (target_p == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), parv[1]);
+ return 0;
+ }
+ if (MyConnect(target_p))
+ heal_nick(source_p, target_p);
+ else
+ sendto_one(target_p, ":%s ENCAP %s HEAL %s",
+ get_id(source_p, target_p),
+ target_p->servptr->name,
+ get_id(target_p, target_p));
+ }
+ else if (strchr(parv[1], '.'))
+ {
+ if (hurt_find_exact(parv[1]) == NULL)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Mask [%s] is not HURT",
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+ hurt_remove(parv[1]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s removed HURT on %s",
+ get_oper_name(source_p), parv[1]);
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS, ":%s ENCAP * HEAL %s",
+ source_p->name, parv[1]);
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :[%s] is not a valid IP address/nick",
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ return 0;
+}
+/* }}} */
+
+static int
+me_heal(struct Client *client_p, struct Client *source_p,
+ int parc, const char **parv)
+{
+ struct Client *target_p;
+
+ /* as noted in me_hurt(), if we don't get sufficient arguments...
+ * *poof*, it's dropped...
+ */
+ if (parc < 2)
+ return 0;
+
+ if (nick_is_valid(parv[1]))
+ {
+ target_p = find_person(parv[1]);
+ if (target_p != NULL && MyConnect(target_p))
+ heal_nick(source_p, target_p);
+ }
+ else if (strchr(parv[1], '.')) /* host or mask to remove ban for */
+ {
+ if (hurt_find_exact(parv[1]) == NULL)
+ return 0;
+
+ hurt_remove(parv[1]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s removed HURT on %s",
+ get_oper_name(source_p), parv[1]);
+ }
+ else
+ return 0;
+
+ return 0;
+}
+
+/*
+ * Event handlers.
+ */
+
+/* {{{ static void hurt_check_event() */
+static void
+hurt_check_event(void *arg)
+{
+ dlink_node *ptr, *next_ptr;
+ struct Client *client_p;
+
+ DLINK_FOREACH_SAFE (ptr, next_ptr, hurt_state.hurt_clients.head) {
+ client_p = ptr->data;
+ if (!EmptyString(client_p->user->suser))
+ {
+ dlinkDestroy(ptr, &hurt_state.hurt_clients);
+ sendto_one_notice(client_p, ":HURT restriction removed for this session");
+ USED_TARGETS(client_p) = 0;
+ client_p->localClient->target_last = CurrentTime; /* don't ask --nenolod */
+ }
+ else if (client_p->localClient->receiveM > hurt_state.cutoff)
+ exit_client(NULL, client_p, &me, hurt_state.exit_reason);
+ }
+}
+/* }}} */
+
+/* {{{ static void hurt_expire_event() */
+static void
+hurt_expire_event(void *unused)
+{
+ dlink_node *ptr, *next_ptr;
+ hurt_t *hurt;
+
+ DLINK_FOREACH_SAFE (ptr, next_ptr, hurt_confs.head)
+ {
+ hurt = (hurt_t *) ptr->data;
+
+ if (hurt->expire <= CurrentTime)
+ {
+ dlinkFindDestroy(hurt, &hurt_confs);
+ hurt_destroy(hurt);
+ }
+ }
+}
+/* }}} */
+
+/*
+ * Hook functions.
+ */
+
+/* {{{ static void client_exit_hook() */
+static void
+client_exit_hook(hook_data_client_exit *data)
+{
+ s_assert(data != NULL);
+ s_assert(data->target != NULL);
+
+ dlinkFindDestroy(data->target, &hurt_state.hurt_clients);
+}
+/* }}} */
+
+/* {{{ static void new_local_user_hook() */
+static void
+new_local_user_hook(struct Client *source_p)
+{
+ if (IsAnyDead(source_p) || !EmptyString(source_p->user->suser) ||
+ IsExemptKline(source_p))
+ return;
+
+ if (hurt_find(source_p->sockhost) || hurt_find(source_p->orighost))
+ {
+ USED_TARGETS(source_p) = 10;
+ source_p->localClient->target_last = CurrentTime + 600; /* don't ask --nenolod */
+ SetTGChange(source_p);
+ dlinkAddAlloc(source_p, &hurt_state.hurt_clients);
+ sendto_one_notice(source_p, ":You are hurt. Please identify to services immediately, or use /stats p for assistance.");
+ }
+}
+/* }}} */
+
+/* {{{ static void doing_stats_hook() */
+static void
+doing_stats_hook(hook_data_int *hdata)
+{
+ dlink_node *ptr;
+ hurt_t *hurt;
+ struct Client *source_p;
+
+ s_assert(hdata);
+ s_assert(hdata->client);
+
+ source_p = hdata->client;
+ if(hdata->arg2 != (int) 's')
+ return;
+ if((ConfigFileEntry.stats_k_oper_only == 2) && !IsOper(source_p))
+ return;
+ if ((ConfigFileEntry.stats_k_oper_only == 1) && !IsOper(source_p))
+ {
+ hurt = hurt_find(source_p->sockhost);
+ if (hurt != NULL)
+ {
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE), 's',
+ "*", hurt->ip, hurt->reason, "", "");
+ return;
+ }
+
+ hurt = hurt_find(source_p->orighost);
+ if (hurt != NULL)
+ {
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE), 's',
+ "*", hurt->ip, hurt->reason, "", "");
+ return;
+ }
+ return;
+ }
+
+ DLINK_FOREACH(ptr, hurt_confs.head)
+ {
+ hurt = (hurt_t *) ptr->data;
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE), 's',
+ "*", hurt->ip, hurt->reason, "", "");
+ }
+}
+/* }}} */
+
+/* {{{ static void hurt_propagate()
+ *
+ * client_p - specific server to propagate HURT to, or NULL to propagate to all
+ * servers.
+ * source_p - source (oper who added the HURT)
+ * hurt - HURT to be propagated
+ */
+static void
+hurt_propagate(struct Client *client_p, struct Client *source_p, hurt_t *hurt)
+{
+ if (client_p)
+ sendto_one(client_p,
+ ":%s ENCAP %s HURT %ld %s :%s",
+ source_p->name, client_p->name,
+ (long)(hurt->expire - CurrentTime),
+ hurt->ip, hurt->reason);
+ else
+ sendto_server(&me, NULL, NOCAPS, NOCAPS,
+ ":%s ENCAP * HURT %ld %s :%s",
+ source_p->name,
+ (long)(hurt->expire - CurrentTime),
+ hurt->ip, hurt->reason);
+}
+/* }}} */
+
+/* {{{ static hurt_t *hurt_new() */
+static hurt_t *
+hurt_new(time_t expire, const char *ip, const char *reason)
+{
+ hurt_t *hurt;
+
+ hurt = MyMalloc(sizeof(hurt_t));
+
+ DupString(hurt->ip, ip);
+ DupString(hurt->reason, reason);
+ hurt->expire = CurrentTime + expire;
+
+ return hurt;
+}
+/* }}} */
+
+/* {{{ static void hurt_destroy() */
+static void
+hurt_destroy(void *hurt)
+{
+ hurt_t *h;
+
+ if (!hurt)
+ return;
+
+ h = (hurt_t *) hurt;
+ MyFree((char *) h->ip);
+ MyFree((char *) h->reason);
+ MyFree(h);
+}
+/* }}} */
+
+static void
+hurt_add(hurt_t *hurt)
+{
+ dlinkAddAlloc(hurt, &hurt_confs);
+}
+
+static hurt_t *
+hurt_find_exact(const char *ip)
+{
+ dlink_node *ptr;
+ hurt_t *hurt;
+
+ DLINK_FOREACH(ptr, hurt_confs.head)
+ {
+ hurt = (hurt_t *) ptr->data;
+
+ if (!strcasecmp(ip, hurt->ip))
+ return hurt;
+ }
+
+ return NULL;
+}
+
+static hurt_t *
+hurt_find(const char *ip)
+{
+ dlink_node *ptr;
+ hurt_t *hurt;
+
+ DLINK_FOREACH(ptr, hurt_confs.head)
+ {
+ hurt = (hurt_t *) ptr->data;
+
+ if (match(hurt->ip, ip))
+ return hurt;
+ }
+
+ return NULL;
+}
+
+static void
+hurt_remove(const char *ip)
+{
+ hurt_t *hurt = hurt_find_exact(ip);
+
+ dlinkFindDestroy(hurt, &hurt_confs);
+ hurt_destroy(hurt);
+}
+
+/* {{{ static int heal_nick() */
+static int
+heal_nick(struct Client *source_p, struct Client *target_p)
+{
+ if (dlinkFindDestroy(target_p, &hurt_state.hurt_clients))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s used HEAL on %s",
+ get_oper_name(source_p), get_client_name(target_p, HIDE_IP));
+ sendto_one_notice(target_p, ":HURT restriction temporarily removed by operator");
+ sendto_one_notice(source_p, ":HURT restriction on %s temporarily removed", target_p->name);
+ USED_TARGETS(target_p) = 0;
+ target_p->localClient->target_last = CurrentTime; /* don't ask --nenolod */
+ return 1;
+ }
+ else
+ {
+ sendto_one_notice(source_p, ":%s was not hurt", target_p->name);
+ return 0;
+ }
+}
+/* }}} */
+
+/*
+ * Anything else...
+ */
+
+/* {{{ static int nick_is_valid() */
+static int
+nick_is_valid(const char *nick)
+{
+ const char *s = nick;
+
+ for (; *s != '\0'; s++) {
+ if (!IsNickChar(*s))
+ return 0;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/*
+ * vim: ts=8 sw=8 noet fdm=marker tw=80
+ */
--- /dev/null
+/* $Id: ip_cloaking.c 2805 2006-12-05 12:45:43Z jilles $ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_user.h"
+#include "s_serv.h"
+#include "tools.h"
+#include "numeric.h"
+
+/* if you're modifying this module, you'll probably to change this */
+#define KEY 0x13748cfa
+
+static int
+_modinit(void)
+{
+ /* add the usermode to the available slot */
+ user_modes['h'] = find_umode_slot();
+ construct_umodebuf();
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ /* disable the umode and remove it from the available list */
+ user_modes['h'] = 0;
+ construct_umodebuf();
+}
+
+static void check_umode_change(void *data);
+static void check_new_user(void *data);
+mapi_hfn_list_av1 ip_cloaking_hfnlist[] = {
+ { "umode_changed", (hookfn) check_umode_change },
+ { "new_local_user", (hookfn) check_new_user },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(ip_cloaking, _modinit, _moddeinit, NULL, NULL,
+ ip_cloaking_hfnlist, "$Revision: 2805 $");
+
+static void
+distribute_hostchange(struct Client *client)
+{
+ if (irccmp(client->host, client->orighost))
+ sendto_one_numeric(client, RPL_HOSTHIDDEN, "%s :is now your hidden host",
+ client->host);
+ else
+ sendto_one_numeric(client, RPL_HOSTHIDDEN, "%s :hostname reset",
+ client->host);
+
+ sendto_server(NULL, NULL,
+ CAP_EUID | CAP_TS6, NOCAPS, ":%s CHGHOST %s :%s",
+ use_id(&me), use_id(client), client->host);
+ sendto_server(NULL, NULL,
+ CAP_TS6, CAP_EUID, ":%s ENCAP * CHGHOST %s :%s",
+ use_id(&me), use_id(client), client->host);
+ sendto_server(NULL, NULL,
+ NOCAPS, CAP_TS6, ":%s ENCAP * CHGHOST %s :%s",
+ me.name, client->name, client->host);
+ if (irccmp(client->host, client->orighost))
+ SetDynSpoof(client);
+ else
+ ClearDynSpoof(client);
+}
+
+static void
+do_host_cloak(const char *inbuf, char *outbuf, int ipmask)
+{
+ int cyc;
+ unsigned int hosthash = 1, hosthash2 = 1;
+ unsigned int maxcycle = strlen(inbuf);
+ int len1;
+ const char *rest, *next;
+
+ for (cyc = 0; cyc < maxcycle - 2; cyc += 2)
+ hosthash *= (unsigned int) inbuf[cyc];
+
+ /* safety: decrement ourselves two steps back */
+ for (cyc = maxcycle - 1; cyc >= 1; cyc -= 2)
+ hosthash2 *= (unsigned int) inbuf[cyc];
+
+ /* lets do some bitshifting -- this pretty much destroys the IP
+ * sequence, while still providing a checksum. exactly what
+ * we're shooting for. --nenolod
+ */
+ hosthash += (hosthash2 / KEY);
+ hosthash2 += (hosthash / KEY);
+
+ if (ipmask == 0)
+ {
+ ircsnprintf(outbuf, HOSTLEN, "%s-%X%X",
+ ServerInfo.network_name, hosthash2, hosthash);
+ len1 = strlen(outbuf);
+ rest = strchr(inbuf, '.');
+ if (rest == NULL)
+ rest = ".";
+ /* try to avoid truncation -- jilles */
+ while (len1 + strlen(rest) >= HOSTLEN && (next = strchr(rest + 1, '.')) != NULL)
+ rest = next;
+ strlcat(outbuf, rest, HOSTLEN);
+ }
+ else
+ ircsnprintf(outbuf, HOSTLEN, "%X%X.%s",
+ hosthash2, hosthash, ServerInfo.network_name);
+}
+
+static void
+check_umode_change(void *vdata)
+{
+ hook_data_umode_changed *data = (hook_data_umode_changed *)vdata;
+ struct Client *source_p = data->client;
+
+ if (!MyClient(source_p))
+ return;
+
+ /* didn't change +h umode, we don't need to do anything */
+ if (!((data->oldumodes ^ source_p->umodes) & user_modes['h']))
+ return;
+
+ if (source_p->umodes & user_modes['h'])
+ {
+ if (IsIPSpoof(source_p) || source_p->localClient->mangledhost == NULL || (IsDynSpoof(source_p) && strcmp(source_p->host, source_p->localClient->mangledhost)))
+ {
+ source_p->umodes &= ~user_modes['h'];
+ return;
+ }
+ if (strcmp(source_p->host, source_p->localClient->mangledhost))
+ {
+ strlcpy(source_p->host, source_p->localClient->mangledhost, HOSTLEN);
+ distribute_hostchange(source_p);
+ }
+ else /* not really nice, but we need to send this numeric here */
+ sendto_one_numeric(source_p, RPL_HOSTHIDDEN, "%s :is now your hidden host",
+ source_p->host);
+ }
+ else if (!(source_p->umodes & user_modes['h']))
+ {
+ if (source_p->localClient->mangledhost != NULL &&
+ !strcmp(source_p->host, source_p->localClient->mangledhost))
+ {
+ strlcpy(source_p->host, source_p->orighost, HOSTLEN);
+ distribute_hostchange(source_p);
+ }
+ }
+}
+
+static void
+check_new_user(void *vdata)
+{
+ struct Client *source_p = (void *)vdata;
+
+ if (IsIPSpoof(source_p))
+ {
+ source_p->umodes &= ~user_modes['h'];
+ return;
+ }
+ source_p->localClient->mangledhost = MyMalloc(HOSTLEN);
+ if (!irccmp(source_p->orighost, source_p->sockhost))
+ do_host_cloak(source_p->orighost, source_p->localClient->mangledhost, 1);
+ else
+ do_host_cloak(source_p->orighost, source_p->localClient->mangledhost, 0);
+ if (IsDynSpoof(source_p))
+ source_p->umodes &= ~user_modes['h'];
+ if (source_p->umodes & user_modes['h'])
+ {
+ strlcpy(source_p->host, source_p->localClient->mangledhost, sizeof(source_p->host));
+ if (irccmp(source_p->host, source_p->orighost))
+ SetDynSpoof(source_p);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) infinity-infinity God <God@Heaven>
+ *
+ * Bob was here
+ * $Id: m_42.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+static int mclient_42(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message hgtg_msgtab = {
+ "42", 0, 0, 0, MFLG_SLOW,
+ { mg_ignore, {mclient_42, 0}, mg_ignore, mg_ignore, mg_ignore, {mclient_42, 0}
+ }
+};
+
+mapi_clist_av1 hgtg_clist[] = { &hgtg_msgtab, NULL };
+
+
+DECLARE_MODULE_AV1(42, NULL, NULL, hgtg_clist, NULL, NULL, "Revision 0.42");
+
+
+static int
+mclient_42(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_one(source_p, ":%s NOTICE %s :The Answer to Life, the Universe, and Everything.",
+ me.name, source_p->name);
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, contrib/m_findforwards.c
+ * Copyright (C) 2002 Hybrid Development Team
+ * Copyright (C) 2004 ircd-ratbox 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 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.
+ *
+ * $Id: m_findforwards.c 986 2006-03-08 00:10:46Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static int m_findforwards(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message findforwards_msgtab = {
+ "FINDFORWARDS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_findforwards, 2}, mg_ignore, mg_ignore, mg_ignore, {m_findforwards, 2}}
+};
+
+mapi_clist_av1 findforwards_clist[] = { &findforwards_msgtab, NULL };
+
+DECLARE_MODULE_AV1(findforwards, NULL, NULL, findforwards_clist, NULL, NULL, "$Revision: 986 $");
+
+/*
+** mo_findforwards
+** parv[0] = sender prefix
+** parv[1] = channel
+*/
+static int
+m_findforwards(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+ struct Channel *chptr;
+ struct membership *msptr;
+ dlink_node *ptr;
+ char buf[414];
+ char *p = buf, *end = buf + sizeof buf - 1;
+ *p = '\0';
+
+ /* Allow ircops to search for forwards to nonexistent channels */
+ if(!IsOper(source_p))
+ {
+ if((chptr = find_channel(parv[1])) == NULL || (msptr = find_channel_membership(chptr, source_p)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL), parv[1]);
+ return 0;
+ }
+
+ if(!is_chanop(msptr))
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "FINDFORWARDS");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+ if(chptr->mode.forward && !irccmp(chptr->mode.forward, parv[1]))
+ {
+ if(p + strlen(chptr->chname) >= end - 13)
+ {
+ strcpy(p, "<truncated> ");
+ p += 12;
+ break;
+ }
+ strcpy(p, chptr->chname);
+ p += strlen(chptr->chname);
+ *p++ = ' ';
+ }
+ }
+
+ if(buf[0])
+ *(--p) = '\0';
+
+ sendto_one_notice(source_p, ":Forwards for %s: %s", parv[1], buf);
+
+ return 0;
+}
--- /dev/null
+/*
+ * m_identify.c: dalnet-style /identify that sends to nickserv or chanserv
+ *
+ * Copyright (C) 2006 Jilles Tjoelker
+ * Copyright (C) 2006 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_identify.c 2729 2006-11-09 23:52:06Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+#define SVS_chanserv_NICK "ChanServ"
+#define SVS_nickserv_NICK "NickServ"
+
+char *reconstruct_parv(int parc, const char *parv[]);
+
+static int m_identify(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message identify_msgtab = {
+ "IDENTIFY", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_identify, 0}, mg_ignore, mg_ignore, mg_ignore, {m_identify, 0}}
+};
+
+mapi_clist_av1 identify_clist[] = {
+ &identify_msgtab,
+ NULL
+};
+
+DECLARE_MODULE_AV1(identify, NULL, NULL, identify_clist, NULL, NULL, "$Revision: 2729 $");
+
+char *reconstruct_parv(int parc, const char *parv[])
+{
+ static char tmpbuf[BUFSIZE]; int i;
+
+ strlcpy(tmpbuf, parv[0], BUFSIZE);
+ for (i = 1; i < parc; i++)
+ {
+ strlcat(tmpbuf, " ", BUFSIZE);
+ strlcat(tmpbuf, parv[i], BUFSIZE);
+ }
+ return tmpbuf;
+}
+
+static int m_identify(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *nick;
+ struct Client *target_p;
+
+ if (parc < 2 || EmptyString(parv[1]))
+ {
+ sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
+ return 0;
+ }
+
+ nick = parv[1][0] == '#' ? SVS_chanserv_NICK : SVS_nickserv_NICK;
+ if ((target_p = find_named_person(nick)) && IsService(target_p))
+ {
+ sendto_one(target_p, ":%s PRIVMSG %s :IDENTIFY %s", get_id(source_p, target_p), get_id(target_p, target_p), reconstruct_parv(parc - 1, &parv[1]));
+ }
+ else
+ {
+ sendto_one_numeric(source_p, ERR_SERVICESDOWN, form_str(ERR_SERVICESDOWN), nick);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * m_mkpasswd.c: Encrypts a password online, DES or MD5.
+ *
+ * Copyright 2002 W. Campbell and the ircd-ratbox development team
+ * Based on mkpasswd.c, originally by Nelson Minar (minar@reed.edu)
+ *
+ * You can use this code in any way as long as these names remain.
+ *
+ * $Id: m_mkpasswd.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+/* List of ircd includes from ../include/ */
+#include "stdinc.h"
+#include "client.h"
+#include "common.h" /* FALSE bleah */
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "patricia.h"
+#include "s_newconf.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+#include <string.h>
+
+extern char *crypt();
+
+static int m_mkpasswd(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+static int mo_mkpasswd(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+static char *make_salt(void);
+static char *make_md5_salt(void);
+
+static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+
+
+struct Message mkpasswd_msgtab = {
+ "MKPASSWD", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_mkpasswd, 2}, mg_ignore, mg_ignore, mg_ignore, {mo_mkpasswd, 2}}
+};
+
+mapi_clist_av1 mkpasswd_clist[] = { &mkpasswd_msgtab, NULL };
+
+DECLARE_MODULE_AV1(mkpasswd, NULL, NULL, mkpasswd_clist, NULL, NULL, "$Revision: 6 $");
+
+
+static int
+m_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+ int is_md5 = 0;
+
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, parv[0]);
+ return 0;
+ }
+ else
+ {
+ last_used = CurrentTime;
+ }
+
+ if(parc == 3)
+ {
+ if(!irccmp(parv[2], "MD5"))
+ {
+ is_md5 = 1;
+ }
+ else if(!irccmp(parv[2], "DES"))
+ {
+ /* Not really needed, but we may want to have a default encryption
+ * setting somewhere down the road
+ */
+ is_md5 = 0;
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :MKPASSWD syntax error: MKPASSWD pass [DES|MD5]",
+ me.name, parv[0]);
+ return 0;
+ }
+ }
+
+ if(parc == 1)
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "MKPASSWD");
+ else
+ sendto_one(source_p, ":%s NOTICE %s :Encryption for [%s]: %s",
+ me.name, parv[0], parv[1], crypt(parv[1],
+ is_md5 ? make_md5_salt() :
+ make_salt()));
+
+ return 0;
+}
+
+/*
+** mo_test
+** parv[0] = sender prefix
+** parv[1] = parameter
+*/
+static int
+mo_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int is_md5 = 0;
+
+ if(parc == 3)
+ {
+ if(!irccmp(parv[2], "MD5"))
+ {
+ is_md5 = 1;
+ }
+ else if(!irccmp(parv[2], "DES"))
+ {
+ /* Not really needed, but we may want to have a default encryption
+ * setting somewhere down the road
+ */
+ is_md5 = 0;
+ }
+ else
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :MKPASSWD syntax error: MKPASSWD pass [DES|MD5]",
+ me.name, parv[0]);
+ return 0;
+ }
+ }
+
+ if(parc == 1)
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "MKPASSWD");
+ else
+ sendto_one(source_p, ":%s NOTICE %s :Encryption for [%s]: %s",
+ me.name, parv[0], parv[1], crypt(parv[1],
+ is_md5 ? make_md5_salt() :
+ make_salt()));
+
+ return 0;
+}
+
+static char *
+make_salt(void)
+{
+ static char salt[3];
+ salt[0] = saltChars[random() % 64];
+ salt[1] = saltChars[random() % 64];
+ salt[2] = '\0';
+ return salt;
+}
+
+static char *
+make_md5_salt(void)
+{
+ static char salt[13];
+ int i;
+ salt[0] = '$';
+ salt[1] = '1';
+ salt[2] = '$';
+ for(i = 3; i < 11; i++)
+ salt[i] = saltChars[random() % 64];
+ salt[11] = '$';
+ salt[12] = '\0';
+ return salt;
+}
--- /dev/null
+/* contrib/m_ojoin.c
+ * Copyright (C) 2002 Hybrid Development Team
+ * Copyright (C) 2004 ircd-ratbox 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 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.
+ *
+ * $Id: m_ojoin.c 3121 2007-01-02 13:23:04Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "patricia.h"
+#include "channel.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+
+static int mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+
+struct Message ojoin_msgtab = {
+ "OJOIN", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_ojoin, 2}}
+};
+
+mapi_clist_av1 ojoin_clist[] = { &ojoin_msgtab, NULL };
+
+DECLARE_MODULE_AV1(ojoin, NULL, NULL, ojoin_clist, NULL, NULL, "$Revision: 3121 $");
+
+/*
+** mo_ojoin
+** parv[0] = sender prefix
+** parv[1] = channel
+*/
+static int
+mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ int move_me = 0;
+
+ /* admins only */
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "ojoin");
+ return 0;
+ }
+
+ if(*parv[1] == '@' || *parv[1] == '%' || *parv[1] == '+')
+ {
+ parv[1]++;
+ move_me = 1;
+ }
+
+ if((chptr = find_channel(parv[1])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ if(IsMember(source_p, chptr))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN",
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ if(move_me == 1)
+ parv[1]--;
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "OJOIN called for %s by %s!%s@%s",
+ parv[1], source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "OJOIN called for %s by %s",
+ parv[1], get_oper_name(source_p));
+ /* only sends stuff for #channels remotely */
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+ ":%s WALLOPS :OJOIN called for %s by %s!%s@%s",
+ me.name, parv[1],
+ source_p->name, source_p->username, source_p->host);
+
+ if(*parv[1] == '@')
+ {
+ add_user_to_channel(chptr, source_p, CHFL_CHANOP);
+ sendto_server(client_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s + :@%s",
+ me.name, (long) chptr->channelts, chptr->chname, source_p->name);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
+ source_p->name,
+ source_p->username, source_p->host, chptr->chname);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
+ me.name, chptr->chname, source_p->name);
+
+ }
+ else if(*parv[1] == '+')
+ {
+ add_user_to_channel(chptr, source_p, CHFL_VOICE);
+ sendto_server(client_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s + :+%s",
+ me.name, (long) chptr->channelts, chptr->chname, source_p->name);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
+ source_p->name,
+ source_p->username, source_p->host, chptr->chname);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
+ me.name, chptr->chname, source_p->name);
+ }
+ else
+ {
+ add_user_to_channel(chptr, source_p, CHFL_PEON);
+ sendto_server(client_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s + :%s",
+ me.name, (long) chptr->channelts, chptr->chname, source_p->name);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
+ source_p->name,
+ source_p->username, source_p->host, chptr->chname);
+ }
+
+ /* send the topic... */
+ if(chptr->topic != NULL)
+ {
+ sendto_one(source_p, form_str(RPL_TOPIC), me.name,
+ source_p->name, chptr->chname, chptr->topic);
+ sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
+ source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
+ }
+
+ source_p->localClient->last_join_time = CurrentTime;
+ channel_member_names(chptr, source_p, 1);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_okick.c: Kicks a user from a channel with much prejudice.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ * Copyright (C) 2004 ircd-ratbox 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
+ *
+ * $Id: m_okick.c 3117 2007-01-02 13:11:04Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "modules.h"
+#include "parse.h"
+#include "hash.h"
+#include "packet.h"
+#include "s_conf.h"
+#include "s_serv.h"
+
+static int mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+
+struct Message okick_msgtab = {
+ "OKICK", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_okick, 4}}
+};
+
+mapi_clist_av1 okick_clist[] = { &okick_msgtab, NULL };
+
+DECLARE_MODULE_AV1(okick, NULL, NULL, okick_clist, NULL, NULL, "$Revision: 3117 $");
+
+/*
+** m_okick
+** parv[0] = sender prefix
+** parv[1] = channel
+** parv[2] = client to kick
+** parv[3] = kick comment
+*/
+static int
+mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *who;
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+ int chasing = 0;
+ char *comment;
+ char *name;
+ char *p = NULL;
+ char *user;
+ static char buf[BUFSIZE];
+
+ if(*parv[2] == '\0')
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "KICK");
+ return 0;
+ }
+
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ comment = (EmptyString(LOCAL_COPY(parv[3]))) ? LOCAL_COPY(parv[2]) : LOCAL_COPY(parv[3]);
+ if(strlen(comment) > (size_t) TOPICLEN)
+ comment[TOPICLEN] = '\0';
+
+ *buf = '\0';
+ if((p = strchr(parv[1], ',')))
+ *p = '\0';
+
+ name = LOCAL_COPY(parv[1]);
+
+ chptr = find_channel(name);
+ if(!chptr)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);
+ return 0;
+ }
+
+
+ if((p = strchr(parv[2], ',')))
+ *p = '\0';
+ user = LOCAL_COPY(parv[2]); // strtoken(&p2, parv[2], ",");
+ if(!(who = find_chasing(source_p, user, &chasing)))
+ {
+ return 0;
+ }
+
+ if((target_p = find_client(user)) == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, parv[0], user);
+ return 0;
+ }
+
+ if((msptr = find_channel_membership(chptr, target_p)) == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
+ me.name, parv[0], parv[1], parv[2]);
+ return 0;
+ }
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "OKICK called for %s %s by %s!%s@%s",
+ chptr->chname, target_p->name,
+ source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "OKICK called for %s %s by %s",
+ chptr->chname, target_p->name,
+ get_oper_name(source_p));
+ /* only sends stuff for #channels remotely */
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+ ":%s WALLOPS :OKICK called for %s %s by %s!%s@%s",
+ me.name, chptr->chname, target_p->name,
+ source_p->name, source_p->username, source_p->host);
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
+ me.name, chptr->chname, who->name, comment);
+ sendto_server(&me, chptr, NOCAPS, NOCAPS,
+ ":%s KICK %s %s :%s", me.name, chptr->chname, who->name, comment);
+ remove_user_from_channel(msptr);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_olist.c: List channels. olist is an oper only command
+ * that shows channels regardless of modes. This
+ * is kinda evil, and might be morally wrong, but
+ * somebody will likely need it.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ * Copyright (C) 2004 ircd-ratbox 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
+ *
+ * $Id: m_olist.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "patricia.h"
+#include "channel.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_newconf.h"
+#include "sprintf_irc.h"
+
+static int mo_olist(struct Client *, struct Client *, int parc, const char *parv[]);
+
+#ifndef STATIC_MODULES
+
+struct Message olist_msgtab = {
+ "OLIST", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_olist, 1}}
+};
+
+mapi_clist_av1 olist_clist[] = { &olist_msgtab, NULL };
+
+DECLARE_MODULE_AV1(okick, NULL, NULL, olist_clist, NULL, NULL, "$Revision: 6 $");
+
+#endif
+
+static void list_all_channels(struct Client *source_p);
+static void list_named_channel(struct Client *source_p, const char *name);
+
+/*
+** mo_olist
+** parv[0] = sender prefix
+** parv[1] = channel
+*/
+static int
+mo_olist(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(IsOperSpy(source_p))
+ {
+ /* If no arg, do all channels *whee*, else just one channel */
+ if(parc < 2 || EmptyString(parv[1]))
+ {
+ report_operspy(source_p, "LIST", NULL);
+ list_all_channels(source_p);
+ }
+ else
+ {
+ report_operspy(source_p, "LIST", parv[1]);
+ list_named_channel(source_p, parv[1]);
+ }
+ }
+
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return 0;
+}
+
+
+/*
+ * list_all_channels
+ * inputs - pointer to client requesting list
+ * output - 0/1
+ * side effects - list all channels to source_p
+ */
+static void
+list_all_channels(struct Client *source_p)
+{
+ struct Channel *chptr;
+ dlink_node *ptr;
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+
+ sendto_one(source_p, form_str(RPL_LIST),
+ me.name, source_p->name, chptr->chname,
+ dlink_list_length(&chptr->members),
+ chptr->topic == NULL ? "" : chptr->topic);
+ }
+
+ return;
+}
+
+/*
+ * list_named_channel
+ * inputs - pointer to client requesting list
+ * output - 0/1
+ * side effects - list all channels to source_p
+ */
+static void
+list_named_channel(struct Client *source_p, const char *name)
+{
+ struct Channel *chptr;
+ char *p;
+ char *n = LOCAL_COPY(name);
+
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ if((p = strchr(n, ',')))
+ *p = '\0';
+
+ if(EmptyString(n))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), n);
+ return;
+ }
+
+ if((chptr = find_channel(n)) == NULL)
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), n);
+ else
+ sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
+ chptr->chname, dlink_list_length(&chptr->members),
+ chptr->topic ? chptr->topic : "");
+}
--- /dev/null
+/*
+ * Charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ * m_omode.c: allows oper mode hacking
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ * Copyright (C) 2006 Charybdis 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
+ *
+ * $Id: m_omode.c 3121 2007-01-02 13:23:04Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static int mo_omode(struct Client *, struct Client *, int, const char **);
+
+struct Message omode_msgtab = {
+ "OMODE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_omode, 3}}
+};
+
+mapi_clist_av1 omode_clist[] = { &omode_msgtab, NULL };
+
+DECLARE_MODULE_AV1(omode, NULL, NULL, omode_clist, NULL, NULL, "$Revision: 3121 $");
+
+/*
+ * mo_omode - MODE command handler
+ * parv[0] - sender
+ * parv[1] - channel
+ */
+static int
+mo_omode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr = NULL;
+ struct membership *msptr;
+ char params[512];
+ int i;
+ int wasonchannel;
+
+ /* admins only */
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ /* Now, try to find the channel in question */
+ if(!IsChanPrefix(parv[1][0]) || !check_channel_name(parv[1]))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME), parv[1]);
+ return 0;
+ }
+
+ chptr = find_channel(parv[1]);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ /* Now know the channel exists */
+ msptr = find_channel_membership(chptr, source_p);
+ wasonchannel = msptr != NULL;
+
+ if (is_chanop(msptr))
+ {
+ sendto_one_notice(source_p, ":Use a normal MODE you idiot");
+ return 0;
+ }
+
+ params[0] = '\0';
+ for (i = 2; i < parc; i++)
+ {
+ if (i != 2)
+ strlcat(params, " ", sizeof params);
+ strlcat(params, parv[i], sizeof params);
+ }
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "OMODE called for [%s] [%s] by %s!%s@%s",
+ parv[1], params, source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "OMODE called for [%s] [%s] by %s",
+ parv[1], params, get_oper_name(source_p));
+
+ if(*chptr->chname != '&')
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS,
+ ":%s WALLOPS :OMODE called for [%s] [%s] by %s!%s@%s",
+ me.name, parv[1], params, source_p->name, source_p->username,
+ source_p->host);
+
+#if 0
+ set_channel_mode(client_p, source_p->servptr, chptr, msptr,
+ parc - 2, parv + 2);
+#else
+ if (parc == 4 && !strcmp(parv[2], "+o") && !irccmp(parv[3], source_p->name))
+ {
+ /* Opping themselves */
+ if (!wasonchannel)
+ {
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
+ return 0;
+ }
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
+ me.name, parv[1], source_p->name);
+ sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
+ ":%s TMODE %ld %s +o %s",
+ me.id, (long) chptr->channelts, parv[1],
+ source_p->id);
+ sendto_server(NULL, chptr, NOCAPS, CAP_TS6,
+ ":%s MODE %s +o %s",
+ me.name, parv[1], source_p->name);
+ msptr->flags |= CHFL_CHANOP;
+ }
+ else
+ {
+ /* Hack it so set_channel_mode() will accept */
+ if (wasonchannel)
+ msptr->flags |= CHFL_CHANOP;
+ else
+ {
+ add_user_to_channel(chptr, source_p, CHFL_CHANOP);
+ msptr = find_channel_membership(chptr, source_p);
+ }
+ set_channel_mode(client_p, source_p, chptr, msptr,
+ parc - 2, parv + 2);
+ /* We know they were not opped before and they can't have opped
+ * themselves as set_channel_mode() does not allow that
+ * -- jilles */
+ if (wasonchannel)
+ msptr->flags &= ~CHFL_CHANOP;
+ else
+ remove_user_from_channel(msptr);
+ }
+#endif
+ return 0;
+}
--- /dev/null
+/* contrib/m_opme.c
+ * Copyright (C) 2002 Hybrid Development Team
+ * Copyright (C) 2004 ircd-ratbox 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 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.
+ *
+ * $Id: m_opme.c 3121 2007-01-02 13:23:04Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "patricia.h"
+#include "channel.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+
+static int mo_opme(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message opme_msgtab = {
+ "OPME", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_opme, 2}}
+};
+
+mapi_clist_av1 opme_clist[] = { &opme_msgtab, NULL };
+
+DECLARE_MODULE_AV1(opme, NULL, NULL, opme_clist, NULL, NULL, "$Revision: 3121 $");
+
+
+/*
+** mo_opme
+** parv[0] = sender prefix
+** parv[1] = channel
+*/
+static int
+mo_opme(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ struct membership *msptr;
+ dlink_node *ptr;
+
+ /* admins only */
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "opme");
+ return 0;
+ }
+
+ if((chptr = find_channel(parv[1])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+
+ if(is_chanop(msptr))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :%s Channel is not opless",
+ me.name, parv[0], parv[1]);
+ return 0;
+ }
+ }
+
+ msptr = find_channel_membership(chptr, source_p);
+
+ if(msptr == NULL)
+ return 0;
+
+ msptr->flags |= CHFL_CHANOP;
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "OPME called for [%s] by %s!%s@%s",
+ parv[1], source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "OPME called for [%s] by %s",
+ parv[1], get_oper_name(source_p));
+
+ /* dont send stuff for local channels remotely. */
+ if(*chptr->chname != '&')
+ {
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS,
+ ":%s WALLOPS :OPME called for [%s] by %s!%s@%s",
+ me.name, parv[1], source_p->name, source_p->username, source_p->host);
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS, ":%s PART %s", source_p->name, parv[1]);
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s + :@%s",
+ me.name, (long) chptr->channelts, parv[1], source_p->name);
+ }
+
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s +o %s", me.name, parv[1], source_p->name);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_webirc.c: Makes CGI:IRC users appear as coming from their real host
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2006 ircd-ratbox 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
+ *
+ * $Id: m_webirc.c 2757 2006-11-10 22:58:15Z jilles $
+ */
+/* Usage:
+ * auth {
+ * user = "webirc@<cgiirc ip>"; # if identd used, put ident username instead
+ * password = "<password>"; # encryption possible
+ * spoof = "webirc."
+ * class = "users";
+ * };
+ * Possible flags:
+ * encrypted - password is encrypted (recommended)
+ * kline_exempt - k/g lines on the cgiirc ip are ignored
+ * gline_exempt - glines on the cgiirc ip are ignored
+ * dlines are checked on the cgiirc ip (of course).
+ * k/d/g/x lines, auth blocks, user limits, etc are checked using the
+ * real host/ip.
+ * The password should be specified unencrypted in webirc_password in
+ * cgiirc.config
+ */
+
+#include "stdinc.h"
+#include "client.h" /* client struct */
+#include "irc_string.h"
+#include "hostmask.h"
+#include "send.h" /* sendto_one */
+#include "numeric.h" /* ERR_xxx */
+#include "ircd.h" /* me */
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "s_conf.h"
+
+static int mr_webirc(struct Client *, struct Client *, int, const char **);
+
+struct Message webirc_msgtab = {
+ "WEBIRC", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_webirc, 4}, mg_reg, mg_ignore, mg_ignore, mg_ignore, mg_reg}
+};
+
+mapi_clist_av1 webirc_clist[] = { &webirc_msgtab, NULL };
+DECLARE_MODULE_AV1(webirc, NULL, NULL, webirc_clist, NULL, NULL, "$Revision: 20702 $");
+
+/*
+ * mr_webirc - webirc message handler
+ * parv[0] = sender prefix
+ * parv[1] = password
+ * parv[2] = fake username (we ignore this)
+ * parv[3] = fake hostname
+ * parv[4] = fake ip
+ */
+static int
+mr_webirc(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct ConfItem *aconf;
+ const char *encr;
+
+ if (!strchr(parv[4], '.') && !strchr(parv[4], ':'))
+ {
+ sendto_one(source_p, "NOTICE * :Invalid IP");
+ return 0;
+ }
+
+ aconf = find_address_conf(client_p->host, client_p->sockhost,
+ IsGotId(client_p) ? client_p->username : "webirc",
+ IsGotId(client_p) ? client_p->username : "webirc",
+ (struct sockaddr *) &client_p->localClient->ip,
+ client_p->localClient->ip.ss_family);
+ if (aconf == NULL || !(aconf->status & CONF_CLIENT))
+ return 0;
+ if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->name, "webirc."))
+ {
+ /* XXX */
+ sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
+ return 0;
+ }
+ if (EmptyString(aconf->passwd))
+ {
+ sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
+ return 0;
+ }
+
+ if (EmptyString(parv[1]))
+ encr = "";
+ else if (IsConfEncrypted(aconf))
+ encr = crypt(parv[1], aconf->passwd);
+ else
+ encr = parv[1];
+
+ if (strcmp(encr, aconf->passwd))
+ {
+ sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
+ return 0;
+ }
+
+
+ strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost));
+
+ if(strlen(parv[3]) <= HOSTLEN)
+ strlcpy(source_p->host, parv[3], sizeof(source_p->host));
+ else
+ strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
+
+ inetpton_sock(parv[4], (struct sockaddr *)&source_p->localClient->ip);
+
+ /* Check dlines now, k/glines will be checked on registration */
+ if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip,
+ source_p->localClient->ip.ss_family)))
+ {
+ if(!(aconf->status & CONF_EXEMPTDLINE))
+ {
+ exit_client(client_p, source_p, &me, "D-lined");
+ return 0;
+ }
+ }
+
+ sendto_one(source_p, "NOTICE * :CGI:IRC host/IP set to %s %s", parv[3], parv[4]);
+ return 0;
+}
--- /dev/null
+/*
+ * Deny opers setting themselves +i unless they are bots (i.e. have
+ * hidden_oper privilege).
+ * -- jilles
+ *
+ * $Id: no_oper_invis.c 1086 2006-03-17 23:20:30Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+
+static void h_noi_umode_changed(hook_data_umode_changed *);
+
+mapi_hfn_list_av1 noi_hfnlist[] = {
+ { "umode_changed", (hookfn) h_noi_umode_changed },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(no_oper_invis, NULL, NULL, NULL, NULL, noi_hfnlist, "$Revision: 1086 $");
+
+static void
+h_noi_umode_changed(hook_data_umode_changed *hdata)
+{
+ struct Client *source_p = hdata->client;
+
+ if (MyClient(source_p) && IsOper(source_p) && !IsOperInvis(source_p) &&
+ IsInvisible(source_p))
+ {
+ ClearInvisible(source_p);
+ /* If they tried /umode +i, complain; do not complain
+ * if they opered up while invisible -- jilles */
+ if (hdata->oldumodes & UMODE_OPER)
+ sendto_one_notice(source_p, ":*** Opers may not set themselves invisible");
+ }
+}
--- /dev/null
+/*
+ * Remote client connect/exit notices on snomask +F (far).
+ * To avoid flooding, connects/exits part of netjoins/netsplits are not shown.
+ * Consequently, it is not possible to use these notices to keep track
+ * of all clients.
+ * -- jilles
+ *
+ * $Id: sno_farconnect.c 1869 2006-08-27 14:24:25Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+#include "snomask.h"
+
+static int _modinit(void);
+static void _moddeinit(void);
+static void h_gcn_new_remote_user(struct Client *);
+static void h_gcn_client_exit(hook_data_client_exit *);
+
+mapi_hfn_list_av1 gcn_hfnlist[] = {
+ { "new_remote_user", (hookfn) h_gcn_new_remote_user },
+ { "client_exit", (hookfn) h_gcn_client_exit },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(globalconnexit, _modinit, _moddeinit, NULL, NULL, gcn_hfnlist, "$Revision: 1869 $");
+
+static int
+_modinit(void)
+{
+ /* add the snomask to the available slot */
+ snomask_modes['F'] = find_snomask_slot();
+
+ /* show the fact that we are showing user information in /version */
+ opers_see_all_users = 1;
+
+ return 0;
+}
+
+static void
+_moddeinit(void)
+{
+ /* disable the snomask and remove it from the available list */
+ snomask_modes['F'] = 0;
+}
+
+static void
+h_gcn_new_remote_user(struct Client *source_p)
+{
+
+ if (!HasSentEob(source_p->servptr))
+ return;
+ sendto_realops_snomask_from(snomask_modes['F'], L_ALL, source_p->servptr,
+ "Client connecting: %s (%s@%s) [%s] {%s} [%s]",
+ source_p->name, source_p->username, source_p->orighost,
+ show_ip(NULL, source_p) ? source_p->sockhost : "255.255.255.255",
+ "?", source_p->info);
+}
+
+static void
+h_gcn_client_exit(hook_data_client_exit *hdata)
+{
+ struct Client *source_p;
+
+ source_p = hdata->target;
+
+ if (MyConnect(source_p) || !IsClient(source_p))
+ return;
+ if (!HasSentEob(source_p->servptr))
+ return;
+ sendto_realops_snomask_from(snomask_modes['F'], L_ALL, source_p->servptr,
+ "Client exiting: %s (%s@%s) [%s] [%s]",
+ source_p->name,
+ source_p->username, source_p->host, hdata->comment,
+ show_ip(NULL, source_p) ? source_p->sockhost : "255.255.255.255");
+}
--- /dev/null
+/*
+ * Shows notices if remote clients exit with "Bad user info" or
+ * ConfigFileEntry.kline_reason.
+ * Assumes client_exit is enabled so users can't fake these reasons,
+ * and kline_reason is enabled and the same everywhere.
+ * Yes, this is a hack, but it is simple and avoids sending
+ * more data across servers -- jilles
+ *
+ * $Id: sno_globalkline.c 613 2006-01-29 03:03:02Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+
+static void h_gla_client_exit(hook_data_client_exit *);
+
+mapi_hfn_list_av1 gla_hfnlist[] = {
+ { "client_exit", (hookfn) h_gla_client_exit },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(globallineactive, NULL, NULL, NULL, NULL, gla_hfnlist, "$Revision: 613 $");
+
+static void
+h_gla_client_exit(hook_data_client_exit *hdata)
+{
+ struct Client *source_p;
+
+ source_p = hdata->target;
+
+ if (MyConnect(source_p) || !IsClient(source_p))
+ return;
+ if (!strcmp(hdata->comment, "Bad user info"))
+ {
+ sendto_realops_snomask_from(SNO_GENERAL, L_ALL, source_p->servptr,
+ "XLINE active for %s[%s@%s]",
+ source_p->name, source_p->username, source_p->host);
+ }
+ else if (ConfigFileEntry.kline_reason != NULL &&
+ !strcmp(hdata->comment, ConfigFileEntry.kline_reason))
+ {
+ sendto_realops_snomask_from(SNO_GENERAL, L_ALL, source_p->servptr,
+ "K/D/GLINE active for %s[%s@%s]",
+ source_p->name, source_p->username, source_p->host);
+ }
+}
--- /dev/null
+/*
+ * Remote oper up notices.
+ *
+ * $Id: sno_globaloper.c 639 2006-01-29 21:42:06Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_conf.h"
+#include "snomask.h"
+
+static void h_sgo_umode_changed(void *);
+
+mapi_hfn_list_av1 sgo_hfnlist[] = {
+ { "umode_changed", (hookfn) h_sgo_umode_changed },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(sno_globaloper, NULL, NULL, NULL, NULL, sgo_hfnlist, "$Revision: 639 $");
+
+static void
+h_sgo_umode_changed(void *vdata)
+{
+ hook_data_umode_changed *data = (hook_data_umode_changed *)vdata;
+ struct Client *source_p = data->client;
+
+ if (MyConnect(source_p) || !HasSentEob(source_p->servptr))
+ return;
+
+ if (!(data->oldumodes & UMODE_OPER) && IsOper(source_p))
+ sendto_realops_snomask_from(SNO_GENERAL, L_ALL, source_p->servptr,
+ "%s (%s@%s) is now an operator",
+ source_p->name, source_p->username, source_p->host);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_admin_notice.c: Sends a notice when someone uses ADMIN.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_admin_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_admin(hook_data *);
+
+mapi_hfn_list_av1 admin_hfnlist[] = {
+ {"doing_admin", (hookfn) show_admin},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(admin_spy, NULL, NULL, NULL, NULL, admin_hfnlist, "$Revision: 498 $");
+
+void
+show_admin(hook_data *data)
+{
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "admin requested by %s (%s@%s) [%s]",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_info_notice.c: Sends a notice when someone uses INFO.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_info_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_info(hook_data *);
+
+mapi_hfn_list_av1 info_hfnlist[] = {
+ {"doing_info", (hookfn) show_info},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(info_spy, NULL, NULL, NULL, NULL, info_hfnlist, "$Revision: 498 $");
+
+void
+show_info(hook_data *data)
+{
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "info requested by %s (%s@%s) [%s]",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_links_notice.c: Sends a notice when someone uses LINKS.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_links_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_links(hook_data *);
+
+mapi_hfn_list_av1 links_hfnlist[] = {
+ {"doing_links", (hookfn) show_links},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(links_spy, NULL, NULL, NULL, NULL, links_hfnlist, "$Revision: 498 $");
+
+void
+show_links(hook_data *data)
+{
+ const char *mask = data->arg1;
+
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "LINKS '%s' requested by %s (%s@%s) [%s]",
+ mask, data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_motd_notice.c: Sends a notice when someone uses MOTD.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_motd_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_motd(hook_data *);
+
+mapi_hfn_list_av1 motd_hfnlist[] = {
+ {"doing_motd", (hookfn) show_motd},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(motd_spy, NULL, NULL, NULL, NULL, motd_hfnlist, "$Revision: 498 $");
+
+void
+show_motd(hook_data *data)
+{
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "motd requested by %s (%s@%s) [%s]",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_stats_notice.c: Sends a notice when someone uses STATS.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_stats_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_stats(hook_data_int *);
+
+mapi_hfn_list_av1 stats_hfnlist[] = {
+ {"doing_stats", (hookfn) show_stats},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(stats_spy, NULL, NULL, NULL, NULL, stats_hfnlist, "$Revision: 498 $");
+
+void
+show_stats(hook_data_int *data)
+{
+ char statchar = (char) data->arg2;
+
+ if(statchar == 'L' || statchar == 'l')
+ {
+ const char *name = data->arg1;
+
+ if(!EmptyString(name))
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "STATS %c requested by %s (%s@%s) [%s] on %s",
+ statchar, data->client->name,
+ data->client->username,
+ data->client->host,
+ data->client->user->server, name);
+ else
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "STATS %c requested by %s (%s@%s) [%s]",
+ statchar, data->client->name,
+ data->client->username,
+ data->client->host, data->client->user->server);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "STATS %c requested by %s (%s@%s) [%s]",
+ statchar, data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_stats_p_notice.c: Sends a notice when someone uses STATS p.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_stats_p_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_stats_p(hook_data *);
+
+mapi_hfn_list_av1 stats_p_hfnlist[] = {
+ {"doing_stats_p", (hookfn) show_stats_p},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(stats_p_spy, NULL, NULL, NULL, NULL, stats_p_hfnlist, "$Revision: 498 $");
+
+void
+show_stats_p(hook_data *data)
+{
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "STATS p requested by %s (%s@%s) [%s]",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_trace_notice.c: Sends a notice when someone uses TRACE or LTRACE
+ *
+ * Copyright (C) 2002 Hybrid 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
+ *
+ * $Id: spy_trace_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_trace(hook_data_client *);
+
+mapi_hfn_list_av1 trace_hfnlist[] = {
+ {"doing_trace", (hookfn) show_trace},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(trace_spy, NULL, NULL, NULL, NULL, trace_hfnlist, "$Revision: 498 $");
+
+void
+show_trace(hook_data_client *data)
+{
+ if(data->target)
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "trace requested by %s (%s@%s) [%s] on %s",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server,
+ data->target->name);
+ else
+ sendto_realops_snomask(SNO_SPY, L_ALL,
+ "trace requested by %s (%s@%s) [%s]",
+ data->client->name, data->client->username,
+ data->client->host, data->client->user->server);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_whois_notice.c: Sends a notice when someone uses WHOIS.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_whois_notice.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_whois(hook_data_client *);
+
+mapi_hfn_list_av1 whois_hfnlist[] = {
+ {"doing_whois", (hookfn) show_whois},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(whois_spy, NULL, NULL, NULL, NULL, whois_hfnlist, "$Revision: 498 $");
+
+void
+show_whois(hook_data_client *data)
+{
+ struct Client *source_p = data->client;
+ struct Client *target_p = data->target;
+
+ /* source being MyConnect() is implicit here from m_whois.c --fl */
+ if(MyClient(target_p) && IsOper(target_p) && (source_p != target_p) &&
+ (target_p->snomask & SNO_SPY))
+ {
+ sendto_one(target_p,
+ ":%s NOTICE %s :*** Notice -- %s (%s@%s) is doing a whois on you [%s]",
+ me.name, target_p->name, source_p->name,
+ source_p->username, source_p->host,
+ source_p->user->server);
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * spy_whois_notice.c: Sends a notice when someone uses WHOIS.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: spy_whois_notice_global.c 498 2006-01-15 16:40:33Z jilles $
+ */
+#include "stdinc.h"
+#include "modules.h"
+#include "hook.h"
+#include "client.h"
+#include "ircd.h"
+#include "send.h"
+
+void show_whois_global(hook_data_client *);
+
+mapi_hfn_list_av1 whois_global_hfnlist[] = {
+ {"doing_whois_global", (hookfn) show_whois_global},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(whois_global_spy, NULL, NULL, NULL, NULL, whois_global_hfnlist,
+ "$Revision: 498 $");
+
+void
+show_whois_global(hook_data_client *data)
+{
+ struct Client *source_p = data->client;
+ struct Client *target_p = data->target;
+
+ if(MyClient(target_p) && IsOper(target_p) && (source_p != target_p) &&
+ (target_p->snomask & SNO_SPY))
+ {
+ sendto_one(target_p,
+ ":%s NOTICE %s :*** Notice -- %s (%s@%s) is doing a whois on you [%s]",
+ me.name, target_p->name, source_p->name,
+ source_p->username, source_p->host,
+ source_p->user->server);
+ }
+}
--- /dev/null
+# Generated automatically from Makefile.in by configure.
+# $Id: Makefile.in 1044 2006-03-12 16:05:39Z jilles $
+# makefile for include/
+
+INSTALL= @INSTALL@
+INSTALL_DATA= @INSTALL_DATA@
+RM= @RM@
+
+prefix= @prefix@
+exec_prefix= @execprefix@
+helpdir= @helpdir@
+uhelpdir= ${helpdir}/users
+ohelpdir= ${helpdir}/opers
+
+SYMLINKS= topic accept cmode admin names links away whowas \
+ version kick who invite quit join list nick oper part \
+ time credits motd userhost users whois ison lusers \
+ user help pass error challenge knock ping pong \
+ cprivmsg cnotice map trace
+
+all:
+build:
+clean:
+depend:
+lint:
+
+index:
+ @echo building index files
+ rm -f users/index.tmp
+ @for help in users/*; do \
+ if [ -f $$help ]; then \
+ echo $$help >> users/index.tmp; \
+ fi \
+ done
+ @for help in $(SYMLINKS); do \
+ echo $$help >> users/index.tmp; \
+ done
+ echo 'Help topics available to users:' > users/index
+ echo '' >> users/index
+ cat users/index.tmp \
+ | sed -e 's|^users/||' \
+ | sort -u \
+ | tr a-z A-Z \
+ | column -c 65 -x \
+ | expand \
+ >> users/index
+ rm -f users/index.tmp
+ rm -f opers/index.tmp
+ @for help in opers/*; do \
+ if [ -f $$help ]; then \
+ echo $$help >> opers/index.tmp; \
+ fi \
+ done
+ echo 'Help topics available to opers:' > opers/index
+ echo '' >> opers/index
+ cat opers/index.tmp \
+ | sed -e 's|^opers/||' \
+ | sort -u \
+ | tr a-z A-Z \
+ | column -c 65 -s ' ' -x \
+ | expand \
+ >> opers/index
+ rm -f opers/index.tmp
+
+install:
+ -@if test -d $(DESTDIR)$(helpdir)-old; then \
+ rm -rf $(DESTDIR)$(helpdir)-old; \
+ fi
+ -@if test -d $(DESTDIR)$(helpdir); then \
+ echo "ircd: backing up old help files"; \
+ mv $(DESTDIR)$(helpdir) $(DESTDIR)$(helpdir)-old; \
+ fi
+
+ @echo "ircd: setting up help directory structure"
+ @mkdir -p -m 755 $(DESTDIR)$(helpdir)
+ @mkdir -p -m 755 $(DESTDIR)$(helpdir)/opers
+ @mkdir -p -m 755 $(DESTDIR)$(helpdir)/users
+
+ @for help in opers/*; do \
+ if [ -f $$help ]; then \
+ ${INSTALL_DATA} $$help $(DESTDIR)$(ohelpdir); \
+ fi \
+ done
+ @for help in users/*; do \
+ if [ -f $$help ]; then \
+ $(INSTALL_DATA) $$help $(DESTDIR)$(uhelpdir); \
+ fi \
+ done
+ @for link in $(SYMLINKS); do \
+ rm -f $(DESTDIR)$(uhelpdir)/$$link; \
+ ln -s $(ohelpdir)/$$link $(DESTDIR)$(uhelpdir); \
+ done
+
+
+distclean:
+ ${RM} -f Makefile
+
+depend:
--- /dev/null
+ACCEPT <parameter>
+
+ACCEPT allows you to control who can send you a NOTICE or PRIVMSG
+while you have user mode +g enabled.
+
+For +g: /QUOTE ACCEPT <nick> -- Add a permitted nickname
+ /QUOTE ACCEPT -<nick> -- Remove a permitted nickname
+ /QUOTE ACCEPT * -- List the present permitted nicknames
--- /dev/null
+ADMIN [server]
+
+With no arguments, ADMIN shows the information that was set by the
+administrator of the server. This information can take any form that
+will fit in three lines of text but is usually a list of contacts
+for the persons that run the server.
+
+With a second argument, the administrative information for the
+specified server is displayed.
+
+See also: stats
--- /dev/null
+AWAY :[MSG]
+
+Without an argument, it will set you back. With an argument,
+it will set you as AWAY with the specified message.
--- /dev/null
+CAPAB - Server to Server Protocol Command.
--- /dev/null
+CHALLENGE <nick|+response>
+
+CHALLENGE is used in the RSA controlled
+oper {} system. CHALLENGE requires you to
+issue the command using the nickname in the
+operator block, while matching the username
+and hostname specified. The server will
+send you an RSA challenge. You must send
+a valid RSA response back to the server,
+proceeded with a '+' symbol.
--- /dev/null
+CHANTRACE <#channel>
+
+Outputs a list of members in #channel in ETRACE format, with the classname
+replaced by the server the users are on.
+
+You must be a member of the channel to perform this command.
--- /dev/null
+CLOSE
+
+Close any connections from clients or servers who have
+not fully registered yet.
--- /dev/null
+MODE <channel> <+|-><modes> [parameters]
+
+CHANNELMODE - DESCRIPTION
+------------------------------------------------------------------------
+NO PARAMETERS:
+ +n - No external messages. Only channel members may talk in
+ the channel.
+ +t - Ops Topic. Only opped (+o) users may set the topic.
+ +s - Secret. Channel will not be shown in /whois and /list etc.
+ +p - Private. Disables /knock to the channel.
+ +m - Moderated. Only opped/voiced users may talk in channel.
+ +i - Invite only. Users need to be /invite'd or match a +I to
+ join the channel.
+ +r - Registered users only. Only users identified to services
+ may join.
+ +c - No color. All color codes in messages are stripped.
+ +g - Free invite. Everyone may invite users. Significantly
+ weakens +i control.
+ +z - Op moderated. Messages blocked by +m are instead sent to ops.
+ +L - Large ban list. Increase maximum number of +beIq entries.
+ Only settable by opers.
+ +P - Permanent. Channel does not disappear when empty. Only
+ settable by opers.
+ +F - Free target. Anyone may set forwards to this (otherwise
+ ops are necessary).
+ +Q - Disable forward. Users cannot be forwarded to the channel
+ (however, new forwards can still be set subject to +F).
+
+WITH PARAMETERS:
+ +f - Forward. Forwards users who cannot join because of +i,
+ +j, +l or +r.
+ PARAMS: /mode #channel +f #channel2
+ +j - Join throttle. Limits number of joins to the channel per time.
+ PARAMS: /mode #channel +j count:time
+ +k - Key. Requires users to issue /join #channel KEY to join.
+ PARAMS: /mode #channel +k key
+ +l - Limit. Impose a maximum number of LIMIT people in the channel.
+ PARAMS: /mode #channel +l limit
+ +v - Voice. Allows a user to talk in a +m channel. Noted by +nick.
+ PARAMS: /mode #channel +v nick
+ +o - Op. Allows a user full control over the channel.
+ PARAMS: /mode #channel +o nick
+ +b - Ban. Prevents a user from entering the channel, based on a
+ nick!ident@host match.
+ PARAMS: /mode #channel +b nick!user@host
+ +q - Quiet. Prevents a user from sending to the channel, based on a
+ nick!ident@host match.
+ PARAMS: /mode #channel +q nick!user@host
+ +e - Exempt. Allows a user to join a channel and send to it even if
+ they are banned (+b) or quieted (+q), based on a nick!ident@host
+ match.
+ PARAMS: /mode #channel +e nick!user@host
+ +I - Invite Exempt. Allows a user to join a +i channel without an
+ invite, based on a nick!user@host match.
+ PARAMS: /mode #channel +I nick!user@host
--- /dev/null
+CNOTICE <nick> <channel> :<text>
+
+Providing you are opped (+o) or voiced (+v) in <channel>, and <nick>
+is a member of <channel>, CNOTICE generates a NOTICE towards
+<nick>. CNOTICE bypasses any anti-spam measures in place.
--- /dev/null
+CONNECT <server_A> [port] [server_B]
+
+When [server_B] is used, CONNECT asks [server_B] to
+connect to <server_A>. Requires Oper Priv: R
+
+The [port] must be specified with [server_B], this is
+usually 6667. To use the default port in the connect
+block, you can use 0 as the port.
+
+When [server_B] is not used, CONNECT tries to connect
+your server to <server_A>.
+
+When [port] is used, the connection will be attempted
+to [port].
+When [port] is not used, 6667 is used as a default,
+unless the port is specified in the conf file.
--- /dev/null
+CPRIVMSG <nick> <channel> :<text>
+
+Providing you are opped (+o) or voiced (+v) in <channel>, and <nick>
+is a member of <channel>, CPRIVMSG generates a PRIVMSG towards
+<nick>. CPRIVMSG bypasses any anti-spam measures in place.
--- /dev/null
+Help File Credits
+
+Help files were written by the following people:
+
+disasta David Daley <disasta@go.com>
+Hwy101 W. Campbell <wcampbel@botbay.net>
+larne Edward Brocklesby <ejb@leguin.org.uk>
+MoeBass anonymous <moe@moebass.com>
+screwedup Jonathan Roes <jroes@magenet.net>
+zartik Daniel Hemmerich <dan@spot.org>
--- /dev/null
+DIE server.name
+
+Terminates the IRC server
+
+- Requires Oper Priv: D
--- /dev/null
+DLINE [duration] <ip> :[reason]
+
+Adds a DLINE to the ircd.conf or klines.conf file
+which will deny any connections from the IP address
+of the banned client. The banned client will receive
+a message saying he/she is banned with reason [reason]
+
+Duration is optional, and is in minutes.
+
+- Requires Oper Priv: K
--- /dev/null
+ERROR :<message>
+
+ERROR is sent by the server to clients
+or other servers when an exception occurs.
+
+If another server sends your server an
+ERROR, it will be shown to all operators
+on the server.
--- /dev/null
+ETRACE [-full|-v4|-v6|nick]
+
+With no argument, ETRACE gives a list of all clients connected
+to the local server, both users and operators.
+
+With -full option, ETRACE lists all clients along with the
+two unused fields sent in the USER command when they connected.
+
+When ipv6 is enabled, the -v4 and -v6 options display clients
+using ipv4 and ipv6 respectively.
+
+You may also specify a specific nickname to ETRACE. The target
+can be a local or remote client, however the ETRACE will be "lost"
+if the remote server does not support this extension. The
+"-full" option will be implied and should not be specified with
+it.
--- /dev/null
+GLINE <user@host> :[reason]
+
+-- if glines are enabled --
+Attempts to add a global IRC-network wide ban on
+<user@host> for the reason [reason].
+
+It takes three different opers on three different
+servers to do the same GLINE within a short interval,
+to have a GLINE triggered for a compiled time of hours.
+
+- Requires Oper Priv: G
--- /dev/null
+HELP [topic]
+
+HELP displays the contents of the help
+file for topic requested. If no topic is
+requested, it will perform the equivalent
+to HELP index.
--- /dev/null
+Help topics available to opers:
+
+ACCEPT ADMIN AWAY CAPAB
+CHALLENGE CHANTRACE CLOSE CMODE
+CNOTICE CONNECT CPRIVMSG CREDITS
+DIE DLINE ERROR ETRACE
+GLINE HELP INDEX INFO
+INVITE ISON JOIN KICK
+KILL KLINE KNOCK LINKS
+LIST LOCOPS LUSERS MAP
+MASKTRACE MODLIST MODLOAD MODRESTART
+MODUNLOAD MOTD NAMES NICK
+NOTICE OPER OPERSPY OPERWALL
+PART PASS PING PONG
+POST PRIVMSG QUIT REHASH
+RESTART RESV SCAN SERVER
+SET SJOIN SNOMASK SQUIT
+STATS SVINFO TESTGECOS TESTLINE
+TESTMASK TIME TOPIC TRACE
+UHELP UMODE UNDLINE UNGLINE
+UNKLINE UNREJECT UNRESV UNXLINE
+USER USERHOST USERS VERSION
+WALLOPS WHO WHOIS WHOWAS
+XLINE
--- /dev/null
+INFO
+
+INFO displays the copyright, list of authors and contributors
+to ircd, and the server configuration (as defined in config.h
+and ircd.conf).
--- /dev/null
+INVITE <nickname> <channel>
+
+INVITE sends a notice to the user that you have
+asked him/her to come to the specified channel.
--- /dev/null
+ISON <nick_A> [nick_B] :[nick_C] [nick_D]
+
+ISON will return a list of users who are present
+on the network from the list that was passed in.
+
+This command is rarely used directly.
--- /dev/null
+JOIN <#channel> [key]
+
+The JOIN command allows you to enter a public chat area known as
+a channel. Network wide channels are proceeded by a '#', while
+a local server channel is proceeded by an '&'. More than one
+channel may be specified, separated with commas (no spaces).
+
+If the channel has a key set, the 2nd argument must be
+given to enter. This allows channels to be password protected.
+
+See also: part, list
--- /dev/null
+KICK <channel> <nick> :[msg]
+
+The KICK command will remove the specified user
+from the specified channel, using the optional
+kick message. You must be a channel operator to
+use this command.
--- /dev/null
+KILL <nick> <reason>
+
+Disconnects user <nick> from the IRC server he/she
+is connected to with reason <reason>.
+- Requires Oper Priv: O for users not on your IRC server
--- /dev/null
+KLINE <user@host> :[reason] [| oper reason]
+
+Adds a KLINE to the kline.conf file which will ban the
+specified user from using this server. The banned
+client will receive a message saying he/she is banned
+with reason [reason].
+
+If an oper reason is added (the pipe must be specified
+to seperate the fields) this will be added into the
+kline.conf but will not be shown to the user when they
+are given the kline reason.
+
+KLINE <user@ip.ip.ip.ip> :[reason] [| oper reason]
+will kline the user at the unresolved ip.
+ip.ip.ip.ip can be in CIDR form i.e. 192.168.0.0/24
+or 192.168.0.* (which is converted to CIDR form internally)
+
+For a temporary KLINE, length of kline is given in
+minutes as the first parameter i.e.
+KLINE 10 <user@host> :cool off for 10 minutes
+
+KLINE [duration] <user@host> ON irc.server :[reason] [| oper reason]
+will kline the user on irc.server if irc.server accepts
+remote klines. irc.server can contain wildcards.
+
+- Requires Oper Priv: K
--- /dev/null
+KNOCK <channel>
+
+KNOCK requests access to a channel that
+for some reason is not open.
+
+KNOCK cannot be used if you are banned, the
+channel is +p, or it is open.
--- /dev/null
+LINKS [[remote] mask]
+
+LINKS shows a list of all servers linked to the host server.
+
+With a mask parameter, LINKS will just show servers matching
+that parameter. With the remote server parameter, LINKS will
+request the LINKS data from the remote server, matching the
+mask given.
+
+The information provided by the LINKS command can be helpful
+for determining the overall shape of the network in addition to
+its size.
+
+NOTE: the links command employs an intensive process to generate
+it's output, so sparing use is recommended.
+
+See also: connect map squit
--- /dev/null
+LIST [#channel]|[modifiers]
+
+Without any arguments, LIST will give an entire list of all
+channels which are not set as secret (+s). The list will be in
+the form:
+
+ <#channel> <amount of users> :[topic]
+
+If an argument supplied is a channel name, LIST will give just
+the statistics for the given channel.
+
+Modifiers are also supported, seperated by a comma:
+ <n - List channels with less than n users
+ >n - List channels with more than n users
+
+eg LIST <100,>20
--- /dev/null
+LOCOPS :<message>
+
+Sends an LOCOPS message of <message> to all
+opers on local server who are umode +l
--- /dev/null
+LUSERS [mask [remoteserver]]
+
+LUSERS will display client count statistics.
+If a remote server is specified, it will
+request the information from that server.
+The mask parameter is obsolete but still
+needs to be used when querying a remote
+server.
--- /dev/null
+MAP
+
+MAP shows a graphical map of the network with user
+counts and TS6 SIDs (if known).
--- /dev/null
+MASKTRACE [<nick>!]<user>@<host> :<gecos>
+
+Outputs a list of local users matching the given masks
+in ETRACE format, with the classname replaced by
+the server the users are on. Gecos uses the same
+wildcards as xlines; nick, user and host use just
+? and *.
+
+Supports using CIDR ip masks as a hostname.
--- /dev/null
+MODLIST [match string]
+
+-- List the modules that are currently loaded into the
+ircd, along with their address and version.
+When a match string is provided, modlist only prints
+modules with names matching the match string.
+NOTE: Restricted to admins only
--- /dev/null
+MODLOAD <[path/]module.so>
+
+-- Load a module into the ircd
+the optional path can be an absolute path
+from / or from the IRCD_PREFIX
+(ie modules/autoload/m_users.so)
+NOTE: Restricted to admins only
--- /dev/null
+MODRESTART
+
+-- Reload all modules into the ircd
+All modules are unloaded, then those in modules/autoload
+are loaded
+NOTE: Restricted to admins only
--- /dev/null
+MODUNLOAD <module.so>
+
+-- Unload a module from the ircd
+Use just the module name, the path is not needed.
+When a module is unloaded, all commands associated
+with it are unloaded as well.
+NOTE: Restricted to admins only
--- /dev/null
+MOTD [servername]
+
+MOTD will display the message of the day for the
+server name specified, or the local server if there
+was no parameter.
--- /dev/null
+NAMES [channel]
+
+With no channel argument, NAMES shows the names (nicks) of all clients
+logged in to the network that do not have +i flag.
+
+With the #channel argument, it displays the nicks on that channel,
+also respecting the +i flag of each client. If the channel specified
+is a channel that the issuing client is currently in, all nicks are
+listed in similar fashion to when the user first joins a channel.
+
+See also: join
--- /dev/null
+NICK <nickname>
+
+When first connected to the IRC server, NICK is required to
+set the client's nickname.
+
+NICK will also change the client's nickname once a connection
+has been established.
--- /dev/null
+NOTICE <nick|channel> :message
+
+NOTICE will send a notice message to the
+user or channel specified.
+
+NOTICE supports the following prefixes for sending
+messages to specific clients in a channel:
+
+@ - channel operators only
++ - channel operators and voiced users
+
+Two other targets are permitted:
+
+$$servermask - Send a message to a server or set of
+ servers
+$#hostmask - Send a message to users matching the
+ hostmask specified.
+
+These two are operator only.
+
+The nick can be extended to fit into the following
+syntax:
+
+username[%hostname]@servername
+
+This syntax (without the hostname) is used to securely
+send a message to a service or a bot.
+
+An extension of this is the syntax to send to all opers
+on a server.
+
+opers@servername
+
+In Hybrid 7, all opers on a server will see a message that
+looks like a modified WALLOPS
--- /dev/null
+OPER <name> <password>
+
+The OPER command requires two arguments to be given. The first
+argument is the name of the operator as specified in the
+configuration file. The second argument is the password for
+the operator matching the name and host.
+
+The operator privileges are shown on a sucessful OPER.
--- /dev/null
+OPERSPY
+
+Opers with the "oper_spy" flag will be allowed uses of the following
+commands if they are compiled in. Usage will be sent to +Z and all
+other servers.
+
+whois !nick - Gives a full output of channels the user is in.
+who !mask - Lists all users networkwide whose nick, ident, host,
+ server or gecos match the mask.
+who !#channel - Gives a full output of users on the channel.
+mode !#channel - Gives the full modes of a channel including any keys.
+chantrace !#channel - Gives full output despite not being on channel.
+masktrace !nick!user@host :gecos - Lists matching users on all servers.
--- /dev/null
+OPERWALL :<message>
+
+Sends an OPERWALL message of <message> to all
+opers who are umode +z
--- /dev/null
+PART <#channel> :[part message]
+
+PART requires at least a channel argument to be given. It will
+exit the client from the specified channel. More than one
+channel may be specified, separated with commas (no spaces).
+
+An optional part message may be given to be displayed to the
+channel.
+
+See also: join
--- /dev/null
+PASS <password>
+
+PASS is used during registration to access
+a password protected auth {} block.
+
+PASS is also used during server registration.
--- /dev/null
+PING <source> :<target>
+
+PING will request a PONG from the target. If a
+user or operator issues this command, the source
+will always be turned into the nick that issued
+the PING.
--- /dev/null
+PONG <pinged-client> :<source-client>
+
+PONG is the response to a PING command. The
+source client is the user or server that issued
+the command, and the pinged client is the
+user or server that received the PING.
--- /dev/null
+POST
+
+The POST command is used to help protect against
+insecure HTTP proxies. Any proxy that sends a POST
+command during registration will be exited.
--- /dev/null
+PRIVMSG <nick|channel> :message
+
+PRIVMSG will send a standard message to the
+user or channel specified.
+
+PRIVMSG supports the following prefixes for sending
+messages to specific clients in a channel:
+
+@ - channel operators only
++ - channel operators and voiced users
+
+Two other targets are permitted:
+
+$$servermask - Send a message to a server or set of
+ servers
+$#hostmask - Send a message to users matching the
+ hostmask specified.
+
+These two are operator only.
+
+The nick can be extended to fit into the following
+syntax:
+
+username[%hostname]@servername
+
+This syntax (without the hostname) is used to securely
+send a message to a service or a bot.
+
+An extension of this is the syntax to send to all opers
+on a server.
+
+opers@servername
+
+In Hybrid 7, all opers on a server will see a message that
+looks like a modified WALLOPS
--- /dev/null
+QUIT :[quit message]
+
+QUIT sends a message to the IRC server letting it know you would
+like to disconnect. The quit message will be displayed to the
+users in the channels you were in when you are disconnected.
--- /dev/null
+REHASH [option]
+
+When no [option] is given, ircd will re-read the
+ircd.conf file.
+
+[option] can be one of the following:
+ BANS - Re-reads kline.conf, dline.conf, resv.conf and xline.conf
+ DNS - Re-read the /etc/resolv.conf file
+ GLINES - Clears G Lines
+ HELP - Re-reads help files
+ MOTD - Re-reads MOTD file
+ NICKDELAY - Clears delayed nicks
+ OMOTD - Re-reads Oper MOTD file
+ PGLINES - Clears pending G Lines
+ REJECTCACHE - Clears the reject cache
+ TDLINES - Clears temporary D Lines
+ TKLINES - Clears temporary K Lines
+ TRESVS - Clears temporary nick and channel resvs
+ TXLINES - Clears temporary X Lines
+
+- Requires Oper Priv: H
+
+REHASH [option] irc.server
+
+Rehashes [option], or the config file if none given, on irc.server if
+irc.server accepts remote rehashes.
+
+- Requires Oper Priv: HB
--- /dev/null
+RESTART server.name
+
+Restarts the IRC server.
+
+- Requires Oper Priv: D
--- /dev/null
+RESV [time] <channel|nick> :<reason>
+
+Reserves a channel or nickname from use. If [time] is not specified this
+is added to resv.conf, otherwise is temporary for [time] minutes.
+
+Nick resvs accept the same wildcard chars as xlines.
+Channel resvs only use exact string comparisons.
+
+RESV [time] <channel|nick> ON <server> :<reason>
+
+Will attempt to set the RESV on <server> if <server> accepts remote RESVs.
--- /dev/null
+SCAN UMODES +<modes>-<modes> [NO-LIST] [LIST] [GLOBAL]
+ [LIST-MAX <number>] [MASK <nick!user@host>]
+
+Searches the local server or network for users that have the
+umodes given with + and do not have the umodes given with -.
+NO-LIST disables the listing of matching users and only
+shows the count. LIST enables the listing (default). GLOBAL
+extends the search to the entire network instead of local
+users only. LIST-MAX limits the listing of matching users to
+the given amount. MASK causes only users matching the given
+nick!user@host mask to be selected. Only the displayed host
+is considered, not the IP address or real host behind
+dynamic spoofs.
+
+Network searches where a listing is given or the MASK option
+is used are operspy commands.
--- /dev/null
+SERVER - Server to Server Protocol Command.
--- /dev/null
+SET <option> <value>
+
+<option> can be one of the following:
+ ADMINSTRING - Sets string shown in WHOIS for admins
+ AUTOCONN - Sets auto-connect on or off for a particular
+ server
+ AUTOCONNALL - Sets auto-connect on or off for all servers
+ FLOODCOUNT - The number of lines allowed before
+ throttling a connection due to flooding
+ Note that this variable is used for both
+ channels and clients
+ IDENTTIMEOUT- Timeout for requesting ident from a client
+ IDLETIME - The number of seconds a client can be idle
+ before disconnecting them
+ MAX - Sets the number of max connections
+ to <value>. (This number cannot exceed
+ HARD_FDLIMIT in config.h)
+ OPERSTRING - Sets string shown in WHOIS for opers
+ SPAMNUM - Sets how many join/parts to channels
+ constitutes a possible spambot.
+ SPAMTIME - Below this time on a channel
+ counts as a join/part as above.
+ SPLITMODE - Sets splitmode to <value>:
+ ON - splitmode is permanently on
+ OFF - splitmode is permanently off
+ AUTO - ircd chooses splitmode based on
+ SPLITUSERS and SPLITNUM
+ SPLITUSERS - Sets the minimum amount of users needed to
+ deactivate automatic splitmode.
+ SPLITNUM - Sets the minimum amount of servers needed to
+ deactivate automatic splitmode.
--- /dev/null
+SJOIN - Server to Server Protocol Command.
--- /dev/null
+MODE <nick> +s <+|-><modes>
+
+Server notice masks:
+
+ SNOMASK DESCRIPTION
+-----------------------------------------------------------------
+ +b - Possible bot warnings
+ +c - Local client connections and exits
+ +C - Extended local client connections and exits
+ +d - Server debug messages
+ +f - 'I-line is full' notices
+ +k - Server and service kill messages
+ +n - Local client nick changes
+ +r - 'Rejected' client notices
+ +s - Generic server messages and oper kills
+ +u - Unauthorised client connections
+ +x - New server introduction and split messages
+ +y - Juped channel join attempts, etc
+ +Z - Operspy notices
--- /dev/null
+SQUIT <server> [reason]
+
+Splits <server> away from your side of the net with [reason].
+- Requires Oper Priv: R for servers not connected to you
--- /dev/null
+STATS <letter> [server|nick]
+
+Queries server [server] (or your own server if no
+server parameter is given) for info corresponding to
+<letter>.
+
+ (X = Admin only.)
+LETTER (* = Oper only.)
+------ (^ = Can be configured to be oper only.)
+X A - Shows DNS servers
+X b - Shows active nick delays
+X B - Shows hash statistics
+^ c - Shows connect blocks (Old C:/N: lines)
+* d - Shows temporary D lines
+* D - Shows D lines
+* e - Shows exemptions to D lines
+X E - Shows Events
+X f - Shows File Descriptors
+* g - Shows pending G lines
+* G - Shows active G lines
+^ h - Shows hub_mask/leaf_mask (Old H:/L: lines)
+^ i - Shows auth blocks (Old I: lines)
+^ K - Shows K lines (or matched klines)
+^ k - Shows temporary K lines (or matched temp klines)
+ L - Shows IP and generic info about [nick]
+ l - Shows hostname and generic info about [nick]
+ m - Shows commands and their usage
+ n - Shows DNS blacklists
+^ o - Shows O/o lines
+^ P - Shows configured ports
+ p - Shows online opers
+* q - Shows temporary resv'd nicks and channels
+* Q - Shows resv'd nicks and channels
+* r - Shows resource usage by ircd
+* t - Shows generic server stats
+* U - Shows shared blocks (Old U: lines)
+ u - Shows server uptime
+^ v - Shows connected servers and brief status information
+* x - Shows temporary gecos bans
+* X - Shows gecos bans (Old X: lines)
+^ y - Shows connection classes (Old Y: lines)
+* z - Shows memory stats
+* Z - Shows ziplinks stats
+^ ? - Shows connected servers and sendq info about them
--- /dev/null
+SVINFO - Server to Server Protocol Command.
--- /dev/null
+TESTGECOS <gecos>
+
+Looks for matching xlines for the given gecos.
--- /dev/null
+TESTLINE [[nick!]user@]host
+
+Looks up given mask, looking for any matching I/K/D/G lines.
+If username is not specified, it will look up "dummy@host".
+If nickname is specified it will also search for RESVs.
+
+This command will not perform dns lookups on a host, for best
+results you must testline a host and its IP form.
--- /dev/null
+TESTMASK <[nick!]user@host> [:gecos]
+
+Will test the given nick!user@host gecos mask, reporting how many local
+and global clients match the given mask. Supports using CIDR ip masks
+as a host.
--- /dev/null
+TIME [server]
+
+The TIME command will return the server's local date and time.
+
+If an argument is supplied, the time for the server specified
+will be returned.
--- /dev/null
+TOPIC <#channel> :[new topic]
+
+With only a channel argument, TOPIC shows the current topic of
+the specified channel.
+
+With a second argument, it changes the topic on that channel to
+<new topic>. If the channel is +t, only chanops may change the
+topic.
+
+See also: cmode
--- /dev/null
+TRACE [server | nick] [location]
+
+With no argument, TRACE gives a list of all clients connected
+to the local server, both users and operators.
+
+With one argument which is a server, TRACE displays the path
+to the specified server, and all servers, opers and -i users
+on that server.
+
+Nonopers can only see themselves, opers and servers in the
+first two forms.
+
+With one argument which is a client, TRACE displays the
+path to that client, and that client's information.
+
+If location is given, the command is executed on that server;
+no path is displayed.
--- /dev/null
+UHELP [topic]
+
+UHELP allows an operator to view help topics
+for users without opening a second client
+or removing their operator status.
--- /dev/null
+MODE <nick> <+|-><modes>
+
+Usermodes: (* designates that the umode is oper only)
+
+ USERMODE DESCRIPTION
+-----------------------------------------------------------------
+ +i - Designates this client 'invisible'.
+ +g - "caller id" mode only allow accept clients to message you
+ +w - Can see oper and server wallops.
+ +o - Designates this client is an IRC Operator.
+ Use the /oper command to attain this.
+ * +a - Is marked as a server admin in whois.
+ * +l - Can see oper locops (local wallops).
+ * +s - Can see server notices (see /quote help snomask).
+ * +z - Can see operwalls.
+ +D - Deaf - ignores all channel messages.
+ +Q - Prevents you from being affected by channel forwarding.
+ +R - Prevents non accept unidentified users from messaging you.
--- /dev/null
+UNDLINE <ip>
+
+Will attempt to undline the given <ip>
+
+- Requires Oper Priv: U
--- /dev/null
+UNGLINE <user@host>
+
+-- if glines are enabled --
+Will attempt to remove gline matching <user@host>
+This will only remove the gline from YOUR server, it
+does not try to remove it globally.
+
+- Requires Oper Privs: G and U
--- /dev/null
+UNKLINE <user@host>
+
+Will attempt to unkline the given <user@host>
+Will unkline a temporary kline.
+
+UNKLINE <user@host> ON irc.server will unkline
+the user on irc.server if irc.server accepts
+remote unklines.
+
+- Requires Oper Priv: U
--- /dev/null
+UNREJECT <ip>
+
+Removes an IP address from the reject cache. IP
+addresses are added to the reject cache if they are
+rejected (e.g. connect and are K-lined) several
+times in a short period of time.
--- /dev/null
+UNRESV <channel|nick>
+
+-- Remove a RESV on a channel or nick
+Will attempt to remove the resv for the given
+channel/nick. If the resv is ircd.conf based,
+the resv will not be removed.
--- /dev/null
+UNXLINE <gecos>
+
+Will attempt to unxline the given <gecos>
+
+
+UNXLINE <gecos> ON <server>
+
+Will attempt to unxline the given <gecos> on <server>.
+
+- Requires Oper Priv: X
--- /dev/null
+USER <username> <unused> <unused> :<real name/gecos>
+
+USER is used during registration to set your gecos
+and to set your username if the server cannot get
+a valid ident response. The second and third fields
+are not used, but there must be something in them.
+The reason is backwards compatibility
--- /dev/null
+USERHOST <nick>
+
+USERHOST displays the username, hostname,
+operator status, and presence of valid ident of
+the specified nickname.
+
+If you use USERHOST on yourself, the hostname
+is replaced with the IP you are connecting from.
+This is needed to provide DCC support for spoofed
+hostnames.
--- /dev/null
+USERS [remoteserver]
+
+USERS will display the local and global current
+and maximum user statistics for the specified
+server, or the local server if there was no
+parameter.
--- /dev/null
+VERSION [servername]
+
+VERSION will display the server version of the specified
+server, or the local server if there was no parameter.
--- /dev/null
+WALLOPS :<message>
+
+Sends a WALLOPS message of <message> to all users
+who are umode +w (including non-opers).
+
+Server sent WALLOPS go to all opers who are umode +w.
--- /dev/null
+WHO <#channel|user>
+
+The WHO command displays information about a user,
+such as their GECOS information, their user@host,
+whether they are an IRC operator or not, etc. A
+sample WHO result from a command issued like
+"WHO pokey" may look something like this:
+
+#lamers pokey H pokey@ppp.newbies.net :0 Jim Jones
+
+The first field indicates the last channel the user
+has joined. The second is the user's nickname.
+The third field describes the status information about
+the user. The possible combinations for this field
+are listed below:
+
+H - The user is not away.
+G - The user is set away.
+* - The user is an IRC operator.
+@ - The user is a channel op in the channel listed
+ in the first field.
++ - The user is voiced in the channel listed.
+
+The next field contains the username@host of the user.
+The final field displays the number of server hops and
+the user's GECOS information.
+
+This command may be executed on a channel, such as
+"WHO #lamers" The output will consist of WHO
+listings for each user on the channel.
+
+This command may also be used in conjunction with wildcards
+such as * and ?.
+
+See also: whois, userhost
--- /dev/null
+WHOIS [remoteserver|nick] nick
+
+WHOIS will display detailed user information for
+the specified nick. If the first parameter is
+specified, WHOIS will display information from
+the specified server, or the server that the
+user is on. This is how to remotely see
+idle time and away status.
--- /dev/null
+WHOWAS <nick>
+
+WHOWAS will show you the last known host and whois
+information for the specified nick. Depending on the
+number of times they have connected to the network, there
+may be more than one listing for a specific user.
+
+The WHOWAS data will expire after time.
--- /dev/null
+XLINE [time] <gecos> :<reason>
+
+Bans by gecos (aka 'real name') field. If [time] is not specified
+this is added to xline.conf, otherwise is temporary for [time]
+minutes.
+
+Eg. /quote xline eggdrop?bot :no bots
+
+The <gecos> field contains certain special characters:
+ ? - Match any single character
+ * - Many any characters
+ @ - Match any letter [A-Za-z]
+ # - Match any digit [0-9]
+
+To use a literal one of these characters, escape it with '\'. A
+literal '\' character must also be escaped. You may also insert \s
+which will be converted into a space.
+
+If the <gecos> field is purely numeric (ie "123") then the time
+field must be specified. "0" must be used to denote a permanent
+numeric XLINE.
+
+XLINE [time] <gecos> ON <server> :<reason>
+
+Will attempt to set the XLINE on <server> if <server> accepts
+remote xlines.
+
+- Requires Oper Priv: X
--- /dev/null
+Help topics available to users:
+
+ACCEPT ADMIN AWAY CHALLENGE
+CMODE CNOTICE CPRIVMSG CREDITS
+ERROR HELP INDEX INFO
+INVITE ISON JOIN KICK
+KNOCK LINKS LIST LUSERS
+MAP MOTD NAMES NICK
+NOTICE OPER PART PASS
+PING PONG PRIVMSG QUIT
+STATS TIME TOPIC TRACE
+UMODE USER USERHOST USERS
+VERSION WHO WHOIS WHOWAS
--- /dev/null
+INFO
+
+INFO displays the copyright, authors and contributors list
+for ircd.
--- /dev/null
+NOTICE <nick|channel> :message
+
+NOTICE will send a notice message to the
+user or channel specified.
+
+NOTICE supports the following prefixes for sending
+messages to specific clients in a channel:
+
+@ - channel operators only
++ - channel operators and voiced users
+
+The nick can be extended to fit into the following
+syntax:
+
+username@servername
+
+This syntax is used to securely send a notice to a
+service or a bot.
--- /dev/null
+PRIVMSG <nick|channel> :message
+
+PRIVMSG will send a standard message to the
+user or channel specified.
+
+PRIVMSG supports the following prefixes for sending
+messages to specific clients in a channel:
+
+@ - channel operators only
++ - channel operators and voiced users
+
+The nick can be extended to fit into the following
+syntax:
+
+username@servername
+
+This syntax is used to securely send a message to a
+service or a bot.
--- /dev/null
+STATS <letter> [server|nick]
+
+Queries server [server] (or your own server if no
+server parameter is given) for info corresponding to
+<letter>.
+
+LETTER
+------ (^ = Can be configured to be oper only.)
+^ c - Shows connect blocks
+^ h - Shows hub_mask/leaf_mask (Old H:/L: lines)
+^ i - Shows auth blocks (or matched auth block)
+^ K - Shows K lines (or matched klines)
+^ k - Shows temporary K lines (or matched temp klines)
+ L - Shows IP and generic info about [nick]
+ l - Shows hostname and generic info about [nick]
+ m - Shows commands and their usage
+ n - Shows DNS blacklists
+^ o - Shows O/o lines
+^ P - Shows configured ports
+ p - Shows online opers
+ u - Shows server uptime
+^ v - Shows connected servers and brief status information
+^ y - Shows connection classes (Old Y: lines)
+^ ? - Shows connected servers and sendq info about them
--- /dev/null
+MODE <nick> <+|-><modes>
+
+Usermodes:
+
+ USERMODE DESCRIPTION
+-----------------------------------------------------------------
+ +o - Designates this client is an IRC Operator.
+ Use the /oper command to attain this.
+ +i - Designates this client 'invisible'.
+ +g - "caller id" mode only allow accept clients to message you
+ +w - Can see oper wallops.
+ +D - Deaf - ignores all channel messages.
+ +Q - Prevents you from being affected by channel forwarding.
+ +R - Prevents non accept unidentified users from messaging you.
--- /dev/null
+Makefile
+setup.h
--- /dev/null
+-i8 -bli0 -cs -ut -nsai -nsaw -nsaf -npcs -nprs -l100
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * blacklist.h: Manages DNS blacklist entries and lookups
+ *
+ * Copyright (C) 2006 charybdis 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
+ *
+ * $Id: blacklist.h 2023 2006-09-02 23:47:27Z jilles $
+ */
+
+#ifndef _BLACKLIST_H_
+#define _BLACKLIST_H_
+
+/* A configured DNSBL */
+struct Blacklist {
+ unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
+ int refcount;
+ char host[HOSTLEN];
+ char reject_reason[IRCD_BUFSIZE];
+ unsigned int hits;
+};
+
+/* A lookup in progress for a particular DNSBL for a particular client */
+struct BlacklistClient {
+ struct Blacklist *blacklist;
+ struct Client *client_p;
+ struct DNSQuery dns_query;
+ dlink_node node;
+};
+
+/* public interfaces */
+struct Blacklist *new_blacklist(char *host, char *reject_entry);
+void lookup_blacklists(struct Client *client_p);
+void abort_blacklist_queries(struct Client *client_p);
+void unref_blacklist(struct Blacklist *blptr);
+void destroy_blacklists(void);
+
+extern dlink_list blacklist_list;
+
+#endif
--- /dev/null
+/* $Id: cache.h 6 2005-09-10 01:02:21Z nenolod $ */
+#ifndef INCLUDED_CACHE_H
+#define INCLUDED_CACHE_H
+
+#include "client.h"
+#include "tools.h"
+
+#define HELP_MAX 100
+
+#define CACHELINELEN 81
+#define CACHEFILELEN 30
+/* two servernames, a gecos, three spaces, ":1", '\0' */
+#define LINKSLINELEN (HOSTLEN + HOSTLEN + REALLEN + 6)
+
+#define HELP_USER 0x001
+#define HELP_OPER 0x002
+
+struct Client;
+
+struct cachefile
+{
+ char name[CACHEFILELEN];
+ dlink_list contents;
+ int flags;
+};
+
+struct cacheline
+{
+ char data[CACHELINELEN];
+ dlink_node linenode;
+};
+
+extern struct cachefile *user_motd;
+extern struct cachefile *oper_motd;
+extern struct cacheline *emptyline;
+extern dlink_list links_cache_list;
+
+extern char user_motd_changed[MAX_DATE_STRING];
+
+extern void init_cache(void);
+extern struct cachefile *cache_file(const char *, const char *, int);
+extern void cache_links(void *unused);
+extern void free_cachefile(struct cachefile *);
+
+extern void load_help(void);
+
+extern void send_user_motd(struct Client *);
+extern void send_oper_motd(struct Client *);
+
+#endif
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * channel.h: The ircd channel header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: channel.h 2727 2006-11-09 23:48:45Z jilles $
+ */
+
+#ifndef INCLUDED_channel_h
+#define INCLUDED_channel_h
+#include "config.h" /* config settings */
+#include "ircd_defs.h" /* buffer sizes */
+
+#define MODEBUFLEN 200
+
+/* Maximum mode changes allowed per client, per server is different */
+#define MAXMODEPARAMS 4
+#define MAXMODEPARAMSSERV 10
+
+struct Client;
+
+/* mode structure for channels */
+struct Mode
+{
+ unsigned int mode;
+ int limit;
+ char key[KEYLEN];
+ unsigned int join_num;
+ unsigned int join_time;
+ char forward[LOC_CHANNELLEN + 1];
+};
+
+/* channel structure */
+struct Channel
+{
+ dlink_node node;
+ struct Mode mode;
+ char *topic;
+ char *topic_info;
+ time_t topic_time;
+ time_t users_last; /* when last user was in channel */
+ time_t last_knock; /* don't allow knock to flood */
+
+ dlink_list members; /* channel members */
+ dlink_list locmembers; /* local channel members */
+
+ dlink_list invites;
+ dlink_list banlist;
+ dlink_list exceptlist;
+ dlink_list invexlist;
+ dlink_list quietlist;
+
+ time_t first_received_message_time; /* channel flood control */
+ int received_number_of_privmsgs;
+ int flood_noticed;
+
+ unsigned int join_count; /* joins within delta */
+ unsigned int join_delta; /* last ts of join */
+
+ unsigned long bants;
+ time_t channelts;
+ char *chname;
+};
+
+struct membership
+{
+ dlink_node channode;
+ dlink_node locchannode;
+ dlink_node usernode;
+
+ struct Channel *chptr;
+ struct Client *client_p;
+ unsigned int flags;
+
+ unsigned long bants;
+};
+
+#define BANLEN NICKLEN+USERLEN+HOSTLEN+6
+struct Ban
+{
+ char *banstr;
+ char *who;
+ time_t when;
+ dlink_node node;
+};
+
+struct ChModeChange
+{
+ char letter;
+ const char *arg;
+ const char *id;
+ int dir;
+ int caps;
+ int nocaps;
+ int mems;
+ struct Client *client;
+};
+
+struct ChCapCombo
+{
+ int count;
+ int cap_yes;
+ int cap_no;
+};
+
+struct ChannelMode
+{
+ void (*set_func) (struct Client * source_p, struct Channel * chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type);
+ long mode_type;
+};
+
+typedef int (*ExtbanFunc)(const char *data, struct Client *client_p,
+ struct Channel *chptr, long mode_type);
+
+/* can_send results */
+#define CAN_SEND_NO 0
+#define CAN_SEND_NONOP 1
+#define CAN_SEND_OPV 2
+
+/* channel status flags */
+#define CHFL_PEON 0x0000 /* normal member of channel */
+#define CHFL_CHANOP 0x0001 /* Channel operator */
+#define CHFL_VOICE 0x0002 /* the power to speak */
+#define CHFL_DEOPPED 0x0004 /* deopped on sjoin, bounce modes */
+#define CHFL_BANNED 0x0008 /* cached as banned */
+#define CHFL_QUIETED 0x0010 /* cached as being +q victim */
+#define ONLY_SERVERS 0x0020
+#define ALL_MEMBERS CHFL_PEON
+#define ONLY_CHANOPS CHFL_CHANOP
+#define ONLY_CHANOPSVOICED (CHFL_CHANOP|CHFL_VOICE)
+
+#define is_chanop(x) ((x) && (x)->flags & CHFL_CHANOP)
+#define is_voiced(x) ((x) && (x)->flags & CHFL_VOICE)
+#define is_chanop_voiced(x) ((x) && (x)->flags & (CHFL_CHANOP|CHFL_VOICE))
+#define is_deop(x) ((x) && (x)->flags & CHFL_DEOPPED)
+#define can_send_banned(x) ((x) && (x)->flags & (CHFL_BANNED|CHFL_QUIETED))
+
+/* channel modes ONLY */
+#define MODE_PRIVATE 0x0001
+#define MODE_SECRET 0x0002
+#define MODE_MODERATED 0x0004
+#define MODE_TOPICLIMIT 0x0008
+#define MODE_INVITEONLY 0x0010
+#define MODE_NOPRIVMSGS 0x0020
+#define MODE_REGONLY 0x0040
+#define MODE_NOCOLOR 0x0080
+#define MODE_EXLIMIT 0x0100 /* exempt from list limits, +b/+e/+I/+q */
+#define MODE_PERMANENT 0x0200 /* permanant channel, +P */
+#define MODE_OPMODERATE 0x0400 /* send rejected messages to ops */
+#define MODE_FREEINVITE 0x0800 /* allow free use of /invite */
+#define MODE_FREETARGET 0x1000 /* can be forwarded to without authorization */
+#define MODE_DISFORWARD 0x2000 /* disable channel forwarding */
+
+#define CHFL_BAN 0x10000000 /* ban channel flag */
+#define CHFL_EXCEPTION 0x20000000 /* exception to ban channel flag */
+#define CHFL_INVEX 0x40000000
+#define CHFL_QUIET 0x80000000
+
+/* mode flags for direction indication */
+#define MODE_QUERY 0
+#define MODE_ADD 1
+#define MODE_DEL -1
+
+#define SecretChannel(x) ((x) && ((x)->mode.mode & MODE_SECRET))
+#define HiddenChannel(x) ((x) && ((x)->mode.mode & MODE_PRIVATE))
+#define PubChannel(x) ((!x) || ((x)->mode.mode &\
+ (MODE_PRIVATE | MODE_SECRET)) == 0)
+
+/* channel visible */
+#define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c)))
+
+#define IsMember(who, chan) ((who && who->user && \
+ find_channel_membership(chan, who)) ? 1 : 0)
+
+#define IsChannelName(name) ((name) && (*(name) == '#' || *(name) == '&'))
+
+/* extban function results */
+#define EXTBAN_INVALID -1 /* invalid mask, false even if negated */
+#define EXTBAN_NOMATCH 0 /* valid mask, no match */
+#define EXTBAN_MATCH 1 /* matches */
+
+extern dlink_list global_channel_list;
+void init_channels(void);
+
+struct Channel *allocate_channel(const char *chname);
+void free_channel(struct Channel *chptr);
+struct Ban *allocate_ban(const char *, const char *);
+void free_ban(struct Ban *bptr);
+
+
+extern void destroy_channel(struct Channel *);
+
+extern int can_send(struct Channel *chptr, struct Client *who,
+ struct membership *);
+extern int is_banned(struct Channel *chptr, struct Client *who,
+ struct membership *msptr, const char *, const char *);
+extern int is_quieted(struct Channel *chptr, struct Client *who,
+ struct membership *msptr, const char *, const char *);
+extern int can_join(struct Client *source_p, struct Channel *chptr, char *key);
+
+extern struct membership *find_channel_membership(struct Channel *, struct Client *);
+extern const char *find_channel_status(struct membership *msptr, int combine);
+extern void add_user_to_channel(struct Channel *, struct Client *, int flags);
+extern void remove_user_from_channel(struct membership *);
+extern void remove_user_from_channels(struct Client *);
+extern void invalidate_bancache_user(struct Client *);
+
+extern void free_channel_list(dlink_list *);
+
+extern int check_channel_name(const char *name);
+
+extern void channel_member_names(struct Channel *chptr, struct Client *,
+ int show_eon);
+
+extern void del_invite(struct Channel *chptr, struct Client *who);
+
+const char *channel_modes(struct Channel *chptr, struct Client *who);
+
+extern struct Channel *find_bannickchange_channel(struct Client *client_p);
+
+extern void check_spambot_warning(struct Client *source_p, const char *name);
+
+extern void check_splitmode(void *);
+
+void set_channel_topic(struct Channel *chptr, const char *topic,
+ const char *topic_info, time_t topicts);
+
+extern void init_chcap_usage_counts(void);
+extern void set_chcap_usage_counts(struct Client *serv_p);
+extern void unset_chcap_usage_counts(struct Client *serv_p);
+extern void send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, struct ChModeChange foo[], int);
+
+extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
+
+extern struct ChannelMode chmode_table[256];
+
+extern int add_id(struct Client *source_p, struct Channel *chptr, const char *banid,
+ dlink_list * list, long mode_type);
+
+extern int del_id(struct Channel *chptr, const char *banid, dlink_list * list, long mode_type);
+
+extern ExtbanFunc extban_table[256];
+
+extern int match_extban(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type);
+extern int valid_extban(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type);
+const char * get_extban_string(void);
+
+
+#endif /* INCLUDED_channel_h */
--- /dev/null
+/*
+ * charybdis: a useful ircd.
+ * charybdis.h: primary include file
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2005 Hybrid Development Team
+ * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
+ *
+ * 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
+ *
+ * $Id: charybdis.h 238 2005-09-21 05:26:03Z nenolod $
+ */
+
+#ifndef CHARYBDIS_H
+#define CHARYBDIS_H
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * class.h: The ircd class management header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: class.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_class_h
+#define INCLUDED_class_h
+
+#include "tools.h"
+
+struct ConfItem;
+struct Client;
+struct _patricia_tree_t;
+
+struct Class
+{
+ struct Class *next;
+ char *class_name;
+ int max_total;
+ int max_local;
+ int max_global;
+ int max_ident;
+ int max_sendq;
+ int con_freq;
+ int ping_freq;
+ int total;
+ struct _patricia_tree_t *ip_limits;
+ int cidr_bitlen;
+ int cidr_amount;
+
+};
+
+extern dlink_list class_list;
+extern struct Class *default_class;
+
+#define ClassName(x) ((x)->class_name)
+#define ConFreq(x) ((x)->con_freq)
+#define MaxLocal(x) ((x)->max_local)
+#define MaxGlobal(x) ((x)->max_global)
+#define MaxIdent(x) ((x)->max_ident)
+#define MaxUsers(x) ((x)->max_total)
+#define PingFreq(x) ((x)->ping_freq)
+#define MaxSendq(x) ((x)->max_sendq)
+#define CurrUsers(x) ((x)->total)
+#define IpLimits(x) ((x)->ip_limits)
+#define CidrBitlen(x) ((x)->cidr_bitlen)
+#define CidrAmount(x) ((x)->cidr_amount)
+#define ClassPtr(x) ((x)->c_class)
+
+#define ConfClassName(x) (ClassPtr(x)->class_name)
+#define ConfConFreq(x) (ClassPtr(x)->con_freq)
+#define ConfMaxLocal(x) (ClassPtr(x)->max_local)
+#define ConfMaxGlobal(x) (ClassPtr(x)->max_global)
+#define ConfMaxIdent(x) (ClassPtr(x)->max_ident)
+#define ConfMaxUsers(x) (ClassPtr(x)->max_total)
+#define ConfPingFreq(x) (ClassPtr(x)->ping_freq)
+#define ConfMaxSendq(x) (ClassPtr(x)->max_sendq)
+#define ConfCurrUsers(x) (ClassPtr(x)->total)
+#define ConfIpLimits(x) (ClassPtr(x)->ip_limits)
+#define ConfCidrAmount(x) (ClassPtr(x)->cidr_amount)
+#define ConfCidrBitlen(x) (ClassPtr(x)->cidr_bitlen)
+
+void add_class(struct Class *);
+
+struct Class *make_class(void);
+
+extern long get_sendq(struct Client *);
+extern int get_con_freq(struct Class *);
+extern struct Class *find_class(const char *);
+extern const char *get_client_class(struct Client *);
+extern int get_client_ping(struct Client *);
+extern void check_class(void);
+extern void initclass(void);
+extern void free_class(struct Class *);
+extern void fix_class(struct ConfItem *, struct ConfItem *);
+extern void report_classes(struct Client *);
+
+#endif /* INCLUDED_class_h */
--- /dev/null
+/*
+ * charybdis: A useful ircd.
+ * client.h: The ircd client header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
+ *
+ * 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
+ *
+ * $Id: client.h 2023 2006-09-02 23:47:27Z jilles $
+ */
+
+#ifndef INCLUDED_client_h
+#define INCLUDED_client_h
+
+#include "config.h"
+
+#if !defined(CONFIG_RATBOX_LEVEL_1)
+#error Incorrect config.h for this revision of ircd.
+#endif
+
+#include "ircd_defs.h"
+#include "linebuf.h"
+#include "channel.h"
+#include "res.h"
+#include "snomask.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "commio.h"
+
+/* other structs */
+struct Blacklist;
+
+/* we store ipv6 ips for remote clients, so this needs to be v6 always */
+#define HOSTIPLEN 53 /* sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.ipv6") */
+#define PASSWDLEN 128
+#define CIPHERKEYLEN 64 /* 512bit */
+#define CLIENT_BUFSIZE 512 /* must be at least 512 bytes */
+
+#define IDLEN 10
+
+/*
+ * pre declare structs
+ */
+struct ConfItem;
+struct Whowas;
+struct DNSReply;
+struct Listener;
+struct Client;
+struct User;
+struct Server;
+struct LocalUser;
+struct AuthRequest;
+struct PreClient;
+struct ListClient;
+
+/*
+ * Atheme's coding standards require that we use BSD-style user-defined types
+ * for stuff. Fun! --nenolod
+ */
+typedef struct User user_t;
+typedef struct Server server_t;
+typedef struct Client client_t;
+typedef struct LocalUser local_user_t;
+typedef struct Listener listener_t;
+typedef struct DNSReply dns_reply_t;
+typedef struct Whowas whowas_entry_t;
+typedef struct ConfItem conf_item_t;
+typedef struct AuthRequest auth_request_t;
+typedef struct PreClient pre_client_t;
+typedef struct ListClient list_client_t;
+
+/*
+ * Client structures
+ */
+struct User
+{
+ dlink_list channel; /* chain of channel pointer blocks */
+ dlink_list invited; /* chain of invite pointer blocks */
+ char *away; /* pointer to away message */
+ int refcnt; /* Number of times this block is referenced */
+ const char *server; /* pointer to scached server name */
+
+ char suser[NICKLEN+1];
+};
+
+struct Server
+{
+ user_t *user; /* who activated this connection */
+ const char *up; /* Pointer to scache name */
+ const char *upid;
+ char by[NICKLEN];
+ dlink_list servers;
+ dlink_list users;
+ int caps; /* capabilities bit-field */
+ char *fullcaps;
+};
+
+struct SlinkRpl
+{
+ int command;
+ int datalen;
+ int gotdatalen;
+ int readdata;
+ unsigned char *data;
+};
+
+struct ZipStats
+{
+ unsigned long in;
+ unsigned long in_wire;
+ unsigned long out;
+ unsigned long out_wire;
+ unsigned long inK;
+ unsigned long inK_wire;
+ unsigned long outK;
+ unsigned long outK_wire;
+ double in_ratio;
+ double out_ratio;
+};
+
+struct Client
+{
+ dlink_node node;
+ dlink_node lnode;
+ user_t *user; /* ...defined, if this is a User */
+ server_t *serv; /* ...defined, if this is a server */
+ client_t *servptr; /* Points to server this Client is on */
+ client_t *from; /* == self, if Local Client, *NEVER* NULL! */
+
+ whowas_entry_t *whowas; /* Pointers to whowas structs */
+ time_t tsinfo; /* TS on the nick, SVINFO on server */
+ unsigned int umodes; /* opers, normal users subset */
+ unsigned int flags; /* client flags */
+ unsigned int flags2; /* ugh. overflow */
+
+ unsigned int snomask; /* server notice mask */
+
+ int hopcount; /* number of servers to this 0 = local */
+ unsigned short status; /* Client type */
+ unsigned char handler; /* Handler index */
+ unsigned long serial; /* used to enforce 1 send per nick */
+
+ /* client->name is the unique name for a client nick or host */
+ char name[HOSTLEN + 1];
+
+ /*
+ * client->username is the username from ident or the USER message,
+ * If the client is idented the USER message is ignored, otherwise
+ * the username part of the USER message is put here prefixed with a
+ * tilde depending on the I:line, Once a client has registered, this
+ * field should be considered read-only.
+ */
+ char username[USERLEN + 1]; /* client's username */
+
+ /*
+ * client->host contains the resolved name or ip address
+ * as a string for the user, it may be fiddled with for oper spoofing etc.
+ */
+ char host[HOSTLEN + 1]; /* client's hostname */
+ char orighost[HOSTLEN + 1]; /* original hostname (before dynamic spoofing) */
+ char sockhost[HOSTIPLEN + 1]; /* clients ip */
+ char info[REALLEN + 1]; /* Free form additional client info */
+
+ char id[IDLEN]; /* UID/SID, unique on the network */
+
+ /* list of who has this client on their allow list, its counterpart
+ * is in LocalUser
+ */
+ dlink_list on_allow_list;
+
+ local_user_t *localClient;
+ pre_client_t *preClient;
+};
+
+struct LocalUser
+{
+ dlink_node tnode; /* This is the node for the local list type the client is on*/
+ /*
+ * The following fields are allocated only for local clients
+ * (directly connected to *this* server with a socket.
+ */
+ /* Anti flooding part, all because of lamers... */
+ time_t last_join_time; /* when this client last
+ joined a channel */
+ time_t last_leave_time; /* when this client last
+ * left a channel */
+ int join_leave_count; /* count of JOIN/LEAVE in less than
+ MIN_JOIN_LEAVE_TIME seconds */
+ int oper_warn_count_down; /* warn opers of this possible
+ spambot every time this gets to 0 */
+ time_t last_caller_id_time;
+ time_t first_received_message_time;
+ int received_number_of_privmsgs;
+ int flood_noticed;
+
+ time_t lasttime; /* last time we parsed something */
+ time_t firsttime; /* time client was created */
+
+ /* Send and receive linebuf queues .. */
+ buf_head_t buf_sendq;
+ buf_head_t buf_recvq;
+ /*
+ * we want to use unsigned int here so the sizes have a better chance of
+ * staying the same on 64 bit machines. The current trend is to use
+ * I32LP64, (32 bit ints, 64 bit longs and pointers) and since ircd
+ * will NEVER run on an operating system where ints are less than 32 bits,
+ * it's a relatively safe bet to use ints. Since right shift operations are
+ * performed on these, it's not safe to allow them to become negative,
+ * which is possible for long running server connections. Unsigned values
+ * generally overflow gracefully. --Bleep
+ */
+ unsigned int sendM; /* Statistics: protocol messages send */
+ unsigned int sendK; /* Statistics: total k-bytes send */
+ unsigned int receiveM; /* Statistics: protocol messages received */
+ unsigned int receiveK; /* Statistics: total k-bytes received */
+ unsigned short sendB; /* counters to count upto 1-k lots of bytes */
+ unsigned short receiveB; /* sent and received. */
+ listener_t *listener; /* listener accepted from */
+ conf_item_t *att_conf; /* attached conf */
+ struct server_conf *att_sconf;
+
+ struct irc_sockaddr_storage ip;
+ time_t last_nick_change;
+ int number_of_nick_changes;
+
+ /*
+ * XXX - there is no reason to save this, it should be checked when it's
+ * received and not stored, this is not used after registration
+ *
+ * agreed. lets get rid of it someday! --nenolod
+ */
+ char *passwd;
+ char *opername; /* name of operator{} block being used or tried (challenge) */
+ char *challenge;
+ char *fullcaps;
+
+ int caps; /* capabilities bit-field */
+ int fd; /* >= 0, for local clients */
+
+ /* time challenge response is valid for */
+ time_t chal_time;
+
+ int ctrlfd; /* For servers:
+ control fd used for sending commands
+ to servlink */
+
+ struct SlinkRpl slinkrpl; /* slink reply being parsed */
+ unsigned char *slinkq; /* sendq for control data */
+ int slinkq_ofs; /* ofset into slinkq */
+ int slinkq_len; /* length remaining after slinkq_ofs */
+
+ struct ZipStats zipstats;
+
+ time_t last_away; /* Away since... */
+ time_t last;
+
+ /* clients allowed to talk through +g */
+ dlink_list allow_list;
+
+ /* nicknames theyre monitoring */
+ dlink_list monitor_list;
+
+ /*
+ * Anti-flood stuff. We track how many messages were parsed and how
+ * many we were allowed in the current second, and apply a simple decay
+ * to avoid flooding.
+ * -- adrian
+ */
+ int allow_read; /* how many we're allowed to read in this second */
+ int actually_read; /* how many we've actually read in this second */
+ int sent_parsed; /* how many messages we've parsed in this second */
+ time_t last_knock; /* time of last knock */
+ unsigned long random_ping;
+ auth_request_t *auth_request;
+
+ /* target change stuff */
+ void *targets[10]; /* targets were aware of */
+ unsigned int targinfo[2]; /* cyclic array, no in use */
+ time_t target_last; /* last time we cleared a slot */
+
+ list_client_t *safelist_data;
+
+ char *mangledhost; /* non-NULL if host mangling module loaded and
+ applicable to this client */
+};
+
+struct PreClient
+{
+ char spoofnick[NICKLEN + 1];
+ char spoofuser[USERLEN + 1];
+ char spoofhost[HOSTLEN + 1];
+
+ char sasl_agent[IDLEN];
+ unsigned char sasl_out;
+ unsigned char sasl_complete;
+
+ dlink_list dnsbl_queries; /* list of struct BlacklistClient * */
+ struct Blacklist *dnsbl_listed; /* first dnsbl where it's listed */
+};
+
+struct ListClient
+{
+ unsigned int hash_indice;
+ unsigned int users_min, users_max;
+
+ /* It would be nice to add other modifiers,
+ * but not for 1.1 --nenolod
+ */
+};
+
+struct exit_client_hook
+{
+ struct Client *client_p;
+ char exit_message[TOPICLEN];
+};
+
+/*
+ * status macros.
+ */
+#define STAT_CONNECTING 0x01
+#define STAT_HANDSHAKE 0x02
+#define STAT_ME 0x04
+#define STAT_UNKNOWN 0x08
+#define STAT_REJECT 0x10
+#define STAT_SERVER 0x20
+#define STAT_CLIENT 0x40
+
+
+#define IsRegisteredUser(x) ((x)->status == STAT_CLIENT)
+#define IsRegistered(x) (((x)->status > STAT_UNKNOWN) && ((x)->status != STAT_REJECT))
+#define IsConnecting(x) ((x)->status == STAT_CONNECTING)
+#define IsHandshake(x) ((x)->status == STAT_HANDSHAKE)
+#define IsMe(x) ((x)->status == STAT_ME)
+#define IsUnknown(x) ((x)->status == STAT_UNKNOWN)
+#define IsServer(x) ((x)->status == STAT_SERVER)
+#define IsClient(x) ((x)->status == STAT_CLIENT)
+#define IsReject(x) ((x)->status == STAT_REJECT)
+
+#define IsAnyServer(x) (IsServer(x) || IsHandshake(x) || IsConnecting(x))
+
+#define IsOper(x) ((x)->umodes & UMODE_OPER)
+#define IsAdmin(x) ((x)->umodes & UMODE_ADMIN)
+
+#define SetReject(x) {(x)->status = STAT_REJECT; \
+ (x)->handler = UNREGISTERED_HANDLER; }
+
+#define SetConnecting(x) {(x)->status = STAT_CONNECTING; \
+ (x)->handler = UNREGISTERED_HANDLER; }
+
+#define SetHandshake(x) {(x)->status = STAT_HANDSHAKE; \
+ (x)->handler = UNREGISTERED_HANDLER; }
+
+#define SetMe(x) {(x)->status = STAT_ME; \
+ (x)->handler = UNREGISTERED_HANDLER; }
+
+#define SetUnknown(x) {(x)->status = STAT_UNKNOWN; \
+ (x)->handler = UNREGISTERED_HANDLER; }
+
+#define SetServer(x) {(x)->status = STAT_SERVER; \
+ (x)->handler = SERVER_HANDLER; }
+
+#define SetClient(x) {(x)->status = STAT_CLIENT; \
+ (x)->handler = IsOper((x)) ? \
+ OPER_HANDLER : CLIENT_HANDLER; }
+#define SetRemoteClient(x) {(x)->status = STAT_CLIENT; \
+ (x)->handler = RCLIENT_HANDLER; }
+
+#define STAT_CLIENT_PARSE (STAT_UNKNOWN | STAT_CLIENT)
+#define STAT_SERVER_PARSE (STAT_CONNECTING | STAT_HANDSHAKE | STAT_SERVER)
+
+#define PARSE_AS_CLIENT(x) ((x)->status & STAT_CLIENT_PARSE)
+#define PARSE_AS_SERVER(x) ((x)->status & STAT_SERVER_PARSE)
+
+
+/*
+ * ts stuff
+ */
+#define TS_CURRENT 6
+
+#ifdef TS6_ONLY
+#define TS_MIN 6
+#else
+#define TS_MIN 3
+#endif
+
+#define TS_DOESTS 0x10000000
+#define DoesTS(x) ((x)->tsinfo & TS_DOESTS)
+
+#define has_id(source) ((source)->id[0] != '\0')
+#define use_id(source) ((source)->id[0] != '\0' ? (source)->id : (source)->name)
+
+/* if target is TS6, use id if it has one, else name */
+#define get_id(source, target) ((IsServer(target->from) && has_id(target->from)) ? \
+ use_id(source) : (source)->name)
+
+/* housekeeping flags */
+
+#define FLAGS_PINGSENT 0x0001 /* Unreplied ping sent */
+#define FLAGS_DEAD 0x0002 /* Local socket is dead--Exiting soon */
+#define FLAGS_KILLED 0x0004 /* Prevents "QUIT" from being sent for this */
+#define FLAGS_SENTUSER 0x0008 /* Client sent a USER command. */
+#define FLAGS_CLOSING 0x0020 /* set when closing to suppress errors */
+#define FLAGS_CHKACCESS 0x0040 /* ok to check clients access if set */
+#define FLAGS_GOTID 0x0080 /* successful ident lookup achieved */
+#define FLAGS_NEEDID 0x0100 /* I-lines say must use ident return */
+#define FLAGS_NORMALEX 0x0400 /* Client exited normally */
+#define FLAGS_SENDQEX 0x0800 /* Sendq exceeded */
+#define FLAGS_SERVLINK 0x10000 /* servlink has servlink process */
+#define FLAGS_MARK 0x20000 /* marked client */
+#define FLAGS_HIDDEN 0x40000 /* hidden server */
+#define FLAGS_EOB 0x80000 /* EOB */
+#define FLAGS_MYCONNECT 0x100000 /* MyConnect */
+#define FLAGS_IOERROR 0x200000 /* IO error */
+#define FLAGS_SERVICE 0x400000 /* network service */
+#define FLAGS_TGCHANGE 0x800000 /* we're allowed to clear something */
+#define FLAGS_DYNSPOOF 0x1000000 /* dynamic spoof, only opers see ip */
+
+/* umodes, settable flags */
+/* lots of this moved to snomask -- jilles */
+#define UMODE_SERVNOTICE 0x0001 /* server notices */
+#define UMODE_WALLOP 0x0100 /* send wallops to them */
+#define UMODE_OPERWALL 0x0200 /* Operwalls */
+#define UMODE_INVISIBLE 0x0400 /* makes user invisible */
+#define UMODE_CALLERID 0x2000 /* block unless caller id's */
+#define UMODE_LOCOPS 0x8000 /* show locops */
+#define UMODE_SERVICE 0x40000
+#define UMODE_DEAF 0x80000
+#define UMODE_NOFORWARD 0x400000 /* don't forward */
+#define UMODE_REGONLYMSG 0x800000 /* only allow logged in users to msg */
+
+/* user information flags, only settable by remote mode or local oper */
+#define UMODE_OPER 0x100000 /* Operator */
+#define UMODE_ADMIN 0x200000 /* Admin on server */
+
+#define UMODE_ALL UMODE_SERVNOTICE
+
+/* overflow flags */
+/* EARLIER FLAGS ARE IN s_newconf.h */
+#define FLAGS2_EXEMPTRESV 0x0080000
+#define FLAGS2_EXEMPTGLINE 0x0100000
+#define FLAGS2_EXEMPTKLINE 0x0200000
+#define FLAGS2_EXEMPTFLOOD 0x0400000
+#define FLAGS2_NOLIMIT 0x0800000
+#define FLAGS2_IDLE_LINED 0x1000000
+#define FLAGS2_CLICAP 0x2000000
+#define FLAGS2_PING_COOKIE 0x4000000
+#define FLAGS2_IP_SPOOFING 0x8000000
+#define FLAGS2_FLOODDONE 0x10000000
+#define FLAGS2_EXEMPTSPAMBOT 0x20000000
+#define FLAGS2_EXEMPTSHIDE 0x40000000
+#define FLAGS2_EXEMPTJUPE 0x80000000
+
+#define DEFAULT_OPER_UMODES (UMODE_SERVNOTICE | UMODE_OPERWALL | \
+ UMODE_WALLOP | UMODE_LOCOPS)
+#define DEFAULT_OPER_SNOMASK SNO_GENERAL
+
+#define FLAGS_ID (FLAGS_NEEDID | FLAGS_GOTID)
+
+#define CLICAP_MULTI_PREFIX 0x0001
+#define CLICAP_SASL 0x0002
+
+/*
+ * flags macros.
+ */
+#define IsPerson(x) (IsClient(x) && (x)->user != NULL)
+#define DoAccess(x) ((x)->flags & FLAGS_CHKACCESS)
+#define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS)
+#define ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS)
+#define HasServlink(x) ((x)->flags & FLAGS_SERVLINK)
+#define SetServlink(x) ((x)->flags |= FLAGS_SERVLINK)
+#define MyConnect(x) ((x)->flags & FLAGS_MYCONNECT)
+#define SetMyConnect(x) ((x)->flags |= FLAGS_MYCONNECT)
+#define ClearMyConnect(x) ((x)->flags &= ~FLAGS_MYCONNECT)
+
+#define MyClient(x) (MyConnect(x) && IsClient(x))
+#define SetMark(x) ((x)->flags |= FLAGS_MARK)
+#define ClearMark(x) ((x)->flags &= ~FLAGS_MARK)
+#define IsMarked(x) ((x)->flags & FLAGS_MARK)
+#define SetHidden(x) ((x)->flags |= FLAGS_HIDDEN)
+#define ClearHidden(x) ((x)->flags &= ~FLAGS_HIDDEN)
+#define IsHidden(x) ((x)->flags & FLAGS_HIDDEN)
+#define ClearEob(x) ((x)->flags &= ~FLAGS_EOB)
+#define SetEob(x) ((x)->flags |= FLAGS_EOB)
+#define HasSentEob(x) ((x)->flags & FLAGS_EOB)
+#define IsDead(x) ((x)->flags & FLAGS_DEAD)
+#define SetDead(x) ((x)->flags |= FLAGS_DEAD)
+#define IsClosing(x) ((x)->flags & FLAGS_CLOSING)
+#define SetClosing(x) ((x)->flags |= FLAGS_CLOSING)
+#define IsIOError(x) ((x)->flags & FLAGS_IOERROR)
+#define SetIOError(x) ((x)->flags |= FLAGS_IOERROR)
+#define IsAnyDead(x) (IsIOError(x) || IsDead(x) || IsClosing(x))
+#define IsTGChange(x) ((x)->flags & FLAGS_TGCHANGE)
+#define SetTGChange(x) ((x)->flags |= FLAGS_TGCHANGE)
+#define ClearTGChange(x) ((x)->flags &= ~FLAGS_TGCHANGE)
+#define IsDynSpoof(x) ((x)->flags & FLAGS_DYNSPOOF)
+#define SetDynSpoof(x) ((x)->flags |= FLAGS_DYNSPOOF)
+#define ClearDynSpoof(x) ((x)->flags &= ~FLAGS_DYNSPOOF)
+
+/* oper flags */
+#define MyOper(x) (MyConnect(x) && IsOper(x))
+
+#define SetOper(x) {(x)->umodes |= UMODE_OPER; \
+ if (MyClient((x))) (x)->handler = OPER_HANDLER;}
+
+#define ClearOper(x) {(x)->umodes &= ~(UMODE_OPER|UMODE_ADMIN); \
+ if (MyClient((x)) && !IsOper((x)) && !IsServer((x))) \
+ (x)->handler = CLIENT_HANDLER; }
+
+#define IsPrivileged(x) (IsOper(x) || IsServer(x))
+
+/* umode flags */
+#define IsInvisible(x) ((x)->umodes & UMODE_INVISIBLE)
+#define SetInvisible(x) ((x)->umodes |= UMODE_INVISIBLE)
+#define ClearInvisible(x) ((x)->umodes &= ~UMODE_INVISIBLE)
+#define SendWallops(x) ((x)->umodes & UMODE_WALLOP)
+#define ClearWallops(x) ((x)->umodes &= ~UMODE_WALLOP)
+#define SendLocops(x) ((x)->umodes & UMODE_LOCOPS)
+#define SendServNotice(x) ((x)->umodes & UMODE_SERVNOTICE)
+#define SendOperwall(x) ((x)->umodes & UMODE_OPERWALL)
+#define SetWallops(x) ((x)->umodes |= UMODE_WALLOP)
+#define SetCallerId(x) ((x)->umodes |= UMODE_CALLERID)
+#define IsSetCallerId(x) ((x)->umodes & UMODE_CALLERID)
+#define IsService(x) ((x)->umodes & UMODE_SERVICE)
+#define IsDeaf(x) ((x)->umodes & UMODE_DEAF)
+#define IsNoForward(x) ((x)->umodes & UMODE_NOFORWARD)
+#define IsSetRegOnlyMsg(x) ((x)->umodes & UMODE_REGONLYMSG)
+
+#define SetNeedId(x) ((x)->flags |= FLAGS_NEEDID)
+#define IsNeedId(x) (((x)->flags & FLAGS_NEEDID) != 0)
+
+#define SetGotId(x) ((x)->flags |= FLAGS_GOTID)
+#define IsGotId(x) (((x)->flags & FLAGS_GOTID) != 0)
+
+/*
+ * flags2 macros.
+ */
+#define IsExemptKline(x) ((x)->flags2 & FLAGS2_EXEMPTKLINE)
+#define SetExemptKline(x) ((x)->flags2 |= FLAGS2_EXEMPTKLINE)
+#define IsExemptLimits(x) ((x)->flags2 & FLAGS2_NOLIMIT)
+#define SetExemptLimits(x) ((x)->flags2 |= FLAGS2_NOLIMIT)
+#define IsExemptGline(x) ((x)->flags2 & FLAGS2_EXEMPTGLINE)
+#define SetExemptGline(x) ((x)->flags2 |= FLAGS2_EXEMPTGLINE)
+#define IsExemptFlood(x) ((x)->flags2 & FLAGS2_EXEMPTFLOOD)
+#define SetExemptFlood(x) ((x)->flags2 |= FLAGS2_EXEMPTFLOOD)
+#define IsExemptSpambot(x) ((x)->flags2 & FLAGS2_EXEMPTSPAMBOT)
+#define SetExemptSpambot(x) ((x)->flags2 |= FLAGS2_EXEMPTSPAMBOT)
+#define IsExemptShide(x) ((x)->flags2 & FLAGS2_EXEMPTSHIDE)
+#define SetExemptShide(x) ((x)->flags2 |= FLAGS2_EXEMPTSHIDE)
+#define IsExemptJupe(x) ((x)->flags2 & FLAGS2_EXEMPTJUPE)
+#define SetExemptJupe(x) ((x)->flags2 |= FLAGS2_EXEMPTJUPE)
+#define IsExemptResv(x) ((x)->flags2 & FLAGS2_EXEMPTRESV)
+#define SetExemptResv(x) ((x)->flags2 |= FLAGS2_EXEMPTRESV)
+#define IsIPSpoof(x) ((x)->flags2 & FLAGS2_IP_SPOOFING)
+#define SetIPSpoof(x) ((x)->flags2 |= FLAGS2_IP_SPOOFING)
+
+#define SetIdlelined(x) ((x)->flags2 |= FLAGS2_IDLE_LINED)
+#define IsIdlelined(x) ((x)->flags2 & FLAGS2_IDLE_LINED)
+
+/* for local users: flood grace period is over
+ * for servers: mentioned in networknotice.c notice
+ */
+#define IsFloodDone(x) ((x)->flags2 & FLAGS2_FLOODDONE)
+#define SetFloodDone(x) ((x)->flags2 |= FLAGS2_FLOODDONE)
+
+/*
+ * definitions for get_client_name
+ */
+#define HIDE_IP 0
+#define SHOW_IP 1
+#define MASK_IP 2
+
+extern void check_banned_lines(void);
+extern void check_klines_event(void *unused);
+extern void check_klines(void);
+extern void check_glines(void);
+extern void check_dlines(void);
+extern void check_xlines(void);
+
+extern const char *get_client_name(struct Client *client, int show_ip);
+extern const char *get_server_name(struct Client *client, int show_ip);
+extern const char *log_client_name(struct Client *, int);
+extern int is_remote_connect(struct Client *);
+extern void init_client(void);
+extern client_t *make_client(struct Client *from);
+extern void free_pre_client(struct Client *client);
+extern void free_client(struct Client *client);
+
+extern int exit_client(struct Client *, struct Client *, struct Client *, const char *);
+
+extern void error_exit_client(struct Client *, int);
+
+
+
+extern void count_local_client_memory(size_t * count, size_t * memory);
+extern void count_remote_client_memory(size_t * count, size_t * memory);
+
+extern client_t *find_chasing(struct Client *, const char *, int *);
+extern client_t *find_person(const char *);
+extern client_t *find_named_person(const char *);
+extern client_t *next_client(struct Client *, const char *);
+
+#define accept_message(s, t) ((s) == (t) || (dlinkFind((s), &((t)->localClient->allow_list))))
+extern void del_all_accepts(struct Client *client_p);
+
+extern void dead_link(struct Client *client_p);
+extern int show_ip(struct Client *source_p, struct Client *target_p);
+extern int show_ip_conf(struct ConfItem *aconf, struct Client *target_p);
+
+extern void initUser(void);
+extern void free_user(struct User *, struct Client *);
+extern user_t *make_user(struct Client *);
+extern server_t *make_server(struct Client *);
+extern void close_connection(struct Client *);
+extern void init_uid(void);
+extern char *generate_uid(void);
+
+#endif /* INCLUDED_client_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * common.h: An ircd header common to most code.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: common.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_common_h
+#define INCLUDED_common_h
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#define FALSE 0
+#define TRUE 1
+#define HIDEME 2
+
+/* Blah. I use these a lot. -Dianora */
+#ifdef YES
+#undef YES
+#endif
+
+#define YES 1
+
+#ifdef NO
+#undef NO
+#endif
+
+#define NO 0
+
+/* Just blindly define our own MIN/MAX macro */
+
+#define IRCD_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define IRCD_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/* Right out of the RFC */
+#define IRCD_BUFSIZE 512
+
+#endif /* INCLUDED_common_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * config.h: The ircd compile-time-configurable header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: config.h 1701 2006-06-27 16:25:52Z jilles $
+ */
+
+#ifndef INCLUDED_config_h
+#define INCLUDED_config_h
+
+#include "setup.h"
+
+/*
+ * Directory paths and filenames for UNIX systems.
+ * IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
+ * The other defaults should be fine.
+ *
+ * NOTE: CHANGING THESE WILL NOT ALTER THE DIRECTORY THAT FILES WILL
+ * BE INSTALLED TO. IF YOU CHANGE THESE, DO NOT USE MAKE INSTALL,
+ * BUT COPY THE FILES MANUALLY TO WHERE YOU WANT THEM.
+ *
+ * IRCD_PREFIX = prefix for all directories,
+ * DPATH = root directory of installation,
+ * BINPATH = directory for binary files,
+ * ETCPATH = directory for configuration files,
+ * LOGPATH = directory for logfiles,
+ * MODPATH = directory for modules,
+ * AUTOMODPATH = directory for autoloaded modules
+ */
+
+/* dirs */
+#define DPATH IRCD_PREFIX
+#define BINPATH IRCD_PREFIX "/bin/"
+#define LIBPATH IRCD_PREFIX "/lib/"
+#define MODPATH MODULE_DIR
+#define AUTOMODPATH MODULE_DIR "/autoload/"
+#define ETCPATH ETC_DIR
+#define LOGPATH LOG_DIR
+#define UHPATH HELP_DIR "/users"
+#define HPATH HELP_DIR "/opers"
+
+/* files */
+#define SPATH BINPATH "/ircd" /* ircd executable */
+#define LIPATH LIBPATH "/libircd" SHARED_SUFFIX /* ircd library */
+#define SLPATH BINPATH "/servlink" /* servlink executable */
+#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */
+#define KPATH ETCPATH "/kline.conf" /* kline file */
+#define DLPATH ETCPATH "/dline.conf" /* dline file */
+#define XPATH ETCPATH "/xline.conf" /* xline file */
+#define RESVPATH ETCPATH "/resv.conf" /* resv file */
+#define RPATH ETCPATH "/ircd.rsa" /* ircd rsa private keyfile */
+#define MPATH ETCPATH "/ircd.motd" /* MOTD file */
+#define LPATH LOGPATH "/ircd.log" /* ircd logfile */
+#define PPATH ETCPATH "/ircd.pid" /* pid file */
+#define OPATH ETCPATH "/opers.motd" /* oper MOTD file */
+
+/* IGNORE_BOGUS_TS
+ * Ignore bogus timestamps from other servers. Yes this will desync
+ * the network, but it will allow chanops to resync with a valid non TS 0
+ *
+ * This should be enabled network wide, or not at all.
+ */
+#undef IGNORE_BOGUS_TS
+
+/* HIDE_SERVERS_IPS
+ *
+ * If this is undefined, anyone can see a servers ip. If it is defined,
+ * noone can.
+ */
+#define HIDE_SERVERS_IPS
+
+/* TS6_ONLY
+ *
+ * If this is defined only TS6 servers may link to the network. See
+ * doc/TS6.txt for more information. If your network has old servers
+ * (hyb7.0, ircd-ratbox-1.x, +CSr) or hybserv you should NOT define this.
+ */
+#undef TS6_ONLY
+
+/* USE_LOGFILE - log errors and such to LPATH
+ * If you wish to have the server send 'vital' messages about server
+ * to a logfile, define USE_LOGFILE.
+ */
+#define USE_LOGFILE
+
+/* CLIENT_FLOOD - client excess flood threshold(in messages)
+ * The number of messages that we can receive before we disconnect the
+ * remote client...
+ */
+#define CLIENT_FLOOD 20
+
+/* HANGONGOODLINK and HANGONRETRYDELAY
+ * Often net breaks for a short time and it's useful to try to
+ * establishing the same connection again faster than CONNECTFREQUENCY
+ * would allow. But, to keep trying on bad connection, we require
+ * that connection has been open for certain minimum time
+ * (HANGONGOODLINK) and we give the net few seconds to steady
+ * (HANGONRETRYDELAY). This latter has to be long enough that the
+ * other end of the connection has time to notice it broke too.
+ * 1997/09/18 recommended values by ThemBones for modern EFnet
+ */
+#define HANGONRETRYDELAY 60 /* Recommended value: 30-60 seconds */
+#define HANGONGOODLINK 3600 /* Recommended value: 30-60 minutes */
+
+/* KILLCHASETIMELIMIT -
+ * Max time from the nickname change that still causes KILL
+ * automatically to switch for the current nick of that user. (seconds)
+ */
+#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
+
+/* RATBOX_SOMAXCONN
+ * Use SOMAXCONN if OS has it, otherwise use this value for the
+ * listen(); backlog. 5 for AIX/SUNOS, 25 for other OSs.
+ */
+#define RATBOX_SOMAXCONN 25
+
+/* ----------------------------------------------------------------
+ * STOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOP
+ * ----------------------------------------------------------------
+ * The options below this line should NOT be modified.
+ * ----------------------------------------------------------------
+ */
+
+/* MAX_BUFFER
+ * The amount of fds to reserve for clients exempt from limits
+ * and dns lookups.
+ */
+#define MAX_BUFFER 60
+
+/* HARD_FDLIMIT_
+ * The maximum amount of FDs to use. MAX_CLIENTS is set in ./configure.
+ */
+#define HARD_FDLIMIT_ MAX_CLIENTS + MAX_BUFFER + 20
+
+#define CONFIG_RATBOX_LEVEL_2
+
+#include "defaults.h"
+#endif /* INCLUDED_config_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * config.h: The ircd compile-time-configurable header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: config.h.dist 438 2006-01-06 01:00:44Z jilles $
+ */
+
+#ifndef INCLUDED_config_h
+#define INCLUDED_config_h
+
+#include "setup.h"
+
+/*
+ * Directory paths and filenames for UNIX systems.
+ * IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
+ * The other defaults should be fine.
+ *
+ * NOTE: CHANGING THESE WILL NOT ALTER THE DIRECTORY THAT FILES WILL
+ * BE INSTALLED TO. IF YOU CHANGE THESE, DO NOT USE MAKE INSTALL,
+ * BUT COPY THE FILES MANUALLY TO WHERE YOU WANT THEM.
+ *
+ * IRCD_PREFIX = prefix for all directories,
+ * DPATH = root directory of installation,
+ * BINPATH = directory for binary files,
+ * ETCPATH = directory for configuration files,
+ * LOGPATH = directory for logfiles,
+ * MODPATH = directory for modules,
+ * AUTOMODPATH = directory for autoloaded modules
+ */
+
+/* dirs */
+#define DPATH IRCD_PREFIX
+#define BINPATH IRCD_PREFIX "/bin/"
+#define MODPATH IRCD_PREFIX "/modules/"
+#define AUTOMODPATH IRCD_PREFIX "/modules/autoload/"
+#define ETCPATH IRCD_PREFIX "/etc"
+#define LOGPATH IRCD_PREFIX "/logs"
+#define UHPATH IRCD_PREFIX "/help/users"
+#define HPATH IRCD_PREFIX "/help/opers"
+
+/* files */
+#define SPATH BINPATH "/ircd" /* ircd executable */
+#define SLPATH BINPATH "/servlink" /* servlink executable */
+#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */
+#define KPATH ETCPATH "/kline.conf" /* kline file */
+#define DLPATH ETCPATH "/dline.conf" /* dline file */
+#define XPATH ETCPATH "/xline.conf" /* xline file */
+#define RESVPATH ETCPATH "/resv.conf" /* resv file */
+#define RPATH ETCPATH "/ircd.rsa" /* ircd rsa private keyfile */
+#define MPATH ETCPATH "/ircd.motd" /* MOTD file */
+#define LPATH LOGPATH "/ircd.log" /* ircd logfile */
+#define PPATH ETCPATH "/ircd.pid" /* pid file */
+#define OPATH ETCPATH "/opers.motd" /* oper MOTD file */
+
+/* IGNORE_BOGUS_TS
+ * Ignore bogus timestamps from other servers. Yes this will desync
+ * the network, but it will allow chanops to resync with a valid non TS 0
+ *
+ * This should be enabled network wide, or not at all.
+ */
+#undef IGNORE_BOGUS_TS
+
+/* HIDE_SERVERS_IPS
+ *
+ * If this is undefined, opers will be unable to see servers ips and will be
+ * shown a masked ip, admins will be shown the real ip.
+ *
+ * If this is defined, nobody can see a servers ip.
+ */
+#define HIDE_SERVERS_IPS
+
+/* TS6_ONLY
+ *
+ * If this is defined only TS6 servers may link to the network. See
+ * doc/TS6.txt for more information. If your network has old servers
+ * (hyb7.0, ircd-ratbox-1.x, +CSr) or hybserv you should NOT define this.
+ */
+#undef TS6_ONLY
+
+/* USE_LOGFILE - log errors and such to LPATH
+ * If you wish to have the server send 'vital' messages about server
+ * to a logfile, define USE_LOGFILE.
+ */
+#define USE_LOGFILE
+
+/* CLIENT_FLOOD - client excess flood threshold(in messages)
+ * The number of messages that we can receive before we disconnect the
+ * remote client...
+ */
+#define CLIENT_FLOOD 20
+
+/* NICKNAMEHISTORYLENGTH - size of WHOWAS array
+ * this defines the length of the nickname history. each time a user changes
+ * nickname or signs off, their old nickname is added to the top of the list.
+ * NOTE: this is directly related to the amount of memory ircd will use whilst
+ * resident and running - it hardly ever gets swapped to disk! Memory
+ * will be preallocated for the entire whowas array when ircd is started.
+ */
+#ifndef SMALL_NET
+#define NICKNAMEHISTORYLENGTH 15000
+#else
+#define NICKNAMEHISTORYLENGTH 1500
+#endif
+
+/* HANGONGOODLINK and HANGONGOODLINK
+ * Often net breaks for a short time and it's useful to try to
+ * establishing the same connection again faster than CONNECTFREQUENCY
+ * would allow. But, to keep trying on bad connection, we require
+ * that connection has been open for certain minimum time
+ * (HANGONGOODLINK) and we give the net few seconds to steady
+ * (HANGONRETRYDELAY). This latter has to be long enough that the
+ * other end of the connection has time to notice it broke too.
+ * 1997/09/18 recommended values by ThemBones for modern EFnet
+ */
+#define HANGONRETRYDELAY 60 /* Recommended value: 30-60 seconds */
+#define HANGONGOODLINK 3600 /* Recommended value: 30-60 minutes */
+
+/* KILLCHASETIMELIMIT -
+ * Max time from the nickname change that still causes KILL
+ * automatically to switch for the current nick of that user. (seconds)
+ */
+#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
+
+/* RATBOX_SOMAXCONN
+ * Use SOMAXCONN if OS has it, otherwise use this value for the
+ * listen(); backlog. 5 for AIX/SUNOS, 25 for other OSs.
+ */
+#define RATBOX_SOMAXCONN 25
+
+/* ----------------------------------------------------------------
+ * STOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOP
+ * ----------------------------------------------------------------
+ * The options below this line should NOT be modified.
+ * ----------------------------------------------------------------
+ */
+
+/* MAX_BUFFER
+ * The amount of fds to reserve for clients exempt from limits
+ * and dns lookups.
+ */
+#define MAX_BUFFER 60
+
+/* HARD_FDLIMIT_
+ * The maximum amount of FDs to use. MAX_CLIENTS is set in ./configure.
+ */
+#define HARD_FDLIMIT_ MAX_CLIENTS + MAX_BUFFER + 20
+
+#define CONFIG_RATBOX_LEVEL_2
+
+#include "defaults.h"
+#endif /* INCLUDED_config_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * defaults.h: The ircd defaults header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: defaults.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_defaults_h
+#define INCLUDED_defaults_h
+
+/* this file is included (only) at the end of config.h, to supply default
+ * values for things which are now configurable at runtime.
+ */
+
+/*
+ * First, set other fd limits based on values from user
+ */
+#ifndef HARD_FDLIMIT_
+error HARD_FDLIMIT_ undefined
+#endif
+#define HARD_FDLIMIT (HARD_FDLIMIT_ - 10)
+#define MAXCONNECTIONS HARD_FDLIMIT
+#define MASTER_MAX (HARD_FDLIMIT - MAX_BUFFER)
+/* class {} default values */
+#define DEFAULT_SENDQ 20000000 /* default max SendQ */
+#define PORTNUM 6667 /* default outgoing portnum */
+#define DEFAULT_PINGFREQUENCY 120 /* Default ping frequency */
+#define DEFAULT_CONNECTFREQUENCY 600 /* Default connect frequency */
+#define TS_MAX_DELTA_MIN 10 /* min value for ts_max_delta */
+#define TS_MAX_DELTA_DEFAULT 600 /* default for ts_max_delta */
+#define TS_WARN_DELTA_MIN 10 /* min value for ts_warn_delta */
+#define TS_WARN_DELTA_DEFAULT 30 /* default for ts_warn_delta */
+/* ServerInfo default values */
+#define NETWORK_NAME_DEFAULT "EFnet" /* default for network_name */
+#define NETWORK_DESC_DEFAULT "Eris Free Network" /* default for network_desc */
+/* General defaults */
+#define CLIENT_FLOOD_DEFAULT 20 /* default for client_flood */
+#define CLIENT_FLOOD_MAX 2000
+#define CLIENT_FLOOD_MIN 10
+#define LINKS_DELAY_DEFAULT 300
+#define MAX_TARGETS_DEFAULT 4 /* default for max_targets */
+#define IDENT_TIMEOUT 10
+#define MIN_JOIN_LEAVE_TIME 60
+#define MAX_JOIN_LEAVE_COUNT 25
+#define OPER_SPAM_COUNTDOWN 5
+#define JOIN_LEAVE_COUNT_EXPIRE_TIME 120
+#define MIN_SPAM_NUM 5
+#define MIN_SPAM_TIME 60
+#define CONFIG_RATBOX_LEVEL_1
+#endif /* INCLUDED_defaults_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * hash.h: A header for the ircd hashtable code.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: hash.h 722 2006-02-08 21:51:28Z nenolod $
+ */
+
+#ifndef INCLUDED_hash_h
+#define INCLUDED_hash_h
+
+#include "tools.h"
+
+extern dlink_list *clientTable;
+extern dlink_list *channelTable;
+extern dlink_list *idTable;
+extern dlink_list *resvTable;
+extern dlink_list *hostTable;
+extern dlink_list *helpTable;
+extern dlink_list *ndTable;
+
+/* Magic value for FNV hash functions */
+#define FNV1_32_INIT 0x811c9dc5UL
+
+/* Client hash table size, used in hash.c/s_debug.c */
+#define U_MAX_BITS (32-17)
+#define U_MAX 131072 /* 2^17 */
+
+/* Channel hash table size, hash.c/s_debug.c */
+#define CH_MAX_BITS (32-16)
+#define CH_MAX 65536 /* 2^16 */
+
+/* hostname hash table size */
+#define HOST_MAX_BITS (32-17)
+#define HOST_MAX 131072 /* 2^17 */
+
+/* RESV/XLINE hash table size, used in hash.c */
+#define R_MAX_BITS (32-10)
+#define R_MAX 1024 /* 2^10 */
+
+
+#define HASH_WALK(i, max, ptr, table) for (i = 0; i < max; i++) { DLINK_FOREACH(ptr, table[i].head)
+#define HASH_WALK_SAFE(i, max, ptr, nptr, table) for (i = 0; i < max; i++) { DLINK_FOREACH_SAFE(ptr, nptr, table[i].head)
+#define HASH_WALK_END }
+
+struct Client;
+struct Channel;
+struct ConfItem;
+struct cachefile;
+struct nd_entry;
+
+extern u_int32_t fnv_hash_upper(const unsigned char *s, int bits);
+extern u_int32_t fnv_hash(const unsigned char *s, int bits);
+extern u_int32_t fnv_hash_len(const unsigned char *s, int bits, int len);
+extern u_int32_t fnv_hash_upper_len(const unsigned char *s, int bits, int len);
+
+extern void init_hash(void);
+
+extern void add_to_client_hash(const char *name, struct Client *client);
+extern void del_from_client_hash(const char *name, struct Client *client);
+extern struct Client *find_any_client(const char *name);
+extern struct Client *find_client(const char *name);
+extern struct Client *find_named_client(const char *name);
+extern struct Client *find_server(struct Client *source_p, const char *name);
+
+extern void add_to_id_hash(const char *, struct Client *);
+extern void del_from_id_hash(const char *name, struct Client *client);
+extern struct Client *find_id(const char *name);
+
+extern struct Channel *get_or_create_channel(struct Client *client_p, const char *chname, int *isnew);
+extern void del_from_channel_hash(const char *name, struct Channel *chan);
+extern struct Channel *find_channel(const char *name);
+
+extern void add_to_hostname_hash(const char *, struct Client *);
+extern void del_from_hostname_hash(const char *, struct Client *);
+extern dlink_node *find_hostname(const char *);
+
+extern void add_to_resv_hash(const char *name, struct ConfItem *aconf);
+extern void del_from_resv_hash(const char *name, struct ConfItem *aconf);
+extern struct ConfItem *hash_find_resv(const char *name);
+extern void clear_resv_hash(void);
+
+extern void add_to_help_hash(const char *name, struct cachefile *hptr);
+extern void clear_help_hash(void);
+extern struct cachefile *hash_find_help(const char *name, int flags);
+
+extern void add_to_nd_hash(const char *name, struct nd_entry *nd);
+extern struct nd_entry *hash_find_nd(const char *name);
+
+extern void hash_stats(struct Client *);
+
+#endif /* INCLUDED_hash_h */
--- /dev/null
+/*
+ * Copyright (C) 2004-2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2004-2005 ircd-ratbox development team
+ *
+ * $Id: hook.h 906 2006-02-21 02:25:43Z nenolod $
+ */
+#ifndef INCLUDED_HOOK_H
+#define INCLUDED_HOOK_H
+
+typedef struct
+{
+ char *name;
+ dlink_list hooks;
+} hook;
+
+typedef void (*hookfn) (void *data);
+
+int h_iosend_id;
+int h_iorecv_id;
+int h_iorecvctrl_id;
+
+int h_burst_client;
+int h_burst_channel;
+int h_burst_finished;
+int h_server_introduced;
+int h_server_eob;
+int h_client_exit;
+int h_umode_changed;
+int h_new_local_user;
+int h_new_remote_user;
+int h_introduce_client;
+
+void init_hook(void);
+int register_hook(const char *name);
+void add_hook(const char *name, hookfn fn);
+void remove_hook(const char *name, hookfn fn);
+void call_hook(int id, void *arg);
+
+typedef struct
+{
+ struct Client *client;
+ const void *arg1;
+ const void *arg2;
+} hook_data;
+
+typedef struct
+{
+ struct Client *client;
+ const void *arg1;
+ int arg2;
+} hook_data_int;
+
+typedef struct
+{
+ struct Client *client;
+ struct Client *target;
+} hook_data_client;
+
+typedef struct
+{
+ struct Client *client;
+ struct Channel *chptr;
+ int approved;
+} hook_data_channel;
+
+typedef struct
+{
+ struct Client *client;
+ struct Channel *chptr;
+ char *key;
+} hook_data_channel_activity;
+
+typedef struct
+{
+ struct Client *client;
+ int approved;
+} hook_data_client_approval;
+
+typedef struct
+{
+ struct Client *local_link; /* local client originating this, or NULL */
+ struct Client *target; /* dying client */
+ struct Client *from; /* causing client (could be &me or target) */
+ const char *comment;
+} hook_data_client_exit;
+
+typedef struct
+{
+ struct Client *client;
+ unsigned int oldumodes;
+ unsigned int oldsnomask;
+} hook_data_umode_changed;
+
+#endif
--- /dev/null
+/*
+ * charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ * hostmask.h: A header for the hostmask code.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis 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
+ *
+ * $Id: hostmask.h 2757 2006-11-10 22:58:15Z jilles $
+ */
+
+#ifndef INCLUDE_hostmask_h
+#define INCLUDE_hostmask_h 1
+enum
+{
+ HM_HOST,
+ HM_IPV4
+#ifdef IPV6
+ , HM_IPV6
+#endif
+};
+
+int parse_netmask(const char *, struct sockaddr *, int *);
+struct ConfItem *find_conf_by_address(const char *host, const char *sockhost,
+ const char *orighost, struct sockaddr *,
+ int, int, const char *);
+void add_conf_by_address(const char *, int, const char *, struct ConfItem *);
+void delete_one_address_conf(const char *, struct ConfItem *);
+void clear_out_address_conf(void);
+void clear_out_address_conf_bans(void);
+void init_host_hash(void);
+struct ConfItem *find_address_conf(const char *host, const char *sockhost,
+ const char *, const char *, struct sockaddr *,
+ int);
+
+struct ConfItem *find_dline(struct sockaddr *, int);
+
+#define find_kline(x) (find_conf_by_address((x)->host, (x)->sockhost, \
+ (x)->orighost, \
+ (struct sockaddr *)&(x)->localClient->ip, CONF_KILL,\
+ (x)->localClient->ip.ss_family, (x)->username))
+#define find_gline(x) (find_conf_by_address((x)->host, (x)->sockhost, \
+ (x)->orighost, \
+ (struct sockaddr *)&(x)->localClient->ip, CONF_GLINE,\
+ (x)->localClient->ip.ss_family, (x)->username))
+
+void report_Klines(struct Client *);
+void report_auth(struct Client *);
+#ifdef IPV6
+int match_ipv6(struct sockaddr *, struct sockaddr *, int);
+#endif
+int match_ipv4(struct sockaddr *, struct sockaddr *, int);
+
+/* Hashtable stuff... */
+#define ATABLE_SIZE 0x1000 /* 2^12 */
+#define ATABLE_BITS (32-12)
+
+extern struct AddressRec *atable[ATABLE_SIZE];
+
+struct AddressRec
+{
+ /* masktype: HM_HOST, HM_IPV4, HM_IPV6 -A1kmm */
+ int masktype;
+
+ union
+ {
+ struct
+ {
+ /* Pointer into ConfItem... -A1kmm */
+ struct irc_sockaddr_storage addr;
+ int bits;
+ }
+ ipa;
+
+ /* Pointer into ConfItem... -A1kmm */
+ const char *hostname;
+ }
+ Mask;
+
+ /* type: CONF_CLIENT, CONF_DLINE, CONF_KILL etc... -A1kmm */
+ int type;
+
+ /* Higher precedences overrule lower ones... */
+ unsigned long precedence;
+
+ /* Only checked if !(type & 1)... */
+ const char *username;
+ struct ConfItem *aconf;
+
+ /* The next record in this hash bucket. */
+ struct AddressRec *next;
+};
+
+
+#endif /* INCLUDE_hostmask_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * irc_string.h: A header for the ircd string functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: irc_string.h 678 2006-02-03 20:25:01Z jilles $
+ */
+
+#ifndef INCLUDED_irc_string_h
+#define INCLUDED_irc_string_h
+
+#include "setup.h"
+#include "ircd_defs.h"
+
+/*
+ * match - compare name with mask, mask may contain * and ? as wildcards
+ * match - returns 1 on successful match, 0 otherwise
+ *
+ * match_esc - compare with support for escaping chars
+ * match_cidr - compares u!h@addr with u!h@addr/cidr
+ * match_ips - compares addr with addr/cidr in ascii form
+ */
+extern int match(const char *mask, const char *name);
+extern int match_esc(const char *mask, const char *name);
+extern int match_cidr(const char *mask, const char *name);
+extern int match_ips(const char *mask, const char *name);
+
+/*
+ * comp_with_mask - compares to IP address
+ */
+int comp_with_mask(void *addr, void *dest, u_int mask);
+int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask);
+
+/*
+ * collapse - collapse a string in place, converts multiple adjacent *'s
+ * into a single *.
+ * collapse - modifies the contents of pattern
+ *
+ * collapse_esc() - collapse with support for escaping chars
+ */
+extern char *collapse(char *pattern);
+extern char *collapse_esc(char *pattern);
+
+/*
+ * irccmp - case insensitive comparison of s1 and s2
+ */
+extern int irccmp(const char *s1, const char *s2);
+/*
+ * ircncmp - counted case insensitive comparison of s1 and s2
+ */
+extern int ircncmp(const char *s1, const char *s2, int n);
+/*
+** canonize - reduce a string of duplicate list entries to contain
+** only the unique items.
+*/
+#ifdef NO_DUPE_MULTI_MESSAGES
+extern char *canonize(char *);
+#endif
+/*
+ * inetntoa - optimized inet_ntoa
+ */
+const char *inetntoa(const char *in_addr);
+
+/*
+ * inetntop()
+ * inetpton()
+ * portable interfaces for inet_ntop() and inet_pton()
+ */
+const char *inetntop(int af, const void *src, char *dst, unsigned int size);
+int inetpton(int af, const char *src, void *dst);
+const char *inetntop_sock(struct sockaddr *src, char *dst, unsigned int size);
+int inetpton_sock(const char *src, struct sockaddr *dst);
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+#ifdef HAVE_STRDUP
+#define DupString(x,y) do { x = strdup(y); if(x == NULL) outofmemory(); } while(0)
+#else
+#define DupString(x,y) do { x = malloc(strlen(y) + 1); if(x == NULL) outofmemory(); strcpy(x, y); } while(0)
+#endif
+
+#ifdef HAVE_STRNDUP
+#define DupNString(x, y, len) do { x = strndup(y, len); if(x == NULL) outofmemory(); } while (0)
+#else
+#define DupNString(x, y, len) do { x = malloc(len+1); if(x == NULL) outofmemory(); strlcpy(x, y, len+1); } while(0)
+#endif
+
+/*
+ * clean_string - cleanup control and high ascii characters
+ * -Dianora
+ */
+char *clean_string(char *dest, const unsigned char *src, size_t len);
+
+/*
+ * strip_colour - remove colour codes from a string
+ * -asuffield (?)
+ */
+char *strip_colour(char *string);
+
+/*
+ * strip_tabs - convert tabs to spaces
+ * - jdc
+ */
+char *strip_tabs(char *dest, const unsigned char *src, size_t len);
+
+const char *myctime(time_t);
+
+#define EmptyString(x) (!(x) || (*(x) == '\0'))
+#define CheckEmpty(x) EmptyString(x) ? "" : x
+
+char *strtoken(char **save, char *str, const char *fs);
+
+unsigned char *ircd_base64_encode(const unsigned char *str, int length);
+unsigned char *ircd_base64_decode(const unsigned char *str, int length, int *ret);
+
+/*
+ * character macros
+ */
+extern const unsigned char ToLowerTab[];
+#define ToLower(c) (ToLowerTab[(unsigned char)(c)])
+
+extern const unsigned char ToUpperTab[];
+#define ToUpper(c) (ToUpperTab[(unsigned char)(c)])
+
+extern const unsigned int CharAttrs[];
+
+#define PRINT_C 0x001
+#define CNTRL_C 0x002
+#define ALPHA_C 0x004
+#define PUNCT_C 0x008
+#define DIGIT_C 0x010
+#define SPACE_C 0x020
+#define NICK_C 0x040
+#define CHAN_C 0x080
+#define KWILD_C 0x100
+#define CHANPFX_C 0x200
+#define USER_C 0x400
+#define HOST_C 0x800
+#define NONEOS_C 0x1000
+#define SERV_C 0x2000
+#define EOL_C 0x4000
+#define MWILD_C 0x8000
+#define LET_C 0x10000 /* an actual letter */
+#define FCHAN_C 0x20000 /* a 'fake' channel char */
+
+#define IsHostChar(c) (CharAttrs[(unsigned char)(c)] & HOST_C)
+#define IsUserChar(c) (CharAttrs[(unsigned char)(c)] & USER_C)
+#define IsChanPrefix(c) (CharAttrs[(unsigned char)(c)] & CHANPFX_C)
+#define IsChanChar(c) (CharAttrs[(unsigned char)(c)] & CHAN_C)
+#define IsFakeChanChar(c) (CharAttrs[(unsigned char)(c)] & FCHAN_C)
+#define IsKWildChar(c) (CharAttrs[(unsigned char)(c)] & KWILD_C)
+#define IsMWildChar(c) (CharAttrs[(unsigned char)(c)] & MWILD_C)
+#define IsNickChar(c) (CharAttrs[(unsigned char)(c)] & NICK_C)
+#define IsServChar(c) (CharAttrs[(unsigned char)(c)] & (NICK_C | SERV_C))
+#define IsIdChar(c) (CharAttrs[(unsigned char)(c)] & (DIGIT_C | LET_C))
+#define IsLetter(c) (CharAttrs[(unsigned char)(c)] & LET_C)
+#define IsCntrl(c) (CharAttrs[(unsigned char)(c)] & CNTRL_C)
+#define IsAlpha(c) (CharAttrs[(unsigned char)(c)] & ALPHA_C)
+#define IsSpace(c) (CharAttrs[(unsigned char)(c)] & SPACE_C)
+#define IsLower(c) (IsAlpha((c)) && ((unsigned char)(c) > 0x5f))
+#define IsUpper(c) (IsAlpha((c)) && ((unsigned char)(c) < 0x60))
+#define IsDigit(c) (CharAttrs[(unsigned char)(c)] & DIGIT_C)
+#define IsXDigit(c) (IsDigit(c) || ('a' <= (c) && (c) <= 'f') || \
+ ('A' <= (c) && (c) <= 'F'))
+#define IsAlNum(c) (CharAttrs[(unsigned char)(c)] & (DIGIT_C | ALPHA_C))
+#define IsPrint(c) (CharAttrs[(unsigned char)(c)] & PRINT_C)
+#define IsAscii(c) ((unsigned char)(c) < 0x80)
+#define IsGraph(c) (IsPrint((c)) && ((unsigned char)(c) != 0x32))
+#define IsPunct(c) (!(CharAttrs[(unsigned char)(c)] & \
+ (CNTRL_C | ALPHA_C | DIGIT_C)))
+
+#define IsNonEOS(c) (CharAttrs[(unsigned char)(c)] & NONEOS_C)
+#define IsEol(c) (CharAttrs[(unsigned char)(c)] & EOL_C)
+
+#endif /* INCLUDED_irc_string_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * ircd.h: A header for the ircd startup routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: ircd.h 1851 2006-08-24 17:16:53Z jilles $
+ */
+
+#ifndef INCLUDED_ircd_h
+#define INCLUDED_ircd_h
+
+#include "config.h"
+#include "tools.h"
+#include "memory.h"
+
+struct Client;
+struct dlink_list;
+
+struct SetOptions
+{
+ int maxclients; /* max clients allowed */
+ int autoconn; /* autoconn enabled for all servers? */
+
+ int idletime;
+
+ int floodcount; /* Number of messages in 1 second */
+ int ident_timeout; /* timeout for identd lookups */
+
+ int spam_num;
+ int spam_time;
+
+ char operstring[REALLEN];
+ char adminstring[REALLEN];
+};
+
+struct Counter
+{
+ int oper; /* Opers */
+ int total; /* total clients */
+ int invisi; /* invisible clients */
+ int max_loc; /* MAX local clients */
+ int max_tot; /* MAX global clients */
+ unsigned long totalrestartcount; /* Total client count ever */
+};
+
+extern struct SetOptions GlobalSetOptions; /* defined in ircd.c */
+
+extern const char *creation;
+extern const char *generation;
+extern const char *platform;
+extern const char *infotext[];
+extern const char *serno;
+extern const char *ircd_version;
+extern const char *logFileName;
+extern const char *pidFileName;
+extern int cold_start;
+extern int dorehash;
+extern int dorehashbans;
+extern int doremotd;
+extern int kline_queued;
+extern int server_state_foreground;
+extern int opers_see_all_users; /* sno_farconnect.so loaded, operspy without
+ accountability, etc */
+
+extern struct Client me;
+extern dlink_list global_client_list;
+extern struct Client *local[];
+extern struct Counter Count;
+#if 0
+extern time_t CurrentTime;
+#endif
+extern struct timeval SystemTime;
+#define CurrentTime SystemTime.tv_sec
+extern int default_server_capabs;
+
+extern time_t startup_time;
+
+extern int splitmode;
+extern int splitchecking;
+extern int split_users;
+extern int split_servers;
+int eob_count;
+
+extern dlink_list unknown_list;
+extern dlink_list lclient_list;
+extern dlink_list serv_list;
+extern dlink_list global_serv_list;
+extern dlink_list local_oper_list;
+extern dlink_list oper_list;
+extern dlink_list dead_list;
+
+extern void get_current_bandwidth(struct Client *source_p, struct Client *target_p);
+
+extern unsigned long get_maxrss(void);
+extern void set_time(void);
+extern void charybdis_io_loop(void);
+
+extern int testing_conf;
+
+#endif
--- /dev/null
+/*
+ * charybdis: An advanced IRCd.
+ * ircd_defs.h: A header for ircd global definitions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ * Copyright (C) 2005-2006 Charybdis 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
+ *
+ * $Id: ircd_defs.h 865 2006-02-16 14:05:37Z nenolod $
+ */
+
+/*
+ * NOTE: NICKLEN and TOPICLEN do not live here anymore. Set it with configure
+ * Otherwise there are no user servicable part here.
+ *
+ */
+ /* ircd_defs.h - Global size definitions for record entries used
+ * througout ircd. Please think 3 times before adding anything to this
+ * file.
+ */
+#ifndef INCLUDED_ircd_defs_h
+#define INCLUDED_ircd_defs_h
+
+#include "config.h"
+
+/* For those unfamiliar with GNU format attributes, a is the 1 based
+ * argument number of the format string, and b is the 1 based argument
+ * number of the variadic ... */
+#ifdef __GNUC__
+#define AFP(a,b) __attribute__((format (printf, a, b)))
+#else
+#define AFP(a,b)
+#endif
+
+
+#include "s_log.h"
+#include "send.h"
+
+#ifdef SOFT_ASSERT
+#ifdef __GNUC__
+#define s_assert(expr) do \
+ if(!(expr)) { \
+ ilog(L_MAIN, \
+ "file: %s line: %d (%s): Assertion failed: (%s)", \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, \
+ "file: %s line: %d (%s): Assertion failed: (%s)", \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
+ } \
+ while(0)
+#else
+#define s_assert(expr) do \
+ if(!(expr)) { \
+ ilog(L_MAIN, \
+ "file: %s line: %d: Assertion failed: (%s)", \
+ __FILE__, __LINE__, #expr); \
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, \
+ "file: %s line: %d: Assertion failed: (%s)" \
+ __FILE__, __LINE__, #expr); \
+ } \
+ while(0)
+#endif
+#else
+#define s_assert(expr) assert(expr)
+#endif
+
+#if !defined(CONFIG_RATBOX_LEVEL_1)
+# error Incorrect config.h for this revision of ircd.
+#endif
+
+/*
+ * This defines the version of the data structures used in the ircd.
+ * In the event of a mismatch (i.e. this is incremented due to a major
+ * change that cannot be accomidated for in the ircd), then a hard
+ * restart occurs.
+ */
+#define CHARYBDIS_DV 0x00010200 /* 1.2.0 */
+
+#define HOSTLEN 63 /* Length of hostname. Updated to */
+ /* comply with RFC1123 */
+
+#define USERLEN 10
+#define REALLEN 50
+#define CHANNELLEN 200
+#define LOC_CHANNELLEN 50
+
+/* reason length of klines, parts, quits etc */
+#define REASONLEN TOPICLEN /* in charybdis, reasonlen is controlled via topiclen */
+#define AWAYLEN TOPICLEN /* ditto for awaylen */
+#define KILLLEN TOPICLEN /* and killlen. have a nice day. --nenolod */
+
+/* 23+1 for \0 */
+#define KEYLEN 24
+#define BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */
+#define MAXRECIPIENTS 20
+#define MAXBANLENGTH 1024
+#define OPERNICKLEN NICKLEN*2 /* Length of OPERNICKs. */
+
+#define USERHOST_REPLYLEN (NICKLEN+HOSTLEN+USERLEN+5)
+#define MAX_DATE_STRING 32 /* maximum string length for a date string */
+
+#define HELPLEN 400
+
+/*
+ * message return values
+ */
+#define CLIENT_EXITED -2
+#define CLIENT_PARSE_ERROR -1
+#define CLIENT_OK 1
+
+#ifdef IPV6
+#ifndef AF_INET6
+#error "AF_INET6 not defined"
+#endif
+
+
+#else /* #ifdef IPV6 */
+
+#ifndef AF_INET6
+#define AF_INET6 AF_MAX /* Dummy AF_INET6 declaration */
+#endif
+#endif /* #ifdef IPV6 */
+
+
+#ifdef IPV6
+#define irc_sockaddr_storage sockaddr_storage
+#else
+#define irc_sockaddr_storage sockaddr
+#define ss_family sa_family
+#ifdef SOCKADDR_IN_HAS_LEN
+#define ss_len sa_len
+#endif
+#endif
+
+#ifdef IPV6
+#define PATRICIA_BITS 128
+#else
+#define PATRICIA_BITS 32
+#endif
+
+#ifdef SOCKADDR_IN_HAS_LEN
+#define SET_SS_LEN(x, y) (x).ss_len = (y)
+#define GET_SS_LEN(x) x.ss_len
+#else
+#define SET_SS_LEN(x, y)
+#ifdef IPV6
+#define GET_SS_LEN(x) x.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)
+#else
+#define GET_SS_LEN(x) sizeof(struct sockaddr_in)
+#endif
+#endif
+
+
+#endif /* INCLUDED_ircd_defs_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * ircd_getopt.h: A header for the getopt() command line option calls.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: ircd_getopt.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef __GETOPT_H_INCLUDED__
+#define __GETOPT_H_INCLUDED__
+
+struct lgetopt
+{
+ const char *opt; /* name of the argument */
+ void *argloc; /* where we store the argument to it (-option argument) */
+ enum
+ { INTEGER, YESNO, STRING, USAGE, ENDEBUG }
+ argtype;
+ const char *desc; /* description of the argument, usage for printing help */
+};
+
+extern struct lgetopt myopts[];
+
+void usage(char *);
+void parseargs(int *, char ***, struct lgetopt *);
+
+#endif /* __GETOPT_H_INCLUDED__ */
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * ircd_linker.h: IRCd symbol table linking and maintainance
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: ircd_linker.h 863 2006-02-16 06:51:59Z nenolod $
+ */
+
+#ifndef _CHARYBDIS_IRCD_LINKER_H
+#define _CHARYBDIS_IRCD_LINKER_H
+
+#include <dlfcn.h>
+
+struct ircd_symbol
+{
+ char *sym; /* name of symbol to be bound to ptr */
+ void *ptr; /* ptr to symbol in library */
+};
+
+extern void build_symtable(void *, struct ircd_symbol *);
+extern void report_symtable(struct ircd_symbol *);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * ircd_signal.h: A header for ircd signals.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: ircd_signal.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_ircd_signal_h
+#define INCLUDED_ircd_signal_h
+
+extern void setup_signals(void);
+
+#endif /* INCLUDED_ircd_signal_h */
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * ircd_state.h: Functions for backing up and synchronizing IRCd's state
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: main.c 867 2006-02-16 14:25:09Z nenolod $
+ */
+
+#ifndef _IRCD_STATE_H
+#define _IRCD_STATE_H
+
+#include "stdinc.h"
+#include "setup.h"
+#include "config.h"
+#include "ircd_defs.h"
+#include "ircd_linker.h"
+#include "ircd_state.h"
+
+#ifdef NOTYET
+
+/* I haven't designed this structure yet, so this is a placeholder. */
+struct IRCdState {
+ void *moo;
+};
+
+#endif
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * listener.h: A header for the listener code.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: listener.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_listener_h
+#define INCLUDED_listener_h
+
+#include "ircd_defs.h"
+
+struct Client;
+
+struct Listener
+{
+ struct Listener *next; /* list node pointer */
+ const char *name; /* listener name */
+ int fd; /* file descriptor */
+ int ref_count; /* number of connection references */
+ int active; /* current state of listener */
+ int index; /* index into poll array */
+ struct irc_sockaddr_storage addr;
+ struct DNSQuery *dns_query;
+ char vhost[HOSTLEN + 1]; /* virtual name of listener */
+};
+
+extern void add_listener(int port, const char *vaddr_ip, int family);
+extern void close_listener(struct Listener *listener);
+extern void close_listeners(void);
+extern const char *get_listener_name(const struct Listener *listener);
+extern void show_ports(struct Client *client);
+extern void free_listener(struct Listener *);
+
+#endif /* INCLUDED_listener_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_info.h: A header for the information sent by /info
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: m_info.h 70 2005-09-10 07:03:09Z nenolod $
+ */
+
+#ifndef INCLUDED_m_info_h
+#define INCLUDED_m_info_h
+
+#include "config.h"
+
+typedef struct Information
+{
+ const char *name; /* name of item */
+ const char *strvalue; /* value of item if it's a boolean */
+ int intvalue; /* value of item if it's an integer */
+ const char *desc; /* short description of item */
+}
+Info;
+
+Info MyInformation[] = {
+
+#ifdef CPATH
+ {"CPATH", CPATH, 0, "Path to Main Configuration File"},
+#else
+ {"CPATH", "NONE", 0, "Path to Main Configuration File"},
+#endif /* CPATH */
+
+#ifdef DPATH
+ {"DPATH", DPATH, 0, "Directory Containing Configuration Files"},
+#else
+ {"DPATH", "NONE", 0, "Directory Containing Configuration Files"},
+#endif /* DPATH */
+
+#ifdef DLPATH
+ {"DLPATH", DLPATH, 0, "Path to D-line File"},
+#else
+ {"DLPATH", "NONE", 0, "Path to D-line File"},
+#endif /* DLPATH */
+
+#ifdef RESVPATH
+ {"RESVPATH", RESVPATH, 0, "Path to resv file"},
+#else
+ {"RESVPATH", "NONE", 0, "Path to resv file"},
+#endif
+
+ {"HARD_FDLIMIT_", "", HARD_FDLIMIT_,
+ "Maximum Number of File Descriptors Available"},
+
+#ifdef HPATH
+ {"HPATH", HPATH, 0, "Path to Operator Help Files"},
+#else
+ {"HPATH", "NONE", 0, "Path to Operator Help Files"},
+#endif /* HPATH */
+
+#ifdef UHPATH
+ {"UHPATH", UHPATH, 0, "Path to User Help Files"},
+#else
+ {"UHPATH", "NONE", 0, "Path to User Help Files"},
+#endif /* UH PATH */
+
+#ifdef SOMAXCONN
+ {"RATBOX_SOMAXCONN", "", SOMAXCONN,
+ "Maximum Queue Length of Pending Connections"},
+#else
+ {"RATBOX_SOMAXCONN", "", RATBOX_SOMAXCONN,
+ "Maximum Queue Length of Pending Connections"},
+#endif /* SOMAXCONN */
+
+#ifdef IPV6
+ {"IPV6", "ON", 0, "IPv6 Support"},
+#else
+ {"IPV6", "OFF", 0, "IPv6 Support"},
+#endif
+
+ {"MAX_CLIENTS", "", MAX_CLIENTS, "Default maximum Clients"},
+
+ {"JOIN_LEAVE_COUNT_EXPIRE_TIME", "", JOIN_LEAVE_COUNT_EXPIRE_TIME,
+ "Anti SpamBot Parameter"},
+
+ {"KILLCHASETIMELIMIT", "", KILLCHASETIMELIMIT,
+ "Nick Change Tracker for KILL"},
+
+#ifdef KPATH
+ {"KPATH", KPATH, 0, "Path to K-line File"},
+#else
+ {"KPATH", "NONE", 0, "Path to K-line File"},
+#endif /* KPATH */
+
+#ifdef LPATH
+ {"LPATH", LPATH, 0, "Path to Log File"},
+#else
+ {"LPATH", "NONE", 0, "Path to Log File"},
+#endif /* LPATH */
+
+ {"MAX_BUFFER", "", MAX_BUFFER, "Maximum Buffer Connections Allowed"},
+
+ {"MAX_JOIN_LEAVE_COUNT", "", MAX_JOIN_LEAVE_COUNT,
+ "Anti SpamBot Parameter"},
+
+ {"MIN_JOIN_LEAVE_TIME", "", MIN_JOIN_LEAVE_TIME,
+ "Anti SpamBot Parameter"},
+
+#ifdef MPATH
+ {"MPATH", MPATH, 0, "Path to MOTD File"},
+#else
+ {"MPATH", "NONE", 0, "Path to MOTD File"},
+#endif /* MPATH */
+
+ {"NICKNAMEHISTORYLENGTH", "", NICKNAMEHISTORYLENGTH,
+ "Size of WHOWAS Array"},
+
+#ifdef OPATH
+ {"OPATH", OPATH, 0, "Path to Operator MOTD File"},
+#else
+ {"OPATH", "NONE", 0, "Path to Operator MOTD File"},
+#endif /* OPATH */
+
+ {"OPER_SPAM_COUNTDOWN", "", OPER_SPAM_COUNTDOWN,
+ "Anti SpamBot Parameter"},
+
+#ifdef HAVE_LIBCRYPTO
+ {"HAVE_LIBCRYPTO", "ON", 0, "Enable OpenSSL CHALLENGE Support"},
+#else
+ {"HAVE_LIBCRYPTO", "OFF", 0, "Enable OpenSSL CHALLENGE Support"},
+#endif /* HAVE_LIBCRYPTO */
+
+#ifdef HAVE_LIBZ
+ {"HAVE_LIBZ", "YES", 0, "zlib (ziplinks) support"},
+#else
+ {"HAVE_LIBZ", "NO", 0, "zlib (ziplinks) support"},
+#endif /* HAVE_LIBZ */
+
+#ifdef PPATH
+ {"PPATH", PPATH, 0, "Path to Pid File"},
+#else
+ {"PPATH", "NONE", 0, "Path to Pid File"},
+#endif /* PPATH */
+
+ {"SELECT_TYPE", SELECT_TYPE, 0, "Method of Multiplexed I/O"},
+
+#ifdef SPATH
+ {"SPATH", SPATH, 0, "Path to Server Executable"},
+#else
+ {"SPATH", "NONE", 0, "Path to Server Executable"},
+#endif /* SPATH */
+
+ {"TS_MAX_DELTA_DEFAULT", "", TS_MAX_DELTA_DEFAULT,
+ "Maximum Allowed TS Delta from another Server"},
+ {"TS_WARN_DELTA_DEFAULT", "", TS_WARN_DELTA_DEFAULT,
+ "Maximum TS Delta before Sending Warning"},
+#ifdef USE_IODEBUG_HOOKS
+ {"USE_IODEBUG_HOOKS", "YES", 0, "IO Debugging support"},
+#else
+ {"USE_IODEBUG_HOOKS", "NO", 0, "IO Debugging support"},
+#endif
+
+ /*
+ * since we don't want to include the world here, NULL probably
+ * isn't defined by the time we read this, just use plain 0 instead
+ * 0 is guaranteed by the language to be assignable to ALL built
+ * in types with the correct results.
+ */
+ {0, 0, 0, 0}
+};
+
+
+#endif /* INCLUDED_m_info_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * modules.h: A header for the modules functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: modules.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_modules_h
+#define INCLUDED_modules_h
+#include "config.h"
+#include "setup.h"
+#include "parse.h"
+
+#define MAPI_RATBOX 1
+
+#if defined(HAVE_SHL_LOAD)
+#include <dl.h>
+#endif
+#if !defined(STATIC_MODULES) && defined(HAVE_DLFCN_H)
+#include <dlfcn.h>
+#endif
+
+#include "msg.h"
+#include "memory.h"
+#include "hook.h"
+
+struct module
+{
+ char *name;
+ const char *version;
+ void *address;
+ int core;
+ int mapi_version;
+ void * mapi_header; /* actually struct mapi_mheader_av<mapi_version> */
+};
+
+struct module_path
+{
+ char path[MAXPATHLEN];
+};
+
+#define MAPI_MAGIC_HDR 0x4D410000
+
+#define MAPI_V1 (MAPI_MAGIC_HDR | 0x1)
+
+#define MAPI_MAGIC(x) ((x) & 0xffff0000)
+#define MAPI_VERSION(x) ((x) & 0x0000ffff)
+
+typedef struct Message* mapi_clist_av1;
+
+typedef struct
+{
+ const char * hapi_name;
+ int * hapi_id;
+} mapi_hlist_av1;
+
+typedef struct
+{
+ const char * hapi_name;
+ hookfn fn;
+} mapi_hfn_list_av1;
+
+struct mapi_mheader_av1
+{
+ int mapi_version; /* Module API version */
+ int (*mapi_register) (void); /* Register function;
+ ret -1 = failure (unload) */
+ void (*mapi_unregister) (void); /* Unregister function. */
+ mapi_clist_av1 * mapi_command_list; /* List of commands to add. */
+ mapi_hlist_av1 * mapi_hook_list; /* List of hooks to add. */
+ mapi_hfn_list_av1 *mapi_hfn_list; /* List of hook_add_hook's to do */
+ const char * mapi_module_version; /* Module's version (freeform) */
+};
+
+#ifndef STATIC_MODULES
+# define DECLARE_MODULE_AV1(name,reg,unreg,cl,hl,hfnlist, v) \
+ struct mapi_mheader_av1 _mheader = { MAPI_V1, reg, unreg, cl, hl, hfnlist, v}
+#else
+# define DECLARE_MODULE_AV1(name,reg,unreg,cl,hl,hfnlist, v) \
+ struct mapi_mheader_av1 name ## _mheader = { MAPI_V1, reg, unreg, cl, hl, hfnlist, v}
+void load_static_modules(void);
+#endif
+
+/* add a path */
+void mod_add_path(const char *path);
+void mod_clear_paths(void);
+
+/* load a module */
+extern void load_module(char *path);
+
+/* load all modules */
+extern void load_all_modules(int warn);
+
+/* load core modules */
+extern void load_core_modules(int);
+
+extern int unload_one_module(const char *, int);
+extern int load_one_module(const char *, int);
+extern int load_a_module(const char *, int, int);
+extern int findmodule_byname(const char *);
+extern char *irc_basename(const char *);
+extern void modules_init(void);
+
+#endif /* INCLUDED_modules_h */
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * monitor.h: Code for server-side notify lists.
+ *
+ * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * $Id: monitor.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+#ifndef INCLUDED_monitor_h
+#define INCLUDED_monitor_h
+
+struct monitor
+{
+ struct monitor *hnext;
+ char name[NICKLEN];
+ dlink_list users;
+};
+
+extern BlockHeap *monitor_heap;
+
+#define MONITOR_HASH_SIZE 65536
+#define MONITOR_HASH_BITS 16
+
+void init_monitor(void);
+struct monitor *find_monitor(const char *name, int add);
+void clear_monitor(struct Client *);
+
+void monitor_signon(struct Client *);
+void monitor_signoff(struct Client *);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * msg.h: A header for the message handler structure.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: msg.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_msg_h
+#define INCLUDED_msg_h
+
+#include "config.h"
+
+struct Client;
+
+/* MessageHandler */
+typedef enum HandlerType
+{
+ UNREGISTERED_HANDLER,
+ CLIENT_HANDLER,
+ RCLIENT_HANDLER,
+ SERVER_HANDLER,
+ ENCAP_HANDLER,
+ OPER_HANDLER,
+ LAST_HANDLER_TYPE
+}
+HandlerType;
+
+/* struct Client* client_p - connection message originated from
+ * struct Client* source_p - source of message, may be different from client_p
+ * int parc - parameter count
+ * char* parv[] - parameter vector
+ */
+typedef int (*MessageHandler) (struct Client *, struct Client *, int, const char *[]);
+
+struct MessageEntry
+{
+ MessageHandler handler;
+ int min_para;
+};
+
+/* Message table structure */
+struct Message
+{
+ const char *cmd;
+ unsigned int count; /* number of times command used */
+ unsigned int rcount; /* number of times command used by server */
+ unsigned long bytes; /* bytes received for this message */
+ unsigned int flags; /* bit 0 set means that this command is allowed
+ * to be used only on the average of once per 2
+ * seconds -SRB
+ */
+ /* handlers:
+ * UNREGISTERED, CLIENT, RCLIENT, SERVER, OPER, LAST
+ */
+ struct MessageEntry handlers[LAST_HANDLER_TYPE];
+};
+
+#define MFLG_SLOW 0x01 /* executed roughly once per 2s */
+#define MFLG_UNREG 0x02 /* available to unregistered clients */
+
+#define MAXPARA 15
+
+/* generic handlers */
+extern int m_ignore(struct Client *, struct Client *, int, const char **);
+extern int m_not_oper(struct Client *, struct Client *, int, const char **);
+extern int m_registered(struct Client *, struct Client *, int, const char **);
+extern int m_unregistered(struct Client *, struct Client *, int, const char **);
+
+#define mg_ignore { m_ignore, 0 }
+#define mg_not_oper { m_not_oper, 0 }
+#define mg_reg { m_registered, 0 }
+#define mg_unreg { m_unregistered, 0 }
+
+/*
+ * m_functions execute protocol messages on this server:
+ * int m_func(struct Client* client_p, struct Client* source_p, int parc, char* parv[]);
+ *
+ * client_p is always NON-NULL, pointing to a *LOCAL* client
+ * structure (with an open socket connected!). This
+ * identifies the physical socket where the message
+ * originated (or which caused the m_function to be
+ * executed--some m_functions may call others...).
+ *
+ * source_p is the source of the message, defined by the
+ * prefix part of the message if present. If not
+ * or prefix not found, then source_p==client_p.
+ *
+ * (!IsServer(client_p)) => (client_p == source_p), because
+ * prefixes are taken *only* from servers...
+ *
+ * (IsServer(client_p))
+ * (source_p == client_p) => the message didn't
+ * have the prefix.
+ *
+ * (source_p != client_p && IsServer(source_p) means
+ * the prefix specified servername. (?)
+ *
+ * (source_p != client_p && !IsServer(source_p) means
+ * that message originated from a remote
+ * user (not local).
+ *
+ *
+ * combining
+ *
+ * (!IsServer(source_p)) means that, source_p can safely
+ * taken as defining the target structure of the
+ * message in this server.
+ *
+ * *Always* true (if 'parse' and others are working correct):
+ *
+ * 1) source_p->from == client_p (note: client_p->from == client_p)
+ *
+ * 2) MyConnect(source_p) <=> source_p == client_p (e.g. source_p
+ * *cannot* be a local connection, unless it's
+ * actually client_p!). [MyConnect(x) should probably
+ * be defined as (x == x->from) --msa ]
+ *
+ * parc number of variable parameter strings (if zero,
+ * parv is allowed to be NULL)
+ *
+ * parv a NULL terminated list of parameter pointers,
+ *
+ * parv[0], sender (prefix string), if not present
+ * this points to an empty string.
+ * parv[1]...parv[parc-1]
+ * pointers to additional parameters
+ * parv[parc] == NULL, *always*
+ *
+ * note: it is guaranteed that parv[0]..parv[parc-1] are all
+ * non-NULL pointers.
+ */
+
+#endif /* INCLUDED_msg_h */
--- /dev/null
+/* This code is in the public domain.
+ * $Nightmare: nightmare/include/config.h,v 1.32.2.2.2.2 2002/07/02 03:41:28 ejb Exp $
+ * $Id: newconf.h 1735 2006-07-19 02:35:40Z nenolod $
+ */
+
+#ifndef _NEWCONF_H_INCLUDED
+#define _NEWCONF_H_INCLUDED
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include "tools.h"
+#include "client.h"
+
+struct ConfEntry
+{
+ const char *cf_name;
+ int cf_type;
+ void (*cf_func) (void *);
+ int cf_len;
+ void *cf_arg;
+};
+
+struct TopConf
+{
+ char *tc_name;
+ int (*tc_sfunc) (struct TopConf *);
+ int (*tc_efunc) (struct TopConf *);
+ dlink_list tc_items;
+ struct ConfEntry *tc_entries;
+};
+
+
+#define CF_QSTRING 0x01
+#define CF_INT 0x02
+#define CF_STRING 0x03
+#define CF_TIME 0x04
+#define CF_YESNO 0x05
+#define CF_LIST 0x06
+#define CF_ONE 0x07
+
+#define CF_MTYPE 0xFF
+
+#define CF_FLIST 0x1000
+#define CF_MFLAG 0xFF00
+
+typedef struct conf_parm_t_stru
+{
+ struct conf_parm_t_stru *next;
+ int type;
+ union
+ {
+ char *string;
+ int number;
+ struct conf_parm_t_stru *list;
+ }
+ v;
+}
+conf_parm_t;
+
+extern struct TopConf *conf_cur_block;
+
+extern char *current_file;
+
+int read_config(char *);
+int conf_start_block(char *, char *);
+int conf_end_block(struct TopConf *);
+int conf_call_set(struct TopConf *, char *, conf_parm_t *, int);
+void conf_report_error(const char *, ...);
+void newconf_init(void);
+int add_conf_item(const char *topconf, const char *name, int type, void (*func) (void *));
+int remove_conf_item(const char *topconf, const char *name);
+int add_top_conf(const char *name, int (*sfunc) (struct TopConf *), int (*efunc) (struct TopConf *), struct ConfEntry *items);
+int remove_top_conf(char *name);
+struct TopConf *find_top_conf(const char *name);
+struct ConfEntry *find_conf_item(const struct TopConf *top, const char *name);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * numeric.h: A header for the numeric functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: numeric.h 1793 2006-08-04 19:56:03Z jilles $
+ */
+
+#ifndef INCLUDED_numeric_h
+#define INCLUDED_numeric_h
+
+#include "config.h"
+
+/*
+ * form_str - return a format string for a message number
+ * messages are defined below
+ */
+extern const char *form_str(int);
+
+/*
+ * Reserve numerics 000-099 for server-client connections where the client
+ * is local to the server. If any server is passed a numeric in this range
+ * from another server then it is remapped to 100-199. -avalon
+ */
+#define RPL_WELCOME 001
+#define RPL_YOURHOST 002
+#define RPL_CREATED 003
+#define RPL_MYINFO 004
+#define RPL_ISUPPORT 005
+
+#define RPL_SNOMASK 8
+
+#define RPL_REDIR 10
+#define RPL_MAP 15 /* Undernet extension */
+#define RPL_MAPMORE 16 /* Undernet extension */
+#define RPL_MAPEND 17 /* Undernet extension */
+#define RPL_SAVENICK 43 /* From ircnet */
+
+/*
+ * Numeric replies from server commands.
+ * These are currently in the range 200-399.
+ */
+#define RPL_TRACELINK 200
+#define RPL_TRACECONNECTING 201
+#define RPL_TRACEHANDSHAKE 202
+#define RPL_TRACEUNKNOWN 203
+#define RPL_TRACEOPERATOR 204
+#define RPL_TRACEUSER 205
+#define RPL_TRACESERVER 206
+#define RPL_TRACENEWTYPE 208
+#define RPL_TRACECLASS 209
+
+#define RPL_STATSLINKINFO 211
+#define RPL_STATSCOMMANDS 212
+#define RPL_STATSCLINE 213
+#define RPL_STATSNLINE 214
+#define RPL_STATSILINE 215
+#define RPL_STATSKLINE 216
+#define RPL_STATSQLINE 217
+#define RPL_STATSYLINE 218
+#define RPL_ENDOFSTATS 219
+/* note ircu uses 217 for STATSPLINE frip. conflict
+ * as RPL_STATSQLINE was used in old 2.8 for Q line
+ * I'm going to steal 220 for now *sigh*
+ * -Dianora
+ */
+#define RPL_STATSPLINE 220
+#define RPL_UMODEIS 221
+
+#define RPL_STATSFLINE 224
+#define RPL_STATSDLINE 225
+
+#define RPL_SERVLIST 234
+#define RPL_SERVLISTEND 235
+
+#define RPL_STATSLLINE 241
+#define RPL_STATSUPTIME 242
+#define RPL_STATSOLINE 243
+#define RPL_STATSHLINE 244
+/* 245 No longer used in ircd-ratbox */
+#define RPL_STATSSLINE 245
+#define RPL_STATSXLINE 247
+#define RPL_STATSULINE 248
+#define RPL_STATSDEBUG 249
+#define RPL_STATSCONN 250
+#define RPL_LUSERCLIENT 251
+#define RPL_LUSEROP 252
+#define RPL_LUSERUNKNOWN 253
+#define RPL_LUSERCHANNELS 254
+#define RPL_LUSERME 255
+#define RPL_ADMINME 256
+#define RPL_ADMINLOC1 257
+#define RPL_ADMINLOC2 258
+#define RPL_ADMINEMAIL 259
+
+#define RPL_TRACELOG 261
+#define RPL_ENDOFTRACE 262
+#define RPL_LOAD2HI 263
+
+#define RPL_LOCALUSERS 265
+#define RPL_GLOBALUSERS 266
+
+#define RPL_ACCEPTLIST 281
+#define RPL_ENDOFACCEPT 282
+
+/* numeric_replies */
+
+#define RPL_NONE 300
+#define RPL_AWAY 301
+#define RPL_USERHOST 302
+#define RPL_ISON 303
+#define RPL_TEXT 304
+#define RPL_UNAWAY 305
+#define RPL_NOWAWAY 306
+
+/* RPL_WHOISADMIN 308 -- hybrid */
+
+#define RPL_WHOISUSER 311
+#define RPL_WHOISSERVER 312
+#define RPL_WHOISOPERATOR 313
+
+#define RPL_WHOWASUSER 314
+/* rpl_endofwho below (315) */
+#define RPL_ENDOFWHOWAS 369
+
+#define RPL_WHOISCHANOP 316 /* redundant and not needed but reserved */
+#define RPL_WHOISIDLE 317
+
+#define RPL_ENDOFWHOIS 318
+#define RPL_WHOISCHANNELS 319
+
+#define RPL_LISTSTART 321
+#define RPL_LIST 322
+#define RPL_LISTEND 323
+#define RPL_CHANNELMODEIS 324
+
+#define RPL_CREATIONTIME 329
+#define RPL_WHOISLOGGEDIN 330
+
+#define RPL_NOTOPIC 331
+#define RPL_TOPIC 332
+#define RPL_TOPICWHOTIME 333
+#define RPL_WHOISACTUALLY 338
+
+#define RPL_INVITING 341
+#define RPL_SUMMONING 342
+
+#define RPL_INVITELIST 346
+#define RPL_ENDOFINVITELIST 347
+#define RPL_EXCEPTLIST 348
+#define RPL_ENDOFEXCEPTLIST 349
+
+#define RPL_VERSION 351
+
+#define RPL_WHOREPLY 352
+#define RPL_ENDOFWHO 315
+#define RPL_NAMREPLY 353
+#define RPL_WHOWASREAL 360
+#define RPL_ENDOFNAMES 366
+
+#define RPL_KILLDONE 361
+#define RPL_CLOSING 362
+#define RPL_CLOSEEND 363
+#define RPL_LINKS 364
+#define RPL_ENDOFLINKS 365
+/* rpl_endofnames above (366) */
+#define RPL_BANLIST 367
+#define RPL_ENDOFBANLIST 368
+/* rpl_endofwhowas above (369) */
+
+#define RPL_INFO 371
+#define RPL_MOTD 372
+#define RPL_INFOSTART 373
+#define RPL_ENDOFINFO 374
+#define RPL_MOTDSTART 375
+#define RPL_ENDOFMOTD 376
+#define RPL_WHOISHOST 378
+
+#define RPL_YOUREOPER 381
+#define RPL_REHASHING 382
+#define RPL_MYPORTIS 384
+#define RPL_NOTOPERANYMORE 385
+#define RPL_RSACHALLENGE 386
+
+#define RPL_TIME 391
+#define RPL_USERSSTART 392
+#define RPL_USERS 393
+#define RPL_ENDOFUSERS 394
+#define RPL_NOUSERS 395
+#define RPL_HOSTHIDDEN 396 /* from ircu -- jilles */
+
+/*
+ * Errors are in the range from 400-599 currently and are grouped by what
+ * commands they come from.
+ */
+#define ERR_NOSUCHNICK 401
+#define ERR_NOSUCHSERVER 402
+#define ERR_NOSUCHCHANNEL 403
+#define ERR_CANNOTSENDTOCHAN 404
+#define ERR_TOOMANYCHANNELS 405
+#define ERR_WASNOSUCHNICK 406
+#define ERR_TOOMANYTARGETS 407
+#define ERR_NOORIGIN 409
+
+#define ERR_INVALIDCAPCMD 410
+
+#define ERR_NORECIPIENT 411
+#define ERR_NOTEXTTOSEND 412
+#define ERR_NOTOPLEVEL 413
+#define ERR_WILDTOPLEVEL 414
+
+#define ERR_TOOMANYMATCHES 416
+
+#define ERR_UNKNOWNCOMMAND 421
+#define ERR_NOMOTD 422
+#define ERR_NOADMININFO 423
+#define ERR_FILEERROR 424
+
+#define ERR_NONICKNAMEGIVEN 431
+#define ERR_ERRONEUSNICKNAME 432
+#define ERR_NICKNAMEINUSE 433
+#define ERR_BANNICKCHANGE 435 /* bahamut's ERR_BANONCHAN -- jilles */
+#define ERR_NICKCOLLISION 436
+#define ERR_UNAVAILRESOURCE 437
+#define ERR_NICKTOOFAST 438 /* We did it first Undernet! ;) db */
+
+#define ERR_SERVICESDOWN 440
+#define ERR_USERNOTINCHANNEL 441
+#define ERR_NOTONCHANNEL 442
+#define ERR_USERONCHANNEL 443
+#define ERR_NOLOGIN 444
+#define ERR_SUMMONDISABLED 445
+#define ERR_USERSDISABLED 446
+
+#define ERR_NOTREGISTERED 451
+
+#define ERR_ACCEPTFULL 456
+#define ERR_ACCEPTEXIST 457
+#define ERR_ACCEPTNOT 458
+
+#define ERR_NEEDMOREPARAMS 461
+#define ERR_ALREADYREGISTRED 462
+#define ERR_NOPERMFORHOST 463
+#define ERR_PASSWDMISMATCH 464
+#define ERR_YOUREBANNEDCREEP 465
+#define ERR_YOUWILLBEBANNED 466
+#define ERR_KEYSET 467
+
+#define ERR_LINKCHANNEL 470
+#define ERR_CHANNELISFULL 471
+#define ERR_UNKNOWNMODE 472
+#define ERR_INVITEONLYCHAN 473
+#define ERR_BANNEDFROMCHAN 474
+#define ERR_BADCHANNELKEY 475
+#define ERR_BADCHANMASK 476
+#define ERR_NEEDREGGEDNICK 477
+#define ERR_BANLISTFULL 478 /* I stole the numeric from ircu -db */
+#define ERR_BADCHANNAME 479
+
+#define ERR_THROTTLE 480
+
+#define ERR_NOPRIVILEGES 481
+#define ERR_CHANOPRIVSNEEDED 482
+#define ERR_CANTKILLSERVER 483
+#define ERR_ISCHANSERVICE 484
+/* #define ERR_RESTRICTED 484 - hyb derived, no longer here */
+#define ERR_BANNEDNICK 485
+#define ERR_NONONREG 486 /* bahamut; aka ERR_ACCOUNTONLY asuka -- jilles */
+
+#define ERR_VOICENEEDED 489
+
+#define ERR_NOOPERHOST 491
+
+#define ERR_UMODEUNKNOWNFLAG 501
+#define ERR_USERSDONTMATCH 502
+
+#define ERR_GHOSTEDCLIENT 503
+
+#define ERR_USERNOTONSERV 504
+
+/* #define ERR_LAST_ERR_MSG 505
+ * moved to 999
+ */
+#define ERR_WRONGPONG 513
+
+#define ERR_HELPNOTFOUND 524
+
+#define RPL_MODLIST 702
+#define RPL_ENDOFMODLIST 703
+
+#define RPL_HELPSTART 704
+#define RPL_HELPTXT 705
+#define RPL_ENDOFHELP 706
+
+#define ERR_TARGCHANGE 707
+
+#define RPL_ETRACEFULL 708
+#define RPL_ETRACE 709
+
+#define RPL_KNOCK 710
+#define RPL_KNOCKDLVR 711
+
+#define ERR_TOOMANYKNOCK 712
+#define ERR_CHANOPEN 713
+#define ERR_KNOCKONCHAN 714
+#define ERR_KNOCKDISABLED 715
+
+#define ERR_TARGUMODEG 716
+#define RPL_TARGNOTIFY 717
+#define RPL_UMODEGMSG 718
+
+#define RPL_OMOTDSTART 720
+#define RPL_OMOTD 721
+#define RPL_ENDOFOMOTD 722
+
+#define ERR_NOPRIVS 723
+
+#define RPL_TESTMASK 724
+#define RPL_TESTLINE 725
+#define RPL_NOTESTLINE 726
+#define RPL_TESTMASKGECOS 727
+
+#define RPL_MONONLINE 730
+#define RPL_MONOFFLINE 731
+#define RPL_MONLIST 732
+#define RPL_ENDOFMONLIST 733
+#define ERR_MONLISTFULL 734
+
+#define RPL_RSACHALLENGE2 740
+#define RPL_ENDOFRSACHALLENGE2 741
+
+#define RPL_SCANMATCHED 750
+#define RPL_SCANUMODES 751
+
+#define RPL_LOGGEDIN 900
+#define RPL_LOGGEDOUT 901
+#define ERR_NICKLOCKED 902
+
+#define RPL_SASLSUCCESS 903
+#define ERR_SASLFAIL 904
+#define ERR_SASLTOOLONG 905
+#define ERR_SASLABORTED 906
+#define ERR_SASLALREADY 907
+
+#define ERR_LAST_ERR_MSG 999
+
+#endif /* INCLUDED_numeric_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * packet.h: A header for the packet functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: packet.h 813 2006-02-14 20:52:15Z nenolod $
+ */
+
+#ifndef INCLUDED_packet_h
+#define INCLUDED_packet_h
+
+#include "commio.h"
+
+/*
+ * this hides in here rather than a config.h because it really shouldn't
+ * be tweaked unless you *REALLY REALLY* know what you're doing!
+ * Remember, messages are only anti-flooded on incoming from the client, not on
+ * incoming from a server for a given client, so if you tweak this you risk
+ * allowing a client to flood differently depending upon where they are on
+ * the network..
+ * -- adrian
+ */
+/* MAX_FLOOD is the amount of lines in a 'burst' we allow from a client,
+ * anything beyond MAX_FLOOD is limited to about one line per second.
+ *
+ * MAX_FLOOD_CONN is the amount of lines we allow from a client who has
+ * just connected. this allows clients to rejoin multiple channels
+ * without being so heavily penalised they excess flood.
+ */
+#define MAX_FLOOD 5
+#define MAX_FLOOD_BURST MAX_FLOOD * 8
+
+extern PF read_ctrl_packet;
+extern PF read_packet;
+extern PF flood_recalc;
+extern void flood_endgrace(struct Client *);
+
+#endif /* INCLUDED_packet_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * parse.h: A header for the message parser.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: parse.h 944 2006-03-06 03:41:31Z nenolod $
+ */
+
+#ifndef INCLUDED_parse_h_h
+#define INCLUDED_parse_h_h
+
+#include "tools.h"
+
+struct Message;
+struct Client;
+
+struct MessageHash
+{
+ char *cmd;
+ struct Message *msg;
+ struct MessageHash *next;
+};
+
+#define MAX_MSG_HASH 387
+
+extern void parse(struct Client *, char *, char *);
+extern void handle_encap(struct Client *, struct Client *,
+ const char *, int, const char *parv[]);
+extern void clear_hash_parse(void);
+extern void mod_add_cmd(struct Message *msg);
+extern void mod_del_cmd(struct Message *msg);
+extern void report_messages(struct Client *);
+
+extern dlink_list alias_hash_table[MAX_MSG_HASH];
+
+#endif /* INCLUDED_parse_h_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * patchlevel.h: A header defining the patchlevel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: patchlevel.h 34 2005-09-10 02:53:04Z nenolod $
+ */
+
+#include "setup.h"
+
+#ifndef PATCHLEVEL
+#define PATCHLEVEL PACKAGE_NAME "-" PACKAGE_VERSION
+#endif
--- /dev/null
+/*
+ * $Id: patricia.h 6 2005-09-10 01:02:21Z nenolod $
+ * Dave Plonka <plonka@doit.wisc.edu>
+ *
+ * This product includes software developed by the University of Michigan,
+ * Merit Network, Inc., and their contributors.
+ *
+ * This file had been called "radix.h" in the MRT sources.
+ *
+ * I renamed it to "patricia.h" since it's not an implementation of a general
+ * radix trie. Also, pulled in various requirements from "mrt.h" and added
+ * some other things it could be used as a standalone API.
+ */
+
+#ifndef _PATRICIA_H
+#define _PATRICIA_H
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#ifndef TESTING
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "memory.h"
+#include "config.h"
+#endif
+
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !(FALSE)
+#endif
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/* typedef unsigned int u_int; */
+typedef void (*void_fn_t) ();
+#define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin)
+#define MAXLINE 1024
+#define BIT_TEST(f, b) ((f) & (b))
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+typedef struct _prefix_t
+{
+ u_short family; /* AF_INET | AF_INET6 */
+ u_short bitlen; /* same as mask? */
+ int ref_count; /* reference count */
+ union
+ {
+ struct in_addr sin;
+#ifdef IPV6
+ struct in6_addr sin6;
+#endif /* IPV6 */
+ }
+ add;
+}
+prefix_t;
+
+
+typedef struct _patricia_node_t
+{
+ u_int bit; /* flag if this node used */
+ prefix_t *prefix; /* who we are in patricia tree */
+ struct _patricia_node_t *l, *r; /* left and right children */
+ struct _patricia_node_t *parent; /* may be used */
+ void *data;
+}
+patricia_node_t;
+
+typedef struct _patricia_tree_t
+{
+ patricia_node_t *head;
+ u_int maxbits; /* for IP, 32 bit addresses */
+ int num_active_node; /* for debug purpose */
+}
+patricia_tree_t;
+
+
+patricia_node_t *match_ip(patricia_tree_t * tree, struct sockaddr *ip);
+patricia_node_t *match_string(patricia_tree_t * tree, const char *string);
+patricia_node_t *match_exact_string(patricia_tree_t * tree, const char *string);
+patricia_node_t *patricia_search_exact(patricia_tree_t * patricia, prefix_t * prefix);
+patricia_node_t *patricia_search_best(patricia_tree_t * patricia, prefix_t * prefix);
+patricia_node_t *patricia_search_best2(patricia_tree_t * patricia,
+ prefix_t * prefix, int inclusive);
+patricia_node_t *patricia_lookup(patricia_tree_t * patricia, prefix_t * prefix);
+
+void patricia_remove(patricia_tree_t * patricia, patricia_node_t * node);
+patricia_tree_t *New_Patricia(int maxbits);
+void Clear_Patricia(patricia_tree_t * patricia, void_fn_t func);
+void Destroy_Patricia(patricia_tree_t * patricia, void_fn_t func);
+void patricia_process(patricia_tree_t * patricia, void_fn_t func);
+void init_patricia(void);
+
+
+#if 0
+prefix_t *ascii2prefix(int family, char *string);
+#endif
+patricia_node_t *make_and_lookup(patricia_tree_t * tree, const char *string);
+patricia_node_t *make_and_lookup_ip(patricia_tree_t * tree, struct sockaddr *, int bitlen);
+
+
+#define PATRICIA_MAXBITS 128
+#define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f))
+#define PATRICIA_NBYTE(x) ((x) >> 3)
+
+#define PATRICIA_DATA_GET(node, type) (type *)((node)->data)
+#define PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))
+
+#define PATRICIA_WALK(Xhead, Xnode) \
+ do { \
+ patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \
+ patricia_node_t **Xsp = Xstack; \
+ patricia_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (Xnode->prefix)
+
+#define PATRICIA_WALK_ALL(Xhead, Xnode) \
+do { \
+ patricia_node_t *Xstack[PATRICIA_MAXBITS+1]; \
+ patricia_node_t **Xsp = Xstack; \
+ patricia_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (1)
+
+#define PATRICIA_WALK_BREAK { \
+ if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (patricia_node_t *) 0; \
+ } \
+ continue; }
+
+#define PATRICIA_WALK_END \
+ if (Xrn->l) { \
+ if (Xrn->r) { \
+ *Xsp++ = Xrn->r; \
+ } \
+ Xrn = Xrn->l; \
+ } else if (Xrn->r) { \
+ Xrn = Xrn->r; \
+ } else if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (patricia_node_t *) 0; \
+ } \
+ } \
+ } while (0)
+
+#endif /* _PATRICIA_H */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd
+ * reject.h: header to a file which rejects users with prejudice
+ *
+ * Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2003-2004 ircd-ratbox 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
+ *
+ *
+ * $Id: reject.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+#ifndef INCLUDED_reject_h
+#define INCLUDED_reject_h
+
+/* amount of time to delay a rejected clients exit */
+#define DELAYED_EXIT_TIME 10
+
+extern dlink_list delay_exit;
+
+void init_reject(void);
+int check_reject(struct Client *);
+void add_reject(struct Client *);
+void flush_reject(void);
+int remove_reject(const char *ip);
+#endif
+
--- /dev/null
+/*
+ * res.h for referencing functions in res.c, reslib.c
+ *
+ * $Id: res.h 2023 2006-09-02 23:47:27Z jilles $
+ */
+
+#ifndef _CHARYBDIS_RES_H
+#define _CHARYBDIS_RES_H
+
+#include "ircd_defs.h"
+#include "common.h"
+#include "commio.h"
+#include "reslib.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+
+/* Maximum number of nameservers in /etc/resolv.conf we care about
+ * In hybrid, this was 2 -- but in Charybdis, we want to track
+ * a few more than that ;) --nenolod
+ */
+#define IRCD_MAXNS 10
+
+struct DNSReply
+{
+ char *h_name;
+ struct irc_sockaddr_storage addr;
+};
+
+struct DNSQuery
+{
+ void *ptr; /* pointer used by callback to identify request */
+ void (*callback)(void* vptr, struct DNSReply *reply); /* callback to call */
+};
+
+extern struct irc_sockaddr_storage irc_nsaddr_list[];
+extern int irc_nscount;
+
+extern void init_resolver(void);
+extern void restart_resolver(void);
+extern void delete_resolver_queries(const struct DNSQuery *);
+extern void gethost_byname_type(const char *, struct DNSQuery *, int);
+extern void gethost_byaddr(const struct irc_sockaddr_storage *, struct DNSQuery *);
+extern void add_local_domain(char *, size_t);
+extern void report_dns_servers(struct Client *);
+
+#endif
--- /dev/null
+/*
+ * include/irc_reslib.h
+ *
+ * $Id: reslib.h 446 2006-02-12 02:46:54Z db $
+ */
+
+#ifndef _CHARYBDIS_RESLIB_H
+#define _CHARYBDIS_RESLIB_H
+
+/* Here we define some values lifted from nameser.h */
+#define NS_NOTIFY_OP 4
+#define NS_INT16SZ 2
+#define NS_IN6ADDRSZ 16
+#define NS_INADDRSZ 4
+#define NS_INT32SZ 4
+#define NS_CMPRSFLGS 0xc0
+#define NS_MAXCDNAME 255
+#define QUERY 0
+#define IQUERY 1
+#define NO_ERRORS 0
+#define SERVFAIL 2
+#define NXDOMAIN 3
+#define T_A 1
+#define T_AAAA 28
+#define T_PTR 12
+#define T_CNAME 5
+#define T_NULL 10
+#define C_IN 1
+#define QFIXEDSZ 4
+#define RRFIXEDSZ 10
+#define HFIXEDSZ 12
+
+typedef struct
+{
+ unsigned id :16; /* query identification number */
+#ifdef WORDS_BIGENDIAN
+ /* fields in third byte */
+ unsigned qr: 1; /* response flag */
+ unsigned opcode: 4; /* purpose of message */
+ unsigned aa: 1; /* authoritive answer */
+ unsigned tc: 1; /* truncated message */
+ unsigned rd: 1; /* recursion desired */
+ /* fields in fourth byte */
+ unsigned ra: 1; /* recursion available */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned rcode :4; /* response code */
+#else
+ /* fields in third byte */
+ unsigned rd :1; /* recursion desired */
+ unsigned tc :1; /* truncated message */
+ unsigned aa :1; /* authoritive answer */
+ unsigned opcode :4; /* purpose of message */
+ unsigned qr :1; /* response flag */
+ /* fields in fourth byte */
+ unsigned rcode :4; /* response code */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra :1; /* recursion available */
+#endif
+ /* remaining bytes */
+ unsigned qdcount :16; /* number of question entries */
+ unsigned ancount :16; /* number of answer entries */
+ unsigned nscount :16; /* number of authority entries */
+ unsigned arcount :16; /* number of resource entries */
+} HEADER;
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ */
+#define IRC_NS_GET16(s, cp) { \
+ const unsigned char *t_cp = (const unsigned char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) \
+ | ((u_int16_t)t_cp[1]) \
+ ; \
+ (cp) += NS_INT16SZ; \
+}
+
+#define IRC_NS_GET32(l, cp) { \
+ const unsigned char *t_cp = (const unsigned char *)(cp); \
+ (l) = ((u_int32_t)t_cp[0] << 24) \
+ | ((u_int32_t)t_cp[1] << 16) \
+ | ((u_int32_t)t_cp[2] << 8) \
+ | ((u_int32_t)t_cp[3]) \
+ ; \
+ (cp) += NS_INT32SZ; \
+}
+
+#define IRC_NS_PUT16(s, cp) { \
+ u_int16_t t_s = (u_int16_t)(s); \
+ unsigned char *t_cp = (unsigned char *)(cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += NS_INT16SZ; \
+}
+
+#define IRC_NS_PUT32(l, cp) { \
+ u_int32_t t_l = (u_int32_t)(l); \
+ unsigned char *t_cp = (unsigned char *)(cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += NS_INT32SZ; \
+}
+
+extern int irc_res_init(void);
+extern int irc_dn_expand(const unsigned char *msg, const unsigned char *eom, const unsigned char *src, char *dst, int dstsiz);
+extern int irc_dn_skipname(const unsigned char *ptr, const unsigned char *eom);
+extern unsigned int irc_ns_get16(const unsigned char *src);
+extern unsigned long irc_ns_get32(const unsigned char *src);
+extern void irc_ns_put16(unsigned int src, unsigned char *dst);
+extern void irc_ns_put32(unsigned long src, unsigned char *dst);
+extern int irc_res_mkquery(const char *dname, int class, int type, unsigned char *buf, int buflen);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * restart.h: A header with restart functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: restart.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_restart_h
+#define INCLUDED_restart_h
+
+void restart(const char *);
+void server_reboot(void);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_auth.h: A header for the ident functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_auth.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_s_auth_h
+#define INCLUDED_s_auth_h
+
+#include "config.h"
+#include "res.h"
+/*
+ * How many auth allocations to allocate in a block. I'm guessing that
+ * a good number here is 64, because these are temporary and don't live
+ * as long as clients do.
+ * -- adrian
+ */
+#define AUTH_BLOCK_SIZE 64
+
+struct Client;
+
+struct AuthRequest
+{
+ dlink_node node;
+ struct Client *client; /* pointer to client struct for request */
+ struct DNSQuery dns_query; /* DNS Query */
+ unsigned int flags; /* current state of request */
+ int fd; /* file descriptor for auth queries */
+ time_t timeout; /* time when query expires */
+#ifdef IPV6
+ int ip6_int;
+#endif
+};
+
+/*
+ * flag values for AuthRequest
+ * NAMESPACE: AM_xxx - Authentication Module
+ */
+#define AM_AUTH_CONNECTING (1 << 0)
+#define AM_AUTH_PENDING (1 << 1)
+#define AM_DNS_PENDING (1 << 2)
+
+#define SetDNSPending(x) ((x)->flags |= AM_DNS_PENDING)
+#define ClearDNSPending(x) ((x)->flags &= ~AM_DNS_PENDING)
+#define IsDNSPending(x) ((x)->flags & AM_DNS_PENDING)
+
+#define SetAuthConnect(x) ((x)->flags |= AM_AUTH_CONNECTING)
+#define ClearAuthConnect(x) ((x)->flags &= ~AM_AUTH_CONNECTING)
+#define IsAuthConnect(x) ((x)->flags & AM_AUTH_CONNECTING)
+
+#define SetAuthPending(x) ((x)->flags |= AM_AUTH_PENDING)
+#define ClearAuthPending(x) ((x)->flags &= AM_AUTH_PENDING)
+#define IsAuthPending(x) ((x)->flags & AM_AUTH_PENDING)
+
+#define ClearAuth(x) ((x)->flags &= ~(AM_AUTH_PENDING | AM_AUTH_CONNECTING))
+#define IsDoingAuth(x) ((x)->flags & (AM_AUTH_PENDING | AM_AUTH_CONNECTING))
+/* #define SetGotId(x) ((x)->flags |= FLAGS_GOTID) */
+
+
+
+extern void start_auth(struct Client *);
+extern void send_auth_query(struct AuthRequest *req);
+extern void remove_auth_request(struct AuthRequest *req);
+extern void init_auth(void);
+extern void delete_auth_queries(struct Client *);
+
+#endif /* INCLUDED_s_auth_h */
--- /dev/null
+/*
+ * charybdis: Advanced, scalable Internet Relay Chat.
+ * s_conf.h: A header for the configuration functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_conf.h 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#ifndef INCLUDED_s_conf_h
+#define INCLUDED_s_conf_h
+#include "setup.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/rsa.h>
+#endif
+
+#include "ircd_defs.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "patricia.h"
+
+struct Client;
+struct DNSReply;
+struct hostent;
+
+/* used by new parser */
+/* yacc/lex love globals!!! */
+
+struct ip_value
+{
+ struct irc_sockaddr_storage ip;
+ int ip_mask;
+ int type;
+};
+
+extern FILE *conf_fbfile_in;
+extern char conf_line_in[256];
+
+struct ConfItem
+{
+ struct ConfItem *next; /* list node pointer */
+ unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
+ unsigned int flags;
+ int clients; /* Number of *LOCAL* clients using this */
+ char *name; /* IRC name, nick, server name, or original u@h */
+ char *host; /* host part of user@host */
+ char *passwd; /* doubles as kline reason *ugh* */
+ char *spasswd; /* Password to send. */
+ char *user; /* user part of user@host */
+ int port;
+ time_t hold; /* Hold action until this time (calendar time) */
+ char *className; /* Name of class */
+ struct Class *c_class; /* Class of connection */
+ patricia_node_t *pnode; /* Our patricia node */
+};
+
+#define CONF_ILLEGAL 0x80000000
+#define CONF_QUARANTINED_NICK 0x0001
+#define CONF_CLIENT 0x0002
+#define CONF_KILL 0x0040
+#define CONF_XLINE 0x0080
+#define CONF_RESV_CHANNEL 0x0100
+#define CONF_RESV_NICK 0x0200
+#define CONF_RESV (CONF_RESV_CHANNEL | CONF_RESV_NICK)
+
+#define CONF_CLASS 0x0400
+#define CONF_LISTEN_PORT 0x1000
+#define CONF_EXEMPTKLINE 0x4000
+#define CONF_NOLIMIT 0x8000
+#define CONF_GLINE 0x10000
+#define CONF_DLINE 0x20000
+#define CONF_EXEMPTDLINE 0x100000
+
+#define IsIllegal(x) ((x)->status & CONF_ILLEGAL)
+
+/* aConfItem->flags */
+
+/* Generic flags... */
+/* access flags... */
+#define CONF_FLAGS_DO_IDENTD 0x00000001
+#define CONF_FLAGS_LIMIT_IP 0x00000002
+#define CONF_FLAGS_NO_TILDE 0x00000004
+#define CONF_FLAGS_NEED_IDENTD 0x00000008
+#define CONF_FLAGS_PASS_IDENTD 0x00000010
+#define CONF_FLAGS_NOMATCH_IP 0x00000020
+#define CONF_FLAGS_EXEMPTKLINE 0x00000040
+#define CONF_FLAGS_NOLIMIT 0x00000080
+#define CONF_FLAGS_IDLE_LINED 0x00000100
+#define CONF_FLAGS_SPOOF_IP 0x00000200
+#define CONF_FLAGS_SPOOF_NOTICE 0x00000400
+#define CONF_FLAGS_REDIR 0x00000800
+#define CONF_FLAGS_EXEMPTGLINE 0x00001000
+#define CONF_FLAGS_EXEMPTRESV 0x00002000 /* exempt from resvs */
+#define CONF_FLAGS_EXEMPTFLOOD 0x00004000
+#define CONF_FLAGS_EXEMPTSPAMBOT 0x00008000
+#define CONF_FLAGS_EXEMPTSHIDE 0x00010000
+#define CONF_FLAGS_EXEMPTJUPE 0x00020000 /* exempt from resv generating warnings */
+#define CONF_FLAGS_NEED_SASL 0x00040000
+/* server flags */
+#define CONF_FLAGS_ALLOW_AUTO_CONN 0x00080000
+#define CONF_FLAGS_LAZY_LINK 0x00100000
+#define CONF_FLAGS_ENCRYPTED 0x00200000
+#define CONF_FLAGS_COMPRESSED 0x00400000
+#define CONF_FLAGS_TEMPORARY 0x00800000
+#define CONF_FLAGS_TB 0x01000000
+#define CONF_FLAGS_VHOSTED 0x02000000
+#define CONF_FLAGS_EXEMPTDNSBL 0x04000000
+
+
+/* Macros for struct ConfItem */
+#define IsLimitIp(x) ((x)->flags & CONF_FLAGS_LIMIT_IP)
+#define IsNoTilde(x) ((x)->flags & CONF_FLAGS_NO_TILDE)
+#define IsNeedIdentd(x) ((x)->flags & CONF_FLAGS_NEED_IDENTD)
+#define IsPassIdentd(x) ((x)->flags & CONF_FLAGS_PASS_IDENTD)
+#define IsNoMatchIp(x) ((x)->flags & CONF_FLAGS_NOMATCH_IP)
+#define IsConfExemptKline(x) ((x)->flags & CONF_FLAGS_EXEMPTKLINE)
+#define IsConfExemptLimits(x) ((x)->flags & CONF_FLAGS_NOLIMIT)
+#define IsConfExemptGline(x) ((x)->flags & CONF_FLAGS_EXEMPTGLINE)
+#define IsConfExemptFlood(x) ((x)->flags & CONF_FLAGS_EXEMPTFLOOD)
+#define IsConfExemptSpambot(x) ((x)->flags & CONF_FLAGS_EXEMPTSPAMBOT)
+#define IsConfExemptShide(x) ((x)->flags & CONF_FLAGS_EXEMPTSHIDE)
+#define IsConfExemptJupe(x) ((x)->flags & CONF_FLAGS_EXEMPTJUPE)
+#define IsConfExemptResv(x) ((x)->flags & CONF_FLAGS_EXEMPTRESV)
+#define IsConfIdlelined(x) ((x)->flags & CONF_FLAGS_IDLE_LINED)
+#define IsConfDoIdentd(x) ((x)->flags & CONF_FLAGS_DO_IDENTD)
+#define IsConfDoSpoofIp(x) ((x)->flags & CONF_FLAGS_SPOOF_IP)
+#define IsConfSpoofNotice(x) ((x)->flags & CONF_FLAGS_SPOOF_NOTICE)
+#define IsConfEncrypted(x) ((x)->flags & CONF_FLAGS_ENCRYPTED)
+#define IsConfCompressed(x) ((x)->flags & CONF_FLAGS_COMPRESSED)
+#define IsConfVhosted(x) ((x)->flags & CONF_FLAGS_VHOSTED)
+#define IsConfTburst(x) ((x)->flags & CONF_FLAGS_TB)
+#define IsNeedSasl(x) ((x)->flags & CONF_FLAGS_NEED_SASL)
+#define IsConfExemptDNSBL(x) ((x)->flags & CONF_FLAGS_EXEMPTDNSBL)
+
+/* flag definitions for opers now in client.h */
+
+struct config_file_entry
+{
+ const char *dpath; /* DPATH if set from command line */
+ const char *configfile;
+ const char *klinefile;
+ const char *dlinefile;
+ const char *xlinefile;
+ const char *resvfile;
+
+ char *servlink_path;
+ char *egdpool_path;
+
+ char *default_operstring;
+ char *default_adminstring;
+ char *servicestring;
+ char *kline_reason;
+
+ char *identifyservice;
+ char *identifycommand;
+
+ char *fname_userlog;
+ char *fname_fuserlog;
+ char *fname_operlog;
+ char *fname_foperlog;
+ char *fname_serverlog;
+ char *fname_killlog;
+ char *fname_glinelog;
+ char *fname_klinelog;
+ char *fname_operspylog;
+ char *fname_ioerrorlog;
+
+ unsigned char compression_level;
+ int disable_fake_channels;
+ int dot_in_ip6_addr;
+ int dots_in_ident;
+ int failed_oper_notice;
+ int anti_nick_flood;
+ int anti_spam_exit_message_time;
+ int max_accept;
+ int max_monitor;
+ int max_nick_time;
+ int max_nick_changes;
+ int ts_max_delta;
+ int ts_warn_delta;
+ int dline_with_reason;
+ int kline_with_reason;
+ int kline_delay;
+ int warn_no_nline;
+ int nick_delay;
+ int non_redundant_klines;
+ int stats_e_disabled;
+ int stats_c_oper_only;
+ int stats_y_oper_only;
+ int stats_h_oper_only;
+ int stats_o_oper_only;
+ int stats_k_oper_only;
+ int stats_i_oper_only;
+ int stats_P_oper_only;
+ int map_oper_only;
+ int operspy_admin_only;
+ int pace_wait;
+ int pace_wait_simple;
+ int short_motd;
+ int no_oper_flood;
+ int glines;
+ int gline_time;
+ int gline_min_cidr;
+ int gline_min_cidr6;
+ int idletime;
+ int hide_server;
+ int hide_spoof_ips;
+ int hide_error_messages;
+ int client_exit;
+ int oper_only_umodes;
+ int oper_umodes;
+ int oper_snomask;
+ int max_targets;
+ int caller_id_wait;
+ int min_nonwildcard;
+ int min_nonwildcard_simple;
+ int default_floodcount;
+ int client_flood;
+ int use_egd;
+ int ping_cookie;
+ int tkline_expire_notices;
+ int use_whois_actually;
+ int disable_auth;
+ int connect_timeout;
+ int burst_away;
+ int reject_ban_time;
+ int reject_after_count;
+ int reject_duration;
+ int target_change;
+ int collision_fnc;
+ int default_umodes;
+ int global_snotices;
+ int operspy_dont_care_user_info;
+};
+
+struct config_channel_entry
+{
+ int use_except;
+ int use_invex;
+ int use_knock;
+ int use_forward;
+ int knock_delay;
+ int knock_delay_channel;
+ int max_bans;
+ int max_bans_large;
+ int max_chans_per_user;
+ int no_create_on_split;
+ int no_join_on_split;
+ int default_split_server_count;
+ int default_split_user_count;
+ int burst_topicwho;
+ int invite_ops_only;
+ int kick_on_split_riding;
+};
+
+struct config_server_hide
+{
+ int flatten_links;
+ int links_delay;
+ int links_disabled;
+ int hidden;
+ int disable_hidden;
+};
+
+struct server_info
+{
+ char *name;
+ char sid[3];
+ char *description;
+ char *network_name;
+ char *network_desc;
+ int hub;
+ int use_ts6;
+ struct sockaddr_in ip;
+#ifdef IPV6
+ struct sockaddr_in6 ip6;
+#endif
+ int specific_ipv4_vhost;
+#ifdef IPV6
+ int specific_ipv6_vhost;
+#endif
+};
+
+struct admin_info
+{
+ char *name;
+ char *description;
+ char *email;
+};
+
+struct alias_entry
+{
+ char *name;
+ char *target;
+ int flags; /* reserved for later use */
+ int hits;
+};
+
+/* All variables are GLOBAL */
+extern int specific_ipv4_vhost; /* used in s_bsd.c */
+extern int specific_ipv6_vhost;
+extern struct config_file_entry ConfigFileEntry; /* defined in ircd.c */
+extern struct config_channel_entry ConfigChannel; /* defined in channel.c */
+extern struct config_server_hide ConfigServerHide; /* defined in s_conf.c */
+extern struct server_info ServerInfo; /* defined in ircd.c */
+extern struct admin_info AdminInfo; /* defined in ircd.c */
+/* End GLOBAL section */
+
+dlink_list service_list;
+
+typedef enum temp_list
+{
+ TEMP_MIN,
+ TEMP_HOUR,
+ TEMP_DAY,
+ TEMP_WEEK,
+ LAST_TEMP_TYPE
+} temp_list;
+
+dlink_list temp_klines[LAST_TEMP_TYPE];
+dlink_list temp_dlines[LAST_TEMP_TYPE];
+
+extern void init_s_conf(void);
+
+extern struct ConfItem *make_conf(void);
+extern void free_conf(struct ConfItem *);
+
+extern void read_conf_files(int cold);
+
+extern int attach_conf(struct Client *, struct ConfItem *);
+extern int check_client(struct Client *client_p, struct Client *source_p, const char *);
+
+extern int detach_conf(struct Client *);
+
+extern struct ConfItem *conf_connect_allowed(struct sockaddr *addr, int);
+
+extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr *);
+extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *);
+extern void get_printable_conf(struct ConfItem *,
+ char **, char **, char **, char **, int *, char **);
+extern void get_printable_kline(struct Client *, struct ConfItem *,
+ char **, char **, char **, char **);
+
+extern void yyerror(const char *);
+extern int conf_yy_fatal_error(const char *);
+extern int conf_fgets(char *, int, FILE *);
+
+typedef enum
+{
+ CONF_TYPE,
+ KLINE_TYPE,
+ DLINE_TYPE,
+ RESV_TYPE
+}
+KlineType;
+
+extern void write_confitem(KlineType, struct Client *, char *, char *,
+ const char *, const char *, const char *, int);
+extern void add_temp_kline(struct ConfItem *);
+extern void add_temp_dline(struct ConfItem *);
+extern void report_temp_klines(struct Client *);
+extern void show_temp_klines(struct Client *, dlink_list *);
+
+extern const char *get_conf_name(KlineType);
+extern int rehash(int);
+extern void rehash_bans(int);
+
+extern int conf_add_server(struct ConfItem *, int);
+extern void conf_add_class_to_conf(struct ConfItem *);
+extern void conf_add_me(struct ConfItem *);
+extern void conf_add_class(struct ConfItem *, int);
+extern void conf_add_d_conf(struct ConfItem *);
+extern void flush_expired_ips(void *);
+
+
+/* XXX consider moving these into kdparse.h */
+extern void parse_k_file(FILE * fb);
+extern void parse_d_file(FILE * fb);
+extern void parse_x_file(FILE * fb);
+extern void parse_resv_file(FILE *);
+extern char *getfield(char *newline);
+
+extern char *get_oper_name(struct Client *client_p);
+
+extern int yylex(void);
+
+extern unsigned long cidr_to_bitmask[];
+
+extern char conffilebuf[IRCD_BUFSIZE + 1];
+extern int lineno;
+
+#define NOT_AUTHORISED (-1)
+#define SOCKET_ERROR (-2)
+#define I_LINE_FULL (-3)
+#define BANNED_CLIENT (-4)
+#define TOO_MANY_LOCAL (-6)
+#define TOO_MANY_GLOBAL (-7)
+#define TOO_MANY_IDENT (-8)
+
+#endif /* INCLUDED_s_conf_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_gline.h: A header for the gline functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_gline.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_s_gline_h
+#define INCLUDED_s_gline_h
+
+#include "config.h"
+#include "ircd_defs.h"
+
+struct Client;
+struct ConfItem;
+
+extern struct ConfItem *find_is_glined(const char *host, const char *name);
+extern void cleanup_glines(void *unused);
+extern void add_gline(struct ConfItem *);
+
+
+typedef struct gline_pending
+{
+ char oper_nick1[NICKLEN + 1];
+ char oper_user1[USERLEN + 1];
+ char oper_host1[HOSTLEN + 1];
+ const char *oper_server1; /* point to scache */
+ char *reason1;
+ time_t time_request1;
+
+ char oper_nick2[NICKLEN + 1];
+ char oper_user2[USERLEN + 1];
+ char oper_host2[HOSTLEN + 1];
+ const char *oper_server2; /* point to scache */
+ char *reason2;
+ time_t time_request2;
+
+ time_t last_gline_time; /* for expiring entry */
+ char user[USERLEN + 1];
+ char host[HOSTLEN + 1];
+}
+gline_pending_t;
+
+/* how long a pending G line can be around
+ * 10 minutes should be plenty
+ */
+
+#define GLINE_PENDING_EXPIRE 600
+#define CLEANUP_GLINES_TIME 300
+
+dlink_list pending_glines;
+extern dlink_list glines;
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ *
+ * Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2003-2004 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: s_log.h 1481 2006-05-27 17:24:05Z nenolod $
+ */
+
+#ifndef INCLUDED_s_log_h
+#define INCLUDED_s_log_h
+
+#include "ircd_defs.h"
+
+typedef enum ilogfile
+{
+ L_MAIN,
+ L_USER,
+ L_FUSER,
+ L_OPERED,
+ L_FOPER,
+ L_SERVER,
+ L_KILL,
+ L_KLINE,
+ L_GLINE,
+ L_OPERSPY,
+ L_IOERROR,
+ LAST_LOGFILE
+} ilogfile;
+
+struct Client;
+
+extern void init_main_logfile(void);
+extern void open_logfiles(void);
+extern void ilog(ilogfile dest, const char *fmt, ...) AFP(2, 3);
+extern void inotice(const char *fmt, ...) AFP(1, 2);
+extern void iwarn(const char *fmt, ...) AFP(1, 2);
+extern void ierror(const char *fmt, ...) AFP(1, 2);
+extern void report_operspy(struct Client *, const char *, const char *);
+extern const char *smalldate(void);
+extern void report_error(const char *, const char *, const char *, int);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * s_newconf.h: code for dealing with conf stuff
+ *
+ * Copyright (C) 2004 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2004 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: s_newconf.h 1747 2006-07-25 21:22:45Z jilles $
+ */
+
+#ifndef INCLUDED_s_newconf_h
+#define INCLUDED_s_newconf_h
+
+#include "setup.h"
+#include "tools.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/rsa.h>
+#endif
+
+struct ConfItem;
+
+extern dlink_list cluster_conf_list;
+extern dlink_list shared_conf_list;
+extern dlink_list oper_conf_list;
+extern dlink_list hubleaf_conf_list;
+extern dlink_list server_conf_list;
+extern dlink_list xline_conf_list;
+extern dlink_list resv_conf_list;
+extern dlink_list nd_list;
+extern dlink_list tgchange_list;
+
+struct _patricia_tree_t *tgchange_tree;
+
+extern void init_s_newconf(void);
+extern void clear_s_newconf(void);
+extern void clear_s_newconf_bans(void);
+
+#define FREE_TARGET(x) ((x)->localClient->targinfo[0])
+#define USED_TARGETS(x) ((x)->localClient->targinfo[1])
+
+typedef struct
+{
+ char *ip;
+ time_t expiry;
+ patricia_node_t *pnode;
+ dlink_node node;
+} tgchange;
+
+void add_tgchange(const char *host);
+tgchange *find_tgchange(const char *host);
+
+/* shared/cluster/hub/leaf confs */
+struct remote_conf
+{
+ char *username;
+ char *host;
+ char *server;
+ int flags;
+ dlink_node node;
+};
+
+/* flags used in shared/cluster */
+#define SHARED_TKLINE 0x0001
+#define SHARED_PKLINE 0x0002
+#define SHARED_UNKLINE 0x0004
+#define SHARED_LOCOPS 0x0008
+#define SHARED_TXLINE 0x0010
+#define SHARED_PXLINE 0x0020
+#define SHARED_UNXLINE 0x0040
+#define SHARED_TRESV 0x0800
+#define SHARED_PRESV 0x0100
+#define SHARED_UNRESV 0x0200
+#define SHARED_REHASH 0x0400
+
+#define SHARED_ALL (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
+ SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
+ SHARED_TRESV | SHARED_PRESV | SHARED_UNRESV)
+#define CLUSTER_ALL (SHARED_ALL | SHARED_LOCOPS)
+
+/* flags used in hub/leaf */
+#define CONF_HUB 0x0001
+#define CONF_LEAF 0x0002
+
+struct oper_conf
+{
+ char *name;
+ char *username;
+ char *host;
+ char *passwd;
+
+ int flags;
+ int umodes;
+
+ unsigned int snomask;
+
+#ifdef HAVE_LIBCRYPTO
+ char *rsa_pubkey_file;
+ RSA *rsa_pubkey;
+#endif
+};
+
+extern struct remote_conf *make_remote_conf(void);
+extern void free_remote_conf(struct remote_conf *);
+
+extern int find_shared_conf(const char *username, const char *host,
+ const char *server, int flags);
+extern void propagate_generic(struct Client *source_p, const char *command,
+ const char *target, int cap, const char *format, ...);
+extern void cluster_generic(struct Client *, const char *, int cltype,
+ int cap, const char *format, ...);
+
+#define OPER_ENCRYPTED 0x00001
+#define OPER_KLINE 0x00002
+#define OPER_UNKLINE 0x00004
+#define OPER_LOCKILL 0x00008
+#define OPER_GLOBKILL 0x00010
+#define OPER_REMOTE 0x00020
+#define OPER_GLINE 0x00040
+#define OPER_XLINE 0x00080
+#define OPER_RESV 0x00100
+#define OPER_NICKS 0x00200
+#define OPER_REHASH 0x00400
+#define OPER_DIE 0x00800
+#define OPER_ADMIN 0x01000
+#define OPER_HADMIN 0x02000
+#define OPER_OPERWALL 0x04000
+#define OPER_INVIS 0x08000
+#define OPER_SPY 0x10000
+#define OPER_REMOTEBAN 0x20000
+/* 0x40000 */
+/* 0x80000 and above are in client.h */
+
+#define OPER_FLAGS (OPER_KLINE|OPER_UNKLINE|OPER_LOCKILL|OPER_GLOBKILL|\
+ OPER_REMOTE|OPER_GLINE|OPER_XLINE|OPER_RESV|\
+ OPER_NICKS|OPER_REHASH|OPER_DIE|OPER_ADMIN|\
+ OPER_HADMIN|OPER_OPERWALL|OPER_INVIS|OPER_SPY|\
+ OPER_REMOTEBAN)
+
+#define IsOperConfEncrypted(x) ((x)->flags & OPER_ENCRYPTED)
+
+#define IsOperGlobalKill(x) ((x)->flags2 & OPER_GLOBKILL)
+#define IsOperLocalKill(x) ((x)->flags2 & OPER_LOCKILL)
+#define IsOperRemote(x) ((x)->flags2 & OPER_REMOTE)
+#define IsOperUnkline(x) ((x)->flags2 & OPER_UNKLINE)
+#define IsOperGline(x) ((x)->flags2 & OPER_GLINE)
+#define IsOperN(x) ((x)->flags2 & OPER_NICKS)
+#define IsOperK(x) ((x)->flags2 & OPER_KLINE)
+#define IsOperXline(x) ((x)->flags2 & OPER_XLINE)
+#define IsOperDie(x) ((x)->flags2 & OPER_DIE)
+#define IsOperRehash(x) ((x)->flags2 & OPER_REHASH)
+#define IsOperHiddenAdmin(x) ((x)->flags2 & OPER_HADMIN)
+#define IsOperAdmin(x) (((x)->flags2 & OPER_ADMIN) || \
+ ((x)->flags2 & OPER_HADMIN))
+#define IsOperOperwall(x) ((x)->flags2 & OPER_OPERWALL)
+#define IsOperSpy(x) ((x)->flags2 & OPER_SPY)
+#define IsOperInvis(x) ((x)->flags2 & OPER_INVIS)
+#define IsOperRemoteBan(x) ((x)->flags2 & OPER_REMOTEBAN)
+
+extern struct oper_conf *make_oper_conf(void);
+extern void free_oper_conf(struct oper_conf *);
+extern void clear_oper_conf(void);
+
+extern struct oper_conf *find_oper_conf(const char *username, const char *host,
+ const char *locip, const char *oname);
+
+extern const char *get_oper_privs(int flags);
+
+struct server_conf
+{
+ char *name;
+ char *host;
+ char *passwd;
+ char *spasswd;
+ int port;
+ int flags;
+ int servers;
+ time_t hold;
+
+ int aftype;
+ struct irc_sockaddr_storage my_ipnum;
+
+ char *class_name;
+ struct Class *class;
+ dlink_node node;
+};
+
+#define SERVER_ILLEGAL 0x0001
+#define SERVER_VHOSTED 0x0002
+#define SERVER_ENCRYPTED 0x0004
+#define SERVER_COMPRESSED 0x0008
+#define SERVER_TB 0x0010
+#define SERVER_AUTOCONN 0x0020
+
+#define ServerConfIllegal(x) ((x)->flags & SERVER_ILLEGAL)
+#define ServerConfVhosted(x) ((x)->flags & SERVER_VHOSTED)
+#define ServerConfEncrypted(x) ((x)->flags & SERVER_ENCRYPTED)
+#define ServerConfCompressed(x) ((x)->flags & SERVER_COMPRESSED)
+#define ServerConfTb(x) ((x)->flags & SERVER_TB)
+#define ServerConfAutoconn(x) ((x)->flags & SERVER_AUTOCONN)
+
+extern struct server_conf *make_server_conf(void);
+extern void free_server_conf(struct server_conf *);
+extern void clear_server_conf(void);
+extern void add_server_conf(struct server_conf *);
+
+extern struct server_conf *find_server_conf(const char *name);
+
+extern void attach_server_conf(struct Client *, struct server_conf *);
+extern void detach_server_conf(struct Client *);
+extern void set_server_conf_autoconn(struct Client *source_p, char *name,
+ int newval);
+
+
+extern struct ConfItem *find_xline(const char *, int);
+extern struct ConfItem *find_nick_resv(const char *name);
+
+extern int valid_wild_card_simple(const char *);
+extern int clean_resv_nick(const char *);
+time_t valid_temp_time(const char *p);
+
+struct nd_entry
+{
+ char name[NICKLEN+1];
+ time_t expire;
+ unsigned int hashv;
+
+ dlink_node hnode; /* node in hash */
+ dlink_node lnode; /* node in ll */
+};
+
+extern void add_nd_entry(const char *name);
+extern void free_nd_entry(struct nd_entry *);
+extern unsigned long get_nd_count(void);
+
+#endif
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_serv.h: A header for the server functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_serv.h 1863 2006-08-27 13:40:37Z jilles $
+ */
+
+#ifndef INCLUDED_serv_h
+#define INCLUDED_serv_h
+
+#include "config.h"
+
+/*
+ * The number of seconds between calls to try_connections(). Fiddle with
+ * this ONLY if you KNOW what you're doing!
+ */
+#define TRY_CONNECTIONS_TIME 60
+
+/* collect ziplinks compression ratios/etc every minute */
+#define ZIPSTATS_TIME 60
+
+/*
+ * number of seconds to wait after server starts up, before
+ * starting try_connections()
+ * TOO SOON and you can nick collide like crazy.
+ */
+#define STARTUP_CONNECTIONS_TIME 60
+
+struct Client;
+struct server_conf;
+struct Channel;
+
+/* Capabilities */
+struct Capability
+{
+ const char *name; /* name of capability */
+ unsigned int cap; /* mask value */
+};
+
+#define CAP_CAP 0x00001 /* received a CAP to begin with */
+#define CAP_QS 0x00002 /* Can handle quit storm removal */
+#define CAP_EX 0x00004 /* Can do channel +e exemptions */
+#define CAP_CHW 0x00008 /* Can do channel wall @# */
+#define CAP_IE 0x00010 /* Can do invite exceptions */
+#define CAP_KLN 0x00040 /* Can do KLINE message */
+#define CAP_GLN 0x00080 /* Can do GLINE message */
+#define CAP_ZIP 0x00100 /* Can do ZIPlinks */
+#define CAP_KNOCK 0x00400 /* supports KNOCK */
+#define CAP_TB 0x00800 /* supports TBURST */
+#define CAP_UNKLN 0x01000 /* supports remote unkline */
+#define CAP_CLUSTER 0x02000 /* supports cluster stuff */
+#define CAP_ENCAP 0x04000 /* supports ENCAP */
+#define CAP_TS6 0x08000 /* supports TS6 or above */
+#define CAP_SERVICE 0x10000
+#define CAP_RSFNC 0x20000 /* rserv FNC */
+#define CAP_SAVE 0x40000 /* supports SAVE (nick collision FNC) */
+#define CAP_EUID 0x80000 /* supports EUID (ext UID + nonencap CHGHOST) */
+
+#define CAP_MASK (CAP_QS | CAP_EX | CAP_CHW | \
+ CAP_IE | CAP_KLN | CAP_SERVICE |\
+ CAP_GLN | CAP_CLUSTER | CAP_ENCAP | \
+ CAP_ZIP | CAP_KNOCK | CAP_UNKLN | \
+ CAP_RSFNC | CAP_SAVE | CAP_EUID)
+
+#ifdef HAVE_LIBZ
+#define CAP_ZIP_SUPPORTED CAP_ZIP
+#else
+#define CAP_ZIP_SUPPORTED 0
+#endif
+
+/*
+ * Capability macros.
+ */
+#define IsCapable(x, cap) (((x)->localClient->caps & (cap)) == cap)
+#define NotCapable(x, cap) (((x)->localClient->caps & (cap)) == 0)
+#define ClearCap(x, cap) ((x)->localClient->caps &= ~(cap))
+
+#define SLINKCMD_SET_ZIP_OUT_LEVEL 1 /* data */
+#define SLINKCMD_START_ZIP_OUT 2
+#define SLINKCMD_START_ZIP_IN 3
+#define SLINKCMD_INJECT_RECVQ 4 /* data */
+#define SLINKCMD_INJECT_SENDQ 5 /* data */
+#define SLINKCMD_INIT 6
+#define SLINKCMD_ZIPSTATS 7
+
+#ifndef HAVE_SOCKETPAIR
+#define LAST_SLINK_FD 7
+#else
+#define LAST_SLINK_FD 5
+#endif
+
+#define SLINKRPL_FLAG_DATA 0x0001 /* reply has data following */
+#define SLINKRPL_ERROR 1
+#define SLINKRPL_ZIPSTATS 2
+
+#define MAX_SLINKRPL 2
+
+typedef void SlinkRplHnd(unsigned int replyid, unsigned int datalen,
+ unsigned char *data, struct Client *client_p);
+struct SlinkRplDef
+{
+ unsigned int replyid;
+ SlinkRplHnd *handler;
+ unsigned int flags;
+};
+
+extern struct SlinkRplDef slinkrpltab[];
+
+/*
+ * Globals
+ *
+ *
+ * list of recognized server capabilities. "TS" is not on the list
+ * because all servers that we talk to already do TS, and the kludged
+ * extra argument to "PASS" takes care of checking that. -orabidoo
+ */
+extern struct Capability captab[];
+
+extern int MaxClientCount; /* GLOBAL - highest number of clients */
+extern int MaxConnectionCount; /* GLOBAL - highest number of connections */
+
+extern int refresh_user_links;
+
+/*
+ * return values for hunt_server()
+ */
+#define HUNTED_NOSUCH (-1) /* if the hunted server is not found */
+#define HUNTED_ISME 0 /* if this server should execute the command */
+#define HUNTED_PASS 1 /* if message passed onwards successfully */
+
+
+extern int hunt_server(struct Client *client_pt,
+ struct Client *source_pt,
+ const char *command, int server, int parc, const char **parv);
+extern void send_capabilities(struct Client *, int);
+extern const char *show_capabilities(struct Client *client);
+extern void try_connections(void *unused);
+extern void start_collect_zipstats(void);
+extern void collect_zipstats(void *unused);
+
+extern int check_server(const char *name, struct Client *server);
+extern int server_estab(struct Client *client_p);
+
+extern int serv_connect(struct server_conf *, struct Client *);
+
+#endif /* INCLUDED_s_serv_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_stats.h: A header for the statistics functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_stats.h 1409 2006-05-21 14:46:17Z jilles $
+ */
+
+#ifndef INCLUDED_s_stats_h
+#define INCLUDED_s_stats_h
+
+#include "config.h"
+
+#define _1MEG (1024.0)
+#define _1GIG (1024.0*1024.0)
+#define _1TER (1024.0*1024.0*1024.0)
+#define _GMKs(x) ( (x > _1TER) ? "Terabytes" : ((x > _1GIG) ? "Gigabytes" : \
+ ((x > _1MEG) ? "Megabytes" : "Kilobytes")))
+#define _GMKv(x) ( (x > _1TER) ? (float)(x/_1TER) : ((x > _1GIG) ? \
+ (float)(x/_1GIG) : ((x > _1MEG) ? (float)(x/_1MEG) : (float)x)))
+
+struct Client;
+
+/*
+ * statistics structures
+ */
+struct ServerStatistics
+{
+ unsigned int is_cl; /* number of client connections */
+ unsigned int is_sv; /* number of server connections */
+ unsigned int is_ni; /* connection but no idea who it was */
+ unsigned short is_cbs; /* bytes sent to clients */
+ unsigned short is_cbr; /* bytes received to clients */
+ unsigned short is_sbs; /* bytes sent to servers */
+ unsigned short is_sbr; /* bytes received to servers */
+ unsigned long is_cks; /* k-bytes sent to clients */
+ unsigned long is_ckr; /* k-bytes received to clients */
+ unsigned long is_sks; /* k-bytes sent to servers */
+ unsigned long is_skr; /* k-bytes received to servers */
+ time_t is_cti; /* time spent connected by clients */
+ time_t is_sti; /* time spent connected by servers */
+ unsigned int is_ac; /* connections accepted */
+ unsigned int is_ref; /* accepts refused */
+ unsigned int is_unco; /* unknown commands */
+ unsigned int is_wrdi; /* command going in wrong direction */
+ unsigned int is_unpf; /* unknown prefix */
+ unsigned int is_empt; /* empty message */
+ unsigned int is_num; /* numeric message */
+ unsigned int is_kill; /* number of kills generated on collisions */
+ unsigned int is_save; /* number of saves generated on collisions */
+ unsigned int is_asuc; /* successful auth requests */
+ unsigned int is_abad; /* bad auth requests */
+ unsigned int is_rej; /* rejected from cache */
+ unsigned int is_ssuc; /* successful sasl authentications */
+ unsigned int is_sbad; /* failed sasl authentications */
+};
+
+extern struct ServerStatistics *ServerStats;
+
+extern void init_stats(void);
+extern void tstats(struct Client *client);
+
+extern void count_memory(struct Client *);
+
+#endif /* INCLUDED_s_stats_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_user.h: A header for the user functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: s_user.h 1887 2006-08-29 13:42:56Z jilles $
+ */
+
+#ifndef INCLUDED_s_user_h
+#define INCLUDED_s_user_h
+
+#include "config.h"
+
+struct Client;
+struct User;
+struct oper_conf;
+extern time_t LastUsedWallops;
+
+extern int valid_hostname(const char *hostname);
+extern int valid_username(const char *username);
+
+extern int user_mode(struct Client *, struct Client *, int, const char **);
+extern void send_umode(struct Client *, struct Client *, int, int, char *);
+extern void send_umode_out(struct Client *, struct Client *, int);
+extern int show_lusers(struct Client *source_p);
+extern int register_local_user(struct Client *, struct Client *, const char *);
+
+extern int introduce_client(struct Client *client_p, struct Client *source_p,
+ struct User *user, const char *nick, int use_euid);
+
+extern void change_nick_user_host(struct Client *target_p, const char *nick, const char *user,
+ const char *host, int newts, char *format, ...);
+
+extern int user_modes[256];
+extern void construct_umodebuf(void);
+
+extern int oper_up(struct Client *, struct oper_conf *);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * scache.h: A header for the servername cache functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: scache.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_scache_h
+#define INCLUDED_scache_h
+
+extern void clear_scache_hash_table(void);
+extern const char *find_or_add(const char *name);
+extern void count_scache(size_t *, size_t *);
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * send.h: A header for the message sending functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: send.h 661 2006-02-03 04:20:31Z gxti $
+ */
+
+#ifndef INCLUDED_send_h
+#define INCLUDED_send_h
+
+#include "ircd_defs.h"
+#include "config.h" /* HAVE_STDARG_H */
+
+struct Client;
+struct Channel;
+struct dlink_list;
+
+/* The nasty global also used in s_serv.c for server bursts */
+extern unsigned long current_serial;
+
+extern void send_queued_write(int fd, void *data);
+extern void send_queued_slink_write(int fd, void *data);
+
+extern void sendto_one(struct Client *target_p, const char *, ...) AFP(2, 3);
+extern void sendto_one_notice(struct Client *target_p,const char *, ...) AFP(2, 3);
+extern void sendto_one_prefix(struct Client *target_p, struct Client *source_p,
+ const char *command, const char *, ...) AFP(4, 5);
+extern void sendto_one_numeric(struct Client *target_p,
+ int numeric, const char *, ...) AFP(3, 4);
+
+extern void sendto_server(struct Client *one, struct Channel *chptr,
+ unsigned long caps, unsigned long nocaps,
+ const char *format, ...) AFP(5, 6);
+
+extern void sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
+ struct Channel *chptr, const char *, ...) AFP(5, 6);
+
+extern void sendto_channel_local(int type, struct Channel *, const char *, ...) AFP(3, 4);
+extern void sendto_channel_local_butone(struct Client *, int type, struct Channel *, const char *, ...) AFP(4, 5);
+extern void sendto_common_channels_local(struct Client *, const char *, ...) AFP(2, 3);
+extern void sendto_common_channels_local_butone(struct Client *, const char *, ...) AFP(2, 3);
+
+
+extern void sendto_match_butone(struct Client *, struct Client *,
+ const char *, int, const char *, ...) AFP(5, 6);
+extern void sendto_match_servs(struct Client *source_p, const char *mask,
+ int capab, int, const char *, ...) AFP(5, 6);
+
+extern void sendto_anywhere(struct Client *, struct Client *, const char *,
+ const char *, ...) AFP(4, 5);
+
+extern void sendto_realops_flags(int, int, const char *, ...) AFP(3, 4);
+extern void sendto_realops_snomask(int, int, const char *, ...) AFP(3, 4);
+extern void sendto_realops_snomask_from(int, int, struct Client *, const char *, ...) AFP(4, 5);
+
+extern void sendto_wallops_flags(int, struct Client *, const char *, ...) AFP(3, 4);
+
+extern void kill_client(struct Client *client_p, struct Client *diedie,
+ const char *pattern, ...) AFP(3, 4);
+extern void kill_client_serv_butone(struct Client *one, struct Client *source_p,
+ const char *pattern, ...) AFP(3, 4);
+
+#define L_ALL 0
+#define L_OPER 1
+#define L_ADMIN 2
+#define L_NETWIDE 256 /* OR with L_ALL or L_OPER */
+
+#define NOCAPS 0 /* no caps */
+
+/* used when sending to #mask or $mask */
+#define MATCH_SERVER 1
+#define MATCH_HOST 2
+
+#endif /* INCLUDED_send_h */
--- /dev/null
+#define SERNO "20070123-3139"
--- /dev/null
+/* include/setup.h.in. Generated from configure.ac by autoheader. */
+
+/* Size of the ban heap. */
+#undef BAN_HEAP_SIZE
+
+/* Size of the channel heap. */
+#undef CHANNEL_HEAP_SIZE
+
+/* Define this if you are profiling. */
+#undef CHARYBDIS_PROFILE
+
+/* Size of the client heap. */
+#undef CLIENT_HEAP_SIZE
+
+/* Size of the confitem heap. */
+#undef CONFITEM_HEAP_SIZE
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Size of the dlink_node heap. */
+#undef DNODE_HEAP_SIZE
+
+/* Prefix where config files are installed. */
+#undef ETC_DIR
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <crypt.h> header file. */
+#undef HAVE_CRYPT_H
+
+/* Define to 1 if you have the <devpoll.h> header file. */
+#undef HAVE_DEVPOLL_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlfunc' function. */
+#undef HAVE_DLFUNC
+
+/* Define if the dlopen function is available. */
+#undef HAVE_DLOPEN
+
+/* Define if your system supports the epoll system calls */
+#undef HAVE_EPOLL
+
+/* Define to 1 if you have the `epoll_ctl' function. */
+#undef HAVE_EPOLL_CTL
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `kevent' function. */
+#undef HAVE_KEVENT
+
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define to 1 if zlib (-lz) is available. */
+#undef HAVE_LIBZ
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+#undef HAVE_MACHINE_ENDIAN_H
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#undef HAVE_MACH_O_DYLD_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define if nanosleep exists */
+#undef HAVE_NANOSLEEP
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define if the shl_load function is available. */
+#undef HAVE_SHL_LOAD
+
+/* Define to 1 if you have the `socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
+/* Define to 1 if you have the <sys/devpoll.h> header file. */
+#undef HAVE_SYS_DEVPOLL_H
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/syslog.h> header file. */
+#undef HAVE_SYS_SYSLOG_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the <wait.h> header file. */
+#undef HAVE_WAIT_H
+
+/* Prefix where help file are installed. */
+#undef HELP_DIR
+
+/* Define if IPv6 support is present and available. */
+#undef IPV6
+
+/* Prefix where the ircd is installed. */
+#undef IRCD_PREFIX
+
+/* Size of the local client heap. */
+#undef LCLIENT_HEAP_SIZE
+
+/* Size of the linebuf heap. */
+#undef LINEBUF_HEAP_SIZE
+
+/* Prefix where to write logfiles. */
+#undef LOG_DIR
+
+/* the system's memory page size */
+#undef MALLOC_PAGESIZE
+
+/* Maximum number of network connections */
+#undef MAX_CLIENTS
+
+/* Sizeof member heap. */
+#undef MEMBER_HEAP_SIZE
+
+/* Prefix where modules are installed. */
+#undef MODULE_DIR
+
+/* Size of the monitor heap. */
+#undef MONITOR_HEAP_SIZE
+
+/* Define this to disable debugging support. */
+#undef NDEBUG
+
+/* Size of the nick delay heap. */
+#undef ND_HEAP_SIZE
+
+/* Nickname length */
+#undef NICKLEN
+
+/* Size of the WHOWAS array. */
+#undef NICKNAMEHISTORYLENGTH
+
+/* Define to 1 if you wish to disable the block allocator. */
+#undef NOBALLOC
+
+/* Define to 1 if your system has no in6addr_any. */
+#undef NO_IN6ADDR_ANY
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Path to /dev/null */
+#undef PATH_DEVNULL
+
+/* Size of the pre-client heap. */
+#undef PCLIENT_HEAP_SIZE
+
+/* Define to 1 if you are using the assembly-based hashing routines. */
+#undef RICER_HASHING
+
+/* This is the type of IO loop we are using */
+#undef SELECT_TYPE
+
+/* Suffix for shared libraries on this platform. */
+#undef SHARED_SUFFIX
+
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of a `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* Define to 1 if sockaddr has a 'sa_len' member. */
+#undef SOCKADDR_IN_HAS_LEN
+
+/* Define this to enable soft asserts. */
+#undef SOFT_ASSERT
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if dynamic modules can't be used. */
+#undef STATIC_MODULES
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if string.h may be included along with strings.h */
+#undef STRING_WITH_STRINGS
+
+/* String containing extra underscores prepended to symbols loaded from
+ modules. */
+#undef SYMBOL_PREFIX
+
+/* Maximum topic length (<=390) */
+#undef TOPICLEN
+
+/* Size of the topic heap. */
+#undef TOPIC_HEAP_SIZE
+
+/* Size of the user heap. */
+#undef USER_HEAP_SIZE
+
+/* Define this to enable IO Debug hooks. */
+#undef USE_IODEBUG_HOOKS
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+
+/* This is needed to use strtok_r on Solaris. */
+#undef __EXTENSIONS__
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* If system does not define in_port_t, define it to what it should be. */
+#undef in_port_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* If system does not define sa_family_t, define it here. */
+#undef sa_family_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* If we don't have a real socklen_t, unsigned int is good enough. */
+#undef socklen_t
+
+/* If system does not define u_int16_t, define a usable substitute. */
+#undef u_int16_t
+
+/* If system does not define u_int32_t, define to unsigned long int here. */
+#undef u_int32_t
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * snomask.h: Management for user server-notice masks.
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef SNOMASK_H
+#define SNOMASK_H
+
+#include "client.h"
+
+#define SNO_ADD 1
+#define SNO_DEL 2
+
+#define SNO_CCONNEXT 0x00000001
+#define SNO_BOTS 0x00000002
+#define SNO_CCONN 0x00000004
+#define SNO_DEBUG 0x00000008
+#define SNO_FULL 0x00000010
+#define SNO_SKILL 0x00000020
+#define SNO_NCHANGE 0x00000040
+#define SNO_REJ 0x00000080
+#define SNO_GENERAL 0x00000100
+#define SNO_UNAUTH 0x00000200
+#define SNO_EXTERNAL 0x00000400
+#define SNO_SPY 0x00000800
+#define SNO_OPERSPY 0x00001000
+
+char *construct_snobuf(unsigned int val);
+unsigned int parse_snobuf_to_mask(unsigned int val, const char *sno);
+unsigned int find_snomask_slot(void);
+
+extern int snomask_modes[];
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * sprintf_irc.h: The irc sprintf header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: sprintf_irc.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef SPRINTF_IRC
+#define SPRINTF_IRC
+
+#include <stdarg.h>
+
+/*=============================================================================
+ * Proto types
+ */
+
+
+/*
+ * ircsprintf - optimized sprintf
+ */
+#ifdef __GNUC__
+int ircsprintf(char *str, const char *fmt, ...) __attribute((format(printf, 2, 3)));
+int ircsnprintf(char *str, const size_t size, const char *, ...) __attribute__ ((format(printf, 3, 4)));
+#else
+int ircsprintf(char *str, const char *format, ...);
+int ircsnprintf(char *str, const size_t size, const char *, ...);
+#endif
+
+int ircvsnprintf(char *str, const size_t size, const char *fmt, va_list args);
+int ircvsprintf(char *str, const char *fmt, va_list args);
+
+#endif /* SPRINTF_IRC */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * stdinc.h: Pull in all of the necessary system headers
+ *
+ * Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
+ *
+ * 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
+ *
+ * $Id: stdinc.h 6 2005-09-10 01:02:21Z nenolod $
+ *
+ */
+
+
+#include "config.h" /* Gotta pull in the autoconf stuff */
+
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+#undef alloca
+#define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef STRING_WITH_STRINGS
+# include <string.h>
+# include <strings.h>
+#else
+# ifdef HAVE_STRING_H
+# include <string.h>
+# else
+# ifdef HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+#endif
+
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdio.h>
+#include <time.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <dirent.h>
+#include <ctype.h>
+
+#include <limits.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#else
+extern int errno;
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#if defined(__INTEL_COMPILER) || defined(__GNUC__)
+# ifdef __unused
+# undef __unused
+# endif
+# ifdef __printf
+# undef __printf
+# endif
+# ifdef __noreturn
+# undef __noreturn
+# endif
+
+# define __unused __attribute__((__unused__))
+# define __printf(x) __attribute__((__format__ (__printf__, x, x + 1)))
+# define __noreturn __attribute__((__noreturn__))
+#else
+# define __unused
+# define __printf
+# define __noreturn
+#endif
+
+
+
+#ifdef strdupa
+#define LOCAL_COPY(s) strdupa(s)
+#else
+#if defined(__INTEL_COMPILER) || defined(__GNUC__)
+# define LOCAL_COPY(s) __extension__({ char *_s = alloca(strlen(s) + 1); strcpy(_s, s); _s; })
+#else
+# define LOCAL_COPY(s) strcpy(alloca(strlen(s) + 1), s) /* XXX Is that allowed? */
+#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */
+#endif /* strdupa */
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * supported.h: isupport (005) numeric
+ *
+ * Entirely rewritten, August 2006 by Jilles Tjoelker
+ * Copyright (C) 2006 Jilles Tjoelker
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: supported.h 1887 2006-08-29 13:42:56Z jilles $
+ */
+
+#ifndef INCLUDED_supported_h
+#define INCLUDED_supported_h
+
+extern void add_isupport(const char *, const char *(*)(void *), void *);
+extern void delete_isupport(const char *);
+extern void show_isupport(struct Client *);
+extern void init_isupport(void);
+
+extern const char *isupport_intptr(void *);
+extern const char *isupport_boolean(void *);
+extern const char *isupport_string(void *);
+extern const char *isupport_stringptr(void *);
+
+#endif /* INCLUDED_supported_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * whowas.h: Header for the whowas functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: whowas.h 1717 2006-07-04 14:41:11Z jilles $
+ */
+#ifndef INCLUDED_whowas_h
+#define INCLUDED_whowas_h
+
+#include "ircd_defs.h"
+#include "client.h"
+
+#include "setup.h"
+
+/*
+ * Whowas hash table size
+ *
+ */
+#define WW_MAX_BITS 16
+#define WW_MAX 65536
+
+struct User;
+struct Client;
+
+/*
+ lets speed this up...
+ also removed away information. *tough*
+ - Dianora
+ */
+struct Whowas
+{
+ int hashv;
+ char name[NICKLEN + 1];
+ char username[USERLEN + 1];
+ char hostname[HOSTLEN + 1];
+ char sockhost[HOSTIPLEN + 1];
+ const char *servername;
+ char realname[REALLEN + 1];
+ time_t logoff;
+ struct Client *online; /* Pointer to new nickname for chasing or NULL */
+ struct Whowas *next; /* for hash table... */
+ struct Whowas *prev; /* for hash table... */
+ struct Whowas *cnext; /* for client struct linked list */
+ struct Whowas *cprev; /* for client struct linked list */
+};
+
+/*
+** initwhowas
+*/
+extern void initwhowas(void);
+
+/*
+** add_history
+** Add the currently defined name of the client to history.
+** usually called before changing to a new name (nick).
+** Client must be a fully registered user (specifically,
+** the user structure must have been allocated).
+*/
+void add_history(struct Client *, int);
+
+/*
+** off_history
+** This must be called when the client structure is about to
+** be released. History mechanism keeps pointers to client
+** structures and it must know when they cease to exist. This
+** also implicitly calls AddHistory.
+*/
+void off_history(struct Client *);
+
+/*
+** get_history
+** Return the current client that was using the given
+** nickname within the timelimit. Returns NULL, if no
+** one found...
+*/
+struct Client *get_history(const char *, time_t);
+ /* Nick name */
+ /* Time limit in seconds */
+
+/*
+** for debugging...counts related structures stored in whowas array.
+*/
+void count_whowas_memory(size_t *, size_t *);
+
+/* XXX m_whowas.c in modules needs these */
+extern struct Whowas WHOWAS[];
+extern struct Whowas *WHOWASHASH[];
+extern unsigned int hash_whowas_name(const char *name);
+
+#endif /* INCLUDED_whowas_h */
--- /dev/null
+#!/bin/sh
+# $Id: install-sh 6 2005-09-10 01:02:21Z nenolod $
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
--- /dev/null
+#
+# Makefile.in for ircd/src/io
+#
+# $Id: Makefile.in 1269 2006-04-30 16:51:11Z nenolod $
+#
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_BIN = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+RM = @RM@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+LDFLAGS = @LDFLAGS@
+MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
+MV = @MV@
+RM = @RM@
+YACC = @YACC@
+AR = @AR@
+RANLIB = @RANLIB@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libexecdir = @libexecdir@
+sysconfdir = @sysconfdir@
+localstatedir = @localstatedir@
+# Change this later! -- adrian
+moduledir = @prefix@/modules
+automoduledir = @prefix@/modules/autoload
+
+INCLUDES = -I../include -I../adns -I.
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+default: all
+
+BASE_SRCS = \
+ balloc.c \
+ commio.c \
+ event.c \
+ libcharybdis.c \
+ linebuf.c \
+ memory.c \
+ snprintf.c \
+ tools.c
+
+SRCS = ${BASE_SRCS} @SELECT_TYPE@.c
+
+OBJS = ${SRCS:.c=.o}
+
+all: libcharybdis.a
+
+build: all
+
+libcharybdis.a: ${OBJS}
+ rm -f $@
+ ${AR} cqv $@ ${OBJS}
+ ${RANLIB} $@
+
+# this is really the default rule for c files
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $<
+
+.PHONY: depend clean distclean
+
+install:
+
+depend:
+ @${MKDEP} ${CPPFLAGS} ${BASE_SRCS} ${EXTRA_SRCS} > .depend.tmp
+ @sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
+ @echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
+ @echo '# make depend needs it.' >>Makefile.depend
+ @cat .depend.tmp >>Makefile.depend
+ @mv Makefile.depend Makefile
+ @rm -f .depend.tmp
+
+clean:
+ ${RM} -f *.o *.exe *~ libcharybdis.a
+
+lint:
+
+distclean: clean
+ ${RM} -f Makefile version.c.last
+
+# DO NOT DELETE THIS LINE!!!
+# make depend needs it.
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * balloc.c: A block allocator.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ *
+ * File: blalloc.c
+ * Owner: Wohali (Joan Touzet)
+ *
+ * Modified 2001/11/29 for mmap() support by Aaron Sethman <androsyn@ratbox.org>
+ *
+ * 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
+ *
+ * $Id: balloc.c 388 2005-12-07 16:34:40Z nenolod $
+ */
+
+/*
+ * About the block allocator
+ *
+ * Basically we have three ways of getting memory off of the operating
+ * system. Below are this list of methods and the order of preference.
+ *
+ * 1. mmap() anonymous pages with the MMAP_ANON flag.
+ * 2. mmap() via the /dev/zero trick.
+ * 3. malloc()
+ *
+ * The advantages of 1 and 2 are this. We can munmap() the pages which will
+ * return the pages back to the operating system, thus reducing the size
+ * of the process as the memory is unused. malloc() on many systems just keeps
+ * a heap of memory to itself, which never gets given back to the OS, except on
+ * exit. This of course is bad, if say we have an event that causes us to allocate
+ * say, 200MB of memory, while our normal memory consumption would be 15MB. In the
+ * malloc() case, the amount of memory allocated to our process never goes down, as
+ * malloc() has it locked up in its heap. With the mmap() method, we can munmap()
+ * the block and return it back to the OS, thus causing our memory consumption to go
+ * down after we no longer need it.
+ *
+ * Of course it is up to the caller to make sure BlockHeapGarbageCollect() gets
+ * called periodically to do this cleanup, otherwise you'll keep the memory in the
+ * process.
+ *
+ *
+ */
+
+#include "stdinc.h"
+#include "libcharybdis.h"
+
+#define WE_ARE_MEMORY_C
+#include "setup.h"
+#include "balloc.h"
+#ifndef NOBALLOC
+
+#include "ircd_defs.h" /* DEBUG_BLOCK_ALLOCATOR */
+#include "ircd.h"
+#include "memory.h"
+#include "irc_string.h"
+#include "tools.h"
+#include "s_log.h"
+#include "client.h"
+#include "event.h"
+
+#ifdef HAVE_MMAP /* We've got mmap() that is good */
+#include <sys/mman.h>
+/* HP-UX sucks */
+#ifdef MAP_ANONYMOUS
+#ifndef MAP_ANON
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+#endif
+#endif
+
+static int newblock(BlockHeap * bh);
+static int BlockHeapGarbageCollect(BlockHeap *);
+static void block_heap_gc(void *unused);
+static dlink_list heap_lists;
+
+#if defined(HAVE_MMAP) && !defined(MAP_ANON)
+static int zero_fd = -1;
+#endif
+
+#define blockheap_fail(x) _blockheap_fail(x, __FILE__, __LINE__)
+
+static void
+_blockheap_fail(const char *reason, const char *file, int line)
+{
+ libcharybdis_log("Blockheap failure: %s (%s:%d)", reason, file, line);
+ abort();
+}
+
+
+/*
+ * static inline void free_block(void *ptr, size_t size)
+ *
+ * Inputs: The block and its size
+ * Output: None
+ * Side Effects: Returns memory for the block back to the OS
+ */
+static inline void
+free_block(void *ptr, size_t size)
+{
+#ifdef HAVE_MMAP
+ munmap(ptr, size);
+#else
+ free(ptr);
+#endif
+}
+
+#ifdef DEBUG_BALLOC
+/* Check the list length the very slow way */
+static unsigned long
+slow_list_length(dlink_list *list)
+{
+ dlink_node *ptr;
+ unsigned long count = 0;
+
+ for (ptr = list->head; ptr; ptr = ptr->next)
+ {
+ count++;
+ if(count > list->length * 2)
+ {
+ blockheap_fail("count > list->length * 2 - I give up");
+ }
+ }
+ return count;
+}
+
+static void
+bh_sanity_check_block(BlockHeap *bh, Block *block)
+{
+ unsigned long s_used, s_free;
+ s_used = slow_list_length(&block->used_list);
+ s_free = slow_list_length(&block->free_list);
+ if(s_used != dlink_list_length(&block->used_list))
+ blockheap_fail("used link count doesn't match head count");
+ if(s_free != dlink_list_length(&block->free_list))
+ blockheap_fail("free link count doesn't match head count");
+
+ if(dlink_list_length(&block->used_list) + dlink_list_length(&block->free_list) != bh->elemsPerBlock)
+ blockheap_fail("used_list + free_list != elemsPerBlock");
+}
+
+#if 0
+/* See how confused we are */
+static void
+bh_sanity_check(BlockHeap *bh)
+{
+ Block *walker;
+ unsigned long real_alloc = 0;
+ unsigned long s_used, s_free;
+ unsigned long blockcount = 0;
+ unsigned long allocated;
+ if(bh == NULL)
+ blockheap_fail("Trying to sanity check a NULL block");
+
+ allocated = bh->blocksAllocated * bh->elemsPerBlock;
+
+ for(walker = bh->base; walker != NULL; walker = walker->next)
+ {
+ blockcount++;
+ s_used = slow_list_length(&walker->used_list);
+ s_free = slow_list_length(&walker->free_list);
+
+ if(s_used != dlink_list_length(&walker->used_list))
+ blockheap_fail("used link count doesn't match head count");
+ if(s_free != dlink_list_length(&walker->free_list))
+ blockheap_fail("free link count doesn't match head count");
+
+ if(dlink_list_length(&walker->used_list) + dlink_list_length(&walker->free_list) != bh->elemsPerBlock)
+ blockheap_fail("used_list + free_list != elemsPerBlock");
+
+ real_alloc += dlink_list_length(&walker->used_list);
+ real_alloc += dlink_list_length(&walker->free_list);
+ }
+
+ if(allocated != real_alloc)
+ blockheap_fail("block allocations don't match heap");
+
+ if(bh->blocksAllocated != blockcount)
+ blockheap_fail("blocksAllocated don't match blockcount");
+
+
+}
+
+static void
+bh_sanity_check_all(void *unused)
+{
+ dlink_node *ptr;
+ DLINK_FOREACH(ptr, heap_lists.head)
+ {
+ bh_sanity_check(ptr->data);
+ }
+}
+#endif
+
+#endif
+
+
+
+/*
+ * void initBlockHeap(void)
+ *
+ * Inputs: None
+ * Outputs: None
+ * Side Effects: Initializes the block heap
+ */
+
+void
+initBlockHeap(void)
+{
+#if defined(HAVE_MMAP) && !defined(MAP_ANON)
+ zero_fd = open("/dev/zero", O_RDWR);
+
+ if(zero_fd < 0)
+ blockheap_fail("Failed opening /dev/zero");
+ comm_socket(zero_fd, FD_FILE, "Anonymous mmap()");
+#endif
+ eventAddIsh("block_heap_gc", block_heap_gc, NULL, 30);
+}
+
+/*
+ * static inline void *get_block(size_t size)
+ *
+ * Input: Size of block to allocate
+ * Output: Pointer to new block
+ * Side Effects: None
+ */
+static inline void *
+get_block(size_t size)
+{
+ void *ptr;
+#ifdef HAVE_MMAP
+#ifdef MAP_ANON
+ ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+#else
+ ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
+#endif
+ if(ptr == MAP_FAILED)
+ {
+ ptr = NULL;
+ }
+#else
+ ptr = malloc(size);
+#endif
+ return (ptr);
+}
+
+
+static void
+block_heap_gc(void *unused)
+{
+ dlink_node *ptr;
+ DLINK_FOREACH(ptr, heap_lists.head)
+ {
+ BlockHeapGarbageCollect(ptr->data);
+ }
+}
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* newblock */
+/* Description: */
+/* Allocates a new block for addition to a blockheap */
+/* Parameters: */
+/* bh (IN): Pointer to parent blockheap. */
+/* Returns: */
+/* 0 if successful, 1 if not */
+/* ************************************************************************ */
+
+static int
+newblock(BlockHeap * bh)
+{
+ MemBlock *newblk;
+ Block *b;
+ unsigned long i;
+ void *offset;
+
+ /* Setup the initial data structure. */
+ b = (Block *) calloc(1, sizeof(Block));
+ if(b == NULL)
+ {
+ return (1);
+ }
+ b->free_list.head = b->free_list.tail = NULL;
+ b->used_list.head = b->used_list.tail = NULL;
+ b->next = bh->base;
+
+ b->alloc_size = (bh->elemsPerBlock + 1) * (bh->elemSize + sizeof(MemBlock));
+
+ b->elems = get_block(b->alloc_size);
+ if(b->elems == NULL)
+ {
+ return (1);
+ }
+ offset = b->elems;
+ /* Setup our blocks now */
+ for (i = 0; i < bh->elemsPerBlock; i++)
+ {
+ void *data;
+ newblk = (void *) offset;
+ newblk->block = b;
+#ifdef DEBUG_BALLOC
+ newblk->magic = BALLOC_MAGIC;
+#endif
+ data = (void *) ((size_t) offset + sizeof(MemBlock));
+ newblk->block = b;
+ dlinkAdd(data, &newblk->self, &b->free_list);
+ offset = (unsigned char *) ((unsigned char *) offset +
+ bh->elemSize + sizeof(MemBlock));
+ }
+
+ ++bh->blocksAllocated;
+ bh->freeElems += bh->elemsPerBlock;
+ bh->base = b;
+
+ return (0);
+}
+
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* BlockHeapCreate */
+/* Description: */
+/* Creates a new blockheap from which smaller blocks can be allocated. */
+/* Intended to be used instead of multiple calls to malloc() when */
+/* performance is an issue. */
+/* Parameters: */
+/* elemsize (IN): Size of the basic element to be stored */
+/* elemsperblock (IN): Number of elements to be stored in a single block */
+/* of memory. When the blockheap runs out of free memory, it will */
+/* allocate elemsize * elemsperblock more. */
+/* Returns: */
+/* Pointer to new BlockHeap, or NULL if unsuccessful */
+/* ************************************************************************ */
+BlockHeap *
+BlockHeapCreate(size_t elemsize, int elemsperblock)
+{
+ BlockHeap *bh;
+ s_assert(elemsize > 0 && elemsperblock > 0);
+
+ /* Catch idiotic requests up front */
+ if((elemsize <= 0) || (elemsperblock <= 0))
+ {
+ blockheap_fail("Attempting to BlockHeapCreate idiotic sizes");
+ }
+
+ /* Allocate our new BlockHeap */
+ bh = (BlockHeap *) calloc(1, sizeof(BlockHeap));
+ if(bh == NULL)
+ {
+ blockheap_fail("Attempt to calloc() failed");
+ outofmemory(); /* die.. out of memory */
+ }
+
+ if((elemsize % sizeof(void *)) != 0)
+ {
+ /* Pad to even pointer boundary */
+ elemsize += sizeof(void *);
+ elemsize &= ~(sizeof(void *) - 1);
+ }
+
+ bh->elemSize = elemsize;
+ bh->elemsPerBlock = elemsperblock;
+ bh->blocksAllocated = 0;
+ bh->freeElems = 0;
+ bh->base = NULL;
+
+ /* Be sure our malloc was successful */
+ if(newblock(bh))
+ {
+ if(bh != NULL)
+ free(bh);
+ libcharybdis_restart("Aiee! -- newblock() failed!!!");
+ }
+
+ if(bh == NULL)
+ {
+ blockheap_fail("bh == NULL when it shouldn't be");
+ }
+ dlinkAdd(bh, &bh->hlist, &heap_lists);
+ return (bh);
+}
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* BlockHeapAlloc */
+/* Description: */
+/* Returns a pointer to a struct within our BlockHeap that's free for */
+/* the taking. */
+/* Parameters: */
+/* bh (IN): Pointer to the Blockheap. */
+/* Returns: */
+/* Pointer to a structure (void *), or NULL if unsuccessful. */
+/* ************************************************************************ */
+
+void *
+BlockHeapAlloc(BlockHeap * bh)
+{
+ Block *walker;
+ dlink_node *new_node;
+
+ s_assert(bh != NULL);
+ if(bh == NULL)
+ {
+ blockheap_fail("Cannot allocate if bh == NULL");
+ }
+
+ if(bh->freeElems == 0)
+ {
+ /* Allocate new block and assign */
+ /* newblock returns 1 if unsuccessful, 0 if not */
+
+ if(newblock(bh))
+ {
+ /* That didn't work..try to garbage collect */
+ BlockHeapGarbageCollect(bh);
+ if(bh->freeElems == 0)
+ {
+ libcharybdis_restart("newblock() failed and garbage collection didn't help");
+ }
+ }
+ }
+
+ for (walker = bh->base; walker != NULL; walker = walker->next)
+ {
+ if(dlink_list_length(&walker->free_list) > 0)
+ {
+#ifdef DEBUG_BALLOC
+ bh_sanity_check_block(bh, walker);
+#endif
+ bh->freeElems--;
+ new_node = walker->free_list.head;
+ dlinkMoveNode(new_node, &walker->free_list, &walker->used_list);
+ s_assert(new_node->data != NULL);
+ if(new_node->data == NULL)
+ blockheap_fail("new_node->data is NULL and that shouldn't happen!!!");
+ memset(new_node->data, 0, bh->elemSize);
+#ifdef DEBUG_BALLOC
+ do
+ {
+ struct MemBlock *memblock = (void *) ((size_t) new_node->data - sizeof(MemBlock));
+ if(memblock->magic == BALLOC_FREE_MAGIC)
+ memblock->magic = BALLOC_MAGIC;
+
+ } while(0);
+ bh_sanity_check_block(bh, walker);
+#endif
+ return (new_node->data);
+ }
+ }
+ blockheap_fail("BlockHeapAlloc failed, giving up");
+ return NULL;
+}
+
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* BlockHeapFree */
+/* Description: */
+/* Returns an element to the free pool, does not free() */
+/* Parameters: */
+/* bh (IN): Pointer to BlockHeap containing element */
+/* ptr (in): Pointer to element to be "freed" */
+/* Returns: */
+/* 0 if successful, 1 if element not contained within BlockHeap. */
+/* ************************************************************************ */
+int
+BlockHeapFree(BlockHeap * bh, void *ptr)
+{
+ Block *block;
+ struct MemBlock *memblock;
+
+ s_assert(bh != NULL);
+ s_assert(ptr != NULL);
+
+ if(bh == NULL)
+ {
+ libcharybdis_restart("balloc.c:BlockHeapFree() bh == NULL");
+ return (1);
+ }
+
+ if(ptr == NULL)
+ {
+ libcharybdis_restart("balloc.BlockHeapFree() ptr == NULL");
+ return (1);
+ }
+
+ memblock = (void *) ((size_t) ptr - sizeof(MemBlock));
+#ifdef DEBUG_BALLOC
+ if(memblock->magic == BALLOC_FREE_MAGIC)
+ {
+ blockheap_fail("double free of a block");
+ outofmemory();
+ } else
+ if(memblock->magic != BALLOC_MAGIC)
+ {
+ blockheap_fail("memblock->magic != BALLOC_MAGIC");
+ outofmemory();
+ }
+#endif
+ s_assert(memblock->block != NULL);
+ if(memblock->block == NULL)
+ {
+ blockheap_fail("memblock->block == NULL, not a valid block?");
+ outofmemory();
+ }
+
+ block = memblock->block;
+#ifdef DEBUG_BALLOC
+ bh_sanity_check_block(bh, block);
+#endif
+ bh->freeElems++;
+ mem_frob(ptr, bh->elemSize);
+ dlinkMoveNode(&memblock->self, &block->used_list, &block->free_list);
+#ifdef DEBUG_BALLOC
+ bh_sanity_check_block(bh, block);
+#endif
+ return (0);
+}
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* BlockHeapGarbageCollect */
+/* Description: */
+/* Performs garbage collection on the block heap. Any blocks that are */
+/* completely unallocated are removed from the heap. Garbage collection */
+/* will never remove the root node of the heap. */
+/* Parameters: */
+/* bh (IN): Pointer to the BlockHeap to be cleaned up */
+/* Returns: */
+/* 0 if successful, 1 if bh == NULL */
+/* ************************************************************************ */
+static int
+BlockHeapGarbageCollect(BlockHeap * bh)
+{
+ Block *walker, *last;
+ if(bh == NULL)
+ {
+ return (1);
+ }
+
+ if(bh->freeElems < bh->elemsPerBlock || bh->blocksAllocated == 1)
+ {
+ /* There couldn't possibly be an entire free block. Return. */
+ return (0);
+ }
+
+ last = NULL;
+ walker = bh->base;
+
+ while (walker != NULL)
+ {
+ if((dlink_list_length(&walker->free_list) == bh->elemsPerBlock) != 0)
+ {
+ free_block(walker->elems, walker->alloc_size);
+ if(last != NULL)
+ {
+ last->next = walker->next;
+ if(walker != NULL)
+ free(walker);
+ walker = last->next;
+ }
+ else
+ {
+ bh->base = walker->next;
+ if(walker != NULL)
+ free(walker);
+ walker = bh->base;
+ }
+ bh->blocksAllocated--;
+ bh->freeElems -= bh->elemsPerBlock;
+ }
+ else
+ {
+ last = walker;
+ walker = walker->next;
+ }
+ }
+ return (0);
+}
+
+/* ************************************************************************ */
+/* FUNCTION DOCUMENTATION: */
+/* BlockHeapDestroy */
+/* Description: */
+/* Completely free()s a BlockHeap. Use for cleanup. */
+/* Parameters: */
+/* bh (IN): Pointer to the BlockHeap to be destroyed. */
+/* Returns: */
+/* 0 if successful, 1 if bh == NULL */
+/* ************************************************************************ */
+int
+BlockHeapDestroy(BlockHeap * bh)
+{
+ Block *walker, *next;
+
+ if(bh == NULL)
+ {
+ return (1);
+ }
+
+ for (walker = bh->base; walker != NULL; walker = next)
+ {
+ next = walker->next;
+ free_block(walker->elems, walker->alloc_size);
+ if(walker != NULL)
+ free(walker);
+ }
+ dlinkDelete(&bh->hlist, &heap_lists);
+ free(bh);
+ return (0);
+}
+
+void
+BlockHeapUsage(BlockHeap * bh, size_t * bused, size_t * bfree, size_t * bmemusage)
+{
+ size_t used;
+ size_t freem;
+ size_t memusage;
+ if(bh == NULL)
+ {
+ return;
+ }
+
+ freem = bh->freeElems;
+ used = (bh->blocksAllocated * bh->elemsPerBlock) - bh->freeElems;
+ memusage = used * (bh->elemSize + sizeof(MemBlock));
+
+ if(bused != NULL)
+ *bused = used;
+ if(bfree != NULL)
+ *bfree = freem;
+ if(bmemusage != NULL)
+ *bmemusage = memusage;
+}
+
+#endif /* NOBALLOC */
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * balloc.h: The ircd block allocator header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: balloc.h 1781 2006-07-30 18:07:38Z jilles $
+ */
+
+#ifndef INCLUDED_blalloc_h
+#define INCLUDED_blalloc_h
+
+#include "setup.h"
+#include "tools.h"
+#include "memory.h"
+#include "ircd_defs.h"
+
+#define CACHEFILE_HEAP_SIZE 32
+#define CACHELINE_HEAP_SIZE 64
+
+
+#ifdef NOBALLOC
+
+typedef struct BlockHeap BlockHeap;
+#define initBlockHeap()
+#define BlockHeapGarbageCollect(x)
+#define BlockHeapCreate(es, epb) ((BlockHeap*)(es))
+#define BlockHeapDestroy(x)
+#define BlockHeapAlloc(x) MyMalloc((int)x)
+#define BlockHeapFree(x,y) MyFree(y)
+#define BlockHeapUsage(bh, bused, bfree, bmemusage) do { if (bused) (*(size_t *)bused) = 0; if (bfree) *((size_t *)bfree) = 0; if (bmemusage) *((size_t *)bmemusage) = 0; } while(0)
+typedef struct MemBlock
+{
+ void *dummy;
+} MemBlock;
+
+#else
+
+#undef DEBUG_BALLOC
+
+#ifdef DEBUG_BALLOC
+#define BALLOC_MAGIC 0x3d3a3c3d
+#define BALLOC_FREE_MAGIC 0xafafafaf
+#endif
+
+/* status information for an allocated block in heap */
+struct Block
+{
+ size_t alloc_size;
+ struct Block *next; /* Next in our chain of blocks */
+ void *elems; /* Points to allocated memory */
+ dlink_list free_list;
+ dlink_list used_list;
+};
+typedef struct Block Block;
+
+struct MemBlock
+{
+#ifdef DEBUG_BALLOC
+ unsigned long magic;
+#endif
+ dlink_node self;
+ Block *block; /* Which block we belong to */
+};
+
+typedef struct MemBlock MemBlock;
+
+/* information for the root node of the heap */
+struct BlockHeap
+{
+ dlink_node hlist;
+ size_t elemSize; /* Size of each element to be stored */
+ unsigned long elemsPerBlock; /* Number of elements per block */
+ unsigned long blocksAllocated; /* Number of blocks allocated */
+ unsigned long freeElems; /* Number of free elements */
+ Block *base; /* Pointer to first block */
+};
+typedef struct BlockHeap BlockHeap;
+
+extern int BlockHeapFree(BlockHeap * bh, void *ptr);
+extern void *BlockHeapAlloc(BlockHeap * bh);
+
+extern BlockHeap *BlockHeapCreate(size_t elemsize, int elemsperblock);
+extern int BlockHeapDestroy(BlockHeap * bh);
+
+extern void initBlockHeap(void);
+extern void BlockHeapUsage(BlockHeap * bh, size_t * bused, size_t * bfree, size_t * bmemusage);
+
+
+
+#endif /* NOBALLOC */
+
+
+
+#endif /* INCLUDED_blalloc_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * commio.c: Network/file related functions
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: commio.c 1779 2006-07-30 16:36:39Z jilles $
+ */
+
+#include "libcharybdis.h"
+
+#ifndef IN_LOOPBACKNET
+#define IN_LOOPBACKNET 0x7f
+#endif
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+const char *const NONB_ERROR_MSG = "set_non_blocking failed for %s:%s";
+const char *const SETBUF_ERROR_MSG = "set_sock_buffers failed for server %s:%s";
+
+static const char *comm_err_str[] = { "Comm OK", "Error during bind()",
+ "Error during DNS lookup", "connect timeout",
+ "Error during connect()",
+ "Comm Error"
+};
+
+fde_t *fd_table = NULL;
+
+static void fdlist_update_biggest(int fd, int opening);
+
+/* Highest FD and number of open FDs .. */
+int highest_fd = -1; /* Its -1 because we haven't started yet -- adrian */
+int number_fd = 0;
+
+static void comm_connect_callback(int fd, int status);
+static PF comm_connect_timeout;
+static void comm_connect_dns_callback(void *vptr, struct DNSReply *reply);
+static PF comm_connect_tryconnect;
+
+/* 32bit solaris is kinda slow and stdio only supports fds < 256
+ * so we got to do this crap below.
+ * (BTW Fuck you Sun, I hate your guts and I hope you go bankrupt soon)
+ */
+#if defined (__SVR4) && defined (__sun)
+static void comm_fd_hack(int *fd)
+{
+ int newfd;
+ if(*fd > 256 || *fd < 0)
+ return;
+ if((newfd = fcntl(*fd, F_DUPFD, 256)) != -1)
+ {
+ close(*fd);
+ *fd = newfd;
+ }
+ return;
+}
+#else
+#define comm_fd_hack(fd)
+#endif
+
+
+/* close_all_connections() can be used *before* the system come up! */
+
+void
+comm_close_all(void)
+{
+ int i;
+#ifndef NDEBUG
+ int fd;
+#endif
+
+ /* XXX someone tell me why we care about 4 fd's ? */
+ /* XXX btw, fd 3 is used for profiler ! */
+
+ for (i = 4; i < MAXCONNECTIONS; ++i)
+ {
+ if(fd_table[i].flags.open)
+ comm_close(i);
+ else
+ close(i);
+ }
+
+ /* XXX should his hack be done in all cases? */
+#ifndef NDEBUG
+ /* fugly hack to reserve fd == 2 */
+ (void) close(2);
+ fd = open("stderr.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
+ if(fd >= 0)
+ {
+ dup2(fd, 2);
+ close(fd);
+ }
+#endif
+}
+
+/*
+ * get_sockerr - get the error value from the socket or the current errno
+ *
+ * Get the *real* error from the socket (well try to anyway..).
+ * This may only work when SO_DEBUG is enabled but its worth the
+ * gamble anyway.
+ */
+int
+comm_get_sockerr(int fd)
+{
+ int errtmp = errno;
+#ifdef SO_ERROR
+ int err = 0;
+ socklen_t len = sizeof(err);
+
+ if(-1 < fd && !getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *) &err, (socklen_t *) & len))
+ {
+ if(err)
+ errtmp = err;
+ }
+ errno = errtmp;
+#endif
+ return errtmp;
+}
+
+/*
+ * set_sock_buffers - set send and receive buffers for socket
+ *
+ * inputs - fd file descriptor
+ * - size to set
+ * output - returns true (1) if successful, false (0) otherwise
+ * side effects -
+ */
+int
+comm_set_buffers(int fd, int size)
+{
+ if(setsockopt
+ (fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size))
+ || setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)))
+ return 0;
+ return 1;
+}
+
+/*
+ * set_non_blocking - Set the client connection into non-blocking mode.
+ *
+ * inputs - fd to set into non blocking mode
+ * output - 1 if successful 0 if not
+ * side effects - use POSIX compliant non blocking and
+ * be done with it.
+ */
+int
+comm_set_nb(int fd)
+{
+ int nonb = 0;
+ int res;
+
+ nonb |= O_NONBLOCK;
+ res = fcntl(fd, F_GETFL, 0);
+ if(-1 == res || fcntl(fd, F_SETFL, res | nonb) == -1)
+ return 0;
+
+ fd_table[fd].flags.nonblocking = 1;
+ return 1;
+}
+
+
+/*
+ * stolen from squid - its a neat (but overused! :) routine which we
+ * can use to see whether we can ignore this errno or not. It is
+ * generally useful for non-blocking network IO related errnos.
+ * -- adrian
+ */
+int
+ignoreErrno(int ierrno)
+{
+ switch (ierrno)
+ {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+ case EALREADY:
+ case EINTR:
+#ifdef ERESTART
+ case ERESTART:
+#endif
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+/*
+ * comm_settimeout() - set the socket timeout
+ *
+ * Set the timeout for the fd
+ */
+void
+comm_settimeout(int fd, time_t timeout, PF * callback, void *cbdata)
+{
+ fde_t *F;
+ s_assert(fd >= 0);
+ F = &fd_table[fd];
+ s_assert(F->flags.open);
+
+ F->timeout = CurrentTime + (timeout / 1000);
+ F->timeout_handler = callback;
+ F->timeout_data = cbdata;
+}
+
+
+/*
+ * comm_setflush() - set a flush function
+ *
+ * A flush function is simply a function called if found during
+ * comm_timeouts(). Its basically a second timeout, except in this case
+ * I'm too lazy to implement multiple timeout functions! :-)
+ * its kinda nice to have it seperate, since this is designed for
+ * flush functions, and when comm_close() is implemented correctly
+ * with close functions, we _actually_ don't call comm_close() here ..
+ */
+void
+comm_setflush(int fd, time_t timeout, PF * callback, void *cbdata)
+{
+ fde_t *F;
+ s_assert(fd >= 0);
+ F = &fd_table[fd];
+ s_assert(F->flags.open);
+
+ F->flush_timeout = CurrentTime + (timeout / 1000);
+ F->flush_handler = callback;
+ F->flush_data = cbdata;
+}
+
+
+/*
+ * comm_checktimeouts() - check the socket timeouts
+ *
+ * All this routine does is call the given callback/cbdata, without closing
+ * down the file descriptor. When close handlers have been implemented,
+ * this will happen.
+ */
+void
+comm_checktimeouts(void *notused)
+{
+ int fd;
+ PF *hdl;
+ void *data;
+ fde_t *F;
+ for (fd = 0; fd <= highest_fd; fd++)
+ {
+ F = &fd_table[fd];
+ if(!F->flags.open)
+ continue;
+ if(F->flags.closing)
+ continue;
+
+ /* check flush functions */
+ if(F->flush_handler &&
+ F->flush_timeout > 0 && F->flush_timeout < CurrentTime)
+ {
+ hdl = F->flush_handler;
+ data = F->flush_data;
+ comm_setflush(F->fd, 0, NULL, NULL);
+ hdl(F->fd, data);
+ }
+
+ /* check timeouts */
+ if(F->timeout_handler &&
+ F->timeout > 0 && F->timeout < CurrentTime)
+ {
+ /* Call timeout handler */
+ hdl = F->timeout_handler;
+ data = F->timeout_data;
+ comm_settimeout(F->fd, 0, NULL, NULL);
+ hdl(F->fd, data);
+ }
+ }
+}
+
+/*
+ * void comm_connect_tcp(int fd, const char *host, u_short port,
+ * struct sockaddr *clocal, int socklen,
+ * CNCB *callback, void *data, int aftype, int timeout)
+ * Input: An fd to connect with, a host and port to connect to,
+ * a local sockaddr to connect from + length(or NULL to use the
+ * default), a callback, the data to pass into the callback, the
+ * address family.
+ * Output: None.
+ * Side-effects: A non-blocking connection to the host is started, and
+ * if necessary, set up for selection. The callback given
+ * may be called now, or it may be called later.
+ */
+void
+comm_connect_tcp(int fd, const char *host, u_short port,
+ struct sockaddr *clocal, int socklen, CNCB * callback,
+ void *data, int aftype, int timeout)
+{
+ void *ipptr = NULL;
+ fde_t *F;
+ s_assert(fd >= 0);
+ F = &fd_table[fd];
+ F->flags.called_connect = 1;
+ s_assert(callback);
+ F->connect.callback = callback;
+ F->connect.data = data;
+
+ memset(&F->connect.hostaddr, 0, sizeof(F->connect.hostaddr));
+#ifdef IPV6
+ if(aftype == AF_INET6)
+ {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&F->connect.hostaddr;
+ SET_SS_LEN(F->connect.hostaddr, sizeof(struct sockaddr_in6));
+ in6->sin6_port = htons(port);
+ in6->sin6_family = AF_INET6;
+ ipptr = &in6->sin6_addr;
+ } else
+#endif
+ {
+ struct sockaddr_in *in = (struct sockaddr_in *)&F->connect.hostaddr;
+ SET_SS_LEN(F->connect.hostaddr, sizeof(struct sockaddr_in));
+ in->sin_port = htons(port);
+ in->sin_family = AF_INET;
+ ipptr = &in->sin_addr;
+ }
+
+ /* Note that we're using a passed sockaddr here. This is because
+ * generally you'll be bind()ing to a sockaddr grabbed from
+ * getsockname(), so this makes things easier.
+ * XXX If NULL is passed as local, we should later on bind() to the
+ * virtual host IP, for completeness.
+ * -- adrian
+ */
+ if((clocal != NULL) && (bind(F->fd, clocal, socklen) < 0))
+ {
+ /* Failure, call the callback with COMM_ERR_BIND */
+ comm_connect_callback(F->fd, COMM_ERR_BIND);
+ /* ... and quit */
+ return;
+ }
+
+ /* Next, if we have been given an IP, get the addr and skip the
+ * DNS check (and head direct to comm_connect_tryconnect().
+ */
+ if(inetpton(aftype, host, ipptr) <= 0)
+ {
+ /* Send the DNS request, for the next level */
+ F->dns_query = MyMalloc(sizeof(struct DNSQuery));
+ F->dns_query->ptr = F;
+ F->dns_query->callback = comm_connect_dns_callback;
+#ifdef IPV6
+ if (aftype == AF_INET6)
+ gethost_byname_type(host, F->dns_query, T_AAAA);
+ else
+#endif
+ gethost_byname_type(host, F->dns_query, T_A);
+ }
+ else
+ {
+ /* We have a valid IP, so we just call tryconnect */
+ /* Make sure we actually set the timeout here .. */
+ comm_settimeout(F->fd, timeout * 1000, comm_connect_timeout, NULL);
+ comm_connect_tryconnect(F->fd, NULL);
+ }
+}
+
+/*
+ * comm_connect_callback() - call the callback, and continue with life
+ */
+static void
+comm_connect_callback(int fd, int status)
+{
+ CNCB *hdl;
+ fde_t *F = &fd_table[fd];
+ /* This check is gross..but probably necessary */
+ if(F->connect.callback == NULL)
+ return;
+ /* Clear the connect flag + handler */
+ hdl = F->connect.callback;
+ F->connect.callback = NULL;
+ F->flags.called_connect = 0;
+
+ /* Clear the timeout handler */
+ comm_settimeout(F->fd, 0, NULL, NULL);
+
+ /* Call the handler */
+ hdl(F->fd, status, F->connect.data);
+}
+
+
+/*
+ * comm_connect_timeout() - this gets called when the socket connection
+ * times out. This *only* can be called once connect() is initially
+ * called ..
+ */
+static void
+comm_connect_timeout(int fd, void *notused)
+{
+ /* error! */
+ comm_connect_callback(fd, COMM_ERR_TIMEOUT);
+}
+
+
+/*
+ * comm_connect_dns_callback() - called at the completion of the DNS request
+ *
+ * The DNS request has completed, so if we've got an error, return it,
+ * otherwise we initiate the connect()
+ */
+static void
+comm_connect_dns_callback(void *vptr, struct DNSReply *reply)
+{
+ fde_t *F = vptr;
+
+ /* Free dns_query now to avoid double reslist free -- jilles */
+ MyFree(F->dns_query);
+ F->dns_query = NULL;
+
+ if(!reply)
+ {
+ comm_connect_callback(F->fd, COMM_ERR_DNS);
+ return;
+ }
+
+ /* No error, set a 10 second timeout */
+ comm_settimeout(F->fd, 30 * 1000, comm_connect_timeout, NULL);
+
+ /* Copy over the DNS reply info so we can use it in the connect() */
+#ifdef IPV6
+ if(reply->addr.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&F->connect.hostaddr;
+ memcpy(&in6->sin6_addr, &((struct sockaddr_in6 *)&reply->addr)->sin6_addr, sizeof(struct in6_addr));
+ }
+ else
+#endif
+ {
+ struct sockaddr_in *in = (struct sockaddr_in *)&F->connect.hostaddr;
+ in->sin_addr.s_addr = ((struct sockaddr_in *)&reply->addr)->sin_addr.s_addr;
+ }
+
+ /* Now, call the tryconnect() routine to try a connect() */
+ comm_connect_tryconnect(F->fd, NULL);
+}
+
+
+/* static void comm_connect_tryconnect(int fd, void *notused)
+ * Input: The fd, the handler data(unused).
+ * Output: None.
+ * Side-effects: Try and connect with pending connect data for the FD. If
+ * we succeed or get a fatal error, call the callback.
+ * Otherwise, it is still blocking or something, so register
+ * to select for a write event on this FD.
+ */
+static void
+comm_connect_tryconnect(int fd, void *notused)
+{
+ int retval;
+ fde_t *F = &fd_table[fd];
+
+ if(F->connect.callback == NULL)
+ return;
+ /* Try the connect() */
+ retval = connect(fd, (struct sockaddr *) &fd_table[fd].connect.hostaddr,
+ GET_SS_LEN(fd_table[fd].connect.hostaddr));
+ /* Error? */
+ if(retval < 0)
+ {
+ /*
+ * If we get EISCONN, then we've already connect()ed the socket,
+ * which is a good thing.
+ * -- adrian
+ */
+ if(errno == EISCONN)
+ comm_connect_callback(F->fd, COMM_OK);
+ else if(ignoreErrno(errno))
+ /* Ignore error? Reschedule */
+ comm_setselect(F->fd, FDLIST_SERVER, COMM_SELECT_WRITE|COMM_SELECT_RETRY,
+ comm_connect_tryconnect, NULL, 0);
+ else
+ /* Error? Fail with COMM_ERR_CONNECT */
+ comm_connect_callback(F->fd, COMM_ERR_CONNECT);
+ return;
+ }
+ /* If we get here, we've suceeded, so call with COMM_OK */
+ comm_connect_callback(F->fd, COMM_OK);
+}
+
+/*
+ * comm_error_str() - return an error string for the given error condition
+ */
+const char *
+comm_errstr(int error)
+{
+ if(error < 0 || error >= COMM_ERR_MAX)
+ return "Invalid error number!";
+ return comm_err_str[error];
+}
+
+
+/*
+ * comm_socket() - open a socket
+ *
+ * This is a highly highly cut down version of squid's comm_open() which
+ * for the most part emulates socket(), *EXCEPT* it fails if we're about
+ * to run out of file descriptors.
+ */
+int
+comm_socket(int family, int sock_type, int proto, const char *note)
+{
+ int fd;
+ /* First, make sure we aren't going to run out of file descriptors */
+ if(number_fd >= MASTER_MAX)
+ {
+ errno = ENFILE;
+ return -1;
+ }
+
+ /*
+ * Next, we try to open the socket. We *should* drop the reserved FD
+ * limit if/when we get an error, but we can deal with that later.
+ * XXX !!! -- adrian
+ */
+ fd = socket(family, sock_type, proto);
+ comm_fd_hack(&fd);
+ if(fd < 0)
+ return -1; /* errno will be passed through, yay.. */
+
+#if defined(IPV6) && defined(IPV6_V6ONLY)
+ /*
+ * Make sure we can take both IPv4 and IPv6 connections
+ * on an AF_INET6 socket
+ */
+ if(family == AF_INET6)
+ {
+ int off = 1;
+ if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)) == -1)
+ {
+ libcharybdis_log("comm_socket: Could not set IPV6_V6ONLY option to 1 on FD %d: %s",
+ fd, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }
+#endif
+
+ /* Set the socket non-blocking, and other wonderful bits */
+ if(!comm_set_nb(fd))
+ {
+ libcharybdis_log("comm_open: Couldn't set FD %d non blocking: %s", fd, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ /* Next, update things in our fd tracking */
+ comm_open(fd, FD_SOCKET, note);
+ return fd;
+}
+
+
+/*
+ * comm_accept() - accept an incoming connection
+ *
+ * This is a simple wrapper for accept() which enforces FD limits like
+ * comm_open() does.
+ */
+int
+comm_accept(int fd, struct sockaddr *pn, socklen_t *addrlen)
+{
+ int newfd;
+ if(number_fd >= MASTER_MAX)
+ {
+ errno = ENFILE;
+ return -1;
+ }
+
+ /*
+ * Next, do the accept(). if we get an error, we should drop the
+ * reserved fd limit, but we can deal with that when comm_open()
+ * also does it. XXX -- adrian
+ */
+ newfd = accept(fd, (struct sockaddr *) pn, addrlen);
+ comm_fd_hack(&newfd);
+
+ if(newfd < 0)
+ return -1;
+
+ /* Set the socket non-blocking, and other wonderful bits */
+ if(!comm_set_nb(newfd))
+ {
+ libcharybdis_log("comm_accept: Couldn't set FD %d non blocking!", newfd);
+ close(newfd);
+ return -1;
+ }
+
+ /* Next, tag the FD as an incoming connection */
+ comm_open(newfd, FD_SOCKET, "Incoming connection");
+
+ /* .. and return */
+ return newfd;
+}
+
+/*
+ * If a sockaddr_storage is AF_INET6 but is a mapped IPv4
+ * socket manged the sockaddr.
+ */
+#ifndef mangle_mapped_sockaddr
+void
+mangle_mapped_sockaddr(struct sockaddr *in)
+{
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
+
+ if(in->sa_family == AF_INET)
+ return;
+
+ if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr))
+ {
+ struct sockaddr_in in4;
+ memset(&in4, 0, sizeof(struct sockaddr_in));
+ in4.sin_family = AF_INET;
+ in4.sin_port = in6->sin6_port;
+ in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3];
+ memcpy(in, &in4, sizeof(struct sockaddr_in));
+ }
+ return;
+}
+#endif
+
+
+static void
+fdlist_update_biggest(int fd, int opening)
+{
+ if(fd < highest_fd)
+ return;
+ s_assert(fd < MAXCONNECTIONS);
+
+ if(fd > highest_fd)
+ {
+ /*
+ * s_assert that we are not closing a FD bigger than
+ * our known biggest FD
+ */
+ s_assert(opening);
+ highest_fd = fd;
+ return;
+ }
+ /* if we are here, then fd == Biggest_FD */
+ /*
+ * s_assert that we are closing the biggest FD; we can't be
+ * re-opening it
+ */
+ s_assert(!opening);
+ while (highest_fd >= 0 && !fd_table[highest_fd].flags.open)
+ highest_fd--;
+}
+
+
+void
+fdlist_init(void)
+{
+ static int initialized = 0;
+
+ if(!initialized)
+ {
+ /* Since we're doing this once .. */
+ fd_table = MyMalloc((MAXCONNECTIONS + 1) * sizeof(fde_t));
+ initialized = 1;
+ }
+}
+
+/* Called to open a given filedescriptor */
+void
+comm_open(int fd, unsigned int type, const char *desc)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+
+ if(F->flags.open)
+ {
+ comm_close(fd);
+ }
+ s_assert(!F->flags.open);
+ F->fd = fd;
+ F->type = type;
+ F->flags.open = 1;
+#ifdef NOTYET
+ F->defer.until = 0;
+ F->defer.n = 0;
+ F->defer.handler = NULL;
+#endif
+ fdlist_update_biggest(fd, 1);
+ F->comm_index = -1;
+ F->list = FDLIST_NONE;
+ if(desc)
+ strlcpy(F->desc, desc, sizeof(F->desc));
+ number_fd++;
+}
+
+
+/* Called to close a given filedescriptor */
+void
+comm_close(int fd)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(F->flags.open);
+ /* All disk fd's MUST go through file_close() ! */
+ s_assert(F->type != FD_FILE);
+ if(F->type == FD_FILE)
+ {
+ s_assert(F->read_handler == NULL);
+ s_assert(F->write_handler == NULL);
+ }
+ comm_setselect(F->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0);
+ comm_setflush(F->fd, 0, NULL, NULL);
+
+ if (F->dns_query != NULL)
+ {
+ delete_resolver_queries(F->dns_query);
+ MyFree(F->dns_query);
+ F->dns_query = NULL;
+ }
+
+ F->flags.open = 0;
+ fdlist_update_biggest(fd, 0);
+ number_fd--;
+ memset(F, '\0', sizeof(fde_t));
+ F->timeout = 0;
+ /* Unlike squid, we're actually closing the FD here! -- adrian */
+ close(fd);
+}
+
+
+/*
+ * comm_dump() - dump the list of active filedescriptors
+ */
+void
+comm_dump(struct Client *source_p)
+{
+ int i;
+
+ for (i = 0; i <= highest_fd; i++)
+ {
+ if(!fd_table[i].flags.open)
+ continue;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "F :fd %-3d desc '%s'",
+ i, fd_table[i].desc);
+ }
+}
+
+/*
+ * comm_note() - set the fd note
+ *
+ * Note: must be careful not to overflow fd_table[fd].desc when
+ * calling.
+ */
+void
+comm_note(int fd, const char *format, ...)
+{
+ va_list args;
+
+ if(format)
+ {
+ va_start(args, format);
+ ircvsnprintf(fd_table[fd].desc, FD_DESC_SZ, format, args);
+ va_end(args);
+ }
+ else
+ fd_table[fd].desc[0] = '\0';
+}
+
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * commio.h: A header for the network subsystem.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: commio.h 1757 2006-07-25 23:34:45Z jilles $
+ */
+
+#ifndef INCLUDED_commio_h
+#define INCLUDED_commio_h
+
+#include "setup.h"
+#include "config.h"
+#include "ircd_defs.h"
+
+/* Callback for completed IO events */
+typedef void PF(int fd, void *);
+
+/* Callback for completed connections */
+/* int fd, int status, void * */
+typedef void CNCB(int fd, int, void *);
+
+#define FD_DESC_SZ 128 /* hostlen + comment */
+
+
+/* FD type values */
+enum
+{
+ FD_NONE,
+ FD_LOG,
+ FD_FILE,
+ FD_FILECLOSE,
+ FD_SOCKET,
+ FD_PIPE,
+ FD_UNKNOWN
+};
+
+enum
+{
+ COMM_OK,
+ COMM_ERR_BIND,
+ COMM_ERR_DNS,
+ COMM_ERR_TIMEOUT,
+ COMM_ERR_CONNECT,
+ COMM_ERROR,
+ COMM_ERR_MAX
+};
+
+typedef enum fdlist_t
+{
+ FDLIST_NONE,
+ FDLIST_SERVICE,
+ FDLIST_SERVER,
+ FDLIST_IDLECLIENT,
+ FDLIST_BUSYCLIENT,
+ FDLIST_MAX
+}
+fdlist_t;
+
+typedef struct _fde fde_t;
+
+
+extern int highest_fd;
+extern int number_fd;
+
+struct Client;
+
+struct _fde
+{
+ /* New-school stuff, again pretty much ripped from squid */
+ /*
+ * Yes, this gives us only one pending read and one pending write per
+ * filedescriptor. Think though: when do you think we'll need more?
+ */
+ int fd; /* So we can use the fde_t as a callback ptr */
+ int type;
+ fdlist_t list; /* Which list this FD should sit on */
+ int comm_index; /* where in the poll list we live */
+ char desc[FD_DESC_SZ];
+ PF *read_handler;
+ void *read_data;
+ PF *write_handler;
+ void *write_data;
+ PF *timeout_handler;
+ void *timeout_data;
+ time_t timeout;
+ PF *flush_handler;
+ void *flush_data;
+ time_t flush_timeout;
+ struct DNSQuery *dns_query;
+ struct
+ {
+ unsigned int open:1;
+ unsigned int close_request:1;
+ unsigned int write_daemon:1;
+ unsigned int closing:1;
+ unsigned int socket_eof:1;
+ unsigned int nolinger:1;
+ unsigned int nonblocking:1;
+ unsigned int ipc:1;
+ unsigned int called_connect:1;
+ }
+ flags;
+ struct
+ {
+ struct irc_sockaddr_storage hostaddr;
+ CNCB *callback;
+ void *data;
+ /* We'd also add the retry count here when we get to that -- adrian */
+ }
+ connect;
+ int pflags;
+};
+
+
+extern fde_t *fd_table;
+
+void fdlist_init(void);
+
+extern void comm_open(int, unsigned int, const char *);
+extern void comm_close(int);
+extern void comm_dump(struct Client *source_p);
+#ifndef __GNUC__
+extern void comm_note(int fd, const char *format, ...);
+#else
+extern void comm_note(int fd, const char *format, ...) __attribute__ ((format(printf, 2, 3)));
+#endif
+
+#define FB_EOF 0x01
+#define FB_FAIL 0x02
+
+
+/* Size of a read buffer */
+#define READBUF_SIZE 16384 /* used by src/packet.c and src/s_serv.c */
+
+/* Type of IO */
+#define COMM_SELECT_READ 0x1
+#define COMM_SELECT_WRITE 0x2
+#define COMM_SELECT_RETRY 0x4
+extern int readcalls;
+extern const char *const NONB_ERROR_MSG;
+extern const char *const SETBUF_ERROR_MSG;
+
+extern void comm_close_all(void);
+extern int comm_set_nb(int);
+extern int comm_set_buffers(int, int);
+
+extern int comm_get_sockerr(int);
+extern int ignoreErrno(int ierrno);
+
+extern void comm_settimeout(int fd, time_t, PF *, void *);
+extern void comm_setflush(int fd, time_t, PF *, void *);
+extern void comm_checktimeouts(void *);
+extern void comm_connect_tcp(int fd, const char *, u_short,
+ struct sockaddr *, int, CNCB *, void *, int, int);
+extern const char *comm_errstr(int status);
+extern int comm_socket(int family, int sock_type, int proto, const char *note);
+extern int comm_accept(int fd, struct sockaddr *pn, socklen_t *addrlen);
+
+/* These must be defined in the network IO loop code of your choice */
+extern void comm_setselect(int fd, fdlist_t list, unsigned int type,
+ PF * handler, void *client_data, time_t timeout);
+extern void init_netio(void);
+extern int read_message(time_t, unsigned char);
+extern int comm_select(unsigned long);
+extern int disable_sock_options(int);
+#ifdef IPV6
+extern void mangle_mapped_sockaddr(struct sockaddr *in);
+#else
+#define mangle_mapped_sockaddr(x)
+#endif
+
+
+#endif /* INCLUDED_commio_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_bsd_devpoll.c: /dev/poll compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: devpoll.c 390 2005-12-07 18:46:56Z nenolod $
+ */
+
+#include "config.h"
+
+#include "stdinc.h"
+#include <sys/devpoll.h>
+
+#include "libcharybdis.h"
+
+#define POLL_LENGTH HARD_FDLIMIT
+
+
+static void devpoll_update_events(int, short, PF *);
+static int dpfd;
+static short fdmask[POLL_LENGTH];
+static void devpoll_update_events(int, short, PF *);
+static void devpoll_write_update(int, int);
+
+/* #define NOTYET 1 */
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Private functions */
+
+/*
+ * Write an update to the devpoll filter.
+ * See, we end up having to do a seperate (?) remove before we do an
+ * add of a new polltype, so we have to have this function seperate from
+ * the others.
+ */
+static void
+devpoll_write_update(int fd, int events)
+{
+ struct pollfd pollfds[1]; /* Just to be careful */
+ int retval;
+
+ /* Build the pollfd entry */
+ pollfds[0].revents = 0;
+ pollfds[0].fd = fd;
+ pollfds[0].events = events;
+
+ /* Write the thing to our poll fd */
+ retval = write(dpfd, &pollfds[0], sizeof(struct pollfd));
+ if(retval != sizeof(struct pollfd))
+ libcharybdis_log("devpoll_write_update: dpfd write failed %d: %s", errno, strerror(errno));
+ /* Done! */
+}
+
+void
+devpoll_update_events(int fd, short filter, PF * handler)
+{
+ int update_required = 0;
+ int cur_mask = fdmask[fd];
+ PF *cur_handler;
+ fdmask[fd] = 0;
+ switch (filter)
+ {
+ case COMM_SELECT_READ:
+ cur_handler = fd_table[fd].read_handler;
+ if(handler)
+ fdmask[fd] |= POLLRDNORM;
+ else
+ fdmask[fd] &= ~POLLRDNORM;
+ if(fd_table[fd].write_handler)
+ fdmask[fd] |= POLLWRNORM;
+ break;
+ case COMM_SELECT_WRITE:
+ cur_handler = fd_table[fd].write_handler;
+ if(handler)
+ fdmask[fd] |= POLLWRNORM;
+ else
+ fdmask[fd] &= ~POLLWRNORM;
+ if(fd_table[fd].read_handler)
+ fdmask[fd] |= POLLRDNORM;
+ break;
+ default:
+#ifdef NOTYET
+ libcharybdis_log("devpoll_update_events called with unknown filter: %hd", filter);
+#endif
+ return;
+ break;
+ }
+
+ if(cur_handler == NULL && handler != NULL)
+ update_required++;
+ else if(cur_handler != NULL && handler == NULL)
+ update_required++;
+ if(cur_mask != fdmask[fd])
+ update_required++;
+ if(update_required)
+ {
+ /*
+ * Ok, we can call devpoll_write_update() here now to re-build the
+ * fd struct. If we end up with nothing on this fd, it won't write
+ * anything.
+ */
+ if(fdmask[fd])
+ {
+ devpoll_write_update(fd, POLLREMOVE);
+ devpoll_write_update(fd, fdmask[fd]);
+ }
+ else
+ devpoll_write_update(fd, POLLREMOVE);
+ }
+}
+
+
+
+
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Public functions */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ memset(&fdmask, 0, sizeof(fdmask));
+ dpfd = open("/dev/poll", O_RDWR);
+ if(dpfd < 0)
+ {
+ fprintf(stderr,
+ "init_netio: Couldn't open /dev/poll - %d: %s\n",
+ errno, strerror(errno));
+ exit(115); /* Whee! */
+ }
+}
+
+/*
+ * comm_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data, time_t timeout)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ /* Update the list, even though we're not using it .. */
+ F->list = list;
+
+ if(type & COMM_SELECT_READ)
+ {
+ devpoll_update_events(fd, COMM_SELECT_READ, handler);
+ F->read_handler = handler;
+ F->read_data = client_data;
+ }
+ if(type & COMM_SELECT_WRITE)
+ {
+ devpoll_update_events(fd, COMM_SELECT_WRITE, handler);
+ F->write_handler = handler;
+ F->write_data = client_data;
+ }
+ if(timeout)
+ F->timeout = CurrentTime + (timeout / 1000);
+}
+
+/*
+ * Check all connections for new connections and input data that is to be
+ * processed. Also check for connections with data queued and whether we can
+ * write it out.
+ */
+
+/*
+ * comm_select
+ *
+ * Called to do the new-style IO, courtesy of squid (like most of this
+ * new IO code). This routine handles the stuff we've hidden in
+ * comm_setselect and fd_table[] and calls callbacks for IO ready
+ * events.
+ */
+
+int
+comm_select(unsigned long delay)
+{
+ int num, i;
+ struct pollfd pollfds[POLL_LENGTH];
+ struct dvpoll dopoll;
+
+ do
+ {
+ for (;;)
+ {
+ dopoll.dp_timeout = delay;
+ dopoll.dp_nfds = POLL_LENGTH;
+ dopoll.dp_fds = &pollfds[0];
+ num = ioctl(dpfd, DP_POLL, &dopoll);
+ if(num >= 0)
+ break;
+ if(ignoreErrno(errno))
+ break;
+ set_time();
+ return COMM_ERROR;
+ }
+
+ set_time();
+ if(num == 0)
+ continue;
+
+ for (i = 0; i < num; i++)
+ {
+ int fd = dopoll.dp_fds[i].fd;
+ PF *hdl = NULL;
+ fde_t *F = &fd_table[fd];
+ if((dopoll.dp_fds[i].
+ revents & (POLLRDNORM | POLLIN | POLLHUP |
+ POLLERR))
+ && (dopoll.dp_fds[i].events & (POLLRDNORM | POLLIN)))
+ {
+ if((hdl = F->read_handler) != NULL)
+ {
+ F->read_handler = NULL;
+ hdl(fd, F->read_data);
+ /*
+ * this call used to be with a NULL pointer, BUT
+ * in the devpoll case we only want to update the
+ * poll set *if* the handler changes state (active ->
+ * NULL or vice versa.)
+ */
+ devpoll_update_events(fd,
+ COMM_SELECT_READ, F->read_handler);
+ }
+ else
+ libcharybdis_log("comm_select: Unhandled read event: fdmask: %x",
+ fdmask[fd]);
+ }
+
+ if(F->flags.open == 0)
+ continue; /* Read handler closed us..go on to do something more useful */
+ if((dopoll.dp_fds[i].
+ revents & (POLLWRNORM | POLLOUT | POLLHUP |
+ POLLERR))
+ && (dopoll.dp_fds[i].events & (POLLWRNORM | POLLOUT)))
+ {
+ if((hdl = F->write_handler) != NULL)
+ {
+ F->write_handler = NULL;
+ hdl(fd, F->write_data);
+ /* See above similar code in the read case */
+ devpoll_update_events(fd,
+ COMM_SELECT_WRITE, F->write_handler);
+ }
+ else
+ libcharybdis_log("comm_select: Unhandled write event: fdmask: %x",
+ fdmask[fd]);
+
+ }
+ if(dopoll.dp_fds[i].revents & POLLNVAL)
+ {
+ libcharybdis_log("revents was Invalid for %d", fd);
+ }
+ }
+ return COMM_OK;
+ }
+ while (0);
+ /* XXX Get here, we broke! */
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * epoll.c: Linux epoll compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
+ *
+ * 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
+ *
+ * $Id: epoll.c 390 2005-12-07 18:46:56Z nenolod $
+ */
+
+#include "config.h"
+#include "stdinc.h"
+#include <sys/epoll.h>
+
+#include "libcharybdis.h"
+
+static int ep; /* epoll file descriptor */
+static struct epoll_event *pfd;
+static int pfd_size;
+
+
+#ifndef HAVE_EPOLL_CTL /* bah..glibc doesn't support epoll yet.. */
+#include <sys/epoll.h>
+#include <sys/syscall.h>
+
+_syscall1(int, epoll_create, int, maxfds);
+_syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, events);
+_syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents,
+ int, maxevents, int, timeout);
+
+#endif /* HAVE_EPOLL_CTL */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ pfd_size = getdtablesize();
+ ep = epoll_create(pfd_size);
+ pfd = MyMalloc(sizeof(struct epoll_event) * pfd_size);
+ if(ep < 0)
+ {
+ fprintf(stderr, "init_netio: Couldn't open epoll fd!\n");
+ exit(115); /* Whee! */
+ }
+ comm_note(ep, "epoll file descriptor");
+}
+
+/*
+ * comm_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data, time_t timeout)
+{
+ struct epoll_event ep_event;
+ fde_t *F = &fd_table[fd];
+ int old_flags = F->pflags;
+ int op = -1;
+
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ /* Update the list, even though we're not using it .. */
+ F->list = list;
+ if(type & COMM_SELECT_READ)
+ {
+ if(handler != NULL)
+ F->pflags |= EPOLLIN;
+ else
+ F->pflags &= ~EPOLLIN;
+ F->read_handler = handler;
+ F->read_data = client_data;
+ }
+
+ if(type & COMM_SELECT_WRITE)
+ {
+ if(handler != NULL)
+ F->pflags |= EPOLLOUT;
+ else
+ F->pflags &= ~EPOLLOUT;
+ F->write_handler = handler;
+ F->write_data = client_data;
+ }
+
+ if(timeout)
+ F->timeout = CurrentTime + (timeout / 1000);
+
+ if(old_flags == 0 && F->pflags == 0)
+ return;
+ else if(F->pflags <= 0)
+ op = EPOLL_CTL_DEL;
+ else if(old_flags == 0 && F->pflags > 0)
+ op = EPOLL_CTL_ADD;
+ else if(F->pflags != old_flags)
+ op = EPOLL_CTL_MOD;
+
+ if(op == -1)
+ return;
+
+
+ ep_event.events = F->pflags;
+ ep_event.data.ptr = F;
+
+ if(epoll_ctl(ep, op, fd, &ep_event) != 0)
+ {
+ libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
+ abort();
+ }
+
+
+}
+
+/*
+ * comm_select
+ *
+ * Called to do the new-style IO, courtesy of squid (like most of this
+ * new IO code). This routine handles the stuff we've hidden in
+ * comm_setselect and fd_table[] and calls callbacks for IO ready
+ * events.
+ */
+
+int
+comm_select(unsigned long delay)
+{
+ int num, i, flags, old_flags, op;
+ struct epoll_event ep_event;
+ void *data;
+
+ num = epoll_wait(ep, pfd, pfd_size, delay);
+ set_time();
+ if(num < 0 && !ignoreErrno(errno))
+ {
+ return COMM_ERROR;
+ }
+
+ if(num == 0)
+ return COMM_OK;
+ for (i = 0; i < num; i++)
+ {
+ PF *hdl;
+ fde_t *F = pfd[i].data.ptr;
+ old_flags = F->pflags;
+ if(pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
+ {
+ hdl = F->read_handler;
+ data = F->read_data;
+ F->read_handler = NULL;
+ F->read_data = NULL;
+ if(hdl) {
+ hdl(F->fd, data);
+ }
+ else
+ libcharybdis_log("epoll.c: NULL read handler called");
+
+ }
+
+
+ if(F->flags.open == 0)
+ continue;
+ if(pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
+ {
+ hdl = F->write_handler;
+ data = F->write_data;
+ F->write_handler = NULL;
+ F->write_data = NULL;
+
+ if(hdl) {
+ hdl(F->fd, data);
+ }
+ else
+ libcharybdis_log("epoll.c: NULL write handler called");
+ }
+
+ if(F->flags.open == 0)
+ continue;
+
+ flags = 0;
+
+ if(F->read_handler != NULL)
+ flags |= EPOLLIN;
+ if(F->write_handler != NULL)
+ flags |= EPOLLOUT;
+
+ if(old_flags != flags)
+ {
+ if(flags == 0)
+ op = EPOLL_CTL_DEL;
+ else
+ op = EPOLL_CTL_MOD;
+ F->pflags = ep_event.events = flags;
+ ep_event.data.ptr = F;
+ if(epoll_ctl(ep, op, F->fd, &ep_event) != 0)
+ {
+ libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
+ }
+ }
+
+ }
+ return COMM_OK;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * event.c: Event functions.
+ *
+ * Copyright (C) 1998-2000 Regents of the University of California
+ * Copyright (C) 2001-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ *
+ * Code borrowed from the squid web cache by Adrian Chadd.
+ * Original header:
+ *
+ * DEBUG: section 41 Event Processing
+ * AUTHOR: Henrik Nordstrom
+ *
+ * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from the
+ * Internet community. Development is led by Duane Wessels of the
+ * National Laboratory for Applied Network Research and funded by the
+ * National Science Foundation. Squid is Copyrighted (C) 1998 by
+ * the Regents of the University of California. Please see the
+ * COPYRIGHT file for full details. Squid incorporates software
+ * developed and/or copyrighted by other sources. Please see the
+ * CREDITS file for full details.
+ *
+ * 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
+ *
+ * $Id: event.c 498 2006-01-15 16:40:33Z jilles $
+ */
+
+/*
+ * How its used:
+ *
+ * Should be pretty self-explanatory. Events are added to the static
+ * array event_table with a frequency time telling eventRun how often
+ * to execute it.
+ */
+
+#include "stdinc.h"
+#include "config.h"
+
+#include "ircd.h"
+#include "event.h"
+#include "client.h"
+#include "send.h"
+#include "memory.h"
+#include "s_log.h"
+#include "numeric.h"
+
+static const char *last_event_ran = NULL;
+struct ev_entry event_table[MAX_EVENTS];
+static time_t event_time_min = -1;
+
+/*
+ * void eventAdd(const char *name, EVH *func, void *arg, time_t when)
+ *
+ * Input: Name of event, function to call, arguments to pass, and frequency
+ * of the event.
+ * Output: None
+ * Side Effects: Adds the event to the event list.
+ */
+void
+eventAdd(const char *name, EVH * func, void *arg, time_t when)
+{
+ int i;
+
+ /* find first inactive index */
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active == 0)
+ {
+ event_table[i].func = func;
+ event_table[i].name = name;
+ event_table[i].arg = arg;
+ event_table[i].when = CurrentTime + when;
+ event_table[i].frequency = when;
+ event_table[i].active = 1;
+
+ if((event_table[i].when < event_time_min) || (event_time_min == -1))
+ event_time_min = event_table[i].when;
+
+ return;
+ }
+ }
+
+ /* erk! couldnt add to event table */
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, "Unable to add event [%s] to event table", name);
+
+}
+
+void
+eventAddOnce(const char *name, EVH *func, void *arg, time_t when)
+{
+ int i;
+
+ /* find first inactive index */
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active == 0)
+ {
+ event_table[i].func = func;
+ event_table[i].name = name;
+ event_table[i].arg = arg;
+ event_table[i].when = CurrentTime + when;
+ event_table[i].frequency = 0;
+ event_table[i].active = 1;
+
+ if ((event_table[i].when < event_time_min) || (event_time_min == -1))
+ event_time_min = event_table[i].when;
+
+ return;
+ }
+ }
+
+ /* erk! couldnt add to event table */
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Unable to add event [%s] to event table", name);
+}
+
+/*
+ * void eventDelete(EVH *func, void *arg)
+ *
+ * Input: Function handler, argument that was passed.
+ * Output: None
+ * Side Effects: Removes the event from the event list
+ */
+void
+eventDelete(EVH * func, void *arg)
+{
+ int i;
+
+ i = eventFind(func, arg);
+
+ if(i == -1)
+ return;
+
+ event_table[i].name = NULL;
+ event_table[i].func = NULL;
+ event_table[i].arg = NULL;
+ event_table[i].active = 0;
+}
+
+/*
+ * void eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_isa)
+ *
+ * Input: Name of event, function to call, arguments to pass, and frequency
+ * of the event.
+ * Output: None
+ * Side Effects: Adds the event to the event list within +- 1/3 of the
+ * specified frequency.
+ */
+void
+eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish)
+{
+ if(delta_ish >= 3.0)
+ {
+ const time_t two_third = (2 * delta_ish) / 3;
+ delta_ish = two_third + ((rand() % 1000) * two_third) / 1000;
+ /*
+ * XXX I hate the above magic, I don't even know if its right.
+ * Grr. -- adrian
+ */
+ }
+ eventAdd(name, func, arg, delta_ish);
+}
+
+/*
+ * void eventRun(void)
+ *
+ * Input: None
+ * Output: None
+ * Side Effects: Runs pending events in the event list
+ */
+void
+eventRun(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active && (event_table[i].when <= CurrentTime))
+ {
+ last_event_ran = event_table[i].name;
+ event_table[i].func(event_table[i].arg);
+ event_time_min = -1;
+
+ /* event is scheduled more than once */
+ if(event_table[i].frequency)
+ event_table[i].when = CurrentTime + event_table[i].frequency;
+ else
+ {
+ event_table[i].name = NULL;
+ event_table[i].func = NULL;
+ event_table[i].arg = NULL;
+ event_table[i].active = 0;
+ }
+ }
+ }
+}
+
+
+/*
+ * time_t eventNextTime(void)
+ *
+ * Input: None
+ * Output: Specifies the next time eventRun() should be run
+ * Side Effects: None
+ */
+time_t
+eventNextTime(void)
+{
+ int i;
+
+ if(event_time_min == -1)
+ {
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active &&
+ ((event_table[i].when < event_time_min) || (event_time_min == -1)))
+ event_time_min = event_table[i].when;
+ }
+ }
+
+ return event_time_min;
+}
+
+/*
+ * void eventInit(void)
+ *
+ * Input: None
+ * Output: None
+ * Side Effects: Initializes the event system.
+ */
+void
+eventInit(void)
+{
+ last_event_ran = NULL;
+ memset((void *) event_table, 0, sizeof(event_table));
+}
+
+/*
+ * int eventFind(EVH *func, void *arg)
+ *
+ * Input: Event function and the argument passed to it
+ * Output: Index to the slow in the event_table
+ * Side Effects: None
+ */
+int
+eventFind(EVH * func, void *arg)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if((event_table[i].func == func) &&
+ (event_table[i].arg == arg) && event_table[i].active)
+ return i;
+ }
+
+ return -1;
+}
+
+/*
+ * void show_events(struct Client *source_p)
+ *
+ * Input: Client requesting the event
+ * Output: List of events
+ * Side Effects: None
+ */
+void
+show_events(struct Client *source_p)
+{
+ int i;
+
+ if(last_event_ran)
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "E :Last event to run: %s",
+ last_event_ran);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "E :Operation Next Execution");
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active)
+ {
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "E :%-28s %-4d seconds",
+ event_table[i].name,
+ (int)(event_table[i].when - CurrentTime));
+ }
+ }
+}
+
+/*
+ * void set_back_events(time_t by)
+ * Input: Time to set back events by.
+ * Output: None.
+ * Side-effects: Sets back all events by "by" seconds.
+ */
+void
+set_back_events(time_t by)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].when > by)
+ event_table[i].when -= by;
+ else
+ event_table[i].when = 0;
+ }
+}
+
+void
+eventUpdate(const char *name, time_t freq)
+{
+ int i;
+
+ for(i = 0; i < MAX_EVENTS; i++)
+ {
+ if(event_table[i].active &&
+ !irccmp(event_table[i].name, name))
+ {
+ event_table[i].frequency = freq;
+
+ /* update when its scheduled to run if its higher
+ * than the new frequency
+ */
+ if((CurrentTime + freq) < event_table[i].when)
+ event_table[i].when = CurrentTime + freq;
+
+ return;
+ }
+ }
+}
+
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * event.h: The ircd event header.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: event.h 380 2005-12-07 15:08:37Z nenolod $
+ */
+
+#ifndef INCLUDED_event_h
+#define INCLUDED_event_h
+
+/*
+ * How many event entries we need to allocate at a time in the block
+ * allocator. 16 should be plenty at a time.
+ */
+#define MAX_EVENTS 50
+
+
+typedef void EVH(void *);
+
+/* The list of event processes */
+struct ev_entry
+{
+ EVH *func;
+ void *arg;
+ const char *name;
+ time_t frequency;
+ time_t when;
+ int active;
+};
+
+extern void eventAdd(const char *name, EVH * func, void *arg, time_t when);
+extern void eventAddOnce(const char *name, EVH * func, void *arg, time_t when);
+extern void eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish);
+extern void eventRun(void);
+extern time_t eventNextTime(void);
+extern void eventInit(void);
+extern void eventDelete(EVH * func, void *);
+extern int eventFind(EVH * func, void *);
+extern void set_back_events(time_t);
+
+void eventUpdate(const char *name, time_t freq);
+
+extern void show_events(struct Client *source_p);
+
+#endif /* INCLUDED_event_h */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * kqueue.c: FreeBSD kqueue compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: kqueue.c 398 2005-12-12 18:12:46Z nenolod $
+ */
+
+#include "stdinc.h"
+#include <sys/event.h>
+
+#include "libcharybdis.h"
+
+#define KE_LENGTH MAX_CLIENTS
+
+/* jlemon goofed up and didn't add EV_SET until fbsd 4.3 */
+
+#ifndef EV_SET
+#define EV_SET(kevp, a, b, c, d, e, f) do { \
+ (kevp)->ident = (a); \
+ (kevp)->filter = (b); \
+ (kevp)->flags = (c); \
+ (kevp)->fflags = (d); \
+ (kevp)->data = (e); \
+ (kevp)->udata = (f); \
+} while(0)
+#endif
+
+static void kq_update_events(fde_t *, short, PF *);
+static int kq;
+static struct timespec zero_timespec;
+
+static struct kevent *kqlst; /* kevent buffer */
+static int kqmax; /* max structs to buffer */
+static int kqoff; /* offset into the buffer */
+
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Private functions */
+
+void
+kq_update_events(fde_t * F, short filter, PF * handler)
+{
+ PF *cur_handler;
+ int kep_flags;
+
+ switch (filter)
+ {
+ case EVFILT_READ:
+ cur_handler = F->read_handler;
+ break;
+ case EVFILT_WRITE:
+ cur_handler = F->write_handler;
+ break;
+ default:
+ /* XXX bad! -- adrian */
+ return;
+ break;
+ }
+
+ if((cur_handler == NULL && handler != NULL) || (cur_handler != NULL && handler == NULL))
+ {
+ struct kevent *kep;
+
+ kep = kqlst + kqoff;
+
+ if(handler != NULL)
+ {
+ if(filter == EVFILT_WRITE)
+ kep_flags = (EV_ADD | EV_ENABLE | EV_ONESHOT);
+ else
+ kep_flags = (EV_ADD | EV_ENABLE);
+ }
+ else
+ {
+ /* lets definately not poll stuff that isn't real --
+ * some kqueue implementations hate doing this... and
+ * it's intended to delete AND disable at the same time.
+ *
+ * don't believe me? read kevent(4). --nenolod
+ */
+ kep_flags = (EV_DELETE | EV_DISABLE);
+ }
+
+ EV_SET(kep, (uintptr_t) F->fd, filter, kep_flags, 0, 0, (void *) F);
+
+ if(kqoff == kqmax)
+ {
+ int ret;
+
+ ret = kevent(kq, kqlst, kqoff, NULL, 0, &zero_timespec);
+ /* jdc -- someone needs to do error checking... */
+ if(ret == -1)
+ {
+ libcharybdis_log("kq_update_events(): kevent(): %s", strerror(errno));
+ return;
+ }
+ kqoff = 0;
+ }
+ else
+ {
+ kqoff++;
+ }
+ }
+}
+
+
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Public functions */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ kq = kqueue();
+ if(kq < 0)
+ {
+ libcharybdis_log("init_netio: Couldn't open kqueue fd!\n");
+ exit(115); /* Whee! */
+ }
+ kqmax = getdtablesize();
+ kqlst = MyMalloc(sizeof(struct kevent) * kqmax);
+ zero_timespec.tv_sec = 0;
+ zero_timespec.tv_nsec = 0;
+}
+
+/*
+ * comm_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data, time_t timeout)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ /* Update the list, even though we're not using it .. */
+ F->list = list;
+
+ if(type & COMM_SELECT_READ)
+ {
+ kq_update_events(F, EVFILT_READ, handler);
+ F->read_handler = handler;
+ F->read_data = client_data;
+ }
+ if(type & COMM_SELECT_WRITE)
+ {
+ kq_update_events(F, EVFILT_WRITE, handler);
+ F->write_handler = handler;
+ F->write_data = client_data;
+ }
+ if(timeout)
+ F->timeout = CurrentTime + (timeout / 1000);
+
+}
+
+/*
+ * Check all connections for new connections and input data that is to be
+ * processed. Also check for connections with data queued and whether we can
+ * write it out.
+ */
+
+/*
+ * comm_select
+ *
+ * Called to do the new-style IO, courtesy of squid (like most of this
+ * new IO code). This routine handles the stuff we've hidden in
+ * comm_setselect and fd_table[] and calls callbacks for IO ready
+ * events.
+ */
+
+int
+comm_select(unsigned long delay)
+{
+ int num, i;
+ static struct kevent ke[KE_LENGTH];
+ struct timespec poll_time;
+
+ /*
+ * remember we are doing NANOseconds here, not micro/milli. God knows
+ * why jlemon used a timespec, but hey, he wrote the interface, not I
+ * -- Adrian
+ */
+
+ poll_time.tv_sec = delay / 1000;
+
+ poll_time.tv_nsec = (delay % 1000) * 1000000;
+
+ for (;;)
+ {
+ num = kevent(kq, kqlst, kqoff, ke, KE_LENGTH, &poll_time);
+ kqoff = 0;
+
+ if(num >= 0)
+ break;
+
+ if(ignoreErrno(errno))
+ break;
+
+ set_time();
+
+ return COMM_ERROR;
+
+ /* NOTREACHED */
+ }
+
+ set_time();
+
+ if(num == 0)
+ return COMM_OK; /* No error.. */
+
+ for (i = 0; i < num; i++)
+ {
+ int fd = (int) ke[i].ident;
+ PF *hdl = NULL;
+ fde_t *F = &fd_table[fd];
+
+ if(ke[i].flags & EV_ERROR)
+ {
+ errno = (int) ke[i].data;
+ /* XXX error == bad! -- adrian */
+ continue; /* XXX! */
+ }
+
+ switch (ke[i].filter)
+ {
+
+ case EVFILT_READ:
+
+ if((hdl = F->read_handler) != NULL)
+ {
+ F->read_handler = NULL;
+ hdl(fd, F->read_data);
+ }
+
+ break;
+
+ case EVFILT_WRITE:
+
+ if((hdl = F->write_handler) != NULL)
+ {
+ F->write_handler = NULL;
+ hdl(fd, F->write_data);
+ }
+ break;
+
+ default:
+ /* Bad! -- adrian */
+ break;
+ }
+ }
+ return COMM_OK;
+}
+
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * libcharybdis.c: library entrypoint
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
+ *
+ * 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
+ *
+ * $Id: libcharybdis.c 386 2005-12-07 16:21:24Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "libcharybdis.h"
+
+static void (*log_callback)(const char *str) = NULL;
+static void (*restart_callback)(const char *str) = NULL;
+static void (*die_callback)(const char *str) = NULL;
+static char errbuf[BUFSIZE * 2];
+
+void libcharybdis_log(const char *str, ...)
+{
+ va_list args;
+
+ if (log_callback == NULL)
+ return;
+
+ va_start(args, str);
+ ircvsnprintf(errbuf, BUFSIZE * 2, str, args);
+ va_end(args);
+
+ log_callback(errbuf);
+}
+
+void libcharybdis_restart(const char *str, ...)
+{
+ va_list args;
+
+ if (restart_callback == NULL)
+ return;
+
+ va_start(args, str);
+ ircvsnprintf(errbuf, BUFSIZE * 2, str, args);
+ va_end(args);
+
+ restart_callback(errbuf);
+}
+
+void libcharybdis_die(const char *str, ...)
+{
+ va_list args;
+
+ if (die_callback == NULL)
+ return;
+
+ va_start(args, str);
+ ircvsnprintf(errbuf, BUFSIZE * 2, str, args);
+ va_end(args);
+
+ die_callback(errbuf);
+}
+
+void libcharybdis_init(void (*log_cb)(const char *str),
+ void (*restart_cb)(const char *str), void (*die_cb)(const char *str))
+{
+ log_callback = log_cb;
+ restart_callback = restart_cb;
+ die_callback = die_cb;
+
+ fdlist_init();
+ init_netio();
+ eventInit();
+ initBlockHeap();
+ init_dlink_nodes();
+ linebuf_init();
+}
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * libcharybdis.h: library entrypoint
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
+ *
+ * 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
+ *
+ * $Id: libcharybdis.h 388 2005-12-07 16:34:40Z nenolod $
+ */
+
+#ifndef _LIBCHARYBDIS_H
+#define _LIBCHARYBDIS_H
+
+#include "stdinc.h"
+#include "res.h"
+#include "numeric.h"
+#include "tools.h"
+#include "memory.h"
+#include "balloc.h"
+#include "linebuf.h"
+#include "sprintf_irc.h"
+#include "commio.h"
+#include "event.h"
+
+extern void libcharybdis_log(const char *str, ...);
+extern void libcharybdis_restart(const char *str, ...);
+extern void libcharybdis_die(const char *str, ...);
+extern void libcharybdis_init(void (*)(const char *),
+ void (*)(const char *), void (*)(const char *));
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * linebuf.c: Maintains linebuffers.
+ *
+ * Copyright (C) 2001-2002 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: linebuf.c 1110 2006-03-29 22:55:25Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "linebuf.h"
+#include "memory.h"
+#include "event.h"
+#include "balloc.h"
+#include "hook.h"
+#include "commio.h"
+#include "sprintf_irc.h"
+
+#ifdef STRING_WITH_STRINGS
+# include <string.h>
+# include <strings.h>
+#else
+# ifdef HAVE_STRING_H
+# include <string.h>
+# else
+# ifdef HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+#endif
+
+extern BlockHeap *linebuf_heap;
+
+static int bufline_count = 0;
+
+
+/*
+ * linebuf_init
+ *
+ * Initialise the linebuf mechanism
+ */
+
+
+void
+linebuf_init(void)
+{
+ linebuf_heap = BlockHeapCreate(sizeof(buf_line_t), LINEBUF_HEAP_SIZE);
+}
+
+static buf_line_t *
+linebuf_allocate(void)
+{
+ buf_line_t *t;
+ t = BlockHeapAlloc(linebuf_heap);
+ t->refcount = 0;
+ return (t);
+
+}
+
+static void
+linebuf_free(buf_line_t * p)
+{
+ BlockHeapFree(linebuf_heap, p);
+}
+
+/*
+ * linebuf_new_line
+ *
+ * Create a new line, and link it to the given linebuf.
+ * It will be initially empty.
+ */
+static buf_line_t *
+linebuf_new_line(buf_head_t * bufhead)
+{
+ buf_line_t *bufline;
+ dlink_node *node;
+
+ bufline = linebuf_allocate();
+ if(bufline == NULL)
+ return NULL;
+ ++bufline_count;
+
+
+ node = make_dlink_node();
+
+ bufline->len = 0;
+ bufline->terminated = 0;
+ bufline->flushing = 0;
+ bufline->raw = 0;
+
+ /* Stick it at the end of the buf list */
+ dlinkAddTail(bufline, node, &bufhead->list);
+ bufline->refcount++;
+
+ /* And finally, update the allocated size */
+ bufhead->alloclen++;
+ bufhead->numlines++;
+
+ return bufline;
+}
+
+
+/*
+ * linebuf_done_line
+ *
+ * We've finished with the given line, so deallocate it
+ */
+static void
+linebuf_done_line(buf_head_t * bufhead, buf_line_t * bufline, dlink_node * node)
+{
+ /* Remove it from the linked list */
+ dlinkDestroy(node, &bufhead->list);
+
+ /* Update the allocated size */
+ bufhead->alloclen--;
+ bufhead->len -= bufline->len;
+ s_assert(bufhead->len >= 0);
+ bufhead->numlines--;
+
+ bufline->refcount--;
+ s_assert(bufline->refcount >= 0);
+
+ if(bufline->refcount == 0)
+ {
+ /* and finally, deallocate the buf */
+ --bufline_count;
+ s_assert(bufline_count >= 0);
+ linebuf_free(bufline);
+ }
+}
+
+
+/*
+ * skip to end of line or the crlfs, return the number of bytes ..
+ */
+static inline int
+linebuf_skip_crlf(char *ch, int len)
+{
+ int orig_len = len;
+
+ /* First, skip until the first non-CRLF */
+ for (; len; len--, ch++)
+ {
+ if(*ch == '\r')
+ break;
+ else if(*ch == '\n')
+ break;
+ }
+
+ /* Then, skip until the last CRLF */
+ for (; len; len--, ch++)
+ {
+ if((*ch != '\r') && (*ch != '\n'))
+ break;
+ }
+ s_assert(orig_len > len);
+ return (orig_len - len);
+}
+
+
+
+/*
+ * linebuf_newbuf
+ *
+ * Initialise the new buffer
+ */
+void
+linebuf_newbuf(buf_head_t * bufhead)
+{
+ /* not much to do right now :) */
+ memset(bufhead, 0, sizeof(buf_head_t));
+}
+
+/*
+ * client_flush_input
+ *
+ * inputs - pointer to client
+ * output - none
+ * side effects - all input line bufs are flushed
+ */
+void
+client_flush_input(struct Client *client_p)
+{
+ /* This way, it can be called for remote client as well */
+
+ if(client_p->localClient == NULL)
+ return;
+
+ linebuf_donebuf(&client_p->localClient->buf_recvq);
+}
+
+
+/*
+ * linebuf_donebuf
+ *
+ * Flush all the lines associated with this buffer
+ */
+void
+linebuf_donebuf(buf_head_t * bufhead)
+{
+ while (bufhead->list.head != NULL)
+ {
+ linebuf_done_line(bufhead,
+ (buf_line_t *) bufhead->list.head->data, bufhead->list.head);
+ }
+}
+
+/*
+ * linebuf_copy_line
+ *
+ * Okay..this functions comments made absolutely no sense.
+ *
+ * Basically what we do is this. Find the first chunk of text
+ * and then scan for a CRLF. If we didn't find it, but we didn't
+ * overflow our buffer..we wait for some more data.
+ * If we found a CRLF, we replace them with a \0 character.
+ * If we overflowed, we copy the most our buffer can handle, terminate
+ * it with a \0 and return.
+ *
+ * The return value is the amount of data we consumed. This could
+ * be different than the size of the linebuffer, as when we discard
+ * the overflow, we don't want to process it again.
+ *
+ * This still sucks in my opinion, but it seems to work.
+ *
+ * -Aaron
+ */
+static int
+linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
+{
+ int cpylen = 0; /* how many bytes we've copied */
+ char *ch = data; /* Pointer to where we are in the read data */
+ char *bufch = bufline->buf + bufline->len;
+ int clen = 0; /* how many bytes we've processed,
+ and don't ever want to see again.. */
+
+ /* If its full or terminated, ignore it */
+
+ bufline->raw = 0;
+ s_assert(bufline->len < BUF_DATA_SIZE);
+ if(bufline->terminated == 1)
+ return 0;
+
+ clen = cpylen = linebuf_skip_crlf(ch, len);
+ if(clen == -1)
+ return -1;
+
+ /* This is the ~overflow case..This doesn't happen often.. */
+ if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
+ {
+ memcpy(bufch, ch, (BUF_DATA_SIZE - bufline->len - 1));
+ bufline->buf[BUF_DATA_SIZE - 1] = '\0';
+ bufch = bufline->buf + BUF_DATA_SIZE - 2;
+ while (cpylen && (*bufch == '\r' || *bufch == '\n'))
+ {
+ *bufch = '\0';
+ cpylen--;
+ bufch--;
+ }
+ bufline->terminated = 1;
+ bufline->len = BUF_DATA_SIZE - 1;
+ bufhead->len += BUF_DATA_SIZE - 1;
+ return clen;
+ }
+
+ memcpy(bufch, ch, cpylen);
+ bufch += cpylen;
+ *bufch = '\0';
+ bufch--;
+
+ if(*bufch != '\r' && *bufch != '\n')
+ {
+ /* No linefeed, bail for the next time */
+ bufhead->len += cpylen;
+ bufline->len += cpylen;
+ bufline->terminated = 0;
+ return clen;
+ }
+
+ /* Yank the CRLF off this, replace with a \0 */
+ while (cpylen && (*bufch == '\r' || *bufch == '\n'))
+ {
+ *bufch = '\0';
+ cpylen--;
+ bufch--;
+ }
+
+ bufline->terminated = 1;
+ bufhead->len += cpylen;
+ bufline->len += cpylen;
+ return clen;
+}
+
+/*
+ * linebuf_copy_raw
+ *
+ * Copy as much data as possible directly into a linebuf,
+ * splitting at \r\n, but without altering any data.
+ *
+ */
+static int
+linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
+{
+ int cpylen = 0; /* how many bytes we've copied */
+ char *ch = data; /* Pointer to where we are in the read data */
+ char *bufch = bufline->buf + bufline->len;
+ int clen = 0; /* how many bytes we've processed,
+ and don't ever want to see again.. */
+
+ /* If its full or terminated, ignore it */
+
+ bufline->raw = 1;
+ s_assert(bufline->len < BUF_DATA_SIZE);
+ if(bufline->terminated == 1)
+ return 0;
+
+ clen = cpylen = linebuf_skip_crlf(ch, len);
+ if(clen == -1)
+ return -1;
+
+ /* This is the overflow case..This doesn't happen often.. */
+ if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
+ {
+ clen = BUF_DATA_SIZE - bufline->len - 1;
+ memcpy(bufch, ch, clen);
+ bufline->buf[BUF_DATA_SIZE - 1] = '\0';
+ bufch = bufline->buf + BUF_DATA_SIZE - 2;
+ bufline->terminated = 1;
+ bufline->len = BUF_DATA_SIZE - 1;
+ bufhead->len += BUF_DATA_SIZE - 1;
+ return clen;
+ }
+
+ memcpy(bufch, ch, cpylen);
+ bufch += cpylen;
+ *bufch = '\0';
+ bufch--;
+
+ if(*bufch != '\r' && *bufch != '\n')
+ {
+ /* No linefeed, bail for the next time */
+ bufhead->len += cpylen;
+ bufline->len += cpylen;
+ bufline->terminated = 0;
+ return clen;
+ }
+
+ bufline->terminated = 1;
+ bufhead->len += cpylen;
+ bufline->len += cpylen;
+ return clen;
+}
+
+
+/*
+ * linebuf_parse
+ *
+ * Take a given buffer and break out as many buffers as we can.
+ * If we find a CRLF, we terminate that buffer and create a new one.
+ * If we don't find a CRLF whilst parsing a buffer, we don't mark it
+ * 'finished', so the next loop through we can continue appending ..
+ *
+ * A few notes here, which you'll need to understand before continuing.
+ *
+ * - right now I'm only dealing with single sized buffers. Later on,
+ * I might consider chaining buffers together to get longer "lines"
+ * but seriously, I don't see the advantage right now.
+ *
+ * - This *is* designed to turn into a reference-counter-protected setup
+ * to dodge copious copies.
+ */
+int
+linebuf_parse(buf_head_t * bufhead, char *data, int len, int raw)
+{
+ buf_line_t *bufline;
+ int cpylen;
+ int linecnt = 0;
+
+ /* First, if we have a partial buffer, try to squeze data into it */
+ if(bufhead->list.tail != NULL)
+ {
+ /* Check we're doing the partial buffer thing */
+ bufline = bufhead->list.tail->data;
+ s_assert(!bufline->flushing);
+ /* just try, the worst it could do is *reject* us .. */
+ if(!raw)
+ cpylen = linebuf_copy_line(bufhead, bufline, data, len);
+ else
+ cpylen = linebuf_copy_raw(bufhead, bufline, data, len);
+
+ if(cpylen == -1)
+ return -1;
+
+ linecnt++;
+ /* If we've copied the same as what we've got, quit now */
+ if(cpylen == len)
+ return linecnt; /* all the data done so soon? */
+
+ /* Skip the data and update len .. */
+ len -= cpylen;
+ s_assert(len >= 0);
+ data += cpylen;
+ }
+
+ /* Next, the loop */
+ while (len > 0)
+ {
+ /* We obviously need a new buffer, so .. */
+ bufline = linebuf_new_line(bufhead);
+
+ /* And parse */
+ if(!raw)
+ cpylen = linebuf_copy_line(bufhead, bufline, data, len);
+ else
+ cpylen = linebuf_copy_raw(bufhead, bufline, data, len);
+
+ if(cpylen == -1)
+ return -1;
+
+ len -= cpylen;
+ s_assert(len >= 0);
+ data += cpylen;
+ linecnt++;
+ }
+ return linecnt;
+}
+
+
+/*
+ * linebuf_get
+ *
+ * get the next buffer from our line. For the time being it will copy
+ * data into the given buffer and free the underlying linebuf.
+ */
+int
+linebuf_get(buf_head_t * bufhead, char *buf, int buflen, int partial, int raw)
+{
+ buf_line_t *bufline;
+ int cpylen;
+ char *start, *ch;
+
+ /* make sure we have a line */
+ if(bufhead->list.head == NULL)
+ return 0; /* Obviously not.. hrm. */
+
+ bufline = bufhead->list.head->data;
+
+ /* make sure that the buffer was actually *terminated */
+ if(!(partial || bufline->terminated))
+ return 0; /* Wait for more data! */
+
+ /* make sure we've got the space, including the NULL */
+ cpylen = bufline->len;
+ s_assert(cpylen + 1 <= buflen);
+
+ /* Copy it */
+ start = bufline->buf;
+
+ /* if we left extraneous '\r\n' characters in the string,
+ * and we don't want to read the raw data, clean up the string.
+ */
+ if(bufline->raw && !raw)
+ {
+ /* skip leading EOL characters */
+ while (cpylen && (*start == '\r' || *start == '\n'))
+ {
+ start++;
+ cpylen--;
+ }
+ /* skip trailing EOL characters */
+ ch = &start[cpylen - 1];
+ while (cpylen && (*ch == '\r' || *ch == '\n'))
+ {
+ ch--;
+ cpylen--;
+ }
+ }
+ memcpy(buf, start, cpylen + 1);
+
+ /* convert CR/LF to NULL */
+ if(bufline->raw && !raw)
+ buf[cpylen] = '\0';
+
+ s_assert(cpylen >= 0);
+
+ /* Deallocate the line */
+ linebuf_done_line(bufhead, bufline, bufhead->list.head);
+
+ /* return how much we copied */
+ return cpylen;
+}
+
+/*
+ * linebuf_attach
+ *
+ * attach the lines in a buf_head_t to another buf_head_t
+ * without copying the data (using refcounts).
+ */
+void
+linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
+{
+ dlink_node *ptr;
+ buf_line_t *line;
+
+ DLINK_FOREACH(ptr, new->list.head)
+ {
+ line = ptr->data;
+ dlinkAddTailAlloc(line, &bufhead->list);
+
+ /* Update the allocated size */
+ bufhead->alloclen++;
+ bufhead->len += line->len;
+ bufhead->numlines++;
+
+ line->refcount++;
+ }
+}
+
+/*
+ * linebuf_putmsg
+ *
+ * Similar to linebuf_put, but designed for use by send.c.
+ *
+ * prefixfmt is used as a format for the varargs, and is inserted first.
+ * Then format/va_args is appended to the buffer.
+ */
+void
+linebuf_putmsg(buf_head_t * bufhead, const char *format, va_list * va_args,
+ const char *prefixfmt, ...)
+{
+ buf_line_t *bufline;
+ int len = 0;
+ va_list prefix_args;
+
+ /* make sure the previous line is terminated */
+#ifndef NDEBUG
+ if(bufhead->list.tail)
+ {
+ bufline = bufhead->list.tail->data;
+ s_assert(bufline->terminated);
+ }
+#endif
+ /* Create a new line */
+ bufline = linebuf_new_line(bufhead);
+
+ if(prefixfmt != NULL)
+ {
+ va_start(prefix_args, prefixfmt);
+ len = ircvsnprintf(bufline->buf, BUF_DATA_SIZE, prefixfmt, prefix_args);
+ va_end(prefix_args);
+ }
+
+ if(va_args != NULL)
+ {
+ len += ircvsnprintf((bufline->buf + len), (BUF_DATA_SIZE - len), format, *va_args);
+ }
+
+ bufline->terminated = 1;
+
+ /* Truncate the data if required */
+ if(len > 510)
+ {
+ len = 510;
+ bufline->buf[len++] = '\r';
+ bufline->buf[len++] = '\n';
+ }
+ else if(len == 0)
+ {
+ bufline->buf[len++] = '\r';
+ bufline->buf[len++] = '\n';
+ bufline->buf[len] = '\0';
+ }
+ else
+ {
+ /* Chop trailing CRLF's .. */
+ while ((bufline->buf[len] == '\r')
+ || (bufline->buf[len] == '\n') || (bufline->buf[len] == '\0'))
+ {
+ len--;
+ }
+
+ bufline->buf[++len] = '\r';
+ bufline->buf[++len] = '\n';
+ bufline->buf[++len] = '\0';
+ }
+
+ bufline->len = len;
+ bufhead->len += len;
+}
+
+
+
+/*
+ * linebuf_flush
+ *
+ * Flush data to the buffer. It tries to write as much data as possible
+ * to the given socket. Any return values are passed straight through.
+ * If there is no data in the socket, EWOULDBLOCK is set as an errno
+ * rather than returning 0 (which would map to an EOF..)
+ *
+ * Notes: XXX We *should* have a clue here when a non-full buffer is arrived.
+ * and tag it so that we don't re-schedule another write until
+ * we have a CRLF.
+ */
+
+int
+linebuf_flush(int fd, buf_head_t * bufhead)
+{
+ buf_line_t *bufline;
+ int retval;
+ /* Check we actually have a first buffer */
+ if(bufhead->list.head == NULL)
+ {
+ /* nope, so we return none .. */
+ errno = EWOULDBLOCK;
+ return -1;
+ }
+
+ bufline = bufhead->list.head->data;
+
+ /* And that its actually full .. */
+ if(!bufline->terminated)
+ {
+ errno = EWOULDBLOCK;
+ return -1;
+ }
+
+ /* Check we're flushing the first buffer */
+ if(!bufline->flushing)
+ {
+ bufline->flushing = 1;
+ bufhead->writeofs = 0;
+ }
+
+ /* Now, try writing data */
+ retval = send(fd, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs, 0);
+
+ if(retval <= 0)
+ return retval;
+
+ /* we've got data, so update the write offset */
+ bufhead->writeofs += retval;
+
+ /* if we've written everything *and* the CRLF, deallocate and update
+ bufhead */
+ if(bufhead->writeofs == bufline->len)
+ {
+ bufhead->writeofs = 0;
+ s_assert(bufhead->len >= 0);
+ linebuf_done_line(bufhead, bufline, bufhead->list.head);
+ }
+
+ /* Return line length */
+ return retval;
+}
+
+
+
+/*
+ * count linebufs for stats z
+ */
+
+void
+count_linebuf_memory(size_t * count, size_t * linebuf_memory_used)
+{
+ BlockHeapUsage(linebuf_heap, count, NULL, linebuf_memory_used);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * linebuf.h: A header for the linebuf code.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: linebuf.h 376 2005-12-07 15:00:41Z nenolod $
+ */
+
+#ifndef __LINEBUF_H__
+#define __LINEBUF_H__
+
+#include "tools.h"
+
+/* How big we want a buffer - 510 data bytes, plus space for a '\0' */
+#define BUF_DATA_SIZE 511
+
+#define LINEBUF_COMPLETE 0
+#define LINEBUF_PARTIAL 1
+#define LINEBUF_PARSED 0
+#define LINEBUF_RAW 1
+
+struct _buf_line;
+struct _buf_head;
+
+typedef struct _buf_line buf_line_t;
+typedef struct _buf_head buf_head_t;
+
+struct _buf_line
+{
+ char buf[BUF_DATA_SIZE + 2];
+ unsigned int terminated; /* Whether we've terminated the buffer */
+ unsigned int flushing; /* Whether we're flushing .. */
+ unsigned int raw; /* Whether this linebuf may hold 8-bit data */
+ int len; /* How much data we've got */
+ int refcount; /* how many linked lists are we in? */
+ struct _buf_line *next; /* next in free list */
+};
+
+struct _buf_head
+{
+ dlink_list list; /* the actual dlink list */
+ int len; /* length of all the data */
+ int alloclen; /* Actual allocated data length */
+ int writeofs; /* offset in the first line for the write */
+ int numlines; /* number of lines */
+};
+
+/* they should be functions, but .. */
+#define linebuf_len(x) ((x)->len)
+#define linebuf_alloclen(x) ((x)->alloclen)
+#define linebuf_numlines(x) ((x)->numlines)
+
+extern void linebuf_init(void);
+/* declared as static */
+/* extern buf_line_t *linebuf_new_line(buf_head_t *); */
+/* extern void linebuf_done_line(buf_head_t *, buf_line_t *, dlink_node *); */
+/* extern int linebuf_skip_crlf(char *, int); */
+/* extern void linebuf_terminate_crlf(buf_head_t *, buf_line_t *); */
+extern void linebuf_newbuf(buf_head_t *);
+extern void client_flush_input(struct Client *);
+extern void linebuf_donebuf(buf_head_t *);
+extern int linebuf_parse(buf_head_t *, char *, int, int);
+extern int linebuf_get(buf_head_t *, char *, int, int, int);
+extern void linebuf_putmsg(buf_head_t *, const char *, va_list *, const char *, ...);
+extern int linebuf_flush(int, buf_head_t *);
+extern void linebuf_attach(buf_head_t *, buf_head_t *);
+extern void count_linebuf_memory(size_t *, size_t *);
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * memory.c: Memory utilities.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: memory.c 388 2005-12-07 16:34:40Z nenolod $
+ */
+
+
+#define WE_ARE_MEMORY_C
+
+#include "libcharybdis.h"
+
+/*
+ * MyMalloc - allocate memory, call outofmemory on failure
+ */
+void *
+MyMalloc(size_t size)
+{
+ void *ret = calloc(1, size);
+ if(ret == NULL)
+ outofmemory();
+ return ret;
+}
+
+/*
+ * MyRealloc - reallocate memory, call outofmemory on failure
+ */
+void *
+MyRealloc(void *x, size_t y)
+{
+ void *ret = realloc(x, y);
+
+ if(ret == NULL)
+ outofmemory();
+ return ret;
+}
+
+/*
+ * outofmemory()
+ *
+ * input - NONE
+ * output - NONE
+ * side effects - simply try to report there is a problem. Abort if it was called more than once
+ */
+void
+outofmemory()
+{
+ static int was_here = 0;
+
+ if(was_here)
+ libcharybdis_die("Out of Memory!");
+
+ was_here = 1;
+
+ libcharybdis_restart("Aiee! Out of memory... >_<!");
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * memory.h: A header for the memory functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: memory.h 382 2005-12-07 15:15:59Z nenolod $
+ */
+
+#ifndef _I_MEMORY_H
+#define _I_MEMORY_H
+
+#include "ircd_defs.h"
+#include "setup.h"
+#include "balloc.h"
+
+/* Needed to use uintptr_t for some pointer manipulation. */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#else /* No inttypes.h */
+#ifndef HAVE_UINTPTR_T
+typedef unsigned long uintptr_t;
+#endif
+#endif
+
+extern void outofmemory(void);
+
+extern void *MyMalloc(size_t size);
+extern void *MyRealloc(void *x, size_t y);
+
+/* forte (and maybe others) dont like double declarations,
+ * so we dont declare the inlines unless GNUC
+ */
+/* darwin doesnt like these.. */
+#ifndef __APPLE__
+
+#ifdef __GNUC__
+extern inline void *
+MyMalloc(size_t size)
+{
+ void *ret = calloc(1, size);
+ if(ret == NULL)
+ outofmemory();
+ return (ret);
+}
+
+extern inline void *
+MyRealloc(void *x, size_t y)
+{
+ void *ret = realloc(x, y);
+
+ if(ret == NULL)
+ outofmemory();
+ return (ret);
+}
+
+#endif /* __GNUC__ */
+#endif /* __APPLE__ */
+
+#define MyFree(x) do { if(x) free(x); } while (0)
+
+#endif /* _I_MEMORY_H */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_bsd_poll.c: POSIX poll() compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: poll.c 390 2005-12-07 18:46:56Z nenolod $
+ */
+
+#include "config.h"
+#include "stdinc.h"
+#include <sys/poll.h>
+
+#include "libcharybdis.h"
+
+/* I hate linux -- adrian */
+#ifndef POLLRDNORM
+#define POLLRDNORM POLLIN
+#endif
+#ifndef POLLWRNORM
+#define POLLWRNORM POLLOUT
+#endif
+
+struct _pollfd_list
+{
+ struct pollfd pollfds[MAXCONNECTIONS];
+ int maxindex; /* highest FD number */
+};
+
+typedef struct _pollfd_list pollfd_list_t;
+
+pollfd_list_t pollfd_list;
+static void poll_update_pollfds(int, short, PF *);
+static unsigned long last_count = 0;
+static unsigned long empty_count = 0;
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Private functions */
+
+/*
+ * find a spare slot in the fd list. We can optimise this out later!
+ * -- adrian
+ */
+static inline int
+poll_findslot(void)
+{
+ int i;
+ for (i = 0; i < MAXCONNECTIONS; i++)
+ {
+ if(pollfd_list.pollfds[i].fd == -1)
+ {
+ /* MATCH!!#$*&$ */
+ return i;
+ }
+ }
+ s_assert(1 == 0);
+ /* NOTREACHED */
+ return -1;
+}
+
+/*
+ * set and clear entries in the pollfds[] array.
+ */
+static void
+poll_update_pollfds(int fd, short event, PF * handler)
+{
+ fde_t *F = &fd_table[fd];
+ int comm_index;
+
+ if(F->comm_index < 0)
+ {
+ F->comm_index = poll_findslot();
+ }
+ comm_index = F->comm_index;
+
+ /* Update the events */
+ if(handler)
+ {
+ F->list = FDLIST_IDLECLIENT;
+ pollfd_list.pollfds[comm_index].events |= event;
+ pollfd_list.pollfds[comm_index].fd = fd;
+ /* update maxindex here */
+ if(comm_index > pollfd_list.maxindex)
+ pollfd_list.maxindex = comm_index;
+ }
+ else
+ {
+ if(comm_index >= 0)
+ {
+ pollfd_list.pollfds[comm_index].events &= ~event;
+ if(pollfd_list.pollfds[comm_index].events == 0)
+ {
+ pollfd_list.pollfds[comm_index].fd = -1;
+ pollfd_list.pollfds[comm_index].revents = 0;
+ F->comm_index = -1;
+ F->list = FDLIST_NONE;
+
+ /* update pollfd_list.maxindex here */
+ if(comm_index == pollfd_list.maxindex)
+ while (pollfd_list.maxindex >= 0 &&
+ pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
+ pollfd_list.maxindex--;
+ }
+ }
+ }
+}
+
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Public functions */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ int fd;
+
+ for (fd = 0; fd < MAXCONNECTIONS; fd++)
+ {
+ pollfd_list.pollfds[fd].fd = -1;
+ }
+ pollfd_list.maxindex = 0;
+}
+
+/*
+ * comm_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data, time_t timeout)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ if(type & COMM_SELECT_READ)
+ {
+ F->read_handler = handler;
+ F->read_data = client_data;
+ poll_update_pollfds(fd, POLLRDNORM, handler);
+ }
+ if(type & COMM_SELECT_WRITE)
+ {
+ F->write_handler = handler;
+ F->write_data = client_data;
+ poll_update_pollfds(fd, POLLWRNORM, handler);
+ }
+ if(timeout)
+ F->timeout = CurrentTime + (timeout / 1000);
+}
+
+static void
+irc_sleep(unsigned long useconds)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec t;
+ t.tv_sec = useconds / (unsigned long) 1000000;
+ t.tv_nsec = (useconds % (unsigned long) 1000000) * 1000;
+ nanosleep(&t, (struct timespec *) NULL);
+#else
+ struct timeval t;
+ t.tv_sec = 0;
+ t.tv_usec = useconds;
+ select(0, NULL, NULL, NULL, &t);
+#endif
+ return;
+}
+
+/* int comm_select_fdlist(unsigned long delay)
+ * Input: The maximum time to delay.
+ * Output: Returns -1 on error, 0 on success.
+ * Side-effects: Deregisters future interest in IO and calls the handlers
+ * if an event occurs for an FD.
+ * Comments: Check all connections for new connections and input data
+ * that is to be processed. Also check for connections with data queued
+ * and whether we can write it out.
+ * Called to do the new-style IO, courtesy of squid (like most of this
+ * new IO code). This routine handles the stuff we've hidden in
+ * comm_setselect and fd_table[] and calls callbacks for IO ready
+ * events.
+ */
+int
+comm_select(unsigned long delay)
+{
+ int num;
+ int fd;
+ int ci;
+ unsigned long ndelay;
+ PF *hdl;
+
+ if(last_count > 0)
+ {
+ empty_count = 0;
+ ndelay = 0;
+ }
+ else {
+ ndelay = ++empty_count * 15000 ;
+ if(ndelay > delay * 1000)
+ ndelay = delay * 1000;
+ }
+
+ for (;;)
+ {
+ /* XXX kill that +1 later ! -- adrian */
+ if(ndelay > 0)
+ irc_sleep(ndelay);
+ last_count = num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0);
+ if(num >= 0)
+ break;
+ if(ignoreErrno(errno))
+ continue;
+ /* error! */
+ set_time();
+ return -1;
+ /* NOTREACHED */
+ }
+
+ /* update current time again, eww.. */
+ set_time();
+
+ if(num == 0)
+ return 0;
+ /* XXX we *could* optimise by falling out after doing num fds ... */
+ for (ci = 0; ci < pollfd_list.maxindex + 1; ci++)
+ {
+ fde_t *F;
+ int revents;
+ if(((revents = pollfd_list.pollfds[ci].revents) == 0) ||
+ (pollfd_list.pollfds[ci].fd) == -1)
+ continue;
+ fd = pollfd_list.pollfds[ci].fd;
+ F = &fd_table[fd];
+ if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
+ {
+ hdl = F->read_handler;
+ F->read_handler = NULL;
+ poll_update_pollfds(fd, POLLRDNORM, NULL);
+ if(hdl)
+ hdl(fd, F->read_data);
+ }
+ if(revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
+ {
+ hdl = F->write_handler;
+ F->write_handler = NULL;
+ poll_update_pollfds(fd, POLLWRNORM, NULL);
+ if(hdl)
+ hdl(fd, F->write_data);
+ }
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * ports.c: Solaris ports compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ * Copyright (C) 2005 Edward Brocklesby.
+ * Copyright (C) 2005 William Pitcock and Jilles Tjoelker
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+#include "stdinc.h"
+#include <port.h>
+#include <time.h>
+
+#include "libcharybdis.h"
+
+#define PE_LENGTH 128
+
+static void pe_update_events(fde_t *, short, PF *);
+static int pe;
+static struct timespec zero_timespec;
+
+static port_event_t *pelst; /* port buffer */
+static int pemax; /* max structs to buffer */
+
+int
+ircd_setup_fd(int fd)
+{
+ return 0;
+}
+
+
+void
+pe_update_events(fde_t * F, short filter, PF * handler)
+{
+ PF *cur_handler = NULL;
+
+ if (filter == POLLRDNORM)
+ cur_handler = F->read_handler;
+ else if (filter == POLLWRNORM)
+ cur_handler = F->write_handler;
+
+ if (!cur_handler && handler)
+ port_associate(pe, PORT_SOURCE_FD, F->fd, filter, F);
+ else if (cur_handler && !handler)
+ port_dissociate(pe, PORT_SOURCE_FD, F->fd);
+}
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Public functions */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ if((pe = port_create()) < 0) {
+ libcharybdis_log("init_netio: Couldn't open port fd!\n");
+ exit(115); /* Whee! */
+ }
+ pemax = getdtablesize();
+ pelst = MyMalloc(sizeof(port_event_t) * pemax);
+ zero_timespec.tv_sec = 0;
+ zero_timespec.tv_nsec = 0;
+}
+
+/*
+ * ircd_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+ircd_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ /* Update the list, even though we're not using it .. */
+ F->list = list;
+
+ if(type & IRCD_SELECT_READ) {
+ pe_update_events(F, POLLRDNORM, handler);
+ F->read_handler = handler;
+ F->read_data = client_data;
+ }
+ if(type & IRCD_SELECT_WRITE) {
+ pe_update_events(F, POLLWRNORM, handler);
+ F->write_handler = handler;
+ F->write_data = client_data;
+ }
+}
+
+/*
+ * ircd_select
+ *
+ * Called to do the new-style IO, courtesy of squid (like most of this
+ * new IO code). This routine handles the stuff we've hidden in
+ * ircd_setselect and fd_table[] and calls callbacks for IO ready
+ * events.
+ */
+
+int
+ircd_select(unsigned long delay)
+{
+ int i, fd;
+ uint nget = 1;
+ struct timespec poll_time;
+ struct timer_data *tdata;
+
+ poll_time.tv_sec = delay / 1000;
+ poll_time.tv_nsec = (delay % 1000) * 1000000;
+
+ i = port_getn(pe, pelst, pemax, &nget, &poll_time);
+ ircd_set_time();
+
+ if (i == -1)
+ return COMM_ERROR;
+
+ for (i = 0; i < nget; i++) {
+ switch(pelst[i].portev_source) {
+ case PORT_SOURCE_FD:
+ fd = pelst[i].portev_object;
+ PF *hdl = NULL;
+ fde_t *F = &fd_table[fd];
+
+ if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) {
+ F->read_handler = NULL;
+ hdl(fd, F->read_data);
+ }
+ if ((pelst[i].portev_events & POLLWRNORM) && (hdl = F->write_handler)) {
+ F->write_handler = NULL;
+ hdl(fd, F->write_data);
+ }
+ break;
+
+ case PORT_SOURCE_TIMER:
+ tdata = pelst[i].portev_user;
+ tdata->td_cb(tdata->td_udata);
+
+ if (!tdata->td_repeat)
+ free(tdata);
+
+ break;
+ }
+ }
+ return COMM_OK;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * select.c: select() compatible network routines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: select.c 390 2005-12-07 18:46:56Z nenolod $
+ */
+
+#include "config.h"
+
+#include "libcharybdis.h"
+
+#if HARD_FDLIMIT_ >= FD_SETSIZE
+#error HARD_FDLIMIT_ must be less than FD_SETSIZE(try using poll instead of select)
+#endif
+/*
+ * Note that this is only a single list - multiple lists is kinda pointless
+ * under select because the list size is a function of the highest FD :-)
+ * -- adrian
+ */
+
+fd_set select_readfds;
+fd_set select_writefds;
+
+/*
+ * You know, I'd rather have these local to comm_select but for some
+ * reason my gcc decides that I can't modify them at all..
+ * -- adrian
+ */
+fd_set tmpreadfds;
+fd_set tmpwritefds;
+
+static void select_update_selectfds(int fd, short event, PF * handler);
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Private functions */
+
+/*
+ * set and clear entries in the select array ..
+ */
+static void
+select_update_selectfds(int fd, short event, PF * handler)
+{
+ /* Update the read / write set */
+ if(event & COMM_SELECT_READ)
+ {
+ if(handler)
+ FD_SET(fd, &select_readfds);
+ else
+ FD_CLR(fd, &select_readfds);
+ }
+ if(event & COMM_SELECT_WRITE)
+ {
+ if(handler)
+ FD_SET(fd, &select_writefds);
+ else
+ FD_CLR(fd, &select_writefds);
+ }
+}
+
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Public functions */
+
+
+/*
+ * init_netio
+ *
+ * This is a needed exported function which will be called to initialise
+ * the network loop code.
+ */
+void
+init_netio(void)
+{
+ FD_ZERO(&select_readfds);
+ FD_ZERO(&select_writefds);
+}
+
+/*
+ * comm_setselect
+ *
+ * This is a needed exported function which will be called to register
+ * and deregister interest in a pending IO state for a given FD.
+ */
+void
+comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
+ void *client_data, time_t timeout)
+{
+ fde_t *F = &fd_table[fd];
+ s_assert(fd >= 0);
+ s_assert(F->flags.open);
+
+ if(type & COMM_SELECT_READ)
+ {
+ F->read_handler = handler;
+ F->read_data = client_data;
+ select_update_selectfds(fd, COMM_SELECT_READ, handler);
+ }
+ if(type & COMM_SELECT_WRITE)
+ {
+ F->write_handler = handler;
+ F->write_data = client_data;
+ select_update_selectfds(fd, COMM_SELECT_WRITE, handler);
+ }
+ if(timeout)
+ F->timeout = CurrentTime + (timeout / 1000);
+}
+
+/*
+ * Check all connections for new connections and input data that is to be
+ * processed. Also check for connections with data queued and whether we can
+ * write it out.
+ */
+
+/*
+ * comm_select
+ *
+ * Do IO events
+ */
+
+int
+comm_select(unsigned long delay)
+{
+ int num;
+ int fd;
+ PF *hdl;
+ fde_t *F;
+ struct timeval to;
+
+ /* Copy over the read/write sets so we don't have to rebuild em */
+ memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set));
+ memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set));
+
+ for (;;)
+ {
+ to.tv_sec = 0;
+ to.tv_usec = delay * 1000;
+ num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
+ if(num >= 0)
+ break;
+ if(ignoreErrno(errno))
+ continue;
+ set_time();
+ /* error! */
+ return -1;
+ /* NOTREACHED */
+ }
+ set_time();
+
+ if(num == 0)
+ return 0;
+
+ /* XXX we *could* optimise by falling out after doing num fds ... */
+ for (fd = 0; fd < highest_fd + 1; fd++)
+ {
+ F = &fd_table[fd];
+
+ if(FD_ISSET(fd, &tmpreadfds))
+ {
+ hdl = F->read_handler;
+ F->read_handler = NULL;
+ if(hdl)
+ hdl(fd, F->read_data);
+ }
+
+ if(F->flags.open == 0)
+ continue; /* Read handler closed us..go on */
+
+ if(FD_ISSET(fd, &tmpwritefds))
+ {
+ hdl = F->write_handler;
+ F->write_handler = NULL;
+ if(hdl)
+ hdl(fd, F->write_data);
+ }
+
+ if(F->read_handler == NULL)
+ select_update_selectfds(fd, COMM_SELECT_READ, NULL);
+ if(F->write_handler == NULL)
+ select_update_selectfds(fd, COMM_SELECT_WRITE, NULL);
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * libString, Copyright (C) 1999 Patrick Alken
+ * This library comes with absolutely NO WARRANTY
+ *
+ * Should you choose to use and/or modify this source code, please
+ * do so under the terms of the GNU General Public License under which
+ * this library is distributed.
+ *
+ * $Id: snprintf.c 382 2005-12-07 15:15:59Z nenolod $
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include "setup.h"
+#include "sprintf_irc.h"
+
+/*
+ * This table is arranged in chronological order from 0-999,
+ * however the numbers are written backwards, so the number 100
+ * is expressed in this table as "001".
+ * It's purpose is to ensure fast conversions from integers to
+ * ASCII strings. When an integer variable is encountered, a
+ * simple hash algorithm is used to determine where to look
+ * in this array for the corresponding string.
+ * This outperforms continually dividing by 10 and using the
+ * digit obtained as a character, because we can now divide by
+ * 1000 and use the remainder directly, thus cutting down on
+ * the number of costly divisions needed. For an integer's worst
+ * case, 2 divisions are needed because it can only go up to
+ * 32767, so after 2 divisions by 1000, and some algebra, we will
+ * be left with 327 which we can get from this table. This is much
+ * better than the 5 divisions by 10 that we would need if we did
+ * it the conventional way. Of course, if we made this table go
+ * from 0-9999, only 1 division would be needed.
+ * Longs and unsigned ints of course, are another matter :-).
+ *
+ * Patrick Alken <wnder@underworld.net>
+ */
+
+/*
+ * Set this to the number of indices (numbers) in our table
+ */
+#define TABLE_MAX 1000
+
+static const char *IntTable[] = {
+ "000", "100", "200", "300", "400",
+ "500", "600", "700", "800", "900",
+ "010", "110", "210", "310", "410",
+ "510", "610", "710", "810", "910",
+ "020", "120", "220", "320", "420",
+ "520", "620", "720", "820", "920",
+ "030", "130", "230", "330", "430",
+ "530", "630", "730", "830", "930",
+ "040", "140", "240", "340", "440",
+ "540", "640", "740", "840", "940",
+ "050", "150", "250", "350", "450",
+ "550", "650", "750", "850", "950",
+ "060", "160", "260", "360", "460",
+ "560", "660", "760", "860", "960",
+ "070", "170", "270", "370", "470",
+ "570", "670", "770", "870", "970",
+ "080", "180", "280", "380", "480",
+ "580", "680", "780", "880", "980",
+ "090", "190", "290", "390", "490",
+ "590", "690", "790", "890", "990",
+ "001", "101", "201", "301", "401",
+ "501", "601", "701", "801", "901",
+ "011", "111", "211", "311", "411",
+ "511", "611", "711", "811", "911",
+ "021", "121", "221", "321", "421",
+ "521", "621", "721", "821", "921",
+ "031", "131", "231", "331", "431",
+ "531", "631", "731", "831", "931",
+ "041", "141", "241", "341", "441",
+ "541", "641", "741", "841", "941",
+ "051", "151", "251", "351", "451",
+ "551", "651", "751", "851", "951",
+ "061", "161", "261", "361", "461",
+ "561", "661", "761", "861", "961",
+ "071", "171", "271", "371", "471",
+ "571", "671", "771", "871", "971",
+ "081", "181", "281", "381", "481",
+ "581", "681", "781", "881", "981",
+ "091", "191", "291", "391", "491",
+ "591", "691", "791", "891", "991",
+ "002", "102", "202", "302", "402",
+ "502", "602", "702", "802", "902",
+ "012", "112", "212", "312", "412",
+ "512", "612", "712", "812", "912",
+ "022", "122", "222", "322", "422",
+ "522", "622", "722", "822", "922",
+ "032", "132", "232", "332", "432",
+ "532", "632", "732", "832", "932",
+ "042", "142", "242", "342", "442",
+ "542", "642", "742", "842", "942",
+ "052", "152", "252", "352", "452",
+ "552", "652", "752", "852", "952",
+ "062", "162", "262", "362", "462",
+ "562", "662", "762", "862", "962",
+ "072", "172", "272", "372", "472",
+ "572", "672", "772", "872", "972",
+ "082", "182", "282", "382", "482",
+ "582", "682", "782", "882", "982",
+ "092", "192", "292", "392", "492",
+ "592", "692", "792", "892", "992",
+ "003", "103", "203", "303", "403",
+ "503", "603", "703", "803", "903",
+ "013", "113", "213", "313", "413",
+ "513", "613", "713", "813", "913",
+ "023", "123", "223", "323", "423",
+ "523", "623", "723", "823", "923",
+ "033", "133", "233", "333", "433",
+ "533", "633", "733", "833", "933",
+ "043", "143", "243", "343", "443",
+ "543", "643", "743", "843", "943",
+ "053", "153", "253", "353", "453",
+ "553", "653", "753", "853", "953",
+ "063", "163", "263", "363", "463",
+ "563", "663", "763", "863", "963",
+ "073", "173", "273", "373", "473",
+ "573", "673", "773", "873", "973",
+ "083", "183", "283", "383", "483",
+ "583", "683", "783", "883", "983",
+ "093", "193", "293", "393", "493",
+ "593", "693", "793", "893", "993",
+ "004", "104", "204", "304", "404",
+ "504", "604", "704", "804", "904",
+ "014", "114", "214", "314", "414",
+ "514", "614", "714", "814", "914",
+ "024", "124", "224", "324", "424",
+ "524", "624", "724", "824", "924",
+ "034", "134", "234", "334", "434",
+ "534", "634", "734", "834", "934",
+ "044", "144", "244", "344", "444",
+ "544", "644", "744", "844", "944",
+ "054", "154", "254", "354", "454",
+ "554", "654", "754", "854", "954",
+ "064", "164", "264", "364", "464",
+ "564", "664", "764", "864", "964",
+ "074", "174", "274", "374", "474",
+ "574", "674", "774", "874", "974",
+ "084", "184", "284", "384", "484",
+ "584", "684", "784", "884", "984",
+ "094", "194", "294", "394", "494",
+ "594", "694", "794", "894", "994",
+ "005", "105", "205", "305", "405",
+ "505", "605", "705", "805", "905",
+ "015", "115", "215", "315", "415",
+ "515", "615", "715", "815", "915",
+ "025", "125", "225", "325", "425",
+ "525", "625", "725", "825", "925",
+ "035", "135", "235", "335", "435",
+ "535", "635", "735", "835", "935",
+ "045", "145", "245", "345", "445",
+ "545", "645", "745", "845", "945",
+ "055", "155", "255", "355", "455",
+ "555", "655", "755", "855", "955",
+ "065", "165", "265", "365", "465",
+ "565", "665", "765", "865", "965",
+ "075", "175", "275", "375", "475",
+ "575", "675", "775", "875", "975",
+ "085", "185", "285", "385", "485",
+ "585", "685", "785", "885", "985",
+ "095", "195", "295", "395", "495",
+ "595", "695", "795", "895", "995",
+ "006", "106", "206", "306", "406",
+ "506", "606", "706", "806", "906",
+ "016", "116", "216", "316", "416",
+ "516", "616", "716", "816", "916",
+ "026", "126", "226", "326", "426",
+ "526", "626", "726", "826", "926",
+ "036", "136", "236", "336", "436",
+ "536", "636", "736", "836", "936",
+ "046", "146", "246", "346", "446",
+ "546", "646", "746", "846", "946",
+ "056", "156", "256", "356", "456",
+ "556", "656", "756", "856", "956",
+ "066", "166", "266", "366", "466",
+ "566", "666", "766", "866", "966",
+ "076", "176", "276", "376", "476",
+ "576", "676", "776", "876", "976",
+ "086", "186", "286", "386", "486",
+ "586", "686", "786", "886", "986",
+ "096", "196", "296", "396", "496",
+ "596", "696", "796", "896", "996",
+ "007", "107", "207", "307", "407",
+ "507", "607", "707", "807", "907",
+ "017", "117", "217", "317", "417",
+ "517", "617", "717", "817", "917",
+ "027", "127", "227", "327", "427",
+ "527", "627", "727", "827", "927",
+ "037", "137", "237", "337", "437",
+ "537", "637", "737", "837", "937",
+ "047", "147", "247", "347", "447",
+ "547", "647", "747", "847", "947",
+ "057", "157", "257", "357", "457",
+ "557", "657", "757", "857", "957",
+ "067", "167", "267", "367", "467",
+ "567", "667", "767", "867", "967",
+ "077", "177", "277", "377", "477",
+ "577", "677", "777", "877", "977",
+ "087", "187", "287", "387", "487",
+ "587", "687", "787", "887", "987",
+ "097", "197", "297", "397", "497",
+ "597", "697", "797", "897", "997",
+ "008", "108", "208", "308", "408",
+ "508", "608", "708", "808", "908",
+ "018", "118", "218", "318", "418",
+ "518", "618", "718", "818", "918",
+ "028", "128", "228", "328", "428",
+ "528", "628", "728", "828", "928",
+ "038", "138", "238", "338", "438",
+ "538", "638", "738", "838", "938",
+ "048", "148", "248", "348", "448",
+ "548", "648", "748", "848", "948",
+ "058", "158", "258", "358", "458",
+ "558", "658", "758", "858", "958",
+ "068", "168", "268", "368", "468",
+ "568", "668", "768", "868", "968",
+ "078", "178", "278", "378", "478",
+ "578", "678", "778", "878", "978",
+ "088", "188", "288", "388", "488",
+ "588", "688", "788", "888", "988",
+ "098", "198", "298", "398", "498",
+ "598", "698", "798", "898", "998",
+ "009", "109", "209", "309", "409",
+ "509", "609", "709", "809", "909",
+ "019", "119", "219", "319", "419",
+ "519", "619", "719", "819", "919",
+ "029", "129", "229", "329", "429",
+ "529", "629", "729", "829", "929",
+ "039", "139", "239", "339", "439",
+ "539", "639", "739", "839", "939",
+ "049", "149", "249", "349", "449",
+ "549", "649", "749", "849", "949",
+ "059", "159", "259", "359", "459",
+ "559", "659", "759", "859", "959",
+ "069", "169", "269", "369", "469",
+ "569", "669", "769", "869", "969",
+ "079", "179", "279", "379", "479",
+ "579", "679", "779", "879", "979",
+ "089", "189", "289", "389", "489",
+ "589", "689", "789", "889", "989",
+ "099", "199", "299", "399", "499",
+ "599", "699", "799", "899", "999"
+};
+
+/*
+ * Since we calculate the right-most digits for %d %u etc first,
+ * we need a temporary buffer to store them in until we get
+ * to the left-most digits
+ */
+
+#define TEMPBUF_MAX 20
+
+static char TempBuffer[TEMPBUF_MAX];
+
+/*
+vSnprintf()
+ Backend to Snprintf() - performs the construction of 'dest'
+using the string 'format' and the given arguments. Also makes sure
+not more than 'bytes' characters are copied to 'dest'
+
+ We always allow room for a terminating \0 character, so at most,
+bytes - 1 characters will be written to dest.
+
+Return: Number of characters written, NOT including the terminating
+ \0 character which is *always* placed at the end of the string
+
+NOTE: This function handles the following flags only:
+ %s %d %c %u %ld %lu
+ In addition, this function performs *NO* precision, padding,
+ or width formatting. If it receives an unknown % character,
+ it will call vsprintf() to complete the remainder of the
+ string.
+*/
+
+int
+ircvsnprintf(char *dest, const size_t bytes, const char *format, va_list args)
+{
+ char ch;
+ int written = 0; /* bytes written so far */
+ int maxbytes = bytes - 1;
+
+ while ((ch = *format++) && (written < maxbytes))
+ {
+ if(ch == '%')
+ {
+ /*
+ * Advance past the %
+ */
+ ch = *format++;
+
+ /*
+ * Put the most common cases first - %s %d etc
+ */
+
+ if(ch == 's')
+ {
+ const char *str = va_arg(args, const char *);
+
+ while ((*dest = *str))
+ {
+ ++dest;
+ ++str;
+
+ if(++written >= maxbytes)
+ break;
+ }
+
+ continue;
+ }
+
+ if(ch == 'd')
+ {
+ int num = va_arg(args, int);
+ int quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ /*
+ * We have to special-case "0" unfortunately
+ */
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ if(num < 0)
+ {
+ *dest++ = '-';
+ if(++written >= maxbytes)
+ continue;
+
+ num = -num;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * We'll start with the right-most digits of 'num'.
+ * Dividing by TABLE_MAX cuts off all but the X
+ * right-most digits, where X is such that:
+ *
+ * 10^X = TABLE_MAX
+ *
+ * For example, if num = 1200, and TABLE_MAX = 1000,
+ * quotient will be 1. Multiplying this by 1000 and
+ * subtracting from 1200 gives: 1200 - (1 * 1000) = 200.
+ * We then go right to slot 200 in our array and behold!
+ * The string "002" (200 backwards) is conveniently
+ * waiting for us. Then repeat the process with the
+ * digits left.
+ *
+ * The reason we need to have the integers written
+ * backwards, is because we don't know how many digits
+ * there are. If we want to express the number 12130
+ * for example, our first pass would leave us with 130,
+ * whose slot in the array yields "031", which we
+ * plug into our TempBuffer[]. The next pass gives us
+ * 12, whose slot yields "21" which we append to
+ * TempBuffer[], leaving us with "03121". This is the
+ * exact number we want, only backwards, so it is
+ * a simple matter to reverse the string. If we used
+ * straightfoward numbers, we would have a TempBuffer
+ * looking like this: "13012" which would be a nightmare
+ * to deal with.
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ /*
+ * If the last quotient was a 1 or 2 digit number, there
+ * will be one or more leading zeroes in TempBuffer[] -
+ * get rid of them.
+ */
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ if(++written >= maxbytes)
+ break;
+ }
+
+ continue;
+ } /* if (ch == 'd') */
+
+ if(ch == 'c')
+ {
+ *dest++ = va_arg(args, int);
+
+ ++written;
+
+ continue;
+ } /* if (ch == 'c') */
+
+ if(ch == 'u')
+ {
+ unsigned int num = va_arg(args, unsigned int);
+ unsigned int quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * Very similar to case 'd'
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ if(++written >= maxbytes)
+ break;
+ }
+
+ continue;
+ } /* if (ch == 'u') */
+
+ if(ch == 'l')
+ {
+ if(*format == 'u')
+ {
+ unsigned long num = va_arg(args, unsigned long);
+ unsigned long quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ ++format;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * Very similar to case 'u'
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ if(++written >= maxbytes)
+ break;
+ }
+
+ continue;
+ } else /* if (*format == 'u') */
+
+ if(*format == 'd')
+ {
+ long num = va_arg(args, long);
+ long quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ ++format;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ if(num < 0)
+ {
+ *dest++ = '-';
+ if(++written >= maxbytes)
+ continue;
+
+ num = -num;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ if(++written >= maxbytes)
+ break;
+ }
+
+ continue;
+ } else /* if (*format == 'd') */
+ {
+ int ret;
+ format -= 2;
+ #ifdef HAVE_VSNPRINTF
+ ret = vsnprintf(dest, maxbytes - written, format, args);
+ #else
+ ret = vsprintf(dest, format, args);
+ #endif
+ dest += ret;
+ written += ret;
+ break;
+ }
+
+
+ } /* if (ch == 'l') */
+
+ if(ch != '%')
+ {
+ int ret;
+
+ /*
+ * The character might be invalid, or be a precision,
+ * padding, or width specification - call vsprintf()
+ * to finish off the string
+ */
+
+ format -= 2;
+ #ifdef HAVE_VSNPRINTF
+ ret = vsnprintf(dest, maxbytes - written, format, args);
+ #else
+ ret = vsprintf(dest, format, args);
+ #endif
+ dest += ret;
+ written += ret;
+
+ break;
+ } /* if (ch != '%') */
+ } /* if (ch == '%') */
+
+ *dest++ = ch;
+ ++written;
+ } /* while ((ch = *format++) && (written < maxbytes)) */
+
+ /*
+ * Terminate the destination buffer with a \0
+ */
+ *dest = '\0';
+
+ return (written);
+} /* vSnprintf() */
+
+/*
+ircvsprintf()
+ Backend to Sprintf() - performs the construction of 'dest'
+using the string 'format' and the given arguments.
+
+ We always place a \0 character onto the end of 'dest'.
+
+Return: Number of characters written, NOT including the terminating
+ \0 character which is *always* placed at the end of the string
+
+NOTE: This function handles the following flags only:
+ %s %d %c %u %ld %lu
+ In addition, this function performs *NO* precision, padding,
+ or width formatting. If it receives an unknown % character,
+ it will call vsprintf() to complete the remainder of the
+ string.
+*/
+
+int
+ircvsprintf(char *dest, const char *format, va_list args)
+{
+ char ch;
+ int written = 0; /* bytes written so far */
+
+ while ((ch = *format++))
+ {
+ if(ch == '%')
+ {
+ /*
+ * Advance past the %
+ */
+ ch = *format++;
+
+ /*
+ * Put the most common cases first - %s %d etc
+ */
+
+ if(ch == 's')
+ {
+ const char *str = va_arg(args, const char *);
+
+ while ((*dest = *str))
+ {
+ ++dest;
+ ++str;
+
+ ++written;
+ }
+
+ continue;
+ } /* if (ch == 's') */
+
+
+ if(ch == 'd')
+ {
+ int num = va_arg(args, int);
+ int quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ /*
+ * We have to special-case "0" unfortunately
+ */
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ if(num < 0)
+ {
+ *dest++ = '-';
+ ++written;
+
+ num = -num;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * We'll start with the right-most digits of 'num'.
+ * Dividing by TABLE_MAX cuts off all but the X
+ * right-most digits, where X is such that:
+ *
+ * 10^X = TABLE_MAX
+ *
+ * For example, if num = 1200, and TABLE_MAX = 1000,
+ * quotient will be 1. Multiplying this by 1000 and
+ * subtracting from 1200 gives: 1200 - (1 * 1000) = 200.
+ * We then go right to slot 200 in our array and behold!
+ * The string "002" (200 backwards) is conveniently
+ * waiting for us. Then repeat the process with the
+ * digits left.
+ *
+ * The reason we need to have the integers written
+ * backwards, is because we don't know how many digits
+ * there are. If we want to express the number 12130
+ * for example, our first pass would leave us with 130,
+ * whose slot in the array yields "031", which we
+ * plug into our TempBuffer[]. The next pass gives us
+ * 12, whose slot yields "21" which we append to
+ * TempBuffer[], leaving us with "03121". This is the
+ * exact number we want, only backwards, so it is
+ * a simple matter to reverse the string. If we used
+ * straightfoward numbers, we would have a TempBuffer
+ * looking like this: "13012" which would be a nightmare
+ * to deal with.
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ /*
+ * If the last quotient was a 1 or 2 digit number, there
+ * will be one or more leading zeroes in TempBuffer[] -
+ * get rid of them.
+ */
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ ++written;
+ }
+
+ continue;
+ } /* if (ch == 'd') */
+
+ if(ch == 'c')
+ {
+ *dest++ = va_arg(args, int);
+
+ ++written;
+
+ continue;
+ } /* if (ch == 'c') */
+
+ if(ch == 'u')
+ {
+ unsigned int num = va_arg(args, unsigned int);
+ unsigned int quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * Very similar to case 'd'
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ ++written;
+ }
+
+ continue;
+ } /* if (ch == 'u') */
+
+ if(ch == 'l')
+ {
+ if(*format == 'u')
+ {
+ unsigned long num = va_arg(args, unsigned long);
+ unsigned long quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ ++format;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ /*
+ * Very similar to case 'u'
+ */
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ ++written;
+ }
+
+ continue;
+ } /* if (*format == 'u') */
+
+ if(*format == 'd')
+ {
+ long num = va_arg(args, long);
+ long quotient;
+ const char *str;
+ char *digitptr = TempBuffer;
+
+ ++format;
+
+ if(num == 0)
+ {
+ *dest++ = '0';
+ ++written;
+ continue;
+ }
+
+ if(num < 0)
+ {
+ *dest++ = '-';
+ ++written;
+
+ num = -num;
+ }
+
+ do
+ {
+ quotient = num / TABLE_MAX;
+
+ str = IntTable[num - (quotient * TABLE_MAX)];
+
+ while ((*digitptr = *str))
+ {
+ ++digitptr;
+ ++str;
+ }
+ }
+ while ((num = quotient) != 0);
+
+ while (*(digitptr - 1) == '0')
+ --digitptr;
+
+ while (digitptr != TempBuffer)
+ {
+ *dest++ = *--digitptr;
+ ++written;
+ }
+
+ continue;
+ } /* if (*format == 'd') */
+
+ continue;
+ } /* if (ch == 'l') */
+
+ if(ch != '%')
+ {
+ int ret;
+
+ format -= 2;
+ ret = vsprintf(dest, format, args);
+ dest += ret;
+ written += ret;
+
+ break;
+ } /* if (ch != '%') */
+ } /* if (ch == '%') */
+
+ *dest++ = ch;
+ ++written;
+ } /* while ((ch = *format++)) */
+
+ /*
+ * Terminate the destination buffer with a \0
+ */
+ *dest = '\0';
+
+ return (written);
+} /* vSprintf() */
+
+/*
+ircsnprintf()
+ Optimized version of snprintf().
+
+Inputs: dest - destination string
+ bytes - number of bytes to copy
+ format - formatted string
+ args - args to 'format'
+
+Return: number of characters copied, NOT including the terminating
+ NULL which is always placed at the end of the string
+*/
+
+int
+ircsnprintf(char *dest, const size_t bytes, const char *format, ...)
+{
+ va_list args;
+ int count;
+
+ va_start(args, format);
+
+ count = ircvsnprintf(dest, bytes, format, args);
+
+ va_end(args);
+
+ return (count);
+} /* Snprintf() */
+
+/*
+ircsprintf()
+ Optimized version of sprintf()
+
+Inputs: dest - destination string
+ format - formatted string
+ args - arguments to 'format'
+
+Return: number of characters copied, NOT including the terminating
+ NULL which is always placed at the end of the string
+*/
+
+int
+ircsprintf(char *dest, const char *format, ...)
+{
+ va_list args;
+ int count;
+
+ va_start(args, format);
+
+ count = ircvsprintf(dest, format, args);
+
+ va_end(args);
+
+ return (count);
+} /* Sprintf() */
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * tools.c: Various functions needed here and there.
+ *
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: tools.c 1110 2006-03-29 22:55:25Z nenolod $
+ *
+ * Here is the original header:
+ *
+ * Useful stuff, ripped from places ..
+ * adrian chadd <adrian@creative.net.au>
+ *
+ * When you update these functions make sure you update the ones in tools.h
+ * as well!!!
+ */
+
+#include "stdinc.h"
+#define TOOLS_C
+#include "tools.h"
+#include "balloc.h"
+#include "s_user.h"
+
+#ifndef NDEBUG
+/*
+ * frob some memory. debugging time.
+ * -- adrian
+ */
+void
+mem_frob(void *data, int len)
+{
+ unsigned long x = 0xdeadbeef;
+ unsigned char *b = (unsigned char *)&x;
+ int i;
+ char *cdata = data;
+ for (i = 0; i < len; i++)
+ {
+ *cdata = b[i % 4];
+ cdata++;
+ }
+}
+#endif
+
+/*
+ * init_dlink_nodes
+ *
+ */
+extern BlockHeap *dnode_heap;
+void
+init_dlink_nodes(void)
+{
+ dnode_heap = BlockHeapCreate(sizeof(dlink_node), DNODE_HEAP_SIZE);
+ if(dnode_heap == NULL)
+ outofmemory();
+}
+
+/*
+ * make_dlink_node
+ *
+ * inputs - NONE
+ * output - pointer to new dlink_node
+ * side effects - NONE
+ */
+dlink_node *
+make_dlink_node(void)
+{
+ return(BlockHeapAlloc(dnode_heap));
+}
+
+/*
+ * free_dlink_node
+ *
+ * inputs - pointer to dlink_node
+ * output - NONE
+ * side effects - free given dlink_node
+ */
+void
+free_dlink_node(dlink_node * ptr)
+{
+ assert(ptr != NULL);
+
+ BlockHeapFree(dnode_heap, ptr);
+}
+
+/*
+ * find_umode_slot
+ *
+ * inputs - NONE
+ * outputs - an available umode bitmask or
+ * 0 if no umodes are available
+ * side effects - NONE
+ */
+unsigned int
+find_umode_slot(void)
+{
+ unsigned int all_umodes = 0, my_umode = 0, i;
+
+ for (i = 0; i < 128; i++)
+ all_umodes |= user_modes[i];
+
+ for (my_umode = 1; my_umode && (all_umodes & my_umode);
+ my_umode <<= 1);
+
+ return my_umode;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * tools.h: Header for the various tool functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox 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
+ *
+ * $Id: tools.h 382 2005-12-07 15:15:59Z nenolod $
+ */
+
+#ifndef __TOOLS_H__
+#define __TOOLS_H__
+
+
+/*
+ * double-linked-list stuff
+ */
+typedef struct _dlink_node dlink_node;
+typedef struct _dlink_list dlink_list;
+
+struct _dlink_node
+{
+ void *data;
+ dlink_node *prev;
+ dlink_node *next;
+
+};
+
+struct _dlink_list
+{
+ dlink_node *head;
+ dlink_node *tail;
+ unsigned long length;
+};
+
+dlink_node *make_dlink_node(void);
+void free_dlink_node(dlink_node * lp);
+void init_dlink_nodes(void);
+
+#ifndef NDEBUG
+void mem_frob(void *data, int len);
+#else
+#define mem_frob(x, y)
+#endif
+
+/* This macros are basically swiped from the linux kernel
+ * they are simple yet effective
+ */
+
+/*
+ * Walks forward of a list.
+ * pos is your node
+ * head is your list head
+ */
+#define DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
+
+/*
+ * Walks forward of a list safely while removing nodes
+ * pos is your node
+ * n is another list head for temporary storage
+ * head is your list head
+ */
+#define DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
+
+#define DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)
+
+
+/* Returns the list length */
+#define dlink_list_length(list) (list)->length
+#define dlink_move_list(oldlist, newlist, node)
+
+#define dlinkAddAlloc(data, list) dlinkAdd(data, make_dlink_node(), list)
+#define dlinkAddTailAlloc(data, list) dlinkAddTail(data, make_dlink_node(), list)
+#define dlinkDestroy(node, list) do { dlinkDelete(node, list); free_dlink_node(node); } while(0)
+
+
+/*
+ * The functions below are included for the sake of inlining
+ * hopefully this will speed up things just a bit
+ *
+ */
+
+/*
+ * dlink_ routines are stolen from squid, except for dlinkAddBefore,
+ * which is mine.
+ * -- adrian
+ */
+
+/* I hate C sometimes */
+#if defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
+#define INLINE_FUNC extern inline
+#define NEED_INLINES
+#else
+#undef INLINE_FUNC
+#define INLINE_FUNC
+#endif
+
+#ifdef TOOLS_C
+#undef INLINE_FUNC
+#define INLINE_FUNC
+#endif
+
+void dlinkMoveNode(dlink_node * m, dlink_list * oldlist, dlink_list * newlist);
+void dlinkAdd(void *data, dlink_node * m, dlink_list * list);
+void dlinkAddBefore(dlink_node * b, void *data, dlink_node * m, dlink_list * list);
+void dlinkMoveTail(dlink_node *m, dlink_list *list);
+void dlinkAddTail(void *data, dlink_node * m, dlink_list * list);
+void dlinkDelete(dlink_node * m, dlink_list * list);
+dlink_node *dlinkFindDelete(void *data, dlink_list *list);
+int dlinkFindDestroy(void *data, dlink_list *list);
+dlink_node *dlinkFind(void *data, dlink_list *list);
+void dlinkMoveList(dlink_list * from, dlink_list * to);
+unsigned int find_umode_slot(void);
+
+#if defined(NEED_INLINES) || defined(TOOLS_C)
+INLINE_FUNC void
+dlinkMoveNode(dlink_node * m, dlink_list * oldlist, dlink_list * newlist)
+{
+ /* Assumption: If m->next == NULL, then list->tail == m
+ * and: If m->prev == NULL, then list->head == m
+ */
+ assert(m != NULL);
+ assert(oldlist != NULL);
+ assert(newlist != NULL);
+
+ if(m->next)
+ m->next->prev = m->prev;
+ else
+ oldlist->tail = m->prev;
+
+ if(m->prev)
+ m->prev->next = m->next;
+ else
+ oldlist->head = m->next;
+
+ m->prev = NULL;
+ m->next = newlist->head;
+ if(newlist->head != NULL)
+ newlist->head->prev = m;
+ else if(newlist->tail == NULL)
+ newlist->tail = m;
+ newlist->head = m;
+
+ oldlist->length--;
+ newlist->length++;
+}
+
+INLINE_FUNC void
+dlinkAdd(void *data, dlink_node * m, dlink_list * list)
+{
+ assert(data != NULL);
+ assert(m != NULL);
+ assert(list != NULL);
+ m->data = data;
+ m->prev = NULL;
+ m->next = list->head;
+
+ /* Assumption: If list->tail != NULL, list->head != NULL */
+ if(list->head != NULL)
+ list->head->prev = m;
+ else if(list->tail == NULL)
+ list->tail = m;
+
+ list->head = m;
+ list->length++;
+}
+
+INLINE_FUNC void
+dlinkAddBefore(dlink_node * b, void *data, dlink_node * m, dlink_list * list)
+{
+ assert(b != NULL);
+ assert(data != NULL);
+ assert(m != NULL);
+ assert(list != NULL);
+
+ /* Shortcut - if its the first one, call dlinkAdd only */
+ if(b == list->head)
+ {
+ dlinkAdd(data, m, list);
+ }
+ else
+ {
+ m->data = data;
+ b->prev->next = m;
+ m->prev = b->prev;
+ b->prev = m;
+ m->next = b;
+ list->length++;
+ }
+}
+
+INLINE_FUNC void
+dlinkMoveTail(dlink_node *m, dlink_list *list)
+{
+ if(list->tail == m)
+ return;
+
+ /* From here assume that m->next != NULL as that can only
+ * be at the tail and assume that the node is on the list
+ */
+
+ m->next->prev = m->prev;
+
+ if(m->prev != NULL)
+ m->prev->next = m->next;
+ else
+ list->head = m->next;
+
+ list->tail->next = m;
+ m->prev = list->tail;
+ m->next = NULL;
+ list->tail = m;
+}
+
+INLINE_FUNC void
+dlinkAddTail(void *data, dlink_node * m, dlink_list * list)
+{
+ assert(m != NULL);
+ assert(list != NULL);
+ assert(data != NULL);
+ m->data = data;
+ m->next = NULL;
+ m->prev = list->tail;
+
+ /* Assumption: If list->tail != NULL, list->head != NULL */
+ if(list->tail != NULL)
+ list->tail->next = m;
+ else if(list->head == NULL)
+ list->head = m;
+
+ list->tail = m;
+ list->length++;
+}
+
+/* Execution profiles show that this function is called the most
+ * often of all non-spontaneous functions. So it had better be
+ * efficient. */
+INLINE_FUNC void
+dlinkDelete(dlink_node * m, dlink_list * list)
+{
+ assert(m != NULL);
+ assert(list != NULL);
+
+ /* Assumption: If m->next == NULL, then list->tail == m
+ * and: If m->prev == NULL, then list->head == m
+ */
+ if(m->next)
+ m->next->prev = m->prev;
+ else
+ list->tail = m->prev;
+
+ if(m->prev)
+ m->prev->next = m->next;
+ else
+ list->head = m->next;
+
+ m->next = m->prev = NULL;
+ list->length--;
+}
+
+INLINE_FUNC dlink_node *
+dlinkFindDelete(void *data, dlink_list *list)
+{
+ dlink_node *m;
+ assert(list != NULL);
+ assert(data != NULL);
+
+ DLINK_FOREACH(m, list->head)
+ {
+ if(m->data != data)
+ continue;
+
+ if(m->next)
+ m->next->prev = m->prev;
+ else
+ list->tail = m->prev;
+
+ if(m->prev)
+ m->prev->next = m->next;
+ else
+ list->head = m->next;
+
+ m->next = m->prev = NULL;
+ list->length--;
+ return m;
+ }
+
+ return NULL;
+}
+
+INLINE_FUNC int
+dlinkFindDestroy(void *data, dlink_list *list)
+{
+ void *ptr;
+
+ assert(list != NULL);
+ assert(data != NULL);
+
+ ptr = dlinkFindDelete(data, list);
+
+ if(ptr != NULL)
+ {
+ free_dlink_node(ptr);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * dlinkFind
+ * inputs - list to search
+ * - data
+ * output - pointer to link or NULL if not found
+ * side effects - Look for ptr in the linked listed pointed to by link.
+ */
+INLINE_FUNC dlink_node *
+dlinkFind(void *data, dlink_list *list)
+{
+ dlink_node *ptr;
+ assert(list != NULL);
+ assert(data != NULL);
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ if(ptr->data == data)
+ return (ptr);
+ }
+ return (NULL);
+}
+
+INLINE_FUNC void
+dlinkMoveList(dlink_list * from, dlink_list * to)
+{
+ assert(from != NULL);
+ assert(to != NULL);
+
+ /* There are three cases */
+ /* case one, nothing in from list */
+ if(from->head == NULL)
+ return;
+
+ /* case two, nothing in to list */
+ if(to->head == NULL)
+ {
+ to->head = from->head;
+ to->tail = from->tail;
+ from->head = from->tail = NULL;
+ to->length = from->length;
+ from->length = 0;
+ return;
+ }
+
+ /* third case play with the links */
+ from->tail->next = to->head;
+ to->head->prev = from->tail;
+ to->head = from->head;
+ from->head = from->tail = NULL;
+ to->length += from->length;
+ from->length = 0;
+}
+#endif
+
+#endif /* __TOOLS_H__ */
--- /dev/null
+Makefile
+static_modules.c
\ No newline at end of file
--- /dev/null
+core/m_die.so: core/m_die.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/irc_string.h ../include/numeric.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/s_log.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_newconf.h
+m_error.so: core/m_error.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/send.h ../include/msg.h ../libcharybdis/memory.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_log.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h
+m_join.so: core/m_join.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/common.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/s_serv.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/sprintf_irc.h \
+ ../include/packet.h
+core/m_kick.so: core/m_kick.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/send.h \
+ ../include/msg.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/parse.h ../include/hash.h \
+ ../include/packet.h ../include/s_serv.h
+core/m_kill.so: core/m_kill.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/sprintf_irc.h ../include/s_log.h ../include/s_serv.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/send.h ../include/whowas.h \
+ ../include/irc_string.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_newconf.h
+core/m_message.so: core/m_message.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/common.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_serv.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/channel.h \
+ ../include/irc_string.h ../include/hash.h ../include/class.h \
+ ../include/packet.h ../include/send.h ../libcharybdis/event.h \
+ ../include/patricia.h ../include/s_newconf.h
+core/m_mode.so: core/m_mode.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../libcharybdis/balloc.h ../include/setup.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/ircd_defs.h ../include/send.h ../libcharybdis/balloc.h \
+ ../include/channel.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/hash.h ../libcharybdis/tools.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/s_user.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/s_log.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/packet.h ../include/sprintf_irc.h ../include/s_newconf.h
+core/m_nick.so: core/m_nick.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_stats.h \
+ ../include/s_user.h ../include/whowas.h ../include/s_serv.h \
+ ../include/send.h ../include/channel.h ../include/s_log.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/common.h ../include/packet.h ../include/scache.h \
+ ../include/s_newconf.h ../include/monitor.h
+core/m_part.so: core/m_part.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/common.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/s_serv.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/packet.h
+core/m_quit.so: core/m_quit.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_serv.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/sprintf_irc.h
+core/m_server.so: core/m_server.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../libcharybdis/event.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_log.h ../include/s_serv.h ../include/s_stats.h \
+ ../include/scache.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+core/m_sjoin.so: core/m_sjoin.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/hash.h \
+ ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/send.h \
+ ../include/common.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_serv.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h
+core/m_squit.so: core/m_squit.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_log.h \
+ ../include/s_serv.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/hash.h \
+ ../include/s_newconf.h
+m_accept.so: m_accept.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_serv.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/sprintf_irc.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_admin.so: m_admin.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/hook.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_away.so: m_away.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_serv.h \
+ ../include/packet.h
+m_cap.so: m_cap.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/s_serv.h \
+ ../include/s_user.h
+m_capab.so: m_capab.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/s_serv.h ../include/s_conf.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_challenge.so: m_challenge.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/numeric.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/irc_string.h \
+ ../include/s_log.h ../include/s_user.h ../include/cache.h \
+ ../include/s_newconf.h
+m_chghost.so: m_chghost.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/memory.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/s_serv.h ../include/hash.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/sprintf_irc.h ../include/whowas.h ../include/monitor.h
+m_close.so: m_close.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_cmessage.so: m_cmessage.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/channel.h ../include/numeric.h ../include/msg.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/hook.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/send.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h
+m_connect.so: m_connect.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/irc_string.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/s_log.h ../include/s_serv.h \
+ ../include/send.h ../include/msg.h ../include/parse.h ../include/hash.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_dline.so: m_dline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/hostmask.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/s_log.h ../include/send.h \
+ ../include/hash.h ../include/s_serv.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_encap.so: m_encap.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/memory.h ../include/s_serv.h \
+ ../include/hash.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/sprintf_irc.h
+m_etrace.so: m_etrace.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/hook.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/s_serv.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_gline.so: m_gline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/s_gline.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/hostmask.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/scache.h \
+ ../include/send.h ../include/msg.h ../include/s_serv.h \
+ ../include/hash.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_log.h
+m_help.so: m_help.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/msg.h ../include/numeric.h \
+ ../include/send.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_log.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/hash.h ../include/cache.h
+m_info.so: m_info.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/m_info.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/hook.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_invite.so: m_invite.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/common.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/packet.h
+m_ison.so: m_ison.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/hash.h
+m_kline.so: m_kline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/hostmask.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/s_log.h ../include/send.h \
+ ../include/hash.h ../include/s_serv.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../libcharybdis/event.h
+m_knock.so: m_knock.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/sprintf_irc.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_serv.h
+m_links.so: m_links.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_serv.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h ../include/hook.h \
+ ../include/cache.h
+m_list_safelist.so: m_list_safelist.c ../include/stdinc.h \
+ ../include/config.h ../include/setup.h ../include/defaults.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_serv.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../libcharybdis/event.h
+m_locops.so: m_locops.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/irc_string.h ../include/numeric.h \
+ ../include/send.h ../include/s_user.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/hash.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/s_serv.h
+m_lusers.so: m_lusers.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_map.so: m_map.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/hook.h \
+ ../include/numeric.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/sprintf_irc.h
+m_monitor.so: m_monitor.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/hook.h \
+ ../include/monitor.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h
+m_motd.so: m_motd.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../libcharybdis/tools.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/send.h \
+ ../include/numeric.h ../include/hook.h ../include/msg.h \
+ ../include/s_serv.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/cache.h
+m_names.so: m_names.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/sprintf_irc.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/hash.h ../libcharybdis/tools.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/send.h \
+ ../include/s_serv.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_oper.so: m_oper.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_log.h ../include/s_user.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/packet.h ../include/cache.h
+m_operspy.so: m_operspy.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/memory.h ../include/s_serv.h \
+ ../include/hash.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/sprintf_irc.h
+m_pass.so: m_pass.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/send.h ../include/numeric.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_serv.h ../include/hash.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h
+m_ping.so: m_ping.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/send.h \
+ ../include/irc_string.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/hash.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h
+m_pong.so: m_pong.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/s_user.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/hash.h \
+ ../include/hook.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/send.h ../include/channel.h ../include/irc_string.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_post.so: m_post.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_serv.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h
+m_rehash.so: m_rehash.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/channel.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/s_gline.h ../include/s_serv.h \
+ ../include/numeric.h ../include/res.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/s_log.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/hostmask.h ../include/reject.h ../include/hash.h \
+ ../include/cache.h
+m_restart.so: m_restart.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/restart.h ../include/s_log.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_resv.so: m_resv.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/channel.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_serv.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/hash.h ../include/s_log.h \
+ ../include/sprintf_irc.h
+m_sasl.so: m_sasl.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/send.h \
+ ../include/msg.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/hook.h ../include/numeric.h ../include/s_serv.h
+m_scan.so: m_scan.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/hook.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/s_serv.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_user.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_services.so: m_services.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/memory.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/hash.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/sprintf_irc.h \
+ ../include/whowas.h ../include/monitor.h
+m_set.so: m_set.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../libcharybdis/event.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/s_serv.h \
+ ../include/send.h ../include/common.h ../include/channel.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_signon.so: m_signon.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/memory.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/hash.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/sprintf_irc.h \
+ ../include/whowas.h ../include/monitor.h ../include/s_stats.h \
+ ../include/snomask.h ../include/irc_string.h
+m_snote.so: m_snote.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/hook.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/s_serv.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_user.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_sshortcut.so: m_sshortcut.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/irc_string.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_log.h ../include/s_serv.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_stats.so: m_stats.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/listener.h \
+ ../include/s_gline.h ../include/msg.h ../include/hostmask.h \
+ ../include/numeric.h ../include/scache.h ../include/send.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/s_stats.h ../include/s_user.h \
+ ../libcharybdis/event.h ../libcharybdis/linebuf.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/hook.h ../include/s_newconf.h \
+ ../include/hash.h
+m_svinfo.so: m_svinfo.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_log.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_tb.so: m_tb.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../libcharybdis/tools.h ../include/send.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../include/channel.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/common.h \
+ ../include/config.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/hash.h \
+ ../include/s_serv.h
+m_testline.so: m_testline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/hook.h ../include/msg.h \
+ ../include/hostmask.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../libcharybdis/tools.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/sprintf_irc.h
+m_testmask.so: m_testmask.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/irc_string.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_log.h ../include/s_serv.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_time.so: m_time.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/packet.h \
+ ../include/sprintf_irc.h
+m_topic.so: m_topic.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/hash.h \
+ ../libcharybdis/tools.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/send.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_serv.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/packet.h
+m_trace.so: m_trace.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/hook.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hash.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/s_serv.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/send.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h
+m_user.so: m_user.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_user.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/sprintf_irc.h
+m_userhost.so: m_userhost.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_serv.h \
+ ../include/send.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h
+m_users.so: m_users.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/send.h ../include/msg.h \
+ ../include/parse.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h
+m_version.so: m_version.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_serv.h ../include/s_user.h ../include/send.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_wallops.so: m_wallops.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/irc_string.h ../include/numeric.h \
+ ../include/send.h ../include/s_user.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/s_newconf.h ../include/msg.h ../include/parse.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/s_serv.h
+m_who.so: m_who.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/common.h ../include/client.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/channel.h \
+ ../include/hash.h ../libcharybdis/tools.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_serv.h ../include/send.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/s_conf.h ../include/class.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_log.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/packet.h ../include/s_newconf.h
+m_whois.so: m_whois.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/common.h ../include/client.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/snomask.h ../include/client.h ../include/hash.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/numeric.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_serv.h ../include/send.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/s_log.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h ../include/hook.h \
+ ../include/s_newconf.h
+m_whowas.so: m_whowas.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/whowas.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/hash.h \
+ ../libcharybdis/tools.h ../include/irc_string.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/s_conf.h \
+ ../include/class.h ../include/common.h ../include/patricia.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h
+m_unreject.so: m_unreject.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/s_conf.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/common.h ../include/patricia.h ../include/irc_string.h \
+ ../include/ircd.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/memory.h \
+ ../include/numeric.h ../include/hostmask.h ../include/reject.h \
+ ../include/msg.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../include/send.h
+m_xline.so: m_xline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/send.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/channel.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/config.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/numeric.h ../libcharybdis/memory.h \
+ ../include/s_log.h ../include/s_serv.h ../include/whowas.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/hash.h \
+ ../include/msg.h ../include/parse.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../include/hook.h \
+ ../include/s_conf.h ../include/class.h ../include/common.h \
+ ../include/patricia.h ../include/irc_string.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_newconf.h
+sno_routing.so: sno_routing.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/modules.h \
+ ../include/parse.h ../include/msg.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/hook.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/res.h ../include/snomask.h ../include/client.h \
+ ../include/hook.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../include/send.h
--- /dev/null
+/* $Id: .indent.pro 238 2005-09-21 05:26:03Z nenolod $ */
+
+/* copy this file to the source dir then run indent file.c */
+
+--gnu-style
+
+/* This is the indent before the brace not inside the block. */
+--brace-indent0
+
+/* Indent case: by 2 and braces inside case by 0(then by 0)... */
+--case-brace-indentation0
+--case-indentation2
+
+--indent-level8
+
+/* Put while() on the brace from do... */
+--cuddle-do-while
+
+/* Disable an annoying format... */
+--no-space-after-function-call-names
+
+/* Disable an annoying format... */
+--dont-break-procedure-type
+
+/* Disable an annoying format... */
+--no-space-after-casts
+
+--line-length200
+
+/* typedefs */
+-T boolean_t
+-T node_t
+-T list_t
+-T tld_t
+-T kline_t
+-T EVH
+-T sra_t
+-T server_t
+-T user_t
+-T channel_t
+-T chanuser_t
+-T myuser_t
+-T mychan_t
+-T chanacs_t
+-T CONFIGENTRY
+-T CONFIGFILE
+-T Block
+-T MemBlock
+-T BlockHeap
--- /dev/null
+#
+# Makefile.in for ircd/modules
+#
+# $Id: Makefile.in 946 2006-03-06 03:43:02Z nenolod $
+#
+CC = @CC@
+AR = @AR@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+PICFLAGS = @PICFLAGS@
+MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+SEDOBJ = @SEDOBJ@
+SHELL = /bin/sh
+MV = @MV@
+LD = @LD@
+
+SSL_LIBS = @SSL_LIBS@
+SSL_INCLUDES = @SSL_INCLUDES@
+
+IRCDLIBS = @LIBS@ $(SSL_LIBS)
+
+prefix = @prefix@
+moduledir = @moduledir@
+# Change this later! -- adrian
+automoduledir = @moduledir@/autoload
+
+INCLUDES = -I../include -I../libcharybdis -I../adns $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+CORE_SRCS = \
+ core/m_die.c \
+ core/m_error.c \
+ core/m_join.c \
+ core/m_kick.c \
+ core/m_kill.c \
+ core/m_message.c \
+ core/m_mode.c \
+ core/m_nick.c \
+ core/m_part.c \
+ core/m_quit.c \
+ core/m_server.c \
+ core/m_sjoin.c \
+ core/m_squit.c
+
+TSRCS = \
+ m_accept.c \
+ m_admin.c \
+ m_away.c \
+ m_cap.c \
+ m_capab.c \
+ m_challenge.c \
+ m_chghost.c \
+ m_close.c \
+ m_cmessage.c \
+ m_connect.c \
+ m_dline.c \
+ m_encap.c \
+ m_etrace.c \
+ m_gline.c \
+ m_help.c \
+ m_info.c \
+ m_invite.c \
+ m_ison.c \
+ m_kline.c \
+ m_knock.c \
+ m_links.c \
+ m_list_safelist.c \
+ m_locops.c \
+ m_lusers.c \
+ m_map.c \
+ m_monitor.c \
+ m_motd.c \
+ m_names.c \
+ m_oper.c \
+ m_operspy.c \
+ m_pass.c \
+ m_ping.c \
+ m_pong.c \
+ m_post.c \
+ m_rehash.c \
+ m_restart.c \
+ m_resv.c \
+ m_sasl.c \
+ m_scan.c \
+ m_services.c \
+ m_set.c \
+ m_signon.c \
+ m_snote.c \
+ m_stats.c \
+ m_svinfo.c \
+ m_tb.c \
+ m_testline.c \
+ m_testmask.c \
+ m_time.c \
+ m_topic.c \
+ m_trace.c \
+ m_user.c \
+ m_userhost.c \
+ m_users.c \
+ m_version.c \
+ m_wallops.c \
+ m_who.c \
+ m_whois.c \
+ m_whowas.c \
+ m_unreject.c \
+ m_xline.c \
+ sno_routing.c
+
+SRCS = ${TSRCS}
+
+ALL_SRCS = $(CORE_SRCS) \
+ $(SRCS)
+
+SH_OBJS = ${SRCS:.c=.so}
+SH_CORE_OBJS = ${CORE_SRCS:.c=.so}
+
+HPUX_OBJS = ${SH_OBJS:.so=.sl}
+HPUX_CORE_OBJS = ${SH_CORE_OBJS:.so=.sl}
+
+S_OBJS = ${ALL_SRCS:.c=.o}
+
+DOLLAR = $$
+
+default: build
+build: all
+all: @MOD_TARGET@
+
+shared_modules: $(SH_CORE_OBJS) $(SH_OBJS)
+
+hpux_modules: $(HPUX_CORE_OBJS) $(HPUX_OBJS)
+
+hpux_shared: $(SH_CORE_OBJS) $(SH_OBJS)
+ ${MAKE} hpux_modules
+
+static_modules.c: static_modules.c.SH
+ /bin/sh ./static_modules.c.SH $(S_OBJS)
+
+libmodules.a: $(S_OBJS) static_modules.o
+ $(RM) -f $@
+ $(AR) cqv $@ $(S_OBJS) static_modules.o
+ $(RANLIB) $@
+
+
+install-mkdirs:
+ @echo "ircd: setting up modular directory structure"
+ -@if test ! -d $(DESTDIR)$(moduledir); then \
+ mkdir $(DESTDIR)$(moduledir); \
+ fi
+ -@if test -d $(DESTDIR)$(moduledir)-old; then \
+ rm -rf $(DESTDIR)$(moduledir)-old; \
+ fi
+ -@if test -d $(DESTDIR)$(moduledir); then \
+ echo "ircd: backing up modules"; \
+ mv $(DESTDIR)$(moduledir) $(DESTDIR)$(moduledir)-old; \
+ fi
+
+ @mkdir -p -m 755 $(DESTDIR)$(moduledir)
+ @mkdir -p -m 755 $(DESTDIR)$(automoduledir)
+
+install: install_@MOD_TARGET@
+
+install_libmodules.a: libmodules.a
+# Ye olde noop here.
+
+install_shared_modules: install-mkdirs
+ @echo "ircd: installing modules"
+ @for file in $(SH_CORE_OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(moduledir); \
+ done
+ @for file in $(SH_OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(automoduledir); \
+ done
+
+install_hpux_shared: install-mkdirs
+ @echo "ircd: installing modules"
+ @for file in $(HPUX_CORE_OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(moduledir); \
+ done
+ @for file in $(HPUX_OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(automoduledir); \
+ done
+
+.SUFFIXES: .sl .so .o
+
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -DMODNAME=`basename $< .c`_mheader -c $< -o $@
+
+.c.so:
+ ${CC} ${PICFLAGS} ${CPPFLAGS} ${CFLAGS} $< -o $@
+
+.so.sl:
+ $(LD) -b $< -o $@
+
+.PHONY: depend clean distclean
+depend:
+ @$(RM) -f .depend
+ ${MKDEP} ${CPPFLAGS} ${ALL_SRCS} > .depend
+ @$(SED) -e '${SEDOBJ}' < .depend > .depend.tmp-1
+ @$(SED) -e 's/^m_\(die\|kick\|kill\|message\|mode\|nick\|part\|quit\|server\|sjoin\|squit\)/core\/m_\1/' .depend.tmp-1 > .depend.tmp
+ @$(MV) -f .depend.tmp .depend
+ @$(RM) -f .depend.tmp-1
+
+clean:
+ ${RM} -f *.so *.sl *~ *.o *.a
+ ${RM} -f core/*.so core/*.sl core/*~ core/*.o
+
+lint:
+ lint -aacgprxhH ${CPPFLAGS} -DIRCD_PREFIX=\"@prefix@\" $(ALL_SRCS) >../lint.out
+
+distclean: clean
+ ${RM} -f Makefile
+
+include .depend
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_die.c: Kills off this server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_die.c 98 2005-09-11 03:37:47Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_newconf.h"
+
+static int mo_die(struct Client *, struct Client *, int, const char **);
+
+static struct Message die_msgtab = {
+ "DIE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_die, 0}}
+};
+
+mapi_clist_av1 die_clist[] = { &die_msgtab, NULL };
+
+DECLARE_MODULE_AV1(die, NULL, NULL, die_clist, NULL, NULL, "$Revision: 98 $");
+
+/*
+ * mo_die - DIE command handler
+ */
+static int
+mo_die(struct Client *client_p __unused, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ if(!IsOperDie(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "die");
+ return 0;
+ }
+
+ if(parc < 2 || EmptyString(parv[1]))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Need server name /die %s",
+ me.name, source_p->name, me.name);
+ return 0;
+ }
+ else if(irccmp(parv[1], me.name))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Mismatch on /die %s",
+ me.name, source_p->name, me.name);
+ return 0;
+ }
+
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p,
+ ":%s NOTICE %s :Server Terminating. %s",
+ me.name, target_p->name, get_client_name(source_p, HIDE_IP));
+ }
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p, ":%s ERROR :Terminated by %s",
+ me.name, get_client_name(source_p, HIDE_IP));
+ }
+
+ /*
+ * XXX we called flush_connections() here. Read server_reboot()
+ * for an explanation as to what we should do.
+ * -- adrian
+ */
+ ilog(L_MAIN, "Server terminated by %s", get_oper_name(source_p));
+
+ /* this is a normal exit, tell the os it's ok */
+ unlink(pidFileName);
+ exit(0);
+ /* NOT REACHED */
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_error.c: Handles error messages from the other end.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_error.c 494 2006-01-15 16:08:28Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h" /* FALSE */
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "memory.h"
+#include "modules.h"
+#include "s_log.h"
+#include "s_conf.h"
+
+static int m_error(struct Client *, struct Client *, int, const char **);
+static int ms_error(struct Client *, struct Client *, int, const char **);
+
+struct Message error_msgtab = {
+ "ERROR", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{m_error, 0}, mg_ignore, mg_ignore, {ms_error, 0}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 error_clist[] = {
+ &error_msgtab, NULL
+};
+
+DECLARE_MODULE_AV1(error, NULL, NULL, error_clist, NULL, NULL, "$Revision: 494 $");
+
+
+/*
+ * Note: At least at protocol level ERROR has only one parameter,
+ * although this is called internally from other functions
+ * --msa
+ *
+ * parv[0] = sender prefix
+ * parv[*] = parameters
+ */
+int
+m_error(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *para;
+
+ para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
+
+ ilog(L_SERVER, "Received ERROR message from %s: %s",
+ log_client_name(source_p, SHOW_IP), para);
+
+ if(IsAnyServer(client_p) && ConfigFileEntry.hide_error_messages < 2)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ADMIN,
+ "ERROR :from %s -- %s",
+ get_server_name(client_p, HIDE_IP), para);
+
+ if(!ConfigFileEntry.hide_error_messages)
+ sendto_realops_snomask(SNO_GENERAL, L_OPER,
+ "ERROR :from %s -- %s",
+ get_server_name(client_p, HIDE_IP), para);
+ }
+
+ exit_client(client_p, source_p, source_p, "ERROR");
+
+ return 0;
+}
+
+static int
+ms_error(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *para;
+
+ para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
+
+ ilog(L_SERVER, "Received ERROR message from %s: %s",
+ log_client_name(source_p, SHOW_IP), para);
+
+ if(ConfigFileEntry.hide_error_messages == 2)
+ return 0;
+
+ if(client_p == source_p)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ADMIN, "ERROR :from %s -- %s",
+ get_server_name(client_p, HIDE_IP), para);
+
+ if(!ConfigFileEntry.hide_error_messages)
+ sendto_realops_snomask(SNO_GENERAL, L_OPER,
+ "ERROR :from %s -- %s",
+ get_server_name(client_p, HIDE_IP), para);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ADMIN, "ERROR :from %s via %s -- %s",
+ source_p->name, get_server_name(client_p, HIDE_IP), para);
+
+ if(!ConfigFileEntry.hide_error_messages)
+ sendto_realops_snomask(SNO_GENERAL, L_OPER,
+ "ERROR :from %s via %s -- %s",
+ source_p->name,
+ get_server_name(client_p, HIDE_IP), para);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_join.c: Joins a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_join.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+#include "packet.h"
+
+static int m_join(struct Client *, struct Client *, int, const char **);
+static int ms_join(struct Client *, struct Client *, int, const char **);
+
+static int h_can_create_channel;
+static int h_channel_join;
+
+struct Message join_msgtab = {
+ "JOIN", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_join, 2}, {ms_join, 2}, mg_ignore, mg_ignore, {m_join, 2}}
+};
+
+mapi_clist_av1 join_clist[] = { &join_msgtab, NULL };
+
+mapi_hlist_av1 join_hlist[] = {
+ { "can_create_channel", &h_can_create_channel },
+ { "channel_join", &h_channel_join },
+ { NULL, NULL },
+};
+
+DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3131 $");
+
+static void do_join_0(struct Client *client_p, struct Client *source_p);
+static int check_channel_name_loc(struct Client *source_p, const char *name);
+
+static void set_final_mode(struct Mode *mode, struct Mode *oldmode);
+static void remove_our_modes(struct Channel *chptr, struct Client *source_p);
+
+static char modebuf[MODEBUFLEN];
+static char parabuf[MODEBUFLEN];
+static char *mbuf;
+
+/* Check what we will forward to, without sending any notices to the user
+ * -- jilles
+ */
+static struct Channel *
+check_forward(struct Client *source_p, struct Channel *chptr,
+ char *key)
+{
+ int depth = 0, i;
+
+ /* User is +Q */
+ if (IsNoForward(source_p))
+ return NULL;
+
+ while (depth < 16)
+ {
+ chptr = find_channel(chptr->mode.forward);
+ /* Can only forward to existing channels */
+ if (chptr == NULL)
+ return NULL;
+ /* Already on there, show original error message */
+ if (IsMember(source_p, chptr))
+ return NULL;
+ /* Juped. Sending a warning notice would be unfair */
+ if (hash_find_resv(chptr->chname))
+ return NULL;
+ /* Don't forward to +Q channel */
+ if (chptr->mode.mode & MODE_DISFORWARD)
+ return NULL;
+ i = can_join(source_p, chptr, key);
+ if (i == 0)
+ return chptr;
+ if (i != ERR_INVITEONLYCHAN && i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_CHANNELISFULL)
+ return NULL;
+ depth++;
+ }
+
+ return NULL;
+}
+
+/*
+ * m_join
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ * parv[2] = channel password (key)
+ */
+static int
+m_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static char jbuf[BUFSIZE];
+ struct Channel *chptr = NULL;
+ struct ConfItem *aconf;
+ char *name;
+ char *key = NULL;
+ int i, flags = 0;
+ char *p = NULL, *p2 = NULL;
+ char *chanlist;
+ char *mykey;
+ int successful_join_count = 0; /* Number of channels successfully joined */
+
+ jbuf[0] = '\0';
+
+ /* rebuild the list of channels theyre supposed to be joining.
+ * this code has a side effect of losing keys, but..
+ */
+ chanlist = LOCAL_COPY(parv[1]);
+ for(name = strtoken(&p, chanlist, ","); name; name = strtoken(&p, NULL, ","))
+ {
+ /* check the length and name of channel is ok */
+ if(!check_channel_name_loc(source_p, name) || (strlen(name) > LOC_CHANNELLEN))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME), (unsigned char *) name);
+ continue;
+ }
+
+ /* join 0 parts all channels */
+ if(*name == '0' && !atoi(name))
+ {
+ (void) strcpy(jbuf, "0");
+ continue;
+ }
+
+ /* check it begins with # or &, and local chans are disabled */
+ else if(!IsChannelName(name))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), name);
+ continue;
+ }
+
+ /* see if its resv'd */
+ if(!IsExemptResv(source_p) && (aconf = hash_find_resv(name)))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME), name);
+
+ /* dont warn for opers */
+ if(!IsExemptJupe(source_p) && !IsOper(source_p))
+ sendto_realops_snomask(SNO_SPY, L_NETWIDE,
+ "User %s (%s@%s) is attempting to join locally juped channel %s (%s)",
+ source_p->name, source_p->username,
+ source_p->host, name, aconf->passwd);
+ /* dont update tracking for jupe exempt users, these
+ * are likely to be spamtrap leaves
+ */
+ else if(IsExemptJupe(source_p))
+ aconf->port--;
+
+ continue;
+ }
+
+ if(splitmode && !IsOper(source_p) && (*name != '&') &&
+ ConfigChannel.no_join_on_split)
+ {
+ sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+ me.name, source_p->name, name);
+ continue;
+ }
+
+ if(*jbuf)
+ (void) strcat(jbuf, ",");
+ (void) strlcat(jbuf, name, sizeof(jbuf));
+ }
+
+ if(parc > 2)
+ {
+ mykey = LOCAL_COPY(parv[2]);
+ key = strtoken(&p2, mykey, ",");
+ }
+
+ for(name = strtoken(&p, jbuf, ","); name;
+ key = (key) ? strtoken(&p2, NULL, ",") : NULL, name = strtoken(&p, NULL, ","))
+ {
+ hook_data_channel_activity hook_info;
+
+ /* JOIN 0 simply parts all channels the user is in */
+ if(*name == '0' && !atoi(name))
+ {
+ if(source_p->user->channel.head == NULL)
+ continue;
+
+ do_join_0(&me, source_p);
+ continue;
+ }
+
+ /* look for the channel */
+ if((chptr = find_channel(name)) != NULL)
+ {
+ if(IsMember(source_p, chptr))
+ continue;
+
+ flags = 0;
+ }
+ else
+ {
+ hook_data_client_approval moduledata;
+
+ moduledata.client = source_p;
+ moduledata.approved = 0;
+
+ call_hook(h_can_create_channel, &moduledata);
+
+ if(moduledata.approved != 0 && !IsOper(source_p))
+ {
+ sendto_one(source_p, form_str(moduledata.approved),
+ me.name, source_p->name, name);
+ continue;
+ }
+
+ if(splitmode && !IsOper(source_p) && (*name != '&') &&
+ ConfigChannel.no_create_on_split)
+ {
+ sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+ me.name, source_p->name, name);
+ continue;
+ }
+
+ flags = CHFL_CHANOP;
+ }
+
+ if((dlink_list_length(&source_p->user->channel) >=
+ (unsigned long) ConfigChannel.max_chans_per_user) &&
+ (!IsOper(source_p) ||
+ (dlink_list_length(&source_p->user->channel) >=
+ (unsigned long) ConfigChannel.max_chans_per_user * 3)))
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
+ me.name, source_p->name, name);
+ if(successful_join_count)
+ source_p->localClient->last_join_time = CurrentTime;
+ return 0;
+ }
+
+ if(flags == 0) /* if channel doesn't exist, don't penalize */
+ successful_join_count++;
+
+ if(chptr == NULL) /* If I already have a chptr, no point doing this */
+ {
+ chptr = get_or_create_channel(source_p, name, NULL);
+
+ if(chptr == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+ me.name, source_p->name, name);
+ if(successful_join_count > 0)
+ successful_join_count--;
+ continue;
+ }
+ }
+
+ if(!IsOper(source_p) && !IsExemptSpambot(source_p))
+ check_spambot_warning(source_p, name);
+
+ /* can_join checks for +i key, bans etc */
+ if((i = can_join(source_p, chptr, key)))
+ {
+ if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) ||
+ (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL))
+ {
+ sendto_one(source_p, form_str(i), me.name, source_p->name, name);
+ if(successful_join_count > 0)
+ successful_join_count--;
+ continue;
+ }
+ sendto_one_numeric(source_p, ERR_LINKCHANNEL, form_str(ERR_LINKCHANNEL), name, chptr->chname);
+ }
+
+ /* add the user to the channel */
+ add_user_to_channel(chptr, source_p, flags);
+ if (chptr->mode.join_num &&
+ CurrentTime - chptr->join_delta >= chptr->mode.join_time)
+ {
+ chptr->join_count = 0;
+ chptr->join_delta = CurrentTime;
+ }
+ chptr->join_count++;
+
+ /* we send the user their join here, because we could have to
+ * send a mode out next.
+ */
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ source_p->name,
+ source_p->username, source_p->host, chptr->chname);
+
+ /* its a new channel, set +nt and burst. */
+ if(flags & CHFL_CHANOP)
+ {
+ chptr->channelts = CurrentTime;
+ chptr->mode.mode |= MODE_TOPICLIMIT;
+ chptr->mode.mode |= MODE_NOPRIVMSGS;
+
+ sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt",
+ me.name, chptr->chname);
+
+ if(*chptr->chname == '#')
+ {
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s SJOIN %ld %s +nt :@%s",
+ me.id, (long) chptr->channelts,
+ chptr->chname, source_p->id);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s SJOIN %ld %s +nt :@%s",
+ me.name, (long) chptr->channelts,
+ chptr->chname, source_p->name);
+ }
+ }
+ else
+ {
+ const char *modes = channel_modes(chptr, &me);
+
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s JOIN %ld %s %s",
+ use_id(source_p), (long) chptr->channelts,
+ chptr->chname, modes);
+
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s SJOIN %ld %s %s :%s",
+ me.name, (long) chptr->channelts,
+ chptr->chname, modes, source_p->name);
+ }
+
+ del_invite(chptr, source_p);
+
+ if(chptr->topic != NULL)
+ {
+ sendto_one(source_p, form_str(RPL_TOPIC), me.name,
+ source_p->name, chptr->chname, chptr->topic);
+
+ sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
+ me.name, source_p->name, chptr->chname,
+ chptr->topic_info, chptr->topic_time);
+ }
+
+ channel_member_names(chptr, source_p, 1);
+
+ if(successful_join_count)
+ source_p->localClient->last_join_time = CurrentTime;
+
+ hook_info.client = source_p;
+ hook_info.chptr = chptr;
+ hook_info.key = key;
+ call_hook(h_channel_join, &hook_info);
+ }
+
+ return 0;
+}
+
+/*
+ * ms_join
+ *
+ * inputs -
+ * output - none
+ * side effects - handles remote JOIN's sent by servers. In TSora
+ * remote clients are joined using SJOIN, hence a
+ * JOIN sent by a server on behalf of a client is an error.
+ * here, the initial code is in to take an extra parameter
+ * and use it for the TimeStamp on a new channel.
+ */
+static int
+ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ static struct Mode mode, *oldmode;
+ const char *s;
+ const char *modes;
+ time_t oldts;
+ time_t newts;
+ int isnew;
+ int args = 0;
+ int keep_our_modes = YES;
+ int keep_new_modes = YES;
+ dlink_node *ptr, *next_ptr;
+
+ /* special case for join 0 */
+ if((parv[1][0] == '0') && (parv[1][1] == '\0') && parc == 2)
+ {
+ do_join_0(client_p, source_p);
+ return 0;
+ }
+
+ if(parc < 4)
+ return 0;
+
+ if(!IsChannelName(parv[2]) || !check_channel_name(parv[2]))
+ return 0;
+
+ /* joins for local channels cant happen. */
+ if(parv[2][0] == '&')
+ return 0;
+
+ mbuf = modebuf;
+ mode.key[0] = mode.forward[0] = '\0';
+ mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
+
+ s = parv[3];
+ while(*s)
+ {
+ switch (*(s++))
+ {
+ case 'i':
+ mode.mode |= MODE_INVITEONLY;
+ break;
+ case 'n':
+ mode.mode |= MODE_NOPRIVMSGS;
+ break;
+ case 'p':
+ mode.mode |= MODE_PRIVATE;
+ break;
+ case 's':
+ mode.mode |= MODE_SECRET;
+ break;
+ case 'm':
+ mode.mode |= MODE_MODERATED;
+ break;
+ case 't':
+ mode.mode |= MODE_TOPICLIMIT;
+ break;
+ case 'r':
+ mode.mode |= MODE_REGONLY;
+ break;
+ case 'L':
+ mode.mode |= MODE_EXLIMIT;
+ break;
+ case 'P':
+ mode.mode |= MODE_PERMANENT;
+ break;
+ case 'c':
+ mode.mode |= MODE_NOCOLOR;
+ break;
+ case 'g':
+ mode.mode |= MODE_FREEINVITE;
+ break;
+ case 'z':
+ mode.mode |= MODE_OPMODERATE;
+ break;
+ case 'F':
+ mode.mode |= MODE_FREETARGET;
+ break;
+ case 'Q':
+ mode.mode |= MODE_DISFORWARD;
+ break;
+ case 'f':
+ if(parc < 5 + args)
+ return 0;
+ strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
+ args++;
+ break;
+ case 'j':
+ /* sent a +j without an arg. */
+ if(parc < 5 + args)
+ return 0;
+ sscanf(parv[4 + args], "%d:%d", &mode.join_num, &mode.join_time);
+ args++;
+ break;
+ case 'k':
+ /* sent a +k without a key, eek. */
+ if(parc < 5 + args)
+ return 0;
+ strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
+ args++;
+ break;
+ case 'l':
+ /* sent a +l without a limit. */
+ if(parc < 5 + args)
+ return 0;
+ mode.limit = atoi(parv[4 + args]);
+ args++;
+ break;
+ }
+ }
+
+ if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
+ return 0;
+
+ newts = atol(parv[1]);
+ oldts = chptr->channelts;
+ oldmode = &chptr->mode;
+
+#ifdef IGNORE_BOGUS_TS
+ if(newts < 800000000)
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "*** Bogus TS %ld on %s ignored from %s",
+ (long) newts, chptr->chname, client_p->name);
+ newts = (oldts == 0) ? oldts : 800000000;
+ }
+#else
+ /* making a channel TS0 */
+ if(!isnew && !newts && oldts)
+ {
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
+ me.name, chptr->chname, chptr->chname, (long) oldts);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Server %s changing TS on %s from %ld to 0",
+ source_p->name, chptr->chname, (long) oldts);
+ }
+#endif
+
+ if(isnew)
+ chptr->channelts = newts;
+ else if(newts == 0 || oldts == 0)
+ chptr->channelts = 0;
+ else if(newts == oldts)
+ ;
+ else if(newts < oldts)
+ {
+ keep_our_modes = NO;
+ chptr->channelts = newts;
+ }
+ else
+ keep_new_modes = NO;
+
+ if(!keep_new_modes)
+ mode = *oldmode;
+ else if(keep_our_modes)
+ {
+ mode.mode |= oldmode->mode;
+ if(oldmode->limit > mode.limit)
+ mode.limit = oldmode->limit;
+ if(strcmp(mode.key, oldmode->key) < 0)
+ strcpy(mode.key, oldmode->key);
+ if(oldmode->join_num > mode.join_num ||
+ (oldmode->join_num == mode.join_num &&
+ oldmode->join_time > mode.join_time))
+ {
+ mode.join_num = oldmode->join_num;
+ mode.join_time = oldmode->join_time;
+ }
+ if(irccmp(mode.forward, oldmode->forward) < 0)
+ strcpy(mode.forward, oldmode->forward);
+ }
+ else
+ {
+ /* If setting -j, clear join throttle state -- jilles */
+ if (!mode.join_num)
+ chptr->join_count = chptr->join_delta = 0;
+ }
+
+ set_final_mode(&mode, oldmode);
+ chptr->mode = mode;
+
+ /* Lost the TS, other side wins, so remove modes on this side */
+ if(!keep_our_modes)
+ {
+ remove_our_modes(chptr, source_p);
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
+ {
+ del_invite(chptr, ptr->data);
+ }
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
+ me.name, chptr->chname, chptr->chname,
+ (long) oldts, (long) newts);
+ }
+
+ if(*modebuf != '\0')
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
+ source_p->user->server, chptr->chname, modebuf, parabuf);
+
+ *modebuf = *parabuf = '\0';
+
+ if(!IsMember(source_p, chptr))
+ {
+ add_user_to_channel(chptr, source_p, CHFL_PEON);
+ if (chptr->mode.join_num &&
+ CurrentTime - chptr->join_delta >= chptr->mode.join_time)
+ {
+ chptr->join_count = 0;
+ chptr->join_delta = CurrentTime;
+ }
+ chptr->join_count++;
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ source_p->name, source_p->username,
+ source_p->host, chptr->chname);
+ }
+
+ modes = channel_modes(chptr, client_p);
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s JOIN %ld %s %s",
+ source_p->id, (long) chptr->channelts, chptr->chname, modes);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s SJOIN %ld %s %s :%s",
+ source_p->user->server, (long) chptr->channelts,
+ chptr->chname, modes, source_p->name);
+ return 0;
+}
+
+/*
+ * do_join_0
+ *
+ * inputs - pointer to client doing join 0
+ * output - NONE
+ * side effects - Use has decided to join 0. This is legacy
+ * from the days when channels were numbers not names. *sigh*
+ * There is a bunch of evilness necessary here due to
+ * anti spambot code.
+ */
+static void
+do_join_0(struct Client *client_p, struct Client *source_p)
+{
+ struct membership *msptr;
+ struct Channel *chptr = NULL;
+ dlink_node *ptr;
+
+ /* Finish the flood grace period... */
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+
+ sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s JOIN 0", source_p->name);
+
+ if(source_p->user->channel.head && MyConnect(source_p) &&
+ !IsOper(source_p) && !IsExemptSpambot(source_p))
+ check_spambot_warning(source_p, NULL);
+
+ while((ptr = source_p->user->channel.head))
+ {
+ msptr = ptr->data;
+ chptr = msptr->chptr;
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
+ source_p->name,
+ source_p->username, source_p->host, chptr->chname);
+ remove_user_from_channel(msptr);
+ }
+}
+
+static int
+check_channel_name_loc(struct Client *source_p, const char *name)
+{
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return 0;
+
+ if(ConfigFileEntry.disable_fake_channels && !IsOper(source_p))
+ {
+ for(; *name; ++name)
+ {
+ if(!IsChanChar(*name) || IsFakeChanChar(*name))
+ return 0;
+ }
+ }
+ else
+ {
+ for(; *name; ++name)
+ {
+ if(!IsChanChar(*name))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+struct mode_letter
+{
+ int mode;
+ char letter;
+};
+
+static struct mode_letter flags[] = {
+ {MODE_NOPRIVMSGS, 'n'},
+ {MODE_TOPICLIMIT, 't'},
+ {MODE_SECRET, 's'},
+ {MODE_MODERATED, 'm'},
+ {MODE_INVITEONLY, 'i'},
+ {MODE_PRIVATE, 'p'},
+ {MODE_REGONLY, 'r'},
+ {MODE_EXLIMIT, 'L'},
+ {MODE_PERMANENT, 'P'},
+ {MODE_NOCOLOR, 'c'},
+ {MODE_FREEINVITE, 'g'},
+ {MODE_OPMODERATE, 'z'},
+ {MODE_FREETARGET, 'F'},
+ {MODE_DISFORWARD, 'Q'},
+ {0, 0}
+};
+
+static void
+set_final_mode(struct Mode *mode, struct Mode *oldmode)
+{
+ int dir = MODE_QUERY;
+ char *pbuf = parabuf;
+ int len;
+ int i;
+
+ /* ok, first get a list of modes we need to add */
+ for(i = 0; flags[i].letter; i++)
+ {
+ if((mode->mode & flags[i].mode) && !(oldmode->mode & flags[i].mode))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = flags[i].letter;
+ }
+ }
+
+ /* now the ones we need to remove. */
+ for(i = 0; flags[i].letter; i++)
+ {
+ if((oldmode->mode & flags[i].mode) && !(mode->mode & flags[i].mode))
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = flags[i].letter;
+ }
+ }
+
+ if(oldmode->limit && !mode->limit)
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'l';
+ }
+ if(oldmode->key[0] && !mode->key[0])
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'k';
+ len = ircsprintf(pbuf, "%s ", oldmode->key);
+ pbuf += len;
+ }
+ if(oldmode->join_num && !mode->join_num)
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'j';
+ }
+ if(oldmode->forward[0] && !mode->forward[0])
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'f';
+ }
+ if(mode->limit && oldmode->limit != mode->limit)
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'l';
+ len = ircsprintf(pbuf, "%d ", mode->limit);
+ pbuf += len;
+ }
+ if(mode->key[0] && strcmp(oldmode->key, mode->key))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'k';
+ len = ircsprintf(pbuf, "%s ", mode->key);
+ pbuf += len;
+ }
+ if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'j';
+ len = ircsprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
+ pbuf += len;
+ }
+ if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'f';
+ len = ircsprintf(pbuf, "%s ", mode->forward);
+ pbuf += len;
+ }
+ *mbuf = '\0';
+}
+
+/*
+ * remove_our_modes
+ *
+ * inputs -
+ * output -
+ * side effects -
+ */
+static void
+remove_our_modes(struct Channel *chptr, struct Client *source_p)
+{
+ struct membership *msptr;
+ dlink_node *ptr;
+ char lmodebuf[MODEBUFLEN];
+ char *lpara[MAXMODEPARAMS];
+ int count = 0;
+ int i;
+
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+
+ for(i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+
+ if(is_chanop(msptr))
+ {
+ msptr->flags &= ~CHFL_CHANOP;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'o';
+
+ /* +ov, might not fit so check. */
+ if(is_voiced(msptr))
+ {
+ if(count >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname,
+ lmodebuf, lpara[0], lpara[1],
+ lpara[2], lpara[3]);
+
+ /* preserve the initial '-' */
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+ count = 0;
+
+ for(i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+ }
+
+ msptr->flags &= ~CHFL_VOICE;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'v';
+ }
+ }
+ else if(is_voiced(msptr))
+ {
+ msptr->flags &= ~CHFL_VOICE;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'v';
+ }
+ else
+ continue;
+
+ if(count >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname, lmodebuf,
+ lpara[0], lpara[1], lpara[2], lpara[3]);
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+ count = 0;
+
+ for(i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+ }
+ }
+
+ if(count != 0)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname, lmodebuf,
+ EmptyString(lpara[0]) ? "" : lpara[0],
+ EmptyString(lpara[1]) ? "" : lpara[1],
+ EmptyString(lpara[2]) ? "" : lpara[2],
+ EmptyString(lpara[3]) ? "" : lpara[3]);
+
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_kick.c: Kicks a user from a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_kick.c 258 2005-09-21 23:57:17Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "modules.h"
+#include "parse.h"
+#include "hash.h"
+#include "packet.h"
+#include "s_serv.h"
+
+static int m_kick(struct Client *, struct Client *, int, const char **);
+#define mg_kick { m_kick, 3 }
+
+struct Message kick_msgtab = {
+ "KICK", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_kick, mg_kick, mg_kick, mg_ignore, mg_kick}
+};
+
+mapi_clist_av1 kick_clist[] = { &kick_msgtab, NULL };
+
+DECLARE_MODULE_AV1(kick, NULL, NULL, kick_clist, NULL, NULL, "$Revision: 258 $");
+
+/*
+** m_kick
+** parv[0] = sender prefix
+** parv[1] = channel
+** parv[2] = client to kick
+** parv[3] = kick comment
+*/
+static int
+m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct membership *msptr;
+ struct Client *who;
+ struct Channel *chptr;
+ int chasing = 0;
+ char *comment;
+ const char *name;
+ char *p = NULL;
+ const char *user;
+ static char buf[BUFSIZE];
+
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ comment = LOCAL_COPY((EmptyString(parv[3])) ? parv[2] : parv[3]);
+ if(strlen(comment) > (size_t) REASONLEN)
+ comment[REASONLEN] = '\0';
+
+ *buf = '\0';
+ if((p = strchr(parv[1], ',')))
+ *p = '\0';
+
+ name = parv[1];
+
+ chptr = find_channel(name);
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);
+ return 0;
+ }
+
+ if(!IsServer(source_p))
+ {
+ msptr = find_channel_membership(chptr, source_p);
+
+ if((msptr == NULL) && MyConnect(source_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL), name);
+ return 0;
+ }
+
+ if(!is_chanop(msptr))
+ {
+ if(MyConnect(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, name);
+ return 0;
+ }
+
+ /* If its a TS 0 channel, do it the old way */
+ if(chptr->channelts == 0)
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ get_id(&me, source_p), get_id(source_p, source_p), name);
+ return 0;
+ }
+ }
+
+ /* Its a user doing a kick, but is not showing as chanop locally
+ * its also not a user ON -my- server, and the channel has a TS.
+ * There are two cases we can get to this point then...
+ *
+ * 1) connect burst is happening, and for some reason a legit
+ * op has sent a KICK, but the SJOIN hasn't happened yet or
+ * been seen. (who knows.. due to lag...)
+ *
+ * 2) The channel is desynced. That can STILL happen with TS
+ *
+ * Now, the old code roger wrote, would allow the KICK to
+ * go through. Thats quite legit, but lets weird things like
+ * KICKS by users who appear not to be chanopped happen,
+ * or even neater, they appear not to be on the channel.
+ * This fits every definition of a desync, doesn't it? ;-)
+ * So I will allow the KICK, otherwise, things are MUCH worse.
+ * But I will warn it as a possible desync.
+ *
+ * -Dianora
+ */
+ }
+
+ if((p = strchr(parv[2], ',')))
+ *p = '\0';
+
+ user = parv[2]; /* strtoken(&p2, parv[2], ","); */
+
+ if(!(who = find_chasing(source_p, user, &chasing)))
+ {
+ return 0;
+ }
+
+ msptr = find_channel_membership(chptr, who);
+
+ if(msptr != NULL)
+ {
+ if(MyClient(source_p) && IsService(who))
+ {
+ sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
+ me.name, source_p->name, who->name, chptr->chname);
+ return 0;
+ }
+
+ /* jdc
+ * - In the case of a server kicking a user (i.e. CLEARCHAN),
+ * the kick should show up as coming from the server which did
+ * the kick.
+ * - Personally, flame and I believe that server kicks shouldn't
+ * be sent anyways. Just waiting for some oper to abuse it...
+ */
+ if(IsServer(source_p))
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
+ source_p->name, name, who->name, comment);
+ else
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s!%s@%s KICK %s %s :%s",
+ source_p->name, source_p->username,
+ source_p->host, name, who->name, comment);
+
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s KICK %s %s :%s",
+ use_id(source_p), chptr->chname, use_id(who), comment);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s KICK %s %s :%s",
+ source_p->name, chptr->chname, who->name, comment);
+ remove_user_from_channel(msptr);
+ }
+ else if (MyClient(source_p))
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL), user, name);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_kill.c: Kills a user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_kill.c 2755 2006-11-10 19:08:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "hash.h" /* for find_client() */
+#include "ircd.h"
+#include "numeric.h"
+#include "sprintf_irc.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "send.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_newconf.h"
+
+static char buf[BUFSIZE];
+
+static int ms_kill(struct Client *, struct Client *, int, const char **);
+static int mo_kill(struct Client *, struct Client *, int, const char **);
+static void relay_kill(struct Client *, struct Client *, struct Client *,
+ const char *, const char *);
+
+struct Message kill_msgtab = {
+ "KILL", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_kill, 2}, {ms_kill, 2}, mg_ignore, {mo_kill, 2}}
+};
+
+mapi_clist_av1 kill_clist[] = { &kill_msgtab, NULL };
+
+DECLARE_MODULE_AV1(kill, NULL, NULL, kill_clist, NULL, NULL, "$Revision: 2755 $");
+
+/*
+** mo_kill
+** parv[0] = sender prefix
+** parv[1] = kill victim
+** parv[2] = kill path
+*/
+static int
+mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *inpath = client_p->name;
+ const char *user;
+ const char *reason;
+
+ user = parv[1];
+
+ if(!IsOperLocalKill(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "local_kill");
+ return 0;
+ }
+
+ if(!EmptyString(parv[2]))
+ {
+ char *s;
+ s = LOCAL_COPY(parv[2]);
+ if(strlen(s) > (size_t) KILLLEN)
+ s[KILLLEN] = '\0';
+ reason = s;
+ }
+ else
+ reason = "<No reason given>";
+
+ if((target_p = find_named_person(user)) == NULL)
+ {
+ /*
+ ** If the user has recently changed nick, automatically
+ ** rewrite the KILL for this new nickname--this keeps
+ ** servers in synch when nick change and kill collide
+ */
+ if((target_p = get_history(user, (long) KILLCHASETIMELIMIT)) == NULL)
+ {
+ if (strchr(user, '.'))
+ sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
+ else
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), user);
+ return 0;
+ }
+ sendto_one(source_p, ":%s NOTICE %s :KILL changed from %s to %s",
+ me.name, parv[0], user, target_p->name);
+ }
+
+ if(!MyConnect(target_p) && (!IsOperGlobalKill(source_p)))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Nick %s isnt on your server",
+ me.name, parv[0], target_p->name);
+ return 0;
+ }
+
+ if(MyConnect(target_p))
+ sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
+ source_p->name, source_p->username, source_p->host,
+ target_p->name, reason);
+
+ /* Do not change the format of this message. There's no point in changing messages
+ * that have been around for ever, for no reason.. */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Received KILL message for %s. From %s Path: %s (%s)",
+ target_p->name, parv[0], me.name, reason);
+
+ ilog(L_KILL, "%c %s %s!%s@%s %s %s",
+ MyConnect(target_p) ? 'L' : 'G', get_oper_name(source_p),
+ target_p->name, target_p->username, target_p->host, target_p->user->server, reason);
+
+ /*
+ ** And pass on the message to other servers. Note, that if KILL
+ ** was changed, the message has to be sent to all links, also
+ ** back.
+ ** Suicide kills are NOT passed on --SRB
+ */
+ if(!MyConnect(target_p))
+ {
+ relay_kill(client_p, source_p, target_p, inpath, reason);
+ /*
+ ** Set FLAGS_KILLED. This prevents exit_one_client from sending
+ ** the unnecessary QUIT for this. (This flag should never be
+ ** set in any other place)
+ */
+ target_p->flags |= FLAGS_KILLED;
+ }
+
+ ircsprintf(buf, "Killed (%s (%s))", source_p->name, reason);
+
+ exit_client(client_p, target_p, source_p, buf);
+
+ return 0;
+}
+
+/*
+ * ms_kill
+ * parv[0] = sender prefix
+ * parv[1] = kill victim
+ * parv[2] = kill path and reason
+ */
+static int
+ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *user;
+ const char *reason;
+ char default_reason[] = "<No reason given>";
+ const char *path;
+ int chasing = 0;
+
+ *buf = '\0';
+
+ user = parv[1];
+
+ if(EmptyString(parv[2]))
+ {
+ reason = default_reason;
+
+ /* hyb6 takes the nick of the killer from the path *sigh* --fl_ */
+ path = source_p->name;
+ }
+ else
+ {
+ char *s = LOCAL_COPY(parv[2]), *t;
+ t = strchr(s, ' ');
+
+ if(t)
+ {
+ *t = '\0';
+ t++;
+ reason = t;
+ }
+ else
+ reason = default_reason;
+
+ path = s;
+ }
+
+ if((target_p = find_person(user)) == NULL)
+ {
+ /*
+ * If the user has recently changed nick, but only if its
+ * not an uid, automatically rewrite the KILL for this new nickname.
+ * --this keeps servers in synch when nick change and kill collide
+ */
+ if(IsDigit(*user) || (!(target_p = get_history(user, (long) KILLCHASETIMELIMIT))))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), IsDigit(*user) ? "*" : user);
+ return 0;
+ }
+ sendto_one_notice(source_p, ":KILL changed from %s to %s", user, target_p->name);
+ chasing = 1;
+ }
+
+ if(IsServer(target_p) || IsMe(target_p))
+ {
+ sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
+ return 0;
+ }
+
+ if(MyConnect(target_p))
+ {
+ if(IsServer(source_p))
+ {
+ sendto_one(target_p, ":%s KILL %s :%s",
+ source_p->name, target_p->name, reason);
+ }
+ else
+ sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
+ source_p->name, source_p->username, source_p->host,
+ target_p->name, reason);
+ }
+
+ /* Be warned, this message must be From %s, or it confuses clients
+ * so dont change it to From: or the case or anything! -- fl -- db */
+ /* path must contain at least 2 !'s, or bitchx falsely declares it
+ * local --fl
+ */
+ if(IsOper(source_p)) /* send it normally */
+ {
+ sendto_realops_snomask(IsService(source_p) ? SNO_SKILL : SNO_GENERAL, L_ALL,
+ "Received KILL message for %s. From %s Path: %s!%s!%s!%s %s",
+ target_p->name, parv[0], source_p->user->server,
+ source_p->host, source_p->username, source_p->name, reason);
+
+ ilog(L_KILL, "%c %s %s!%s@%s %s %s",
+ MyConnect(target_p) ? 'O' : 'R', get_oper_name(source_p),
+ target_p->name, target_p->username, target_p->host,
+ target_p->user->server, reason);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_SKILL, L_ALL,
+ "Received KILL message for %s. From %s %s",
+ target_p->name, parv[0], reason);
+
+ ilog(L_KILL, "S %s %s!%s@%s %s %s",
+ source_p->name, target_p->name, target_p->username,
+ target_p->host, target_p->user->server, reason);
+ }
+
+ relay_kill(client_p, source_p, target_p, path, reason);
+
+ /* FLAGS_KILLED prevents a quit being sent out */
+ target_p->flags |= FLAGS_KILLED;
+
+ ircsprintf(buf, "Killed (%s %s)", source_p->name, reason);
+
+ exit_client(client_p, target_p, source_p, buf);
+
+ return 0;
+}
+
+static void
+relay_kill(struct Client *one, struct Client *source_p,
+ struct Client *target_p, const char *inpath, const char *reason)
+{
+ struct Client *client_p;
+ dlink_node *ptr;
+ char buffer[BUFSIZE];
+
+ if(MyClient(source_p))
+ ircsnprintf(buffer, sizeof(buffer),
+ "%s!%s!%s!%s (%s)",
+ me.name, source_p->host, source_p->username, source_p->name, reason);
+ else
+ ircsnprintf(buffer, sizeof(buffer), "%s %s", inpath, reason);
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ client_p = ptr->data;
+
+ if(!client_p || client_p == one)
+ continue;
+
+ sendto_one(client_p, ":%s KILL %s :%s",
+ get_id(source_p, client_p), get_id(target_p, client_p), buffer);
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_message.c: Sends a (PRIVMSG|NOTICE) message to a user or channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_message.c 1761 2006-07-27 19:27:49Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "common.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "channel.h"
+#include "irc_string.h"
+#include "hash.h"
+#include "class.h"
+#include "msg.h"
+#include "packet.h"
+#include "send.h"
+#include "event.h"
+#include "patricia.h"
+#include "s_newconf.h"
+
+static int m_message(int, const char *, struct Client *, struct Client *, int, const char **);
+static int m_privmsg(struct Client *, struct Client *, int, const char **);
+static int m_notice(struct Client *, struct Client *, int, const char **);
+
+static void expire_tgchange(void *unused);
+
+static int
+modinit(void)
+{
+ eventAddIsh("expire_tgchange", expire_tgchange, NULL, 300);
+ expire_tgchange(NULL);
+ return 0;
+}
+
+static void
+moddeinit(void)
+{
+ eventDelete(expire_tgchange, NULL);
+}
+
+struct Message privmsg_msgtab = {
+ "PRIVMSG", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {mg_unreg, {m_privmsg, 0}, {m_privmsg, 0}, mg_ignore, mg_ignore, {m_privmsg, 0}}
+};
+struct Message notice_msgtab = {
+ "NOTICE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_notice, 0}, {m_notice, 0}, {m_notice, 0}, mg_ignore, {m_notice, 0}}
+};
+
+mapi_clist_av1 message_clist[] = { &privmsg_msgtab, ¬ice_msgtab, NULL };
+
+DECLARE_MODULE_AV1(message, modinit, moddeinit, message_clist, NULL, NULL, "$Revision: 1761 $");
+
+struct entity
+{
+ void *ptr;
+ int type;
+ int flags;
+};
+
+static int build_target_list(int p_or_n, const char *command,
+ struct Client *client_p,
+ struct Client *source_p, const char *nicks_channels, const char *text);
+
+static int flood_attack_client(int p_or_n, struct Client *source_p, struct Client *target_p);
+static int flood_attack_channel(int p_or_n, struct Client *source_p,
+ struct Channel *chptr, char *chname);
+static struct Client *find_userhost(const char *, const char *, int *);
+
+#define ENTITY_NONE 0
+#define ENTITY_CHANNEL 1
+#define ENTITY_CHANOPS_ON_CHANNEL 2
+#define ENTITY_CLIENT 3
+
+static struct entity targets[512];
+static int ntargets = 0;
+
+static int duplicate_ptr(void *);
+
+static void msg_channel(int p_or_n, const char *command,
+ struct Client *client_p,
+ struct Client *source_p, struct Channel *chptr, const char *text);
+
+static void msg_channel_flags(int p_or_n, const char *command,
+ struct Client *client_p,
+ struct Client *source_p,
+ struct Channel *chptr, int flags, const char *text);
+
+static void msg_client(int p_or_n, const char *command,
+ struct Client *source_p, struct Client *target_p, const char *text);
+
+static void handle_special(int p_or_n, const char *command,
+ struct Client *client_p, struct Client *source_p, const char *nick,
+ const char *text);
+
+/*
+** m_privmsg
+**
+** massive cleanup
+** rev argv 6/91
+**
+** Another massive cleanup Nov, 2000
+** (I don't think there is a single line left from 6/91. Maybe.)
+** m_privmsg and m_notice do basically the same thing.
+** in the original 2.8.2 code base, they were the same function
+** "m_message.c." When we did the great cleanup in conjuncton with bleep
+** of ircu fame, we split m_privmsg.c and m_notice.c.
+** I don't see the point of that now. Its harder to maintain, its
+** easier to introduce bugs into one version and not the other etc.
+** Really, the penalty of an extra function call isn't that big a deal folks.
+** -db Nov 13, 2000
+**
+*/
+
+#define PRIVMSG 0
+#define NOTICE 1
+
+static int
+m_privmsg(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ return m_message(PRIVMSG, "PRIVMSG", client_p, source_p, parc, parv);
+}
+
+static int
+m_notice(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ return m_message(NOTICE, "NOTICE", client_p, source_p, parc, parv);
+}
+
+/*
+ * inputs - flag privmsg or notice
+ * - pointer to command "PRIVMSG" or "NOTICE"
+ * - pointer to client_p
+ * - pointer to source_p
+ * - pointer to channel
+ */
+static int
+m_message(int p_or_n,
+ const char *command,
+ struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int i;
+
+ if(parc < 2 || EmptyString(parv[1]))
+ {
+ if(p_or_n != NOTICE)
+ sendto_one(source_p, form_str(ERR_NORECIPIENT), me.name,
+ source_p->name, command);
+ return 0;
+ }
+
+ if(parc < 3 || EmptyString(parv[2]))
+ {
+ if(p_or_n != NOTICE)
+ sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
+ return 0;
+ }
+
+ /* Finish the flood grace period if theyre not messaging themselves
+ * as some clients (ircN) do this as a "lag check"
+ */
+ if(MyClient(source_p) && !IsFloodDone(source_p) && irccmp(source_p->name, parv[1]))
+ flood_endgrace(source_p);
+
+ if(build_target_list(p_or_n, command, client_p, source_p, parv[1], parv[2]) < 0)
+ {
+ return 0;
+ }
+
+ for(i = 0; i < ntargets; i++)
+ {
+ switch (targets[i].type)
+ {
+ case ENTITY_CHANNEL:
+ msg_channel(p_or_n, command, client_p, source_p,
+ (struct Channel *) targets[i].ptr, parv[2]);
+ break;
+
+ case ENTITY_CHANOPS_ON_CHANNEL:
+ msg_channel_flags(p_or_n, command, client_p, source_p,
+ (struct Channel *) targets[i].ptr,
+ targets[i].flags, parv[2]);
+ break;
+
+ case ENTITY_CLIENT:
+ msg_client(p_or_n, command, source_p,
+ (struct Client *) targets[i].ptr, parv[2]);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * build_target_list
+ *
+ * inputs - pointer to given client_p (server)
+ * - pointer to given source (oper/client etc.)
+ * - pointer to list of nicks/channels
+ * - pointer to table to place results
+ * - pointer to text (only used if source_p is an oper)
+ * output - number of valid entities
+ * side effects - target_table is modified to contain a list of
+ * pointers to channels or clients
+ * if source client is an oper
+ * all the classic old bizzare oper privmsg tricks
+ * are parsed and sent as is, if prefixed with $
+ * to disambiguate.
+ *
+ */
+
+static int
+build_target_list(int p_or_n, const char *command, struct Client *client_p,
+ struct Client *source_p, const char *nicks_channels, const char *text)
+{
+ int type;
+ char *p, *nick, *target_list;
+ struct Channel *chptr = NULL;
+ struct Client *target_p;
+
+ target_list = LOCAL_COPY(nicks_channels); /* skip strcpy for non-lazyleafs */
+
+ ntargets = 0;
+
+ for(nick = strtoken(&p, target_list, ","); nick; nick = strtoken(&p, NULL, ","))
+ {
+ char *with_prefix;
+ /*
+ * channels are privmsg'd a lot more than other clients, moved up
+ * here plain old channel msg?
+ */
+
+ if(IsChanPrefix(*nick))
+ {
+ /* ignore send of local channel to a server (should not happen) */
+ if(IsServer(client_p) && *nick == '&')
+ continue;
+
+ if((chptr = find_channel(nick)) != NULL)
+ {
+ if(!duplicate_ptr(chptr))
+ {
+ if(ntargets >= ConfigFileEntry.max_targets)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
+ me.name, source_p->name, nick);
+ return (1);
+ }
+ targets[ntargets].ptr = (void *) chptr;
+ targets[ntargets++].type = ENTITY_CHANNEL;
+ }
+ }
+
+ /* non existant channel */
+ else if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+
+ continue;
+ }
+
+ if(MyClient(source_p))
+ target_p = find_named_person(nick);
+ else
+ target_p = find_person(nick);
+
+ /* look for a privmsg to another client */
+ if(target_p)
+ {
+ if(!duplicate_ptr(target_p))
+ {
+ if(ntargets >= ConfigFileEntry.max_targets)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
+ me.name, source_p->name, nick);
+ return (1);
+ }
+ targets[ntargets].ptr = (void *) target_p;
+ targets[ntargets].type = ENTITY_CLIENT;
+ targets[ntargets++].flags = 0;
+ }
+ continue;
+ }
+
+ /* @#channel or +#channel message ? */
+
+ type = 0;
+ with_prefix = nick;
+ /* allow %+@ if someone wants to do that */
+ for(;;)
+ {
+ if(*nick == '@')
+ type |= CHFL_CHANOP;
+ else if(*nick == '+')
+ type |= CHFL_CHANOP | CHFL_VOICE;
+ else
+ break;
+ nick++;
+ }
+
+ if(type != 0)
+ {
+ /* no recipient.. */
+ if(EmptyString(nick))
+ {
+ sendto_one(source_p, form_str(ERR_NORECIPIENT),
+ me.name, source_p->name, command);
+ continue;
+ }
+
+ /* At this point, nick+1 should be a channel name i.e. #foo or &foo
+ * if the channel is found, fine, if not report an error
+ */
+
+ if((chptr = find_channel(nick)) != NULL)
+ {
+ struct membership *msptr;
+
+ msptr = find_channel_membership(chptr, source_p);
+
+ if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr))
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, with_prefix);
+ return (-1);
+ }
+
+ if(!duplicate_ptr(chptr))
+ {
+ if(ntargets >= ConfigFileEntry.max_targets)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
+ me.name, source_p->name, nick);
+ return (1);
+ }
+ targets[ntargets].ptr = (void *) chptr;
+ targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL;
+ targets[ntargets++].flags = type;
+ }
+ }
+ else if(p_or_n != NOTICE)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+ }
+
+ continue;
+ }
+
+ if(strchr(nick, '@') || (IsOper(source_p) && (*nick == '$')))
+ {
+ handle_special(p_or_n, command, client_p, source_p, nick, text);
+ continue;
+ }
+
+ /* no matching anything found - error if not NOTICE */
+ if(p_or_n != NOTICE)
+ {
+ /* dont give this numeric when source is local,
+ * because its misleading --anfl
+ */
+ if(!MyClient(source_p) && IsDigit(*nick))
+ sendto_one(source_p, ":%s %d %s * :Target left IRC. "
+ "Failed to deliver: [%.20s]",
+ get_id(&me, source_p), ERR_NOSUCHNICK,
+ get_id(source_p, source_p), text);
+ else
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+ }
+
+ }
+ return (1);
+}
+
+/*
+ * duplicate_ptr
+ *
+ * inputs - pointer to check
+ * - pointer to table of entities
+ * - number of valid entities so far
+ * output - YES if duplicate pointer in table, NO if not.
+ * note, this does the canonize using pointers
+ * side effects - NONE
+ */
+static int
+duplicate_ptr(void *ptr)
+{
+ int i;
+ for(i = 0; i < ntargets; i++)
+ if(targets[i].ptr == ptr)
+ return YES;
+ return NO;
+}
+
+/*
+ * msg_channel
+ *
+ * inputs - flag privmsg or notice
+ * - pointer to command "PRIVMSG" or "NOTICE"
+ * - pointer to client_p
+ * - pointer to source_p
+ * - pointer to channel
+ * output - NONE
+ * side effects - message given channel
+ *
+ * XXX - We need to rework this a bit, it's a tad ugly. --nenolod
+ */
+static void
+msg_channel(int p_or_n, const char *command,
+ struct Client *client_p, struct Client *source_p, struct Channel *chptr,
+ const char *text)
+{
+ int result;
+ char text2[BUFSIZE];
+
+ if(MyClient(source_p))
+ {
+ /* idle time shouldnt be reset by notices --fl */
+ if(p_or_n != NOTICE)
+ source_p->localClient->last = CurrentTime;
+ }
+
+ if(chptr->mode.mode & MODE_NOCOLOR)
+ {
+ strlcpy(text2, text, BUFSIZE);
+ strip_colour(text2);
+ text = text2;
+ if (EmptyString(text))
+ {
+ /* could be empty after colour stripping and
+ * that would cause problems later */
+ if(p_or_n != NOTICE)
+ sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
+ return;
+ }
+ }
+
+ /* chanops and voiced can flood their own channel with impunity */
+ if((result = can_send(chptr, source_p, NULL)))
+ {
+ if(result == CAN_SEND_OPV ||
+ !flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
+ {
+ sendto_channel_flags(client_p, ALL_MEMBERS, source_p, chptr,
+ "%s %s :%s", command, chptr->chname, text);
+ }
+ }
+ else if(chptr->mode.mode & MODE_OPMODERATE &&
+ chptr->mode.mode & MODE_MODERATED &&
+ IsMember(source_p, chptr))
+ {
+ /* only do +z for +m channels for now, as bans/quiets
+ * aren't tested for remote clients -- jilles */
+ if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
+ {
+ sendto_channel_flags(client_p, ONLY_CHANOPS, source_p, chptr,
+ "%s %s :%s", command, chptr->chname, text);
+ }
+ }
+ else
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+ form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
+ }
+}
+
+/*
+ * msg_channel_flags
+ *
+ * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC
+ * say NOTICE must not auto reply
+ * - pointer to command, "PRIVMSG" or "NOTICE"
+ * - pointer to client_p
+ * - pointer to source_p
+ * - pointer to channel
+ * - flags
+ * - pointer to text to send
+ * output - NONE
+ * side effects - message given channel either chanop or voice
+ */
+static void
+msg_channel_flags(int p_or_n, const char *command, struct Client *client_p,
+ struct Client *source_p, struct Channel *chptr, int flags, const char *text)
+{
+ int type;
+ char c;
+
+ if(flags & CHFL_VOICE)
+ {
+ type = ONLY_CHANOPSVOICED;
+ c = '+';
+ }
+ else
+ {
+ type = ONLY_CHANOPS;
+ c = '@';
+ }
+
+ if(MyClient(source_p))
+ {
+ /* idletime shouldnt be reset by notice --fl */
+ if(p_or_n != NOTICE)
+ source_p->localClient->last = CurrentTime;
+ }
+
+ sendto_channel_flags(client_p, type, source_p, chptr, "%s %c%s :%s",
+ command, c, chptr->chname, text);
+}
+
+#define PREV_FREE_TARGET(x) ((FREE_TARGET(x) == 0) ? 9 : FREE_TARGET(x) - 1)
+#define PREV_TARGET(i) ((i == 0) ? i = 9 : --i)
+#define NEXT_TARGET(i) ((i == 9) ? i = 0 : ++i)
+
+static void
+expire_tgchange(void *unused)
+{
+ tgchange *target;
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, tgchange_list.head)
+ {
+ target = ptr->data;
+
+ if(target->expiry < CurrentTime)
+ {
+ dlinkDelete(ptr, &tgchange_list);
+ patricia_remove(tgchange_tree, target->pnode);
+ MyFree(target->ip);
+ MyFree(target);
+ }
+ }
+}
+
+static int
+add_target(struct Client *source_p, struct Client *target_p)
+{
+ int i, j;
+
+ /* can msg themselves or services without using any target slots */
+ if(source_p == target_p || IsService(target_p))
+ return 1;
+
+ /* special condition for those who have had PRIVMSG crippled to allow them
+ * to talk to IRCops still.
+ *
+ * XXX: is this controversial?
+ */
+ if(source_p->localClient->target_last > CurrentTime && IsOper(target_p))
+ return 1;
+
+ if(USED_TARGETS(source_p))
+ {
+ /* hunt for an existing target */
+ for(i = PREV_FREE_TARGET(source_p), j = USED_TARGETS(source_p);
+ j; --j, PREV_TARGET(i))
+ {
+ if(source_p->localClient->targets[i] == target_p)
+ return 1;
+ }
+
+ /* first message after connect, we may only start clearing
+ * slots after this message --anfl
+ */
+ if(!IsTGChange(source_p))
+ {
+ SetTGChange(source_p);
+ source_p->localClient->target_last = CurrentTime;
+ }
+ /* clear as many targets as we can */
+ else if((i = (CurrentTime - source_p->localClient->target_last) / 60))
+ {
+ if(i > USED_TARGETS(source_p))
+ USED_TARGETS(source_p) = 0;
+ else
+ USED_TARGETS(source_p) -= i;
+
+ source_p->localClient->target_last = CurrentTime;
+ }
+ /* cant clear any, full target list */
+ else if(USED_TARGETS(source_p) == 10)
+ {
+ add_tgchange(source_p->sockhost);
+ return 0;
+ }
+ }
+ /* no targets in use, reset their target_last so that they cant
+ * abuse a long idle to get targets back more quickly
+ */
+ else
+ {
+ source_p->localClient->target_last = CurrentTime;
+ SetTGChange(source_p);
+ }
+
+ source_p->localClient->targets[FREE_TARGET(source_p)] = target_p;
+ NEXT_TARGET(FREE_TARGET(source_p));
+ ++USED_TARGETS(source_p);
+ return 1;
+}
+
+/*
+ * msg_client
+ *
+ * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC
+ * say NOTICE must not auto reply
+ * - pointer to command, "PRIVMSG" or "NOTICE"
+ * - pointer to source_p source (struct Client *)
+ * - pointer to target_p target (struct Client *)
+ * - pointer to text
+ * output - NONE
+ * side effects - message given channel either chanop or voice
+ */
+static void
+msg_client(int p_or_n, const char *command,
+ struct Client *source_p, struct Client *target_p, const char *text)
+{
+ if(MyClient(source_p))
+ {
+ /* reset idle time for message only if its not to self
+ * and its not a notice */
+ if(p_or_n != NOTICE)
+ source_p->localClient->last = CurrentTime;
+
+ /* target change stuff, dont limit ctcp replies as that
+ * would allow people to start filling up random users
+ * targets just by ctcping them
+ */
+ if((p_or_n != NOTICE || *text != '\001') &&
+ ConfigFileEntry.target_change && !IsOper(source_p))
+ {
+ if(!add_target(source_p, target_p))
+ {
+ sendto_one(source_p, form_str(ERR_TARGCHANGE),
+ me.name, source_p->name, target_p->name);
+ return;
+ }
+ }
+ }
+ else if(source_p->from == target_p->from)
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Send message to %s[%s] dropped from %s(Fake Dir)",
+ target_p->name, target_p->from->name, source_p->name);
+ return;
+ }
+
+ if(MyConnect(source_p) && (p_or_n != NOTICE) && target_p->user && target_p->user->away)
+ sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY),
+ target_p->name, target_p->user->away);
+
+ if(MyClient(target_p))
+ {
+ /* XXX Controversial? allow opers always to send through a +g */
+ if(!IsServer(source_p) && (IsSetCallerId(target_p) ||
+ (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])))
+ {
+ /* Here is the anti-flood bot/spambot code -db */
+ if(accept_message(source_p, target_p) || IsOper(source_p))
+ {
+ sendto_one(target_p, ":%s!%s@%s %s %s :%s",
+ source_p->name,
+ source_p->username,
+ source_p->host, command, target_p->name, text);
+ }
+ else if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])
+ {
+ if (p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NONONREG,
+ form_str(ERR_NONONREG),
+ target_p->name);
+ /* Only so opers can watch for floods */
+ (void) flood_attack_client(p_or_n, source_p, target_p);
+ }
+ else
+ {
+ /* check for accept, flag recipient incoming message */
+ if(p_or_n != NOTICE)
+ {
+ sendto_one_numeric(source_p, ERR_TARGUMODEG,
+ form_str(ERR_TARGUMODEG),
+ target_p->name);
+ }
+
+ if((target_p->localClient->last_caller_id_time +
+ ConfigFileEntry.caller_id_wait) < CurrentTime)
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, RPL_TARGNOTIFY,
+ form_str(RPL_TARGNOTIFY),
+ target_p->name);
+
+ sendto_one(target_p, form_str(RPL_UMODEGMSG),
+ me.name, target_p->name, source_p->name,
+ source_p->username, source_p->host);
+
+ target_p->localClient->last_caller_id_time = CurrentTime;
+ }
+ /* Only so opers can watch for floods */
+ (void) flood_attack_client(p_or_n, source_p, target_p);
+ }
+ }
+ else
+ {
+ /* If the client is remote, we dont perform a special check for
+ * flooding.. as we wouldnt block their message anyway.. this means
+ * we dont give warnings.. we then check if theyre opered
+ * (to avoid flood warnings), lastly if theyre our client
+ * and flooding -- fl */
+ if(!MyClient(source_p) || IsOper(source_p) ||
+ !flood_attack_client(p_or_n, source_p, target_p))
+ sendto_anywhere(target_p, source_p, command, ":%s", text);
+ }
+ }
+ else if(!MyClient(source_p) || IsOper(source_p) ||
+ !flood_attack_client(p_or_n, source_p, target_p))
+ sendto_anywhere(target_p, source_p, command, ":%s", text);
+
+ return;
+}
+
+/*
+ * flood_attack_client
+ * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC
+ * say NOTICE must not auto reply
+ * - pointer to source Client
+ * - pointer to target Client
+ * output - 1 if target is under flood attack
+ * side effects - check for flood attack on target target_p
+ */
+static int
+flood_attack_client(int p_or_n, struct Client *source_p, struct Client *target_p)
+{
+ int delta;
+
+ if(GlobalSetOptions.floodcount && MyConnect(target_p) && IsClient(source_p))
+ {
+ if((target_p->localClient->first_received_message_time + 1) < CurrentTime)
+ {
+ delta = CurrentTime - target_p->localClient->first_received_message_time;
+ target_p->localClient->received_number_of_privmsgs -= delta;
+ target_p->localClient->first_received_message_time = CurrentTime;
+ if(target_p->localClient->received_number_of_privmsgs <= 0)
+ {
+ target_p->localClient->received_number_of_privmsgs = 0;
+ target_p->localClient->flood_noticed = 0;
+ }
+ }
+
+ if((target_p->localClient->received_number_of_privmsgs >=
+ GlobalSetOptions.floodcount) || target_p->localClient->flood_noticed)
+ {
+ if(target_p->localClient->flood_noticed == 0)
+ {
+ sendto_realops_snomask(SNO_BOTS, L_ALL,
+ "Possible Flooder %s[%s@%s] on %s target: %s",
+ source_p->name, source_p->username,
+ source_p->host,
+ source_p->user->server, target_p->name);
+ target_p->localClient->flood_noticed = 1;
+ /* add a bit of penalty */
+ target_p->localClient->received_number_of_privmsgs += 2;
+ }
+ if(MyClient(source_p) && (p_or_n != NOTICE))
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Message to %s throttled due to flooding",
+ me.name, source_p->name, target_p->name);
+ return 1;
+ }
+ else
+ target_p->localClient->received_number_of_privmsgs++;
+ }
+
+ return 0;
+}
+
+/*
+ * flood_attack_channel
+ * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC
+ * says NOTICE must not auto reply
+ * - pointer to source Client
+ * - pointer to target channel
+ * output - 1 if target is under flood attack
+ * side effects - check for flood attack on target chptr
+ */
+static int
+flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname)
+{
+ int delta;
+
+ if(GlobalSetOptions.floodcount && MyClient(source_p))
+ {
+ if((chptr->first_received_message_time + 1) < CurrentTime)
+ {
+ delta = CurrentTime - chptr->first_received_message_time;
+ chptr->received_number_of_privmsgs -= delta;
+ chptr->first_received_message_time = CurrentTime;
+ if(chptr->received_number_of_privmsgs <= 0)
+ {
+ chptr->received_number_of_privmsgs = 0;
+ chptr->flood_noticed = 0;
+ }
+ }
+
+ if((chptr->received_number_of_privmsgs >= GlobalSetOptions.floodcount)
+ || chptr->flood_noticed)
+ {
+ if(chptr->flood_noticed == 0)
+ {
+ sendto_realops_snomask(SNO_BOTS, L_ALL,
+ "Possible Flooder %s[%s@%s] on %s target: %s",
+ source_p->name, source_p->username,
+ source_p->host,
+ source_p->user->server, chptr->chname);
+ chptr->flood_noticed = 1;
+
+ /* Add a bit of penalty */
+ chptr->received_number_of_privmsgs += 2;
+ }
+ if(MyClient(source_p) && (p_or_n != NOTICE))
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Message to %s throttled due to flooding",
+ me.name, source_p->name, chptr->chname);
+ return 1;
+ }
+ else
+ chptr->received_number_of_privmsgs++;
+ }
+
+ return 0;
+}
+
+
+/*
+ * handle_special
+ *
+ * inputs - server pointer
+ * - client pointer
+ * - nick stuff to grok for opers
+ * - text to send if grok
+ * output - none
+ * side effects - all the traditional oper type messages are parsed here.
+ * i.e. "/msg #some.host."
+ * However, syntax has been changed.
+ * previous syntax "/msg #some.host.mask"
+ * now becomes "/msg $#some.host.mask"
+ * previous syntax of: "/msg $some.server.mask" remains
+ * This disambiguates the syntax.
+ */
+static void
+handle_special(int p_or_n, const char *command, struct Client *client_p,
+ struct Client *source_p, const char *nick, const char *text)
+{
+ struct Client *target_p;
+ char *host;
+ char *server;
+ char *s;
+ int count;
+
+ /* user[%host]@server addressed?
+ * NOTE: users can send to user@server, but not user%host@server
+ * or opers@server
+ */
+ if((server = strchr(nick, '@')) != NULL)
+ {
+ if((target_p = find_server(source_p, server + 1)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER), server + 1);
+ return;
+ }
+
+ count = 0;
+
+ if(!IsOper(source_p))
+ {
+ if(strchr(nick, '%') || (strncmp(nick, "opers", 5) == 0))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+ return;
+ }
+ }
+
+ /* somewhere else.. */
+ if(!IsMe(target_p))
+ {
+ sendto_one(target_p, ":%s %s %s :%s",
+ get_id(source_p, target_p), command, nick, text);
+ return;
+ }
+
+ *server = '\0';
+
+ if((host = strchr(nick, '%')) != NULL)
+ *host++ = '\0';
+
+ /* Check if someones msg'ing opers@our.server */
+ if(strcmp(nick, "opers") == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "To opers: From: %s: %s",
+ source_p->name, text);
+ return;
+ }
+
+ /*
+ * Look for users which match the destination host
+ * (no host == wildcard) and if one and one only is
+ * found connected to me, deliver message!
+ */
+ target_p = find_userhost(nick, host, &count);
+
+ if(target_p != NULL)
+ {
+ if(server != NULL)
+ *server = '@';
+ if(host != NULL)
+ *--host = '%';
+
+ if(count == 1)
+ sendto_anywhere(target_p, source_p, command, ":%s", text);
+ else
+ sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
+ get_id(&me, source_p), get_id(source_p, source_p), nick);
+ }
+ }
+
+ /*
+ * the following two cases allow masks in NOTICEs
+ * (for OPERs only)
+ *
+ * Armin, 8Jun90 (gruner@informatik.tu-muenchen.de)
+ */
+ if(IsOper(source_p) && *nick == '$')
+ {
+ if((*(nick + 1) == '$' || *(nick + 1) == '#'))
+ nick++;
+ else if(MyOper(source_p))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :The command %s %s is no longer supported, please use $%s",
+ me.name, source_p->name, command, nick, nick);
+ return;
+ }
+
+ if((s = strrchr(nick, '.')) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOTOPLEVEL,
+ form_str(ERR_NOTOPLEVEL), nick);
+ return;
+ }
+ while(*++s)
+ if(*s == '.' || *s == '*' || *s == '?')
+ break;
+ if(*s == '*' || *s == '?')
+ {
+ sendto_one_numeric(source_p, ERR_WILDTOPLEVEL,
+ form_str(ERR_WILDTOPLEVEL), nick);
+ return;
+ }
+
+ sendto_match_butone(IsServer(client_p) ? client_p : NULL, source_p,
+ nick + 1,
+ (*nick == '#') ? MATCH_HOST : MATCH_SERVER,
+ "%s $%s :%s", command, nick, text);
+ return;
+ }
+}
+
+/*
+ * find_userhost - find a user@host (server or user).
+ * inputs - user name to look for
+ * - host name to look for
+ * - pointer to count of number of matches found
+ * outputs - pointer to client if found
+ * - count is updated
+ * side effects - none
+ *
+ */
+static struct Client *
+find_userhost(const char *user, const char *host, int *count)
+{
+ struct Client *c2ptr;
+ struct Client *res = NULL;
+ char *u = LOCAL_COPY(user);
+ dlink_node *ptr;
+ *count = 0;
+ if(collapse(u) != NULL)
+ {
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ c2ptr = ptr->data;
+ if(!MyClient(c2ptr)) /* implies mine and an user */
+ continue;
+ if((!host || match(host, c2ptr->host)) && irccmp(u, c2ptr->username) == 0)
+ {
+ (*count)++;
+ res = c2ptr;
+ }
+ }
+ }
+ return (res);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_mode.c: Sets a user or channel mode.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_mode.c 1006 2006-03-09 15:32:14Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "balloc.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "s_log.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+#include "sprintf_irc.h"
+#include "s_newconf.h"
+
+static int m_mode(struct Client *, struct Client *, int, const char **);
+static int ms_mode(struct Client *, struct Client *, int, const char **);
+static int ms_tmode(struct Client *, struct Client *, int, const char **);
+static int ms_bmask(struct Client *, struct Client *, int, const char **);
+
+struct Message mode_msgtab = {
+ "MODE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_mode, 2}, {m_mode, 3}, {ms_mode, 3}, mg_ignore, {m_mode, 2}}
+};
+struct Message tmode_msgtab = {
+ "TMODE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, {ms_tmode, 4}, {ms_tmode, 4}, mg_ignore, mg_ignore}
+};
+struct Message bmask_msgtab = {
+ "BMASK", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &bmask_msgtab, NULL };
+
+DECLARE_MODULE_AV1(mode, NULL, NULL, mode_clist, NULL, NULL, "$Revision: 1006 $");
+
+/*
+ * m_mode - MODE command handler
+ * parv[0] - sender
+ * parv[1] - channel
+ */
+static int
+m_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr = NULL;
+ struct membership *msptr;
+ int n = 2;
+ const char *dest;
+ int operspy = 0;
+
+ dest = parv[1];
+
+ if(IsOperSpy(source_p) && *dest == '!')
+ {
+ dest++;
+ operspy = 1;
+
+ if(EmptyString(dest))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "MODE");
+ return 0;
+ }
+ }
+
+ /* Now, try to find the channel in question */
+ if(!IsChanPrefix(*dest))
+ {
+ /* if here, it has to be a non-channel name */
+ user_mode(client_p, source_p, parc, parv);
+ return 0;
+ }
+
+ if(!check_channel_name(dest))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[1]);
+ return 0;
+ }
+
+ chptr = find_channel(dest);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ /* Now know the channel exists */
+ if(parc < n + 1)
+ {
+ if(operspy)
+ report_operspy(source_p, "MODE", chptr->chname);
+
+ sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
+ me.name, source_p->name, parv[1],
+ operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p));
+
+ sendto_one(source_p, form_str(RPL_CREATIONTIME),
+ me.name, source_p->name, parv[1], chptr->channelts);
+ }
+ else
+ {
+ msptr = find_channel_membership(chptr, source_p);
+
+ if(is_deop(msptr))
+ return 0;
+
+ /* Finish the flood grace period... */
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ {
+ if(!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
+ flood_endgrace(source_p);
+ }
+
+ set_channel_mode(client_p, source_p, chptr, msptr, parc - n, parv + n);
+ }
+
+ return 0;
+}
+
+static int
+ms_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+
+ chptr = find_channel(parv[1]);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2);
+
+ return 0;
+}
+
+static int
+ms_tmode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr = NULL;
+ struct membership *msptr;
+
+ /* Now, try to find the channel in question */
+ if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[2]);
+ return 0;
+ }
+
+ chptr = find_channel(parv[2]);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[2]);
+ return 0;
+ }
+
+ /* TS is higher, drop it. */
+ if(atol(parv[1]) > chptr->channelts)
+ return 0;
+
+ if(IsServer(source_p))
+ {
+ set_channel_mode(client_p, source_p, chptr, NULL, parc - 3, parv + 3);
+ }
+ else
+ {
+ msptr = find_channel_membership(chptr, source_p);
+
+ /* this can still happen on a mixed ts network. */
+ if(is_deop(msptr))
+ return 0;
+
+ set_channel_mode(client_p, source_p, chptr, msptr, parc - 3, parv + 3);
+ }
+
+ return 0;
+}
+
+static int
+ms_bmask(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static char modebuf[BUFSIZE];
+ static char parabuf[BUFSIZE];
+ struct Channel *chptr;
+ dlink_list *banlist;
+ const char *s;
+ char *t;
+ char *mbuf;
+ char *pbuf;
+ long mode_type;
+ int mlen;
+ int plen = 0;
+ int tlen;
+ int arglen;
+ int modecount = 0;
+ int needcap = NOCAPS;
+ int mems;
+ struct Client *fakesource_p;
+
+ if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
+ return 0;
+
+ if((chptr = find_channel(parv[2])) == NULL)
+ return 0;
+
+ /* TS is higher, drop it. */
+ if(atol(parv[1]) > chptr->channelts)
+ return 0;
+
+ switch (parv[3][0])
+ {
+ case 'b':
+ banlist = &chptr->banlist;
+ mode_type = CHFL_BAN;
+ mems = ALL_MEMBERS;
+ break;
+
+ case 'e':
+ banlist = &chptr->exceptlist;
+ mode_type = CHFL_EXCEPTION;
+ needcap = CAP_EX;
+ mems = ONLY_CHANOPS;
+ break;
+
+ case 'I':
+ banlist = &chptr->invexlist;
+ mode_type = CHFL_INVEX;
+ needcap = CAP_IE;
+ mems = ONLY_CHANOPS;
+ break;
+
+ case 'q':
+ banlist = &chptr->quietlist;
+ mode_type = CHFL_QUIET;
+ mems = ALL_MEMBERS;
+ break;
+
+ /* maybe we should just blindly propagate this? */
+ default:
+ return 0;
+ }
+
+ parabuf[0] = '\0';
+ s = LOCAL_COPY(parv[4]);
+
+ /* Hide connecting server on netburst -- jilles */
+ if (ConfigServerHide.flatten_links && !HasSentEob(source_p))
+ fakesource_p = &me;
+ else
+ fakesource_p = source_p;
+ mlen = ircsprintf(modebuf, ":%s MODE %s +", fakesource_p->name, chptr->chname);
+ mbuf = modebuf + mlen;
+ pbuf = parabuf;
+
+ while(*s == ' ')
+ s++;
+
+ /* next char isnt a space, point t to the next one */
+ if((t = strchr(s, ' ')) != NULL)
+ {
+ *t++ = '\0';
+
+ /* double spaces will break the parser */
+ while(*t == ' ')
+ t++;
+ }
+
+ /* couldve skipped spaces and got nothing.. */
+ while(!EmptyString(s))
+ {
+ /* ban with a leading ':' -- this will break the protocol */
+ if(*s == ':')
+ goto nextban;
+
+ tlen = strlen(s);
+
+ /* I dont even want to begin parsing this.. */
+ if(tlen > MODEBUFLEN)
+ break;
+
+ if(add_id(fakesource_p, chptr, s, banlist, mode_type))
+ {
+ /* this new one wont fit.. */
+ if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 5 ||
+ modecount >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ *(pbuf - 1) = '\0';
+ sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf);
+ sendto_server(client_p, chptr, needcap, CAP_TS6,
+ "%s %s", modebuf, parabuf);
+
+ mbuf = modebuf + mlen;
+ pbuf = parabuf;
+ plen = modecount = 0;
+ }
+
+ *mbuf++ = parv[3][0];
+ arglen = ircsprintf(pbuf, "%s ", s);
+ pbuf += arglen;
+ plen += arglen;
+ modecount++;
+ }
+
+ nextban:
+ s = t;
+
+ if(s != NULL)
+ {
+ if((t = strchr(s, ' ')) != NULL)
+ {
+ *t++ = '\0';
+
+ while(*t == ' ')
+ t++;
+ }
+ }
+ }
+
+ if(modecount)
+ {
+ *mbuf = '\0';
+ *(pbuf - 1) = '\0';
+ sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf);
+ sendto_server(client_p, chptr, needcap, CAP_TS6, "%s %s", modebuf, parabuf);
+ }
+
+ sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",
+ source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_nick.c: Sets a users nick.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_nick.c 1885 2006-08-28 10:09:50Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_stats.h"
+#include "s_user.h"
+#include "hash.h"
+#include "whowas.h"
+#include "s_serv.h"
+#include "send.h"
+#include "channel.h"
+#include "s_log.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "common.h"
+#include "packet.h"
+#include "scache.h"
+#include "s_newconf.h"
+#include "monitor.h"
+
+static int mr_nick(struct Client *, struct Client *, int, const char **);
+static int m_nick(struct Client *, struct Client *, int, const char **);
+static int mc_nick(struct Client *, struct Client *, int, const char **);
+static int ms_nick(struct Client *, struct Client *, int, const char **);
+static int ms_uid(struct Client *, struct Client *, int, const char **);
+static int ms_euid(struct Client *, struct Client *, int, const char **);
+static int ms_save(struct Client *, struct Client *, int, const char **);
+static int can_save(struct Client *);
+static void save_user(struct Client *, struct Client *, struct Client *);
+
+struct Message nick_msgtab = {
+ "NICK", 0, 0, 0, MFLG_SLOW,
+ {{mr_nick, 0}, {m_nick, 0}, {mc_nick, 3}, {ms_nick, 8}, mg_ignore, {m_nick, 0}}
+};
+struct Message uid_msgtab = {
+ "UID", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, {ms_uid, 9}, mg_ignore, mg_ignore}
+};
+struct Message euid_msgtab = {
+ "EUID", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, {ms_euid, 12}, mg_ignore, mg_ignore}
+};
+struct Message save_msgtab = {
+ "SAVE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, {ms_save, 3}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 nick_clist[] = { &nick_msgtab, &uid_msgtab, &euid_msgtab,
+ &save_msgtab, NULL };
+
+DECLARE_MODULE_AV1(nick, NULL, NULL, nick_clist, NULL, NULL, "$Revision: 1885 $");
+
+static int change_remote_nick(struct Client *, struct Client *, time_t,
+ const char *, int);
+
+static int clean_nick(const char *, int loc_client);
+static int clean_username(const char *);
+static int clean_host(const char *);
+static int clean_uid(const char *uid);
+
+static void set_initial_nick(struct Client *client_p, struct Client *source_p, char *nick);
+static void change_local_nick(struct Client *client_p, struct Client *source_p, char *nick, int);
+static int register_client(struct Client *client_p, struct Client *server,
+ const char *nick, time_t newts, int parc, const char *parv[]);
+
+static int perform_nick_collides(struct Client *, struct Client *,
+ struct Client *, int, const char **,
+ time_t, const char *, const char *);
+static int perform_nickchange_collides(struct Client *, struct Client *,
+ struct Client *, int, const char **, time_t, const char *);
+
+/* mr_nick()
+ * parv[0] = sender prefix
+ * parv[1] = nickname
+ */
+static int
+mr_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ char nick[NICKLEN];
+ char *s;
+
+ if (strlen(client_p->id) == 3)
+ {
+ exit_client(client_p, client_p, client_p, "Mixing client and server protocol");
+ return 0;
+ }
+
+ if(parc < 2 || EmptyString(parv[1]) || (parv[1][0] == '~'))
+ {
+ sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name);
+ return 0;
+ }
+
+ /* due to the scandinavian origins, (~ being uppercase of ^) and ~
+ * being disallowed as a nick char, we need to chop the first ~
+ * instead of just erroring.
+ */
+ if((s = strchr(parv[1], '~')))
+ *s = '\0';
+
+ /* copy the nick and terminate it */
+ strlcpy(nick, parv[1], sizeof(nick));
+
+ /* check the nickname is ok */
+ if(!clean_nick(nick, 1))
+ {
+ sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
+ me.name, EmptyString(parv[0]) ? "*" : parv[0], parv[1]);
+ return 0;
+ }
+
+ /* check if the nick is resv'd */
+ if(find_nick_resv(nick))
+ {
+ sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name, nick);
+ return 0;
+ }
+
+ if(hash_find_nd(nick))
+ {
+ sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name, nick);
+ return 0;
+ }
+
+ if((target_p = find_named_client(nick)) == NULL)
+ set_initial_nick(client_p, source_p, nick);
+ else if(source_p == target_p)
+ strcpy(source_p->name, nick);
+ else
+ sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick);
+
+ return 0;
+}
+
+/* m_nick()
+ * parv[0] = sender prefix
+ * parv[1] = nickname
+ */
+static int
+m_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ char nick[NICKLEN];
+ char *s;
+
+ if(parc < 2 || EmptyString(parv[1]) || (parv[1][0] == '~'))
+ {
+ sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, source_p->name);
+ return 0;
+ }
+
+ /* due to the scandinavian origins, (~ being uppercase of ^) and ~
+ * being disallowed as a nick char, we need to chop the first ~
+ * instead of just erroring.
+ */
+ if((s = strchr(parv[1], '~')))
+ *s = '\0';
+
+ /* mark end of grace period, to prevent nickflooding */
+ if(!IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ /* terminate nick to NICKLEN, we dont want clean_nick() to error! */
+ strlcpy(nick, parv[1], sizeof(nick));
+
+ /* check the nickname is ok */
+ if(!clean_nick(nick, 1))
+ {
+ sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], nick);
+ return 0;
+ }
+
+ if(!IsExemptResv(source_p) && find_nick_resv(nick))
+ {
+ sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, source_p->name, nick);
+ return 0;
+ }
+
+ if(hash_find_nd(nick))
+ {
+ sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name, nick);
+ return 0;
+ }
+
+ if((target_p = find_named_client(nick)))
+ {
+ /* If(target_p == source_p) the client is changing nicks between
+ * equivalent nicknames ie: [nick] -> {nick}
+ */
+ if(target_p == source_p)
+ {
+ /* check the nick isnt exactly the same */
+ if(strcmp(target_p->name, nick))
+ change_local_nick(client_p, source_p, nick, 1);
+
+ }
+
+ /* drop unregged client */
+ else if(IsUnknown(target_p))
+ {
+ exit_client(NULL, target_p, &me, "Overridden");
+ change_local_nick(client_p, source_p, nick, 1);
+ }
+ else
+ sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], nick);
+
+ return 0;
+ }
+ else
+ change_local_nick(client_p, source_p, nick, 1);
+
+ return 0;
+}
+
+/* ms_nick()
+ *
+ * server -> server nick change
+ * parv[0] = sender prefix
+ * parv[1] = nickname
+ * parv[2] = TS when nick change
+ *
+ * server introducing new nick
+ * parv[0] = sender prefix
+ * parv[1] = nickname
+ * parv[2] = hop count
+ * parv[3] = TS
+ * parv[4] = umode
+ * parv[5] = username
+ * parv[6] = hostname
+ * parv[7] = server
+ * parv[8] = ircname
+ */
+static int
+mc_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ time_t newts = 0;
+
+ /* if nicks erroneous, or too long, kill */
+ if(!clean_nick(parv[1], 0))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad Nick: %s From: %s(via %s)",
+ parv[1], source_p->user->server, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.name, parv[1], me.name);
+
+ /* bad nick change, issue kill for the old nick to the rest
+ * of the network.
+ */
+ kill_client_serv_butone(client_p, source_p, "%s (Bad Nickname)", me.name);
+ source_p->flags |= FLAGS_KILLED;
+ exit_client(client_p, source_p, &me, "Bad Nickname");
+ return 0;
+ }
+
+ newts = atol(parv[2]);
+ target_p = find_named_client(parv[1]);
+
+ /* if the nick doesnt exist, allow it and process like normal */
+ if(target_p == NULL)
+ {
+ change_remote_nick(client_p, source_p, newts, parv[1], 1);
+ }
+ else if(IsUnknown(target_p))
+ {
+ exit_client(NULL, target_p, &me, "Overridden");
+ change_remote_nick(client_p, source_p, newts, parv[1], 1);
+ }
+ else if(target_p == source_p)
+ {
+ /* client changing case of nick */
+ if(strcmp(target_p->name, parv[1]))
+ change_remote_nick(client_p, source_p, newts, parv[1], 1);
+ }
+ /* we've got a collision! */
+ else
+ perform_nickchange_collides(source_p, client_p, target_p,
+ parc, parv, newts, parv[1]);
+
+ return 0;
+}
+
+static int
+ms_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ time_t newts = 0;
+
+ if(parc != 9)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Dropping server %s due to (invalid) command 'NICK' "
+ "with %d arguments (expecting 9)", client_p->name, parc);
+ ilog(L_SERVER, "Excess parameters (%d) for command 'NICK' from %s.",
+ parc, client_p->name);
+ exit_client(client_p, client_p, client_p, "Excess parameters to NICK command");
+ return 0;
+ }
+
+ /* if nicks empty, erroneous, or too long, kill */
+ if(!clean_nick(parv[1], 0))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad Nick: %s From: %s(via %s)",
+ parv[1], parv[7], client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.name, parv[1], me.name);
+ return 0;
+ }
+
+ /* invalid username or host? */
+ if(!clean_username(parv[5]) || !clean_host(parv[6]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad user@host: %s@%s From: %s(via %s)",
+ parv[5], parv[6], parv[7], client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.name, parv[1], me.name);
+ return 0;
+ }
+
+ /* check the length of the clients gecos */
+ if(strlen(parv[8]) > REALLEN)
+ {
+ char *s = LOCAL_COPY(parv[8]);
+ /* why exactly do we care? --fl */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Long realname from server %s for %s", parv[7], parv[1]);
+
+ s[REALLEN] = '\0';
+ parv[8] = s;
+ }
+
+ newts = atol(parv[3]);
+
+ target_p = find_named_client(parv[1]);
+
+ /* if the nick doesnt exist, allow it and process like normal */
+ if(target_p == NULL)
+ {
+ register_client(client_p, NULL, parv[1], newts, parc, parv);
+ }
+ else if(IsUnknown(target_p))
+ {
+ exit_client(NULL, target_p, &me, "Overridden");
+ register_client(client_p, NULL, parv[1], newts, parc, parv);
+ }
+ else if(target_p == source_p)
+ {
+ /* client changing case of nick */
+ if(strcmp(target_p->name, parv[1]))
+ register_client(client_p, NULL, parv[1], newts, parc, parv);
+ }
+ /* we've got a collision! */
+ else
+ perform_nick_collides(source_p, client_p, target_p, parc, parv,
+ newts, parv[1], NULL);
+
+ return 0;
+}
+
+/* ms_uid()
+ * parv[1] - nickname
+ * parv[2] - hops
+ * parv[3] - TS
+ * parv[4] - umodes
+ * parv[5] - username
+ * parv[6] - hostname
+ * parv[7] - IP
+ * parv[8] - UID
+ * parv[9] - gecos
+ */
+static int
+ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ time_t newts = 0;
+
+ newts = atol(parv[3]);
+
+ if(parc != 10)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Dropping server %s due to (invalid) command 'UID' "
+ "with %d arguments (expecting 10)", client_p->name, parc);
+ ilog(L_SERVER, "Excess parameters (%d) for command 'UID' from %s.",
+ parc, client_p->name);
+ exit_client(client_p, client_p, client_p, "Excess parameters to UID command");
+ return 0;
+ }
+
+ /* if nicks erroneous, or too long, kill */
+ if(!clean_nick(parv[1], 0))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad Nick: %s From: %s(via %s)",
+ parv[1], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ if(!clean_username(parv[5]) || !clean_host(parv[6]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad user@host: %s@%s From: %s(via %s)",
+ parv[5], parv[6], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ if(!clean_uid(parv[8]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad UID: %s From: %s(via %s)",
+ parv[8], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad UID)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ /* check length of clients gecos */
+ if(strlen(parv[9]) > REALLEN)
+ {
+ char *s = LOCAL_COPY(parv[9]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Long realname from server %s for %s",
+ parv[0], parv[1]);
+ s[REALLEN] = '\0';
+ parv[9] = s;
+ }
+
+ target_p = find_named_client(parv[1]);
+
+ if(target_p == NULL)
+ {
+ register_client(client_p, source_p, parv[1], newts, parc, parv);
+ }
+ else if(IsUnknown(target_p))
+ {
+ exit_client(NULL, target_p, &me, "Overridden");
+ register_client(client_p, source_p, parv[1], newts, parc, parv);
+ }
+ /* we've got a collision! */
+ else
+ perform_nick_collides(source_p, client_p, target_p, parc, parv,
+ newts, parv[1], parv[8]);
+
+ return 0;
+}
+
+/* ms_euid()
+ * parv[1] - nickname
+ * parv[2] - hops
+ * parv[3] - TS
+ * parv[4] - umodes
+ * parv[5] - username
+ * parv[6] - hostname
+ * parv[7] - IP
+ * parv[8] - UID
+ * parv[9] - realhost
+ * parv[10] - account
+ * parv[11] - gecos
+ */
+static int
+ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ time_t newts = 0;
+
+ newts = atol(parv[3]);
+
+ if(parc != 12)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Dropping server %s due to (invalid) command 'EUID' "
+ "with %d arguments (expecting 12)", client_p->name, parc);
+ ilog(L_SERVER, "Excess parameters (%d) for command 'EUID' from %s.",
+ parc, client_p->name);
+ exit_client(client_p, client_p, client_p, "Excess parameters to EUID command");
+ return 0;
+ }
+
+ /* if nicks erroneous, or too long, kill */
+ if(!clean_nick(parv[1], 0))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad Nick: %s From: %s(via %s)",
+ parv[1], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ if(!clean_username(parv[5]) || !clean_host(parv[6]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad user@host: %s@%s From: %s(via %s)",
+ parv[5], parv[6], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ if(!clean_uid(parv[8]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad UID: %s From: %s(via %s)",
+ parv[8], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad UID)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ if(strcmp(parv[9], "*") && !clean_host(parv[9]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad realhost: %s From: %s(via %s)",
+ parv[9], source_p->name, client_p->name);
+ sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name);
+ return 0;
+ }
+
+ /* check length of clients gecos */
+ if(strlen(parv[11]) > REALLEN)
+ {
+ char *s = LOCAL_COPY(parv[11]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Long realname from server %s for %s",
+ parv[0], parv[1]);
+ s[REALLEN] = '\0';
+ parv[11] = s;
+ }
+
+ target_p = find_named_client(parv[1]);
+
+ if(target_p == NULL)
+ {
+ register_client(client_p, source_p, parv[1], newts, parc, parv);
+ }
+ else if(IsUnknown(target_p))
+ {
+ exit_client(NULL, target_p, &me, "Overridden");
+ register_client(client_p, source_p, parv[1], newts, parc, parv);
+ }
+ /* we've got a collision! */
+ else
+ perform_nick_collides(source_p, client_p, target_p, parc, parv,
+ newts, parv[1], parv[8]);
+
+ return 0;
+}
+
+/* ms_save()
+ * parv[1] - UID
+ * parv[2] - TS
+ */
+static int
+ms_save(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ target_p = find_id(parv[1]);
+ if (target_p == NULL)
+ return 0;
+ if (!IsPerson(target_p))
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Ignored SAVE message for non-person %s from %s",
+ target_p->name, source_p->name);
+ else if (IsDigit(target_p->name[0]))
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Ignored noop SAVE message for %s from %s",
+ target_p->name, source_p->name);
+ else if (target_p->tsinfo == atol(parv[2]))
+ save_user(client_p, source_p, target_p);
+ else
+ sendto_realops_snomask(SNO_SKILL, L_ALL,
+ "Ignored SAVE message for %s from %s",
+ target_p->name, source_p->name);
+ return 0;
+}
+
+/* clean_nick()
+ *
+ * input - nickname to check
+ * output - 0 if erroneous, else 1
+ * side effects -
+ */
+static int
+clean_nick(const char *nick, int loc_client)
+{
+ int len = 0;
+
+ /* nicks cant start with a digit or -, and must have a length */
+ if(*nick == '-' || *nick == '\0')
+ return 0;
+
+ if(loc_client && IsDigit(*nick))
+ return 0;
+
+ for(; *nick; nick++)
+ {
+ len++;
+ if(!IsNickChar(*nick))
+ return 0;
+ }
+
+ /* nicklen is +1 */
+ if(len >= NICKLEN)
+ return 0;
+
+ return 1;
+}
+
+/* clean_username()
+ *
+ * input - username to check
+ * output - 0 if erroneous, else 0
+ * side effects -
+ */
+static int
+clean_username(const char *username)
+{
+ int len = 0;
+
+ for(; *username; username++)
+ {
+ len++;
+
+ if(!IsUserChar(*username))
+ return 0;
+ }
+
+ if(len > USERLEN)
+ return 0;
+
+ return 1;
+}
+
+/* clean_host()
+ *
+ * input - host to check
+ * output - 0 if erroneous, else 0
+ * side effects -
+ */
+static int
+clean_host(const char *host)
+{
+ int len = 0;
+
+ for(; *host; host++)
+ {
+ len++;
+
+ if(!IsHostChar(*host))
+ return 0;
+ }
+
+ if(len > HOSTLEN)
+ return 0;
+
+ return 1;
+}
+
+static int
+clean_uid(const char *uid)
+{
+ int len = 1;
+
+ if(!IsDigit(*uid++))
+ return 0;
+
+ for(; *uid; uid++)
+ {
+ len++;
+
+ if(!IsIdChar(*uid))
+ return 0;
+ }
+
+ if(len != IDLEN - 1)
+ return 0;
+
+ return 1;
+}
+
+static void
+set_initial_nick(struct Client *client_p, struct Client *source_p, char *nick)
+{
+ char buf[USERLEN + 1];
+
+ /* This had to be copied here to avoid problems.. */
+ source_p->tsinfo = CurrentTime;
+ if(source_p->name[0])
+ del_from_client_hash(source_p->name, source_p);
+
+ strcpy(source_p->name, nick);
+ add_to_client_hash(nick, source_p);
+
+ /* fd_desc is long enough */
+ comm_note(client_p->localClient->fd, "Nick: %s", nick);
+
+ if(source_p->flags & FLAGS_SENTUSER)
+ {
+ strlcpy(buf, source_p->username, sizeof(buf));
+
+ /* got user, heres nick. */
+ register_local_user(client_p, source_p, buf);
+
+ }
+}
+
+static void
+change_local_nick(struct Client *client_p, struct Client *source_p,
+ char *nick, int dosend)
+{
+ struct Client *target_p;
+ dlink_node *ptr, *next_ptr;
+ struct Channel *chptr;
+ int samenick;
+
+ if (dosend)
+ {
+ chptr = find_bannickchange_channel(source_p);
+ if (chptr != NULL)
+ {
+ sendto_one_numeric(source_p, ERR_BANNICKCHANGE,
+ form_str(ERR_BANNICKCHANGE),
+ nick, chptr->chname);
+ return;
+ }
+ if((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < CurrentTime)
+ source_p->localClient->number_of_nick_changes = 0;
+
+ source_p->localClient->last_nick_change = CurrentTime;
+ source_p->localClient->number_of_nick_changes++;
+
+ if(ConfigFileEntry.anti_nick_flood && !IsOper(source_p) &&
+ source_p->localClient->number_of_nick_changes > ConfigFileEntry.max_nick_changes)
+ {
+ sendto_one(source_p, form_str(ERR_NICKTOOFAST),
+ me.name, source_p->name, source_p->name,
+ nick, ConfigFileEntry.max_nick_time);
+ return;
+ }
+ }
+
+ samenick = irccmp(source_p->name, nick) ? 0 : 1;
+
+ /* dont reset TS if theyre just changing case of nick */
+ if(!samenick)
+ {
+ source_p->tsinfo = CurrentTime;
+ monitor_signoff(source_p);
+ /* we only do bancache for local users -- jilles */
+ if(source_p->user)
+ invalidate_bancache_user(source_p);
+ }
+
+ sendto_realops_snomask(SNO_NCHANGE, L_ALL,
+ "Nick change: From %s to %s [%s@%s]",
+ source_p->name, nick, source_p->username, source_p->host);
+
+ /* send the nick change to the users channels */
+ sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s",
+ source_p->name, source_p->username, source_p->host, nick);
+
+ /* send the nick change to servers.. */
+ if(source_p->user)
+ {
+ add_history(source_p, 1);
+
+ if (dosend)
+ {
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
+ use_id(source_p), nick, (long) source_p->tsinfo);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld",
+ source_p->name, nick, (long) source_p->tsinfo);
+ }
+ }
+
+ /* Finally, add to hash */
+ del_from_client_hash(source_p->name, source_p);
+ strcpy(source_p->name, nick);
+ add_to_client_hash(nick, source_p);
+
+ if(!samenick)
+ monitor_signon(source_p);
+
+ /* Make sure everyone that has this client on its accept list
+ * loses that reference.
+ */
+ /* we used to call del_all_accepts() here, but theres no real reason
+ * to clear a clients own list of accepted clients. So just remove
+ * them from everyone elses list --anfl
+ */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->on_allow_list.head)
+ {
+ target_p = ptr->data;
+
+ dlinkFindDestroy(source_p, &target_p->localClient->allow_list);
+ dlinkDestroy(ptr, &source_p->on_allow_list);
+ }
+
+ /* fd_desc is long enough */
+ comm_note(client_p->localClient->fd, "Nick: %s", nick);
+
+ return;
+}
+
+/*
+ * change_remote_nick()
+ */
+static int
+change_remote_nick(struct Client *client_p, struct Client *source_p,
+ time_t newts, const char *nick, int dosend)
+{
+ struct nd_entry *nd;
+ int samenick = irccmp(source_p->name, nick) ? 0 : 1;
+
+ /* client changing their nick - dont reset ts if its same */
+ if(!samenick)
+ {
+ source_p->tsinfo = newts ? newts : CurrentTime;
+ monitor_signoff(source_p);
+ }
+
+ sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s",
+ source_p->name, source_p->username, source_p->host, nick);
+
+ if(source_p->user)
+ {
+ add_history(source_p, 1);
+ if (dosend)
+ {
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
+ use_id(source_p), nick, (long) source_p->tsinfo);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld",
+ source_p->name, nick, (long) source_p->tsinfo);
+ }
+ }
+
+ del_from_client_hash(source_p->name, source_p);
+
+ /* invalidate nick delay when a remote client uses the nick.. */
+ if((nd = hash_find_nd(nick)))
+ free_nd_entry(nd);
+
+ strcpy(source_p->name, nick);
+ add_to_client_hash(nick, source_p);
+
+ if(!samenick)
+ monitor_signon(source_p);
+
+ /* remove all accepts pointing to the client */
+ del_all_accepts(source_p);
+
+ return 0;
+}
+
+static int
+perform_nick_collides(struct Client *source_p, struct Client *client_p,
+ struct Client *target_p, int parc, const char *parv[],
+ time_t newts, const char *nick, const char *uid)
+{
+ int sameuser;
+ int use_save;
+ const char *action;
+
+ use_save = ConfigFileEntry.collision_fnc && can_save(target_p) &&
+ uid != NULL && can_save(source_p);
+ action = use_save ? "saved" : "killed";
+
+ /* if we dont have a ts, or their TS's are the same, kill both */
+ if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision on %s(%s <- %s)(both %s)",
+ target_p->name, target_p->from->name, client_p->name, action);
+
+ if (use_save)
+ {
+ save_user(&me, &me, target_p);
+ ServerStats->is_save++;
+ sendto_one(client_p, ":%s SAVE %s %ld", me.id,
+ uid, (long)newts);
+ register_client(client_p, source_p,
+ uid, newts, parc, parv);
+ }
+ else
+ {
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* if the new client being introduced has a UID, we need to
+ * issue a KILL for it..
+ */
+ if(uid)
+ sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))",
+ me.id, uid, me.name);
+
+ /* we then need to KILL the old client everywhere */
+ kill_client_serv_butone(NULL, target_p, "%s (Nick collision (new))", me.name);
+ ServerStats->is_kill++;
+
+ target_p->flags |= FLAGS_KILLED;
+ exit_client(client_p, target_p, &me, "Nick collision (new)");
+ }
+ return 0;
+ }
+ /* the timestamps are different */
+ else
+ {
+ sameuser = (target_p->user) && !irccmp(target_p->username, parv[5])
+ && !irccmp(target_p->host, parv[6]);
+
+ if((sameuser && newts < target_p->tsinfo) ||
+ (!sameuser && newts > target_p->tsinfo))
+ {
+ /* if we have a UID, then we need to issue a KILL,
+ * otherwise we do nothing and hope that the other
+ * client will collide it..
+ */
+ if (use_save)
+ {
+ sendto_one(client_p, ":%s SAVE %s %ld", me.id,
+ uid, (long)newts);
+ register_client(client_p, source_p,
+ uid, newts, parc, parv);
+ }
+ else if(uid)
+ sendto_one(client_p,
+ ":%s KILL %s :%s (Nick collision (new))",
+ me.id, uid, me.name);
+ return 0;
+ }
+ else
+ {
+ if(sameuser)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision on %s(%s <- %s)(older %s)",
+ target_p->name, target_p->from->name,
+ client_p->name, action);
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision on %s(%s <- %s)(newer %s)",
+ target_p->name, target_p->from->name,
+ client_p->name, action);
+
+ if (use_save)
+ {
+ ServerStats->is_save++;
+ save_user(&me, &me, target_p);
+ }
+ else
+ {
+ ServerStats->is_kill++;
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* now we just need to kill the existing client */
+ kill_client_serv_butone(client_p, target_p,
+ "%s (Nick collision (new))", me.name);
+
+ target_p->flags |= FLAGS_KILLED;
+ (void) exit_client(client_p, target_p, &me, "Nick collision");
+ }
+
+ register_client(client_p, parc >= 10 ? source_p : NULL,
+ nick, newts, parc, parv);
+
+ return 0;
+ }
+ }
+}
+
+
+static int
+perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
+ struct Client *target_p, int parc,
+ const char *parv[], time_t newts, const char *nick)
+{
+ int sameuser;
+ int use_save;
+ const char *action;
+
+ use_save = ConfigFileEntry.collision_fnc && can_save(target_p) &&
+ can_save(source_p);
+ action = use_save ? "saved" : "killed";
+
+ /* its a client changing nick and causing a collide */
+ if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from %s to %s(%s <- %s)(both %s)",
+ source_p->name, target_p->name, target_p->from->name,
+ client_p->name, action);
+
+ if (use_save)
+ {
+ ServerStats->is_save += 2;
+ save_user(&me, &me, target_p);
+ sendto_one(client_p, ":%s SAVE %s %ld", me.id,
+ source_p->id, (long)newts);
+ /* don't send a redundant nick change */
+ if (!IsDigit(source_p->name[0]))
+ change_remote_nick(client_p, source_p, CurrentTime, source_p->id, 1);
+ }
+ else
+ {
+ ServerStats->is_kill++;
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);
+
+ ServerStats->is_kill++;
+
+ kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);
+
+ target_p->flags |= FLAGS_KILLED;
+ exit_client(NULL, target_p, &me, "Nick collision(new)");
+ source_p->flags |= FLAGS_KILLED;
+ exit_client(client_p, source_p, &me, "Nick collision(old)");
+ }
+ return 0;
+ }
+ else
+ {
+ sameuser = !irccmp(target_p->username, source_p->username) &&
+ !irccmp(target_p->host, source_p->host);
+
+ if((sameuser && newts < target_p->tsinfo) ||
+ (!sameuser && newts > target_p->tsinfo))
+ {
+ if(sameuser)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from %s to %s(%s <- %s)(older %s)",
+ source_p->name, target_p->name,
+ target_p->from->name, client_p->name, action);
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from %s to %s(%s <- %s)(newer %s)",
+ source_p->name, target_p->name,
+ target_p->from->name, client_p->name, action);
+
+ if (use_save)
+ {
+ ServerStats->is_save++;
+ /* can't broadcast a SAVE because the
+ * nickchange has happened at client_p
+ * but not in other directions -- jilles */
+ sendto_one(client_p, ":%s SAVE %s %ld", me.id,
+ source_p->id, (long)newts);
+ /* same CurrentTime as in save_user() */
+ /* send a :<id> NICK <id> <ts> (!) */
+ if (!IsDigit(source_p->name[0]))
+ change_remote_nick(client_p, source_p, CurrentTime, source_p->id, 1);
+ }
+ else
+ {
+ ServerStats->is_kill++;
+
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* kill the client issuing the nickchange */
+ kill_client_serv_butone(client_p, source_p,
+ "%s (Nick change collision)", me.name);
+
+ source_p->flags |= FLAGS_KILLED;
+
+ if(sameuser)
+ exit_client(client_p, source_p, &me, "Nick collision(old)");
+ else
+ exit_client(client_p, source_p, &me, "Nick collision(new)");
+ }
+ return 0;
+ }
+ else
+ {
+ if(sameuser)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision on %s(%s <- %s)(older %s)",
+ target_p->name, target_p->from->name,
+ client_p->name, action);
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision on %s(%s <- %s)(newer %s)",
+ target_p->name, target_p->from->name,
+ client_p->name, action);
+
+ if (use_save)
+ {
+ ServerStats->is_save++;
+ save_user(&me, &me, target_p);
+ }
+ else
+ {
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* kill the client who existed before hand */
+ kill_client_serv_butone(client_p, target_p, "%s (Nick collision)", me.name);
+
+ ServerStats->is_kill++;
+
+ target_p->flags |= FLAGS_KILLED;
+ (void) exit_client(client_p, target_p, &me, "Nick collision");
+ }
+ }
+ }
+
+ change_remote_nick(client_p, source_p, newts, nick, 1);
+
+ return 0;
+}
+
+static int
+register_client(struct Client *client_p, struct Client *server,
+ const char *nick, time_t newts, int parc, const char *parv[])
+{
+ struct Client *source_p;
+ struct User *user;
+ struct nd_entry *nd;
+ const char *m;
+ int flag;
+
+ source_p = make_client(client_p);
+ user = make_user(source_p);
+ dlinkAddTail(source_p, &source_p->node, &global_client_list);
+
+ source_p->hopcount = atoi(parv[2]);
+ source_p->tsinfo = newts;
+
+ strcpy(source_p->name, nick);
+ strlcpy(source_p->username, parv[5], sizeof(source_p->username));
+ strlcpy(source_p->host, parv[6], sizeof(source_p->host));
+ strlcpy(source_p->orighost, source_p->host, sizeof(source_p->orighost));
+
+ if(parc == 12)
+ {
+ user->server = find_or_add(server->name);
+ strlcpy(source_p->info, parv[11], sizeof(source_p->info));
+ strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost));
+ strlcpy(source_p->id, parv[8], sizeof(source_p->id));
+ add_to_id_hash(source_p->id, source_p);
+ if (strcmp(parv[9], "*"))
+ {
+ strlcpy(source_p->orighost, parv[9], sizeof(source_p->orighost));
+ if (irccmp(source_p->host, source_p->orighost))
+ SetDynSpoof(source_p);
+ }
+ if (strcmp(parv[10], "*"))
+ strlcpy(source_p->user->suser, parv[10], sizeof(source_p->user->suser));
+ }
+ else if(parc == 10)
+ {
+ user->server = find_or_add(server->name);
+ strlcpy(source_p->info, parv[9], sizeof(source_p->info));
+ strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost));
+ strlcpy(source_p->id, parv[8], sizeof(source_p->id));
+ add_to_id_hash(source_p->id, source_p);
+ }
+ else
+ {
+ user->server = find_or_add(parv[7]);
+ strlcpy(source_p->info, parv[8], sizeof(source_p->info));
+ }
+
+ /* remove any nd entries for this nick */
+ if((nd = hash_find_nd(nick)))
+ free_nd_entry(nd);
+
+ add_to_client_hash(nick, source_p);
+ add_to_hostname_hash(source_p->host, source_p);
+ monitor_signon(source_p);
+
+ m = &parv[4][1];
+ while(*m)
+ {
+ flag = user_modes[(unsigned char) *m];
+
+ if(flag & UMODE_SERVICE)
+ {
+ int hit = 0;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, service_list.head)
+ {
+ if(!irccmp((const char *) ptr->data, user->server))
+ {
+ hit++;
+ break;
+ }
+ }
+
+ if(!hit)
+ {
+ m++;
+ continue;
+ }
+ }
+
+ /* increment +i count if theyre invis */
+ if(!(source_p->umodes & UMODE_INVISIBLE) && (flag & UMODE_INVISIBLE))
+ Count.invisi++;
+
+ /* increment opered count if theyre opered */
+ if(!(source_p->umodes & UMODE_OPER) && (flag & UMODE_OPER))
+ Count.oper++;
+
+ source_p->umodes |= flag;
+ m++;
+ }
+
+ if(IsOper(source_p) && !IsService(source_p))
+ dlinkAddAlloc(source_p, &oper_list);
+
+ SetRemoteClient(source_p);
+
+ if(++Count.total > Count.max_tot)
+ Count.max_tot = Count.total;
+
+ if(server == NULL)
+ {
+ if((source_p->servptr = find_server(NULL, user->server)) == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Ghost killed: %s on invalid server %s",
+ source_p->name, user->server);
+ kill_client(client_p, source_p, "%s (Server doesn't exist)", me.name);
+ source_p->flags |= FLAGS_KILLED;
+ return exit_client(NULL, source_p, &me, "Ghosted Client");
+ }
+ }
+ else
+ source_p->servptr = server;
+
+ dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users);
+
+ /* fake direction */
+ if(source_p->servptr->from != source_p->from)
+ {
+ struct Client *target_p = source_p->servptr->from;
+
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad User [%s] :%s USER %s@%s %s, != %s[%s]",
+ client_p->name, source_p->name,
+ source_p->username, source_p->host,
+ user->server, target_p->name, target_p->from->name);
+ kill_client(client_p, source_p,
+ "%s (NICK from wrong direction (%s != %s))",
+ me.name, user->server, target_p->from->name);
+ source_p->flags |= FLAGS_KILLED;
+ return exit_client(source_p, source_p, &me, "USER server wrong direction");
+ }
+
+ call_hook(h_new_remote_user, source_p);
+
+ return (introduce_client(client_p, source_p, user, nick, parc == 12));
+}
+
+/* Check if we can do SAVE. target_p can be a client to save or a
+ * server introducing a client -- jilles */
+static int
+can_save(struct Client *target_p)
+{
+ struct Client *serv_p;
+
+ if (MyClient(target_p))
+ return 1;
+ if (!has_id(target_p))
+ return 0;
+ serv_p = IsServer(target_p) ? target_p : target_p->servptr;
+ while (serv_p != NULL && serv_p != &me)
+ {
+ if (!(serv_p->serv->caps & CAP_SAVE))
+ return 0;
+ serv_p = serv_p->servptr;
+ }
+ return serv_p == &me;
+}
+
+static void
+save_user(struct Client *client_p, struct Client *source_p,
+ struct Client *target_p)
+{
+ if (!MyConnect(target_p) && (!has_id(target_p) || !IsCapable(target_p->from, CAP_SAVE)))
+ {
+ /* This shouldn't happen */
+ /* Note we only need SAVE support in this direction */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Killed %s!%s@%s for nick collision detected by %s (%s does not support SAVE)",
+ target_p->name, target_p->username, target_p->host, source_p->name, target_p->from->name);
+ kill_client_serv_butone(NULL, target_p, "%s (Nick collision (no SAVE support))", me.name);
+ ServerStats->is_kill++;
+
+ target_p->flags |= FLAGS_KILLED;
+ (void) exit_client(NULL, target_p, &me, "Nick collision (no SAVE support)");
+ return;
+ }
+ sendto_server(client_p, NULL, CAP_SAVE|CAP_TS6, NOCAPS, ":%s SAVE %s %ld",
+ source_p->id, target_p->id, (long)target_p->tsinfo);
+ sendto_server(client_p, NULL, CAP_TS6, CAP_SAVE, ":%s NICK %s :%ld",
+ target_p->id, target_p->id, (long)CurrentTime);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld",
+ target_p->name, target_p->id, (long)CurrentTime);
+ if (!IsMe(client_p))
+ sendto_realops_snomask(SNO_SKILL, L_ALL,
+ "Received SAVE message for %s from %s",
+ target_p->name, source_p->name);
+ if (MyClient(target_p))
+ {
+ sendto_one_numeric(target_p, RPL_SAVENICK,
+ form_str(RPL_SAVENICK), target_p->id);
+ change_local_nick(target_p, target_p, target_p->id, 0);
+ }
+ else
+ {
+ /* XXX the uid nick gets garbage TS; shouldn't matter though */
+ change_remote_nick(target_p, target_p, CurrentTime, target_p->id, 0);
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_part.c: Parts a user from a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_part.c 98 2005-09-11 03:37:47Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "packet.h"
+
+static int m_part(struct Client *, struct Client *, int, const char **);
+
+struct Message part_msgtab = {
+ "PART", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_part, 2}, {m_part, 2}, mg_ignore, mg_ignore, {m_part, 2}}
+};
+
+mapi_clist_av1 part_clist[] = { &part_msgtab, NULL };
+
+DECLARE_MODULE_AV1(part, NULL, NULL, part_clist, NULL, NULL, "$Revision: 98 $");
+
+static void part_one_client(struct Client *client_p,
+ struct Client *source_p, char *name, char *reason);
+
+
+/*
+** m_part
+** parv[0] = sender prefix
+** parv[1] = channel
+** parv[2] = reason
+*/
+static int
+m_part(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char *p, *name;
+ char reason[REASONLEN + 1];
+ char *s = LOCAL_COPY(parv[1]);
+
+ reason[0] = '\0';
+
+ if(parc > 2)
+ strlcpy(reason, parv[2], sizeof(reason));
+
+ name = strtoken(&p, s, ",");
+
+ /* Finish the flood grace period... */
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ strip_colour(reason);
+
+ while(name)
+ {
+ part_one_client(client_p, source_p, name, reason);
+ name = strtoken(&p, NULL, ",");
+ }
+ return 0;
+}
+
+/*
+ * part_one_client
+ *
+ * inputs - pointer to server
+ * - pointer to source client to remove
+ * - char pointer of name of channel to remove from
+ * output - none
+ * side effects - remove ONE client given the channel name
+ */
+static void
+part_one_client(struct Client *client_p, struct Client *source_p, char *name, char *reason)
+{
+ struct Channel *chptr;
+ struct membership *msptr;
+
+ if((chptr = find_channel(name)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);
+ return;
+ }
+
+ msptr = find_channel_membership(chptr, source_p);
+ if(msptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name);
+ return;
+ }
+
+ if(MyConnect(source_p) && !IsOper(source_p) && !IsExemptSpambot(source_p))
+ check_spambot_warning(source_p, NULL);
+
+ /*
+ * Remove user from the old channel (if any)
+ * only allow /part reasons in -m chans
+ */
+ if(reason[0] && (is_chanop(msptr) || !MyConnect(source_p) ||
+ ((can_send(chptr, source_p, msptr) > 0 &&
+ (source_p->localClient->firsttime +
+ ConfigFileEntry.anti_spam_exit_message_time) < CurrentTime))))
+ {
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s PART %s :%s", use_id(source_p), chptr->chname, reason);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s PART %s :%s", source_p->name, chptr->chname, reason);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
+ source_p->name, source_p->username,
+ source_p->host, chptr->chname, reason);
+ }
+ else
+ {
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s PART %s", use_id(source_p), chptr->chname);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s PART %s", source_p->name, chptr->chname);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
+ source_p->name, source_p->username,
+ source_p->host, chptr->chname);
+ }
+ remove_user_from_channel(msptr);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_quit.c: Makes a user quit from IRC.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_quit.c 1333 2006-05-14 13:47:33Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "sprintf_irc.h"
+
+static int m_quit(struct Client *, struct Client *, int, const char **);
+static int ms_quit(struct Client *, struct Client *, int, const char **);
+
+struct Message quit_msgtab = {
+ "QUIT", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{m_quit, 0}, {m_quit, 0}, {ms_quit, 0}, mg_ignore, mg_ignore, {m_quit, 0}}
+};
+
+mapi_clist_av1 quit_clist[] = { &quit_msgtab, NULL };
+
+DECLARE_MODULE_AV1(quit, NULL, NULL, quit_clist, NULL, NULL, "$Revision: 1333 $");
+
+/*
+** m_quit
+** parv[0] = sender prefix
+** parv[1] = comment
+*/
+static int
+m_quit(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char *comment = LOCAL_COPY((parc > 1 && parv[1]) ? parv[1] : client_p->name);
+ char reason[REASONLEN + 1];
+
+ source_p->flags |= FLAGS_NORMALEX;
+
+ if(strlen(comment) > (size_t) REASONLEN)
+ comment[REASONLEN] = '\0';
+
+ strip_colour(comment);
+
+ if(ConfigFileEntry.client_exit && comment[0])
+ {
+ ircsnprintf(reason, sizeof(reason), "Quit: %s", comment);
+ comment = reason;
+ }
+
+ if(!IsOper(source_p) &&
+ (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) >
+ CurrentTime)
+ {
+ exit_client(client_p, source_p, source_p, "Client Quit");
+ return 0;
+ }
+
+ exit_client(client_p, source_p, source_p, comment);
+
+ return 0;
+}
+
+/*
+** ms_quit
+** parv[0] = sender prefix
+** parv[1] = comment
+*/
+static int
+ms_quit(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char *comment = LOCAL_COPY((parc > 1 && parv[1]) ? parv[1] : client_p->name);
+
+ source_p->flags |= FLAGS_NORMALEX;
+ if(strlen(comment) > (size_t) REASONLEN)
+ comment[REASONLEN] = '\0';
+
+ exit_client(client_p, source_p, source_p, comment);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_server.c: Introduces a server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_server.c 2733 2006-11-10 00:04:08Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h" /* client struct */
+#include "common.h" /* TRUE bleah */
+#include "event.h"
+#include "hash.h" /* add_to_client_hash */
+#include "irc_string.h"
+#include "ircd.h" /* me */
+#include "numeric.h" /* ERR_xxx */
+#include "s_conf.h" /* struct ConfItem */
+#include "s_newconf.h"
+#include "s_log.h" /* log level defines */
+#include "s_serv.h" /* server_estab, check_server */
+#include "s_stats.h" /* ServerStats */
+#include "scache.h" /* find_or_add */
+#include "send.h" /* sendto_one */
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mr_server(struct Client *, struct Client *, int, const char **);
+static int ms_server(struct Client *, struct Client *, int, const char **);
+static int ms_sid(struct Client *, struct Client *, int, const char **);
+
+struct Message server_msgtab = {
+ "SERVER", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_server, 4}, mg_reg, mg_ignore, {ms_server, 4}, mg_ignore, mg_reg}
+};
+struct Message sid_msgtab = {
+ "SID", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_reg, mg_ignore, {ms_sid, 5}, mg_ignore, mg_reg}
+};
+
+mapi_clist_av1 server_clist[] = { &server_msgtab, &sid_msgtab, NULL };
+
+DECLARE_MODULE_AV1(server, NULL, NULL, server_clist, NULL, NULL, "$Revision: 2733 $");
+
+int bogus_host(const char *host);
+struct Client *server_exists(const char *);
+static int set_server_gecos(struct Client *, const char *);
+
+/*
+ * mr_server - SERVER message handler
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ * parv[2] = serverinfo/hopcount
+ * parv[3] = serverinfo
+ */
+static int
+mr_server(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char info[REALLEN + 1];
+ const char *name;
+ struct Client *target_p;
+ int hop;
+
+ name = parv[1];
+ hop = atoi(parv[2]);
+ strlcpy(info, parv[3], sizeof(info));
+
+ /*
+ * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
+ */
+ if(!DoesTS(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Link %s dropped, non-TS server",
+ get_server_name(client_p, HIDE_IP));
+ exit_client(client_p, client_p, client_p, "Non-TS server");
+ return 0;
+ }
+
+ if(bogus_host(name))
+ {
+ exit_client(client_p, client_p, client_p, "Bogus server name");
+ return 0;
+ }
+
+ /* Now we just have to call check_server and everything should be
+ * check for us... -A1kmm. */
+ switch (check_server(name, client_p))
+ {
+ case -1:
+ if(ConfigFileEntry.warn_no_nline)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Unauthorised server connection attempt from %s: "
+ "No entry for servername %s",
+ get_server_name(client_p, HIDE_IP), name);
+
+ ilog(L_SERVER, "Access denied, no connect block for server %s%s",
+ EmptyString(client_p->name) ? name : "",
+ log_client_name(client_p, SHOW_IP));
+ }
+
+ exit_client(client_p, client_p, client_p, "Invalid servername.");
+ return 0;
+ /* NOT REACHED */
+ break;
+
+ case -2:
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Unauthorised server connection attempt from %s: "
+ "Bad password for server %s",
+ get_server_name(client_p, HIDE_IP), name);
+
+ ilog(L_SERVER, "Access denied, invalid password for server %s%s",
+ EmptyString(client_p->name) ? name : "",
+ log_client_name(client_p, SHOW_IP));
+
+ exit_client(client_p, client_p, client_p, "Invalid password.");
+ return 0;
+ /* NOT REACHED */
+ break;
+
+ case -3:
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Unauthorised server connection attempt from %s: "
+ "Invalid host for server %s",
+ get_server_name(client_p, HIDE_IP), name);
+
+ ilog(L_SERVER, "Access denied, invalid host for server %s%s",
+ EmptyString(client_p->name) ? name : "",
+ log_client_name(client_p, SHOW_IP));
+
+ exit_client(client_p, client_p, client_p, "Invalid host.");
+ return 0;
+ /* NOT REACHED */
+ break;
+
+ /* servername is > HOSTLEN */
+ case -4:
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Invalid servername %s from %s",
+ name, get_server_name(client_p, HIDE_IP));
+ ilog(L_SERVER, "Access denied, invalid servername from %s",
+ log_client_name(client_p, SHOW_IP));
+
+ exit_client(client_p, client_p, client_p, "Invalid servername.");
+ return 0;
+ /* NOT REACHED */
+ break;
+ }
+
+ if((target_p = server_exists(name)))
+ {
+ /*
+ * This link is trying feed me a server that I already have
+ * access through another path -- multiple paths not accepted
+ * currently, kill this link immediately!!
+ *
+ * Rather than KILL the link which introduced it, KILL the
+ * youngest of the two links. -avalon
+ *
+ * Definitely don't do that here. This is from an unregistered
+ * connect - A1kmm.
+ */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Attempt to re-introduce server %s from %s",
+ name, get_server_name(client_p, HIDE_IP));
+ ilog(L_SERVER, "Attempt to re-introduce server %s from %s",
+ name, log_client_name(client_p, SHOW_IP));
+
+ sendto_one(client_p, "ERROR :Server already exists.");
+ exit_client(client_p, client_p, client_p, "Server Exists");
+ return 0;
+ }
+
+ if(has_id(client_p) && (target_p = find_id(client_p->id)) != NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Attempt to re-introduce SID %s from %s%s",
+ client_p->id,
+ EmptyString(client_p->name) ? name : "",
+ get_server_name(client_p, HIDE_IP));
+ ilog(L_SERVER, "Attempt to re-introduce SID %s from %s%s",
+ client_p->id,
+ EmptyString(client_p->name) ? name : "",
+ log_client_name(client_p, SHOW_IP));
+
+ sendto_one(client_p, "ERROR :SID already exists.");
+ exit_client(client_p, client_p, client_p, "SID Exists");
+ return 0;
+ }
+
+ /*
+ * if we are connecting (Handshake), we already have the name from the
+ * C:line in client_p->name
+ */
+
+ strlcpy(client_p->name, name, sizeof(client_p->name));
+ set_server_gecos(client_p, info);
+ client_p->hopcount = hop;
+ server_estab(client_p);
+
+ return 0;
+}
+
+/*
+ * ms_server - SERVER message handler
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ * parv[2] = serverinfo/hopcount
+ * parv[3] = serverinfo
+ */
+static int
+ms_server(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char info[REALLEN + 1];
+ /* same size as in s_misc.c */
+ const char *name;
+ struct Client *target_p;
+ struct remote_conf *hub_p;
+ hook_data_client hdata;
+ int hop;
+ int hlined = 0;
+ int llined = 0;
+ dlink_node *ptr;
+
+ name = parv[1];
+ hop = atoi(parv[2]);
+ strlcpy(info, parv[3], sizeof(info));
+
+ if((target_p = server_exists(name)))
+ {
+ /*
+ * This link is trying feed me a server that I already have
+ * access through another path -- multiple paths not accepted
+ * currently, kill this link immediately!!
+ *
+ * Rather than KILL the link which introduced it, KILL the
+ * youngest of the two links. -avalon
+ *
+ * I think that we should exit the link itself, not the introducer,
+ * and we should always exit the most recently received(i.e. the
+ * one we are receiving this SERVER for. -A1kmm
+ *
+ * You *cant* do this, if you link somewhere, it bursts you a server
+ * that already exists, then sends you a client burst, you squit the
+ * server, but you keep getting the burst of clients on a server that
+ * doesnt exist, although ircd can handle it, its not a realistic
+ * solution.. --fl_
+ */
+ /* It is behind a host-masked server. Completely ignore the
+ * server message(don't propagate or we will delink from whoever
+ * we propagate to). -A1kmm */
+ if(irccmp(target_p->name, name) && target_p->from == client_p)
+ return 0;
+
+ sendto_one(client_p, "ERROR :Server %s already exists", name);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled, server %s already exists",
+ get_server_name(client_p, SHOW_IP), name);
+ ilog(L_SERVER, "Link %s cancelled, server %s already exists",
+ client_p->name, name);
+
+ exit_client(client_p, client_p, &me, "Server Exists");
+ return 0;
+ }
+
+ /*
+ * User nicks never have '.' in them and server names
+ * must always have '.' in them.
+ */
+ if(strchr(name, '.') == NULL)
+ {
+ /*
+ * Server trying to use the same name as a person. Would
+ * cause a fair bit of confusion. Enough to make it hellish
+ * for a while and servers to send stuff to the wrong place.
+ */
+ sendto_one(client_p, "ERROR :Nickname %s already exists!", name);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled: Server/nick collision on %s",
+ get_server_name(client_p, HIDE_IP), name);
+ ilog(L_SERVER, "Link %s cancelled: Server/nick collision on %s",
+ client_p->name, name);
+
+ exit_client(client_p, client_p, client_p, "Nick as Server");
+ return 0;
+ }
+
+ /*
+ * Server is informing about a new server behind
+ * this link. Create REMOTE server structure,
+ * add it to list and propagate word to my other
+ * server links...
+ */
+ if(parc == 1 || EmptyString(info))
+ {
+ sendto_one(client_p, "ERROR :No server info specified for %s", name);
+ return 0;
+ }
+
+ /*
+ * See if the newly found server is behind a guaranteed
+ * leaf. If so, close the link.
+ *
+ */
+ DLINK_FOREACH(ptr, hubleaf_conf_list.head)
+ {
+ hub_p = ptr->data;
+
+ if(match(hub_p->server, client_p->name) && match(hub_p->host, name))
+ {
+ if(hub_p->flags & CONF_HUB)
+ hlined++;
+ else
+ llined++;
+ }
+ }
+
+ /* Ok, this way this works is
+ *
+ * A server can have a CONF_HUB allowing it to introduce servers
+ * behind it.
+ *
+ * connect {
+ * name = "irc.bighub.net";
+ * hub_mask="*";
+ * ...
+ *
+ * That would allow "irc.bighub.net" to introduce anything it wanted..
+ *
+ * However
+ *
+ * connect {
+ * name = "irc.somehub.fi";
+ * hub_mask="*";
+ * leaf_mask="*.edu";
+ *...
+ * Would allow this server in finland to hub anything but
+ * .edu's
+ */
+
+ /* Ok, check client_p can hub the new server, and make sure it's not a LL */
+ if(!hlined)
+ {
+ /* OOOPs nope can't HUB */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Non-Hub link %s introduced %s.",
+ get_server_name(client_p, HIDE_IP), name);
+ ilog(L_SERVER, "Non-Hub link %s introduced %s.",
+ client_p->name, name);
+
+ exit_client(NULL, client_p, &me, "No matching hub_mask.");
+ return 0;
+ }
+
+ /* Check for the new server being leafed behind this HUB */
+ if(llined)
+ {
+ /* OOOPs nope can't HUB this leaf */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s introduced leafed server %s.",
+ get_server_name(client_p, HIDE_IP), name);
+ ilog(L_SERVER, "Link %s introduced leafed server %s.",
+ client_p->name, name);
+
+ exit_client(NULL, client_p, &me, "Leafed Server.");
+ return 0;
+ }
+
+
+
+ if(strlen(name) > HOSTLEN)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s introduced server with invalid servername %s",
+ get_server_name(client_p, HIDE_IP), name);
+ ilog(L_SERVER, "Link %s introduced server with invalid servername %s",
+ client_p->name, name);
+
+ exit_client(NULL, client_p, &me, "Invalid servername introduced.");
+ return 0;
+ }
+
+ target_p = make_client(client_p);
+ make_server(target_p);
+ target_p->hopcount = hop;
+
+ strlcpy(target_p->name, name, sizeof(target_p->name));
+
+ set_server_gecos(target_p, info);
+
+ target_p->serv->up = find_or_add(source_p->name);
+
+ if(has_id(source_p))
+ target_p->serv->upid = source_p->id;
+
+ target_p->servptr = source_p;
+
+ SetServer(target_p);
+
+ dlinkAddTail(target_p, &target_p->node, &global_client_list);
+ dlinkAddTailAlloc(target_p, &global_serv_list);
+ add_to_client_hash(target_p->name, target_p);
+ dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->servers);
+
+ sendto_server(client_p, NULL, NOCAPS, NOCAPS,
+ ":%s SERVER %s %d :%s%s",
+ source_p->name, target_p->name, target_p->hopcount + 1,
+ IsHidden(target_p) ? "(H) " : "", target_p->info);
+
+ sendto_realops_snomask(SNO_EXTERNAL, L_ALL,
+ "Server %s being introduced by %s", target_p->name, source_p->name);
+
+ /* quick, dirty EOB. you know you love it. */
+ sendto_one(target_p, ":%s PING %s %s", get_id(&me, target_p), me.name, target_p->name);
+
+ hdata.client = source_p;
+ hdata.target = target_p;
+ call_hook(h_server_introduced, &hdata);
+
+ return 0;
+}
+
+static int
+ms_sid(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct remote_conf *hub_p;
+ hook_data_client hdata;
+ dlink_node *ptr;
+ int hop;
+ int hlined = 0;
+ int llined = 0;
+
+ hop = atoi(parv[2]);
+
+ /* collision on the name? */
+ if((target_p = server_exists(parv[1])) != NULL)
+ {
+ sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled, server %s already exists",
+ get_server_name(client_p, SHOW_IP), parv[1]);
+ ilog(L_SERVER, "Link %s cancelled, server %s already exists",
+ client_p->name, parv[1]);
+
+ exit_client(NULL, client_p, &me, "Server Exists");
+ return 0;
+ }
+
+ /* collision on the SID? */
+ if((target_p = find_id(parv[3])) != NULL)
+ {
+ sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled, SID %s already exists",
+ get_server_name(client_p, SHOW_IP), parv[3]);
+ ilog(L_SERVER, "Link %s cancelled, SID %s already exists",
+ client_p->name, parv[3]);
+
+ exit_client(NULL, client_p, &me, "Server Exists");
+ return 0;
+ }
+
+ if(bogus_host(parv[1]) || strlen(parv[1]) > HOSTLEN)
+ {
+ sendto_one(client_p, "ERROR :Invalid servername");
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled, servername %s invalid",
+ get_server_name(client_p, SHOW_IP), parv[1]);
+ ilog(L_SERVER, "Link %s cancelled, servername %s invalid",
+ client_p->name, parv[1]);
+
+ exit_client(NULL, client_p, &me, "Bogus server name");
+ return 0;
+ }
+
+ if(!IsDigit(parv[3][0]) || !IsIdChar(parv[3][1]) ||
+ !IsIdChar(parv[3][2]) || parv[3][3] != '\0')
+ {
+ sendto_one(client_p, "ERROR :Invalid SID");
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s cancelled, SID %s invalid",
+ get_server_name(client_p, SHOW_IP), parv[3]);
+ ilog(L_SERVER, "Link %s cancelled, SID %s invalid",
+ client_p->name, parv[3]);
+
+ exit_client(NULL, client_p, &me, "Bogus SID");
+ return 0;
+ }
+
+ /* for the directly connected server:
+ * H: allows it to introduce a server matching that mask
+ * L: disallows it introducing a server matching that mask
+ */
+ DLINK_FOREACH(ptr, hubleaf_conf_list.head)
+ {
+ hub_p = ptr->data;
+
+ if(match(hub_p->server, client_p->name) && match(hub_p->host, parv[1]))
+ {
+ if(hub_p->flags & CONF_HUB)
+ hlined++;
+ else
+ llined++;
+ }
+ }
+
+ /* no matching hub_mask */
+ if(!hlined)
+ {
+ sendto_one(client_p, "ERROR :No matching hub_mask");
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Non-Hub link %s introduced %s.",
+ get_server_name(client_p, SHOW_IP), parv[1]);
+ ilog(L_SERVER, "Non-Hub link %s introduced %s.",
+ client_p->name, parv[1]);
+ exit_client(NULL, client_p, &me, "No matching hub_mask.");
+ return 0;
+ }
+
+ /* matching leaf_mask */
+ if(llined)
+ {
+ sendto_one(client_p, "ERROR :Matching leaf_mask");
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s introduced leafed server %s.",
+ get_server_name(client_p, SHOW_IP), parv[1]);
+ ilog(L_SERVER, "Link %s introduced leafed server %s.",
+ client_p->name, parv[1]);
+ exit_client(NULL, client_p, &me, "Leafed Server.");
+ return 0;
+ }
+
+ /* ok, alls good */
+ target_p = make_client(client_p);
+ make_server(target_p);
+
+ strlcpy(target_p->name, parv[1], sizeof(target_p->name));
+ target_p->hopcount = atoi(parv[2]);
+ strcpy(target_p->id, parv[3]);
+ set_server_gecos(target_p, parv[4]);
+
+ target_p->serv->up = find_or_add(source_p->name);
+
+ if(has_id(source_p))
+ target_p->serv->upid = source_p->id;
+
+ target_p->servptr = source_p;
+ SetServer(target_p);
+
+ dlinkAddTail(target_p, &target_p->node, &global_client_list);
+ dlinkAddTailAlloc(target_p, &global_serv_list);
+ add_to_client_hash(target_p->name, target_p);
+ add_to_id_hash(target_p->id, target_p);
+ dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->servers);
+
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+ ":%s SID %s %d %s :%s%s",
+ source_p->id, target_p->name, target_p->hopcount + 1,
+ target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ ":%s SERVER %s %d :%s%s",
+ source_p->name, target_p->name, target_p->hopcount + 1,
+ IsHidden(target_p) ? "(H) " : "", target_p->info);
+
+ sendto_realops_snomask(SNO_EXTERNAL, L_ALL,
+ "Server %s being introduced by %s", target_p->name, source_p->name);
+
+ /* quick, dirty EOB. you know you love it. */
+ sendto_one(target_p, ":%s PING %s %s",
+ get_id(&me, target_p), me.name, get_id(target_p, target_p));
+
+ hdata.client = source_p;
+ hdata.target = target_p;
+ call_hook(h_server_introduced, &hdata);
+
+ return 0;
+}
+
+/* set_server_gecos()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - servers gecos field is set
+ */
+static int
+set_server_gecos(struct Client *client_p, const char *info)
+{
+ /* check the info for [IP] */
+ if(info[0])
+ {
+ char *p;
+ char *s;
+ char *t;
+
+ s = LOCAL_COPY(info);
+
+ /* we should only check the first word for an ip */
+ if((p = strchr(s, ' ')))
+ *p = '\0';
+
+ /* check for a ] which would symbolise an [IP] */
+ if((t = strchr(s, ']')))
+ {
+ /* set s to after the first space */
+ if(p)
+ s = ++p;
+ else
+ s = NULL;
+ }
+ /* no ], put the space back */
+ else if(p)
+ *p = ' ';
+
+ /* p may have been set to a trailing space, so check s exists and that
+ * it isnt \0 */
+ if(s && (*s != '\0'))
+ {
+ /* a space? if not (H) could be the last part of info.. */
+ if((p = strchr(s, ' ')))
+ *p = '\0';
+
+ /* check for (H) which is a hidden server */
+ if(!strcmp(s, "(H)"))
+ {
+ SetHidden(client_p);
+
+ /* if there was no space.. theres nothing to set info to */
+ if(p)
+ s = ++p;
+ else
+ s = NULL;
+ }
+ else if(p)
+ *p = ' ';
+
+ /* if there was a trailing space, s could point to \0, so check */
+ if(s && (*s != '\0'))
+ {
+ strlcpy(client_p->info, s, sizeof(client_p->info));
+ return 1;
+ }
+ }
+ }
+
+ strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
+
+ return 1;
+}
+
+/*
+ * bogus_host
+ *
+ * inputs - hostname
+ * output - 1 if a bogus hostname input, 0 if its valid
+ * side effects - none
+ */
+int
+bogus_host(const char *host)
+{
+ int bogus_server = 0;
+ const char *s;
+ int dots = 0;
+
+ for(s = host; *s; s++)
+ {
+ if(!IsServChar(*s))
+ {
+ bogus_server = 1;
+ break;
+ }
+ if('.' == *s)
+ ++dots;
+ }
+
+ if(!dots || bogus_server)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * server_exists()
+ *
+ * inputs - servername
+ * output - 1 if server exists, 0 if doesnt exist
+ */
+struct Client *
+server_exists(const char *servername)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(match(target_p->name, servername) || match(servername, target_p->name))
+ return target_p;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_sjoin.c: Joins a user to a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_sjoin.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "common.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+#include "s_conf.h"
+
+static int ms_sjoin(struct Client *, struct Client *, int, const char **);
+
+struct Message sjoin_msgtab = {
+ "SJOIN", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, {ms_sjoin, 0}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 sjoin_clist[] = { &sjoin_msgtab, NULL };
+
+DECLARE_MODULE_AV1(sjoin, NULL, NULL, sjoin_clist, NULL, NULL, "$Revision: 3131 $");
+
+/*
+ * ms_sjoin
+ * parv[0] - sender
+ * parv[1] - TS
+ * parv[2] - channel
+ * parv[3] - modes + n arguments (key and/or limit)
+ * parv[4+n] - flags+nick list (all in one parameter)
+ *
+ * process a SJOIN, taking the TS's into account to either ignore the
+ * incoming modes or undo the existing ones or merge them, and JOIN
+ * all the specified users while sending JOIN/MODEs to local clients
+ */
+
+
+static char modebuf[MODEBUFLEN];
+static char parabuf[MODEBUFLEN];
+static const char *para[MAXMODEPARAMS];
+static char *mbuf;
+static int pargs;
+
+static void set_final_mode(struct Mode *mode, struct Mode *oldmode);
+static void remove_our_modes(struct Channel *chptr, struct Client *source_p);
+static void remove_ban_list(struct Channel *chptr, struct Client *source_p,
+ dlink_list * list, char c, int cap, int mems);
+
+static int
+ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static char buf_nick[BUFSIZE];
+ static char buf_uid[BUFSIZE];
+ static const char empty_modes[] = "0";
+ struct Channel *chptr;
+ struct Client *target_p, *fakesource_p;
+ time_t newts;
+ time_t oldts;
+ static struct Mode mode, *oldmode;
+ const char *modes;
+ int args = 0;
+ int keep_our_modes = 1;
+ int keep_new_modes = 1;
+ int fl;
+ int isnew;
+ int mlen_nick, mlen_uid;
+ int len_nick;
+ int len_uid;
+ int len;
+ int joins = 0;
+ const char *s;
+ char *ptr_nick;
+ char *ptr_uid;
+ char *p;
+ int i, joinc = 0, timeslice = 0;
+ static char empty[] = "";
+ dlink_node *ptr, *next_ptr;
+
+ if(!IsChannelName(parv[2]) || !check_channel_name(parv[2]))
+ return 0;
+
+ /* SJOIN's for local channels can't happen. */
+ if(*parv[2] == '&')
+ return 0;
+
+ modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0';
+ pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
+
+ /* Hide connecting server on netburst -- jilles */
+ if (ConfigServerHide.flatten_links && !HasSentEob(source_p))
+ fakesource_p = &me;
+ else
+ fakesource_p = source_p;
+
+ mbuf = modebuf;
+ newts = atol(parv[1]);
+
+ s = parv[3];
+ while (*s)
+ {
+ switch (*(s++))
+ {
+ case 'i':
+ mode.mode |= MODE_INVITEONLY;
+ break;
+ case 'n':
+ mode.mode |= MODE_NOPRIVMSGS;
+ break;
+ case 'p':
+ mode.mode |= MODE_PRIVATE;
+ break;
+ case 's':
+ mode.mode |= MODE_SECRET;
+ break;
+ case 'm':
+ mode.mode |= MODE_MODERATED;
+ break;
+ case 't':
+ mode.mode |= MODE_TOPICLIMIT;
+ break;
+ case 'r':
+ mode.mode |= MODE_REGONLY;
+ break;
+ case 'L':
+ mode.mode |= MODE_EXLIMIT;
+ break;
+ case 'P':
+ mode.mode |= MODE_PERMANENT;
+ break;
+ case 'c':
+ mode.mode |= MODE_NOCOLOR;
+ break;
+ case 'g':
+ mode.mode |= MODE_FREEINVITE;
+ break;
+ case 'z':
+ mode.mode |= MODE_OPMODERATE;
+ break;
+ case 'F':
+ mode.mode |= MODE_FREETARGET;
+ break;
+ case 'Q':
+ mode.mode |= MODE_DISFORWARD;
+ break;
+ case 'f':
+ strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
+ args++;
+ if(parc < 5 + args)
+ return 0;
+ break;
+ case 'j':
+ sscanf(parv[4 + args], "%d:%d", &joinc, ×lice);
+ args++;
+ mode.join_num = joinc;
+ mode.join_time = timeslice;
+ if(parc < 5 + args)
+ return 0;
+ break;
+ case 'k':
+ strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
+ args++;
+ if(parc < 5 + args)
+ return 0;
+ break;
+ case 'l':
+ mode.limit = atoi(parv[4 + args]);
+ args++;
+ if(parc < 5 + args)
+ return 0;
+ break;
+ }
+ }
+
+ if(parv[args + 4])
+ {
+ s = parv[args + 4];
+
+ /* remove any leading spaces */
+ while (*s == ' ')
+ s++;
+ }
+ else
+ s = "";
+
+ if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
+ return 0; /* channel name too long? */
+
+
+ oldts = chptr->channelts;
+ oldmode = &chptr->mode;
+
+#ifdef IGNORE_BOGUS_TS
+ if(newts < 800000000)
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "*** Bogus TS %ld on %s ignored from %s",
+ (long) newts, chptr->chname, client_p->name);
+
+ newts = (oldts == 0) ? oldts : 800000000;
+ }
+#else
+ if(!isnew && !newts && oldts)
+ {
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s NOTICE %s :*** Notice -- TS for %s "
+ "changed from %ld to 0",
+ me.name, chptr->chname, chptr->chname, (long) oldts);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Server %s changing TS on %s from %ld to 0",
+ source_p->name, chptr->chname, (long) oldts);
+ }
+#endif
+
+ if(isnew)
+ chptr->channelts = newts;
+
+ else if(newts == 0 || oldts == 0)
+ chptr->channelts = 0;
+ else if(newts == oldts)
+ ;
+ else if(newts < oldts)
+ {
+ /* If configured, kick people trying to join +i/+k
+ * channels by recreating them on split servers.
+ * Don't kick if the source has sent EOB (services
+ * deopping everyone by TS-1 SJOIN).
+ * -- jilles */
+ if (ConfigChannel.kick_on_split_riding &&
+ !HasSentEob(source_p) &&
+ ((mode.mode & MODE_INVITEONLY) ||
+ (mode.key[0] != 0 && irccmp(mode.key, oldmode->key) != 0)))
+ {
+ struct membership *msptr;
+ struct Client *who;
+ int l = dlink_list_length(&chptr->members);
+ int b = dlink_list_length(&chptr->banlist) +
+ dlink_list_length(&chptr->exceptlist) +
+ dlink_list_length(&chptr->invexlist) +
+ dlink_list_length(&chptr->quietlist);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
+ {
+ msptr = ptr->data;
+ who = msptr->client_p;
+ sendto_one(who, ":%s KICK %s %s :Net Rider",
+ me.name, chptr->chname, who->name);
+
+ sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
+ ":%s KICK %s %s :Net Rider",
+ me.id, chptr->chname,
+ who->id);
+ sendto_server(NULL, chptr, NOCAPS, CAP_TS6,
+ ":%s KICK %s %s :Net Rider",
+ me.name, chptr->chname, who->name);
+ remove_user_from_channel(msptr);
+ if (--l == 0)
+ break;
+ }
+ if (l == 0)
+ {
+ /* Channel was emptied, create a new one */
+ if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
+ return 0; /* oops! */
+
+ /* If the source does not do TS6,
+ * nontimestamped bans have been sent to it,
+ * but we have just lost those here. Let's
+ * warn the channel about this. Because
+ * of the kicks, any users on the channel
+ * will be at client_p. -- jilles */
+ if (!has_id(source_p) && b > 0)
+ sendto_one(client_p, ":%s NOTICE %s :*** Notice -- possible ban desync on %s, please remove any bans just added by servers", get_id(&me, client_p), parv[2], parv[2]);
+ oldmode = &chptr->mode;
+ }
+ }
+ keep_our_modes = NO;
+ chptr->channelts = newts;
+ }
+ else
+ keep_new_modes = NO;
+
+ if(!keep_new_modes)
+ mode = *oldmode;
+ else if(keep_our_modes)
+ {
+ mode.mode |= oldmode->mode;
+ if(oldmode->limit > mode.limit)
+ mode.limit = oldmode->limit;
+ if(strcmp(mode.key, oldmode->key) < 0)
+ strcpy(mode.key, oldmode->key);
+ if(oldmode->join_num > mode.join_num ||
+ (oldmode->join_num == mode.join_num &&
+ oldmode->join_time > mode.join_time))
+ {
+ mode.join_num = oldmode->join_num;
+ mode.join_time = oldmode->join_time;
+ }
+ if(irccmp(mode.forward, oldmode->forward) < 0)
+ strcpy(mode.forward, oldmode->forward);
+ }
+ else
+ {
+ /* If setting -j, clear join throttle state -- jilles */
+ if (!mode.join_num)
+ chptr->join_count = chptr->join_delta = 0;
+ }
+
+ set_final_mode(&mode, oldmode);
+ chptr->mode = mode;
+
+ /* Lost the TS, other side wins, so remove modes on this side */
+ if(!keep_our_modes)
+ {
+ remove_our_modes(chptr, fakesource_p);
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
+ {
+ del_invite(chptr, ptr->data);
+ }
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
+ me.name, chptr->chname, chptr->chname,
+ (long) oldts, (long) newts);
+ }
+
+ if(*modebuf != '\0')
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
+ fakesource_p->name, chptr->chname, modebuf, parabuf);
+
+ *modebuf = *parabuf = '\0';
+
+ if(parv[3][0] != '0' && keep_new_modes)
+ modes = channel_modes(chptr, source_p);
+ else
+ modes = empty_modes;
+
+ mlen_nick = ircsprintf(buf_nick, ":%s SJOIN %ld %s %s :",
+ source_p->name, (long) chptr->channelts, parv[2], modes);
+ ptr_nick = buf_nick + mlen_nick;
+
+ /* working on the presumption eventually itll be more efficient to
+ * build a TS6 buffer without checking its needed..
+ */
+ mlen_uid = ircsprintf(buf_uid, ":%s SJOIN %ld %s %s :",
+ use_id(source_p), (long) chptr->channelts, parv[2], modes);
+ ptr_uid = buf_uid + mlen_uid;
+
+ mbuf = modebuf;
+ para[0] = para[1] = para[2] = para[3] = empty;
+ pargs = 0;
+ len_nick = len_uid = 0;
+
+ /* if theres a space, theres going to be more than one nick, change the
+ * first space to \0, so s is just the first nick, and point p to the
+ * second nick
+ */
+ if((p = strchr(s, ' ')) != NULL)
+ {
+ *p++ = '\0';
+ }
+
+ *mbuf++ = '+';
+
+ while (s)
+ {
+ fl = 0;
+
+ for (i = 0; i < 2; i++)
+ {
+ if(*s == '@')
+ {
+ fl |= CHFL_CHANOP;
+ s++;
+ }
+ else if(*s == '+')
+ {
+ fl |= CHFL_VOICE;
+ s++;
+ }
+ }
+
+ /* if the client doesnt exist or is fake direction, skip. */
+ if(!(target_p = find_client(s)) ||
+ (target_p->from != client_p) || !IsPerson(target_p))
+ goto nextnick;
+
+ /* we assume for these we can fit at least one nick/uid in.. */
+
+ /* check we can fit another status+nick+space into a buffer */
+ if((mlen_nick + len_nick + NICKLEN + 3) > (BUFSIZE - 3))
+ {
+ *(ptr_nick - 1) = '\0';
+ sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick);
+ ptr_nick = buf_nick + mlen_nick;
+ len_nick = 0;
+ }
+
+ if((mlen_uid + len_uid + IDLEN + 3) > (BUFSIZE - 3))
+ {
+ *(ptr_uid - 1) = '\0';
+ sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid);
+ ptr_uid = buf_uid + mlen_uid;
+ len_uid = 0;
+ }
+
+ if(keep_new_modes)
+ {
+ if(fl & CHFL_CHANOP)
+ {
+ *ptr_nick++ = '@';
+ *ptr_uid++ = '@';
+ len_nick++;
+ len_uid++;
+ }
+ if(fl & CHFL_VOICE)
+ {
+ *ptr_nick++ = '+';
+ *ptr_uid++ = '+';
+ len_nick++;
+ len_uid++;
+ }
+ }
+
+ /* copy the nick to the two buffers */
+ len = ircsprintf(ptr_nick, "%s ", target_p->name);
+ ptr_nick += len;
+ len_nick += len;
+ len = ircsprintf(ptr_uid, "%s ", use_id(target_p));
+ ptr_uid += len;
+ len_uid += len;
+
+ if(!keep_new_modes)
+ {
+ if(fl & CHFL_CHANOP)
+ fl = CHFL_DEOPPED;
+ else
+ fl = 0;
+ }
+
+ if(!IsMember(target_p, chptr))
+ {
+ add_user_to_channel(chptr, target_p, fl);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ target_p->name,
+ target_p->username, target_p->host, parv[2]);
+ joins++;
+ }
+
+ if(fl & CHFL_CHANOP)
+ {
+ *mbuf++ = 'o';
+ para[pargs++] = target_p->name;
+
+ /* a +ov user.. bleh */
+ if(fl & CHFL_VOICE)
+ {
+ /* its possible the +o has filled up MAXMODEPARAMS, if so, start
+ * a new buffer
+ */
+ if(pargs >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ fakesource_p->name, chptr->chname,
+ modebuf,
+ para[0], para[1], para[2], para[3]);
+ mbuf = modebuf;
+ *mbuf++ = '+';
+ para[0] = para[1] = para[2] = para[3] = NULL;
+ pargs = 0;
+ }
+
+ *mbuf++ = 'v';
+ para[pargs++] = target_p->name;
+ }
+ }
+ else if(fl & CHFL_VOICE)
+ {
+ *mbuf++ = 'v';
+ para[pargs++] = target_p->name;
+ }
+
+ if(pargs >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ fakesource_p->name,
+ chptr->chname,
+ modebuf, para[0], para[1], para[2], para[3]);
+ mbuf = modebuf;
+ *mbuf++ = '+';
+ para[0] = para[1] = para[2] = para[3] = NULL;
+ pargs = 0;
+ }
+
+ nextnick:
+ /* p points to the next nick */
+ s = p;
+
+ /* if there was a trailing space and p was pointing to it, then we
+ * need to exit.. this has the side effect of breaking double spaces
+ * in an sjoin.. but that shouldnt happen anyway
+ */
+ if(s && (*s == '\0'))
+ s = p = NULL;
+
+ /* if p was NULL due to no spaces, s wont exist due to the above, so
+ * we cant check it for spaces.. if there are no spaces, then when
+ * we next get here, s will be NULL
+ */
+ if(s && ((p = strchr(s, ' ')) != NULL))
+ {
+ *p++ = '\0';
+ }
+ }
+
+ *mbuf = '\0';
+ if(pargs)
+ {
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ fakesource_p->name, chptr->chname, modebuf,
+ para[0], CheckEmpty(para[1]),
+ CheckEmpty(para[2]), CheckEmpty(para[3]));
+ }
+
+ if(!joins && !(chptr->mode.mode & MODE_PERMANENT))
+ {
+ if(isnew)
+ destroy_channel(chptr);
+
+ return 0;
+ }
+
+ /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
+ if (joins)
+ {
+ *(ptr_nick - 1) = '\0';
+ *(ptr_uid - 1) = '\0';
+ }
+
+ sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid);
+ sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick);
+
+ /* if the source does TS6 we have to remove our bans. Its now safe
+ * to issue -b's to the non-ts6 servers, as the sjoin we've just
+ * sent will kill any ops they have.
+ */
+ if(!keep_our_modes && source_p->id[0] != '\0')
+ {
+ if(dlink_list_length(&chptr->banlist) > 0)
+ remove_ban_list(chptr, fakesource_p, &chptr->banlist, 'b', NOCAPS, ALL_MEMBERS);
+
+ if(dlink_list_length(&chptr->exceptlist) > 0)
+ remove_ban_list(chptr, fakesource_p, &chptr->exceptlist,
+ 'e', CAP_EX, ONLY_CHANOPS);
+
+ if(dlink_list_length(&chptr->invexlist) > 0)
+ remove_ban_list(chptr, fakesource_p, &chptr->invexlist,
+ 'I', CAP_IE, ONLY_CHANOPS);
+
+ if(dlink_list_length(&chptr->quietlist) > 0)
+ remove_ban_list(chptr, fakesource_p, &chptr->quietlist,
+ 'q', NOCAPS, ALL_MEMBERS);
+
+ chptr->bants++;
+ }
+
+ return 0;
+}
+
+struct mode_letter
+{
+ int mode;
+ char letter;
+};
+
+static struct mode_letter flags[] = {
+ {MODE_NOPRIVMSGS, 'n'},
+ {MODE_TOPICLIMIT, 't'},
+ {MODE_SECRET, 's'},
+ {MODE_MODERATED, 'm'},
+ {MODE_INVITEONLY, 'i'},
+ {MODE_PRIVATE, 'p'},
+ {MODE_REGONLY, 'r'},
+ {MODE_EXLIMIT, 'L'},
+ {MODE_PERMANENT, 'P'},
+ {MODE_NOCOLOR, 'c'},
+ {MODE_FREEINVITE, 'g'},
+ {MODE_OPMODERATE, 'z'},
+ {MODE_FREETARGET, 'F'},
+ {MODE_DISFORWARD, 'Q'},
+ {0, 0}
+};
+
+static void
+set_final_mode(struct Mode *mode, struct Mode *oldmode)
+{
+ int dir = MODE_QUERY;
+ char *pbuf = parabuf;
+ int len;
+ int i;
+
+ /* ok, first get a list of modes we need to add */
+ for (i = 0; flags[i].letter; i++)
+ {
+ if((mode->mode & flags[i].mode) && !(oldmode->mode & flags[i].mode))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = flags[i].letter;
+ }
+ }
+
+ /* now the ones we need to remove. */
+ for (i = 0; flags[i].letter; i++)
+ {
+ if((oldmode->mode & flags[i].mode) && !(mode->mode & flags[i].mode))
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = flags[i].letter;
+ }
+ }
+
+ if(oldmode->limit && !mode->limit)
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'l';
+ }
+ if(oldmode->key[0] && !mode->key[0])
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'k';
+ len = ircsprintf(pbuf, "%s ", oldmode->key);
+ pbuf += len;
+ pargs++;
+ }
+ if(oldmode->join_num && !mode->join_num)
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'j';
+ }
+ if(oldmode->forward[0] && !mode->forward[0])
+ {
+ if(dir != MODE_DEL)
+ {
+ *mbuf++ = '-';
+ dir = MODE_DEL;
+ }
+ *mbuf++ = 'f';
+ }
+ if(mode->limit && oldmode->limit != mode->limit)
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'l';
+ len = ircsprintf(pbuf, "%d ", mode->limit);
+ pbuf += len;
+ pargs++;
+ }
+ if(mode->key[0] && strcmp(oldmode->key, mode->key))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'k';
+ len = ircsprintf(pbuf, "%s ", mode->key);
+ pbuf += len;
+ pargs++;
+ }
+ if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time))
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'j';
+ len = ircsprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
+ pbuf += len;
+ pargs++;
+ }
+ if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
+ {
+ if(dir != MODE_ADD)
+ {
+ *mbuf++ = '+';
+ dir = MODE_ADD;
+ }
+ *mbuf++ = 'f';
+ len = ircsprintf(pbuf, "%s ", mode->forward);
+ pbuf += len;
+ pargs++;
+ }
+ *mbuf = '\0';
+}
+
+/*
+ * remove_our_modes
+ *
+ * inputs -
+ * output -
+ * side effects -
+ */
+static void
+remove_our_modes(struct Channel *chptr, struct Client *source_p)
+{
+ struct membership *msptr;
+ dlink_node *ptr;
+ char lmodebuf[MODEBUFLEN];
+ char *lpara[MAXMODEPARAMS];
+ int count = 0;
+ int i;
+
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+
+ for (i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+
+ if(is_chanop(msptr))
+ {
+ msptr->flags &= ~CHFL_CHANOP;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'o';
+
+ /* +ov, might not fit so check. */
+ if(is_voiced(msptr))
+ {
+ if(count >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname,
+ lmodebuf, lpara[0], lpara[1],
+ lpara[2], lpara[3]);
+
+ /* preserve the initial '-' */
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+ count = 0;
+
+ for (i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+ }
+
+ msptr->flags &= ~CHFL_VOICE;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'v';
+ }
+ }
+ else if(is_voiced(msptr))
+ {
+ msptr->flags &= ~CHFL_VOICE;
+ lpara[count++] = msptr->client_p->name;
+ *mbuf++ = 'v';
+ }
+ else
+ continue;
+
+ if(count >= MAXMODEPARAMS)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname, lmodebuf,
+ lpara[0], lpara[1], lpara[2], lpara[3]);
+ mbuf = lmodebuf;
+ *mbuf++ = '-';
+ count = 0;
+
+ for (i = 0; i < MAXMODEPARAMS; i++)
+ lpara[i] = NULL;
+ }
+ }
+
+ if(count != 0)
+ {
+ *mbuf = '\0';
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s MODE %s %s %s %s %s %s",
+ me.name, chptr->chname, lmodebuf,
+ EmptyString(lpara[0]) ? "" : lpara[0],
+ EmptyString(lpara[1]) ? "" : lpara[1],
+ EmptyString(lpara[2]) ? "" : lpara[2],
+ EmptyString(lpara[3]) ? "" : lpara[3]);
+
+ }
+}
+
+/* remove_ban_list()
+ *
+ * inputs - channel, source, list to remove, char of mode, caps needed
+ * outputs -
+ * side effects - given list is removed, with modes issued to local clients
+ * and non-TS6 servers.
+ */
+static void
+remove_ban_list(struct Channel *chptr, struct Client *source_p,
+ dlink_list * list, char c, int cap, int mems)
+{
+ static char lmodebuf[BUFSIZE];
+ static char lparabuf[BUFSIZE];
+ struct Ban *banptr;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ char *pbuf;
+ int count = 0;
+ int cur_len, mlen, plen;
+
+ pbuf = lparabuf;
+
+ cur_len = mlen = ircsprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname);
+ mbuf = lmodebuf + mlen;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
+ {
+ banptr = ptr->data;
+
+ /* trailing space, and the mode letter itself */
+ plen = strlen(banptr->banstr) + 2;
+
+ if(count >= MAXMODEPARAMS || (cur_len + plen) > BUFSIZE - 4)
+ {
+ /* remove trailing space */
+ *mbuf = '\0';
+ *(pbuf - 1) = '\0';
+
+ sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf);
+ /* Tricky tricky. If we changed source_p to &me
+ * in ms_sjoin(), this still won't send stuff
+ * where it should not be sent, because the
+ * real source_p does TS6 -- jilles */
+ sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf);
+
+ cur_len = mlen;
+ mbuf = lmodebuf + mlen;
+ pbuf = lparabuf;
+ count = 0;
+ }
+
+ *mbuf++ = c;
+ cur_len += plen;
+ pbuf += ircsprintf(pbuf, "%s ", banptr->banstr);
+ count++;
+
+ free_ban(banptr);
+ }
+
+ *mbuf = '\0';
+ *(pbuf - 1) = '\0';
+ sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf);
+ sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf);
+
+ list->head = list->tail = NULL;
+ list->length = 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_squit.c: Makes a server quit.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_squit.c 698 2006-02-04 18:26:55Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h" /* FALSE bleah */
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "hash.h"
+#include "s_newconf.h"
+
+static int ms_squit(struct Client *, struct Client *, int, const char **);
+static int mo_squit(struct Client *, struct Client *, int, const char **);
+
+struct Message squit_msgtab = {
+ "SQUIT", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_squit, 0}, {ms_squit, 0}, mg_ignore, {mo_squit, 2}}
+};
+
+mapi_clist_av1 squit_clist[] = { &squit_msgtab, NULL };
+
+DECLARE_MODULE_AV1(squit, NULL, NULL, squit_clist, NULL, NULL, "$Revision: 698 $");
+
+struct squit_parms
+{
+ const char *server_name;
+ struct Client *target_p;
+};
+
+static struct squit_parms *find_squit(struct Client *client_p,
+ struct Client *source_p, const char *server);
+
+
+/*
+ * mo_squit - SQUIT message handler
+ * parv[0] = sender prefix
+ * parv[1] = server name
+ * parv[2] = comment
+ */
+static int
+mo_squit(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct squit_parms *found_squit;
+ const char *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name;
+
+ if((found_squit = find_squit(client_p, source_p, parv[1])))
+ {
+ if(MyConnect(found_squit->target_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Received SQUIT %s from %s (%s)",
+ found_squit->target_p->name,
+ get_client_name(source_p, HIDE_IP), comment);
+ ilog(L_SERVER, "Received SQUIT %s from %s (%s)",
+ found_squit->target_p->name, log_client_name(source_p, HIDE_IP),
+ comment);
+ }
+ else if(!IsOperRemote(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remote");
+ return 0;
+ }
+
+ exit_client(client_p, found_squit->target_p, source_p, comment);
+ return 0;
+ }
+ else
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER, form_str(ERR_NOSUCHSERVER), parv[1]);
+ }
+
+ return 0;
+}
+
+/*
+ * ms_squit - SQUIT message handler
+ * parv[0] = sender prefix
+ * parv[1] = server name
+ * parv[2] = comment
+ */
+static int
+ms_squit(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name;
+
+ if(parc < 2)
+ target_p = client_p;
+ else
+ {
+ if((target_p = find_server(NULL, parv[1])) == NULL)
+ return 0;
+
+ if(IsMe(target_p))
+ target_p = client_p;
+ if(!IsServer(target_p))
+ return 0;
+ }
+
+ /* Server is closing its link */
+ if (target_p == client_p)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Server %s closing link (%s)",
+ target_p->name, comment);
+ }
+ /*
+ ** Notify all opers, if my local link is remotely squitted
+ */
+ else if(MyConnect(target_p))
+ {
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "Remote SQUIT %s from %s (%s)",
+ target_p->name, source_p->name, comment);
+
+ sendto_server(NULL, NULL, CAP_TS6, NOCAPS,
+ ":%s WALLOPS :Remote SQUIT %s from %s (%s)",
+ me.id, target_p->name, source_p->name, comment);
+
+ sendto_server(NULL, NULL, NOCAPS, CAP_TS6,
+ ":%s WALLOPS :Remote SQUIT %s from %s (%s)",
+ me.name, target_p->name, source_p->name, comment);
+
+ ilog(L_SERVER, "SQUIT From %s : %s (%s)", parv[0], target_p->name, comment);
+
+ }
+ exit_client(client_p, target_p, source_p, comment);
+ return 0;
+}
+
+
+/*
+ * find_squit
+ * inputs - local server connection
+ * -
+ * -
+ * output - pointer to struct containing found squit or none if not found
+ * side effects -
+ */
+static struct squit_parms *
+find_squit(struct Client *client_p, struct Client *source_p, const char *server)
+{
+ static struct squit_parms found_squit;
+ struct Client *target_p = NULL;
+ struct Client *p;
+ dlink_node *ptr;
+
+ /* must ALWAYS be reset */
+ found_squit.target_p = NULL;
+ found_squit.server_name = NULL;
+
+
+ /*
+ ** The following allows wild cards in SQUIT. Only useful
+ ** when the command is issued by an oper.
+ */
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ p = ptr->data;
+ if(IsServer(p) || IsMe(p))
+ {
+ if(match(server, p->name))
+ {
+ target_p = p;
+ break;
+ }
+ }
+ }
+
+ if(target_p == NULL)
+ return NULL;
+
+ found_squit.target_p = target_p;
+ found_squit.server_name = server;
+
+ if(IsMe(target_p))
+ {
+ if(IsClient(client_p))
+ {
+ if(MyClient(client_p))
+ sendto_one(source_p, ":%s NOTICE %s :You are trying to squit me.",
+ me.name, client_p->name);
+ return NULL;
+ }
+ else
+ {
+ found_squit.target_p = client_p;
+ found_squit.server_name = client_p->name;
+ }
+ }
+
+ if(found_squit.target_p != NULL)
+ return &found_squit;
+ else
+ return (NULL);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_accept.c: Allows a user to talk to a +g user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_accept.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "hash.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "sprintf_irc.h"
+#include "modules.h"
+
+static int m_accept(struct Client *, struct Client *, int, const char **);
+static void build_nicklist(struct Client *, char *, char *, const char *);
+
+static void add_accept(struct Client *, struct Client *);
+static void list_accepts(struct Client *);
+
+struct Message accept_msgtab = {
+ "ACCEPT", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {mg_unreg, {m_accept, 2}, mg_ignore, mg_ignore, mg_ignore, {m_accept, 2}}
+};
+
+mapi_clist_av1 accept_clist[] = {
+ &accept_msgtab, NULL
+};
+DECLARE_MODULE_AV1(accept, NULL, NULL, accept_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_accept - ACCEPT command handler
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+m_accept(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char *nick;
+ char *p = NULL;
+ static char addbuf[BUFSIZE];
+ static char delbuf[BUFSIZE];
+ struct Client *target_p;
+ int accept_num;
+
+ if(*parv[1] == '*')
+ {
+ list_accepts(source_p);
+ return 0;
+ }
+
+ build_nicklist(source_p, addbuf, delbuf, parv[1]);
+
+ /* parse the delete list */
+ for (nick = strtoken(&p, delbuf, ","); nick != NULL; nick = strtoken(&p, NULL, ","))
+ {
+ /* shouldnt happen, but lets be paranoid */
+ if((target_p = find_named_person(nick)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+ continue;
+ }
+
+ /* user isnt on clients accept list */
+ if(!accept_message(target_p, source_p))
+ {
+ sendto_one(source_p, form_str(ERR_ACCEPTNOT),
+ me.name, source_p->name, target_p->name);
+ continue;
+ }
+
+ dlinkFindDestroy(target_p, &source_p->localClient->allow_list);
+ dlinkFindDestroy(source_p, &target_p->on_allow_list);
+ }
+
+ /* get the number of accepts they have */
+ accept_num = dlink_list_length(&source_p->localClient->allow_list);
+
+ /* parse the add list */
+ for (nick = strtoken(&p, addbuf, ","); nick; nick = strtoken(&p, NULL, ","))
+ {
+ /* shouldnt happen, but lets be paranoid */
+ if((target_p = find_named_person(nick)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), nick);
+ continue;
+ }
+
+ /* user is already on clients accept list */
+ if(accept_message(target_p, source_p))
+ {
+ sendto_one(source_p, form_str(ERR_ACCEPTEXIST),
+ me.name, source_p->name, target_p->name);
+ continue;
+ }
+
+ if(accept_num >= ConfigFileEntry.max_accept)
+ {
+ sendto_one(source_p, form_str(ERR_ACCEPTFULL), me.name, source_p->name);
+ return 0;
+ }
+
+ /* why is this here? */
+ /* del_from accept(target_p, source_p); */
+ add_accept(source_p, target_p);
+ accept_num++;
+ }
+
+ return 0;
+}
+
+/*
+ * build_nicklist()
+ *
+ * input - pointer to client
+ * - pointer to addbuffer
+ * - pointer to remove buffer
+ * - pointer to list of nicks
+ * output -
+ * side effects - addbuf/delbuf are modified to give valid nicks
+ */
+static void
+build_nicklist(struct Client *source_p, char *addbuf, char *delbuf, const char *nicks)
+{
+ char *name;
+ char *p;
+ int lenadd;
+ int lendel;
+ int del;
+ struct Client *target_p;
+ char *n = LOCAL_COPY(nicks);
+
+ *addbuf = *delbuf = '\0';
+ del = lenadd = lendel = 0;
+
+ /* build list of clients to add into addbuf, clients to remove in delbuf */
+ for (name = strtoken(&p, n, ","); name; name = strtoken(&p, NULL, ","), del = 0)
+ {
+ if(*name == '-')
+ {
+ del = 1;
+ name++;
+ }
+
+ if((target_p = find_named_person(name)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), name);
+ continue;
+ }
+
+ /* we're deleting a client */
+ if(del)
+ {
+ if(*delbuf)
+ (void) strcat(delbuf, ",");
+
+ (void) strncat(delbuf, name, BUFSIZE - lendel - 1);
+ lendel += strlen(name) + 1;
+ }
+ /* adding a client */
+ else
+ {
+ if(*addbuf)
+ (void) strcat(addbuf, ",");
+
+ (void) strncat(addbuf, name, BUFSIZE - lenadd - 1);
+ lenadd += strlen(name) + 1;
+ }
+ }
+}
+
+/*
+ * add_accept()
+ *
+ * input - pointer to clients accept list to add to
+ * - pointer to client to add
+ * output - none
+ * side effects - target is added to clients list
+ */
+static void
+add_accept(struct Client *source_p, struct Client *target_p)
+{
+ dlinkAddAlloc(target_p, &source_p->localClient->allow_list);
+ dlinkAddAlloc(source_p, &target_p->on_allow_list);
+}
+
+
+/*
+ * list_accepts()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - print accept list to client
+ */
+static void
+list_accepts(struct Client *source_p)
+{
+ dlink_node *ptr;
+ struct Client *target_p;
+ char nicks[BUFSIZE];
+ int len = 0;
+ int len2 = 0;
+ int count = 0;
+
+ *nicks = '\0';
+ len2 = strlen(source_p->name) + 10;
+
+ DLINK_FOREACH(ptr, source_p->localClient->allow_list.head)
+ {
+ target_p = ptr->data;
+
+ if(target_p)
+ {
+
+ if((len + strlen(target_p->name) + len2 > BUFSIZE) || count > 14)
+ {
+ sendto_one(source_p, form_str(RPL_ACCEPTLIST),
+ me.name, source_p->name, nicks);
+
+ len = count = 0;
+ *nicks = '\0';
+ }
+
+ len += ircsnprintf(nicks + len, sizeof(nicks) - len, "%s ", target_p->name);
+ count++;
+ }
+ }
+
+ if(*nicks)
+ sendto_one(source_p, form_str(RPL_ACCEPTLIST),
+ me.name, source_p->name, nicks);
+
+ sendto_one(source_p, form_str(RPL_ENDOFACCEPT),
+ me.name, source_p->name);
+
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_admin.c: Sends administrative information to a user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_admin.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "hook.h"
+#include "modules.h"
+
+static int m_admin(struct Client *, struct Client *, int, const char **);
+static int mr_admin(struct Client *, struct Client *, int, const char **);
+static int ms_admin(struct Client *, struct Client *, int, const char **);
+static void do_admin(struct Client *source_p);
+
+static void admin_spy(struct Client *);
+
+struct Message admin_msgtab = {
+ "ADMIN", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_admin, 0}, {m_admin, 0}, {ms_admin, 0}, mg_ignore, mg_ignore, {ms_admin, 0}}
+};
+
+int doing_admin_hook;
+
+mapi_clist_av1 admin_clist[] = { &admin_msgtab, NULL };
+mapi_hlist_av1 admin_hlist[] = {
+ { "doing_admin", &doing_admin_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(admin, NULL, NULL, admin_clist, admin_hlist, NULL, "$Revision: 254 $");
+
+/*
+ * mr_admin - ADMIN command handler
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+mr_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name,
+ EmptyString(source_p->name) ? "*" : source_p->name,
+ "ADMIN");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ do_admin(source_p);
+
+ return 0;
+}
+
+/*
+ * m_admin - ADMIN command handler
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+m_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ if(parc > 1)
+ {
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "ADMIN");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ if(hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+ }
+
+ do_admin(source_p);
+
+ return 0;
+}
+
+
+/*
+ * ms_admin - ADMIN command handler, used for OPERS as well
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+ms_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ do_admin(source_p);
+
+ return 0;
+}
+
+
+/*
+ * do_admin
+ *
+ * inputs - pointer to client to report to
+ * output - none
+ * side effects - admin info is sent to client given
+ */
+static void
+do_admin(struct Client *source_p)
+{
+ const char *myname;
+ const char *nick;
+
+ if(IsPerson(source_p))
+ admin_spy(source_p);
+
+ myname = get_id(&me, source_p);
+ nick = EmptyString(source_p->name) ? "*" : get_id(source_p, source_p);
+
+ sendto_one(source_p, form_str(RPL_ADMINME), myname, nick, me.name);
+ if(AdminInfo.name != NULL)
+ sendto_one(source_p, form_str(RPL_ADMINLOC1), myname, nick, AdminInfo.name);
+ if(AdminInfo.description != NULL)
+ sendto_one(source_p, form_str(RPL_ADMINLOC2), myname, nick, AdminInfo.description);
+ if(AdminInfo.email != NULL)
+ sendto_one(source_p, form_str(RPL_ADMINEMAIL), myname, nick, AdminInfo.email);
+}
+
+/* admin_spy()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - event doing_admin is called
+ */
+static void
+admin_spy(struct Client *source_p)
+{
+ hook_data hd;
+
+ hd.client = source_p;
+ hd.arg1 = hd.arg2 = NULL;
+
+ call_hook(doing_admin_hook, &hd);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_away.c: Sets/removes away status on a user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_away.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "packet.h"
+
+
+static int m_away(struct Client *, struct Client *, int, const char **);
+
+struct Message away_msgtab = {
+ "AWAY", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_away, 0}, {m_away, 0}, mg_ignore, mg_ignore, {m_away, 0}}
+};
+
+mapi_clist_av1 away_clist[] = { &away_msgtab, NULL };
+DECLARE_MODULE_AV1(away, NULL, NULL, away_clist, NULL, NULL, "$Revision: 254 $");
+
+/***********************************************************************
+ * m_away() - Added 14 Dec 1988 by jto.
+ * Not currently really working, I don't like this
+ * call at all...
+ *
+ * ...trying to make it work. I don't like it either,
+ * but perhaps it's worth the load it causes to net.
+ * This requires flooding of the whole net like NICK,
+ * USER, MODE, etc messages... --msa
+ *
+ * The above comments have long since irrelvant, but
+ * are kept for historical purposes now ;)
+ ***********************************************************************/
+
+/*
+** m_away
+** parv[0] = sender prefix
+** parv[1] = away message
+*/
+static int
+m_away(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char *away;
+ char *awy2;
+
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ if(!IsClient(source_p))
+ return 0;
+
+ away = source_p->user->away;
+
+ if(parc < 2 || EmptyString(parv[1]))
+ {
+ /* Marking as not away */
+ if(away)
+ {
+ /* we now send this only if they were away before --is */
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+ ":%s AWAY", use_id(source_p));
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ ":%s AWAY", source_p->name);
+ MyFree(away);
+ source_p->user->away = NULL;
+ }
+ if(MyConnect(source_p))
+ sendto_one(source_p, form_str(RPL_UNAWAY),
+ me.name, source_p->name);
+ return 0;
+ }
+
+ /* Marking as away */
+
+ if(MyConnect(source_p))
+ {
+ if(!IsOper(source_p) &&
+ (CurrentTime - source_p->localClient->last_away) < ConfigFileEntry.pace_wait)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "AWAY");
+ return 0;
+ }
+
+ source_p->localClient->last_away = CurrentTime;
+ }
+
+ awy2 = LOCAL_COPY(parv[1]);
+ if(strlen(awy2) > AWAYLEN)
+ awy2[AWAYLEN] = '\0';
+
+ /* we now send this only if they weren't away already --is */
+ if(!away)
+ {
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+ ":%s AWAY :%s", use_id(source_p), awy2);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ ":%s AWAY :%s", source_p->name, awy2);
+ }
+ else
+ MyFree(away);
+
+ DupString(away, awy2);
+
+ source_p->user->away = away;
+
+ if(MyConnect(source_p))
+ sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, source_p->name);
+
+ return 0;
+}
--- /dev/null
+/* modules/m_cap.c
+ *
+ * Copyright (C) 2005 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_cap.c 676 2006-02-03 20:05:09Z gxti $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "class.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+#include "s_user.h"
+
+typedef int (*bqcmp)(const void *, const void *);
+
+static int m_cap(struct Client *, struct Client *, int, const char **);
+static int modinit(void);
+
+struct Message cap_msgtab = {
+ "CAP", 0, 0, 0, MFLG_SLOW,
+ {{m_cap, 2}, {m_cap, 2}, mg_ignore, mg_ignore, mg_ignore, {m_cap, 2}}
+};
+
+mapi_clist_av1 cap_clist[] = { &cap_msgtab, NULL };
+DECLARE_MODULE_AV1(cap, modinit, NULL, cap_clist, NULL, NULL, "$Revision: 676 $");
+
+#define _CLICAP(name, capserv, capclient, flags) \
+ { (name), (capserv), (capclient), (flags), sizeof(name) - 1 }
+
+#define CLICAP_FLAGS_STICKY 0x001
+
+static struct clicap
+{
+ const char *name;
+ int cap_serv; /* for altering s->c */
+ int cap_cli; /* for altering c->s */
+ int flags;
+ int namelen;
+} clicap_list[] = {
+ _CLICAP("multi-prefix", CLICAP_MULTI_PREFIX, 0, 0),
+ _CLICAP("sasl", CLICAP_SASL, 0, 0)
+};
+
+#define CLICAP_LIST_LEN (sizeof(clicap_list) / sizeof(struct clicap))
+
+static int clicap_sort(struct clicap *, struct clicap *);
+
+static int
+modinit(void)
+{
+ qsort(clicap_list, CLICAP_LIST_LEN, sizeof(struct clicap),
+ (bqcmp) clicap_sort);
+ return 0;
+}
+
+static int
+clicap_sort(struct clicap *one, struct clicap *two)
+{
+ return irccmp(one->name, two->name);
+}
+
+static int
+clicap_compare(const char *name, struct clicap *cap)
+{
+ return irccmp(name, cap->name);
+}
+
+/* clicap_find()
+ * Used iteratively over a buffer, extracts individual cap tokens.
+ *
+ * Inputs: buffer to start iterating over (NULL to iterate over existing buf)
+ * int pointer to whether the cap token is negated
+ * int pointer to whether we finish with success
+ * Ouputs: Cap entry if found, NULL otherwise.
+ */
+static struct clicap *
+clicap_find(const char *data, int *negate, int *finished)
+{
+ static char buf[BUFSIZE];
+ static char *p;
+ struct clicap *cap;
+ char *s;
+
+ *negate = 0;
+
+ if(data)
+ {
+ strlcpy(buf, data, sizeof(buf));
+ p = buf;
+ }
+
+ if(*finished)
+ return NULL;
+
+ /* skip any whitespace */
+ while(*p && IsSpace(*p))
+ p++;
+
+ if(EmptyString(p))
+ {
+ *finished = 1;
+ return NULL;
+ }
+
+ if(*p == '-')
+ {
+ *negate = 1;
+ p++;
+
+ /* someone sent a '-' without a parameter.. */
+ if(*p == '\0')
+ return NULL;
+ }
+
+ if((s = strchr(p, ' ')))
+ *s++ = '\0';
+
+ if((cap = bsearch(p, clicap_list, CLICAP_LIST_LEN,
+ sizeof(struct clicap), (bqcmp) clicap_compare)))
+ {
+ if(s)
+ p = s;
+ else
+ *finished = 1;
+ }
+
+ return cap;
+}
+
+/* clicap_generate()
+ * Generates a list of capabilities.
+ *
+ * Inputs: client to send to, subcmd to send,
+ * flags to match against: 0 to do none, -1 if client has no flags,
+ * int to whether we are doing CAP CLEAR
+ * Outputs: None
+ */
+static void
+clicap_generate(struct Client *source_p, const char *subcmd, int flags, int clear)
+{
+ char buf[BUFSIZE];
+ char capbuf[BUFSIZE];
+ char *p;
+ int buflen = 0;
+ int curlen, mlen;
+ int i;
+
+ mlen = ircsprintf(buf, ":%s CAP %s %s",
+ me.name,
+ EmptyString(source_p->name) ? "*" : source_p->name,
+ subcmd);
+
+ p = capbuf;
+ buflen = mlen;
+
+ /* shortcut, nothing to do */
+ if(flags == -1)
+ {
+ sendto_one(source_p, "%s :", buf);
+ return;
+ }
+
+ for(i = 0; i < CLICAP_LIST_LEN; i++)
+ {
+ if(flags)
+ {
+ if(!IsCapable(source_p, clicap_list[i].cap_serv))
+ continue;
+ /* they are capable of this, check sticky */
+ else if(clear && clicap_list[i].flags & CLICAP_FLAGS_STICKY)
+ continue;
+ }
+
+ /* \r\n\0, possible "-~=", space, " *" */
+ if(buflen + clicap_list[i].namelen >= BUFSIZE - 10)
+ {
+ /* remove our trailing space -- if buflen == mlen
+ * here, we didnt even succeed in adding one.
+ */
+ if(buflen != mlen)
+ *(p - 1) = '\0';
+ else
+ *p = '\0';
+
+ sendto_one(source_p, "%s * :%s", buf, capbuf);
+ p = capbuf;
+ buflen = mlen;
+ }
+
+ if(clear)
+ {
+ *p++ = '-';
+ buflen++;
+
+ /* needs a client ack */
+ if(clicap_list[i].cap_cli &&
+ IsCapable(source_p, clicap_list[i].cap_cli))
+ {
+ *p++ = '~';
+ buflen++;
+ }
+ }
+ else
+ {
+ if(clicap_list[i].flags & CLICAP_FLAGS_STICKY)
+ {
+ *p++ = '=';
+ buflen++;
+ }
+
+ /* if we're doing an LS, then we only send this if
+ * they havent ack'd
+ */
+ if(clicap_list[i].cap_cli &&
+ (!flags || !IsCapable(source_p, clicap_list[i].cap_cli)))
+ {
+ *p++ = '~';
+ buflen++;
+ }
+ }
+
+ curlen = ircsprintf(p, "%s ", clicap_list[i].name);
+ p += curlen;
+ buflen += curlen;
+ }
+
+ /* remove trailing space */
+ if(buflen != mlen)
+ *(p - 1) = '\0';
+ else
+ *p = '\0';
+
+ sendto_one(source_p, "%s :%s", buf, capbuf);
+}
+
+static void
+cap_ack(struct Client *source_p, const char *arg)
+{
+ struct clicap *cap;
+ int capadd = 0, capdel = 0;
+ int finished = 0, negate;
+
+ if(EmptyString(arg))
+ return;
+
+ for(cap = clicap_find(arg, &negate, &finished); cap;
+ cap = clicap_find(NULL, &negate, &finished))
+ {
+ /* sent an ACK for something they havent REQd */
+ if(!IsCapable(source_p, cap->cap_serv))
+ continue;
+
+ if(negate)
+ {
+ /* dont let them ack something sticky off */
+ if(cap->flags & CLICAP_FLAGS_STICKY)
+ continue;
+
+ capdel |= cap->cap_cli;
+ }
+ else
+ capadd |= cap->cap_cli;
+ }
+
+ source_p->localClient->caps |= capadd;
+ source_p->localClient->caps &= ~capdel;
+}
+
+static void
+cap_clear(struct Client *source_p, const char *arg)
+{
+ clicap_generate(source_p, "ACK",
+ source_p->localClient->caps ? source_p->localClient->caps : -1, 1);
+
+ /* XXX - sticky capabs */
+#ifdef CLICAP_STICKY
+ source_p->localClient->caps = source_p->localClient->caps & CLICAP_STICKY;
+#else
+ source_p->localClient->caps = 0;
+#endif
+}
+
+static void
+cap_end(struct Client *source_p, const char *arg)
+{
+ if(IsRegistered(source_p))
+ return;
+
+ source_p->flags2 &= ~FLAGS2_CLICAP;
+
+ if(source_p->name[0] && source_p->user)
+ {
+ char buf[USERLEN+1];
+ strlcpy(buf, source_p->username, sizeof(buf));
+ register_local_user(source_p, source_p, buf);
+ }
+}
+
+static void
+cap_list(struct Client *source_p, const char *arg)
+{
+ /* list of what theyre currently using */
+ clicap_generate(source_p, "LIST",
+ source_p->localClient->caps ? source_p->localClient->caps : -1, 0);
+}
+
+static void
+cap_ls(struct Client *source_p, const char *arg)
+{
+ if(!IsRegistered(source_p))
+ source_p->flags2 |= FLAGS2_CLICAP;
+
+ /* list of what we support */
+ clicap_generate(source_p, "LS", 0, 0);
+}
+
+static void
+cap_req(struct Client *source_p, const char *arg)
+{
+ char buf[BUFSIZE];
+ char pbuf[2][BUFSIZE];
+ struct clicap *cap;
+ int buflen, plen;
+ int i = 0;
+ int capadd = 0, capdel = 0;
+ int finished = 0, negate;
+
+ if(!IsRegistered(source_p))
+ source_p->flags2 |= FLAGS2_CLICAP;
+
+ if(EmptyString(arg))
+ return;
+
+ buflen = ircsnprintf(buf, sizeof(buf), ":%s CAP %s ACK",
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name);
+
+ pbuf[0][0] = '\0';
+ plen = 0;
+
+ for(cap = clicap_find(arg, &negate, &finished); cap;
+ cap = clicap_find(NULL, &negate, &finished))
+ {
+ /* filled the first array, but cant send it in case the
+ * request fails. one REQ should never fill more than two
+ * buffers --fl
+ */
+ if(buflen + plen + cap->namelen + 6 >= BUFSIZE)
+ {
+ pbuf[1][0] = '\0';
+ plen = 0;
+ i = 1;
+ }
+
+ if(negate)
+ {
+ if(cap->flags & CLICAP_FLAGS_STICKY)
+ {
+ finished = 0;
+ break;
+ }
+
+ strcat(pbuf[i], "-");
+ plen++;
+
+ capdel |= cap->cap_serv;
+ }
+ else
+ {
+ if(cap->flags & CLICAP_FLAGS_STICKY)
+ {
+ strcat(pbuf[i], "=");
+ plen++;
+ }
+
+ capadd |= cap->cap_serv;
+ }
+
+ if(cap->cap_cli)
+ {
+ strcat(pbuf[i], "~");
+ plen++;
+ }
+
+ strcat(pbuf[i], cap->name);
+ strcat(pbuf[i], " ");
+ plen += (cap->namelen + 1);
+ }
+
+ if(!finished)
+ {
+ sendto_one(source_p, ":%s CAP %s NAK :%s",
+ me.name, EmptyString(source_p->name) ? "*" : source_p->name, arg);
+ return;
+ }
+
+ if(i)
+ {
+ sendto_one(source_p, "%s * :%s", buf, pbuf[0]);
+ sendto_one(source_p, "%s :%s", buf, pbuf[1]);
+ }
+ else
+ sendto_one(source_p, "%s :%s", buf, pbuf[0]);
+
+ source_p->localClient->caps |= capadd;
+ source_p->localClient->caps &= ~capdel;
+}
+
+static struct clicap_cmd
+{
+ const char *cmd;
+ void (*func)(struct Client *source_p, const char *arg);
+} clicap_cmdlist[] = {
+ /* This list *MUST* be in alphabetical order */
+ { "ACK", cap_ack },
+ { "CLEAR", cap_clear },
+ { "END", cap_end },
+ { "LIST", cap_list },
+ { "LS", cap_ls },
+ { "REQ", cap_req },
+};
+
+static int
+clicap_cmd_search(const char *command, struct clicap_cmd *entry)
+{
+ return irccmp(command, entry->cmd);
+}
+
+static int
+m_cap(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct clicap_cmd *cmd;
+
+ if(!(cmd = bsearch(parv[1], clicap_cmdlist,
+ sizeof(clicap_cmdlist) / sizeof(struct clicap_cmd),
+ sizeof(struct clicap_cmd), (bqcmp) clicap_cmd_search)))
+ {
+ sendto_one(source_p, form_str(ERR_INVALIDCAPCMD),
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ (cmd->func)(source_p, parv[2]);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_away.c: Negotiates capabilities with a remote server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_capab.c 1295 2006-05-08 13:05:25Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mr_capab(struct Client *, struct Client *, int, const char **);
+static int me_gcap(struct Client *, struct Client *, int, const char **);
+
+struct Message capab_msgtab = {
+ "CAPAB", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_capab, 0}, mg_ignore, mg_ignore, mg_ignore, mg_ignore, mg_ignore}
+};
+struct Message gcap_msgtab = {
+ "GCAP", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_gcap, 2}, mg_ignore}
+};
+
+mapi_clist_av1 capab_clist[] = { &capab_msgtab, &gcap_msgtab, NULL };
+DECLARE_MODULE_AV1(capab, NULL, NULL, capab_clist, NULL, NULL, "$Revision: 1295 $");
+
+/*
+ * mr_capab - CAPAB message handler
+ * parv[0] = sender prefix
+ * parv[1] = space-separated list of capabilities
+ *
+ */
+static int
+mr_capab(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Capability *cap;
+ int i;
+ char *p;
+ char *s;
+
+ /* ummm, this shouldn't happen. Could argue this should be logged etc. */
+ if(client_p->localClient == NULL)
+ return 0;
+
+ if(client_p->user)
+ return 0;
+
+ /* CAP_TS6 is set in PASS, so is valid.. */
+ if((client_p->localClient->caps & ~CAP_TS6) != 0)
+ {
+ exit_client(client_p, client_p, client_p, "CAPAB received twice");
+ return 0;
+ }
+ else
+ client_p->localClient->caps |= CAP_CAP;
+
+ MyFree(client_p->localClient->fullcaps);
+ DupString(client_p->localClient->fullcaps, parv[1]);
+
+ for (i = 1; i < parc; i++)
+ {
+ char *t = LOCAL_COPY(parv[i]);
+ for (s = strtoken(&p, t, " "); s; s = strtoken(&p, NULL, " "))
+ {
+ for (cap = captab; cap->name; cap++)
+ {
+ if(!irccmp(cap->name, s))
+ {
+ client_p->localClient->caps |= cap->cap;
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+me_gcap(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Capability *cap;
+ char *t = LOCAL_COPY(parv[1]);
+ char *s;
+ char *p;
+
+ if(!IsServer(source_p))
+ return 0;
+
+ /* already had GCAPAB?! */
+ if(!EmptyString(source_p->serv->fullcaps))
+ return 0;
+
+ DupString(source_p->serv->fullcaps, parv[1]);
+
+ for (s = strtoken(&p, t, " "); s; s = strtoken(&p, NULL, " "))
+ {
+ for (cap = captab; cap->name; cap++)
+ {
+ if(!irccmp(cap->name, s))
+ {
+ source_p->serv->caps |= cap->cap;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_challenge.c: Allows an IRC Operator to securely authenticate.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_challenge.c 1483 2006-05-27 18:58:12Z jilles $
+ */
+
+#include "stdinc.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/md5.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#endif
+
+#include "memory.h"
+#include "client.h"
+#include "ircd.h"
+#include "modules.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "irc_string.h"
+#include "s_log.h"
+#include "s_user.h"
+#include "cache.h"
+#include "s_newconf.h"
+
+#define CHALLENGE_WIDTH BUFSIZE - (NICKLEN + HOSTLEN + 12)
+#define CHALLENGE_EXPIRES 180 /* 180 seconds should be more than long enough */
+#define CHALLENGE_SECRET_LENGTH 128 /* how long our challenge secret should be */
+
+#ifndef HAVE_LIBCRYPTO
+/* Maybe this should be an error or something?-davidt */
+/* now it is -larne */
+static int challenge_load(void)
+{
+#ifndef STATIC_MODULES
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Challenge module not loaded because OpenSSL is not available.");
+ ilog(L_MAIN, "Challenge module not loaded because OpenSSL is not available.");
+ return -1;
+#else
+ return 0;
+#endif
+}
+
+DECLARE_MODULE_AV1(challenge, challenge_load, NULL, NULL, NULL, NULL, "$Revision: 1483 $");
+#else
+
+static int m_challenge(struct Client *, struct Client *, int, const char **);
+
+/* We have openssl support, so include /CHALLENGE */
+struct Message challenge_msgtab = {
+ "CHALLENGE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_challenge, 2}, mg_ignore, mg_ignore, mg_ignore, {m_challenge, 2}}
+};
+
+mapi_clist_av1 challenge_clist[] = { &challenge_msgtab, NULL };
+DECLARE_MODULE_AV1(challenge, NULL, NULL, challenge_clist, NULL, NULL, "$Revision: 1483 $");
+
+static int generate_challenge(char **r_challenge, char **r_response, RSA * key);
+
+static void
+cleanup_challenge(struct Client *target_p)
+{
+ if(target_p->localClient == NULL)
+ return;
+
+ MyFree(target_p->localClient->challenge);
+ MyFree(target_p->localClient->opername);
+ target_p->localClient->challenge = NULL;
+ target_p->localClient->opername = NULL;
+ target_p->localClient->chal_time = 0;
+}
+
+/*
+ * m_challenge - generate RSA challenge for wouldbe oper
+ * parv[0] = sender prefix
+ * parv[1] = operator to challenge for, or +response
+ *
+ */
+static int
+m_challenge(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct oper_conf *oper_p;
+ char *challenge = NULL; /* to placate gcc */
+ char chal_line[CHALLENGE_WIDTH];
+ unsigned char *b_response;
+ size_t cnt;
+ int len = 0;
+
+ /* if theyre an oper, reprint oper motd and ignore */
+ if(IsOper(source_p))
+ {
+ sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
+ send_oper_motd(source_p);
+ return 0;
+ }
+
+ if(*parv[1] == '+')
+ {
+ /* Ignore it if we aren't expecting this... -A1kmm */
+ if(!source_p->localClient->challenge)
+ return 0;
+
+ if((CurrentTime - source_p->localClient->chal_time) > CHALLENGE_EXPIRES)
+ {
+ sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
+ ilog(L_FOPER, "EXPIRED CHALLENGE (%s) by (%s!%s@%s) (%s)",
+ source_p->localClient->opername, source_p->name,
+ source_p->username, source_p->host, source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Expired CHALLENGE attempt by %s (%s@%s)",
+ source_p->name, source_p->username,
+ source_p->host);
+ cleanup_challenge(source_p);
+ return 0;
+ }
+
+ b_response = ircd_base64_decode((const unsigned char *)++parv[1], strlen(parv[1]), &len);
+
+ if(len != SHA_DIGEST_LENGTH ||
+ memcmp(source_p->localClient->challenge, b_response, SHA_DIGEST_LENGTH))
+ {
+ sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
+ ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s)",
+ source_p->localClient->opername, source_p->name,
+ source_p->username, source_p->host, source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Failed CHALLENGE attempt by %s (%s@%s)",
+ source_p->name, source_p->username,
+ source_p->host);
+
+ MyFree(b_response);
+ cleanup_challenge(source_p);
+ return 0;
+ }
+
+ MyFree(b_response);
+
+ oper_p = find_oper_conf(source_p->username, source_p->orighost,
+ source_p->sockhost,
+ source_p->localClient->opername);
+
+ if(oper_p == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOOPERHOST),
+ me.name, source_p->name);
+ ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
+ source_p->localClient->opername, source_p->name,
+ source_p->username, source_p->host,
+ source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)",
+ source_p->name, source_p->username,
+ source_p->host);
+ return 0;
+ }
+
+ cleanup_challenge(source_p);
+
+ oper_up(source_p, oper_p);
+
+ ilog(L_OPERED, "OPER %s by %s!%s@%s (%s)",
+ source_p->localClient->opername, source_p->name,
+ source_p->username, source_p->host, source_p->sockhost);
+ return 0;
+ }
+
+ cleanup_challenge(source_p);
+
+ oper_p = find_oper_conf(source_p->username, source_p->orighost,
+ source_p->sockhost, parv[1]);
+
+ if(oper_p == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
+ ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
+ parv[1], source_p->name,
+ source_p->username, source_p->host, source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)",
+ source_p->name, source_p->username, source_p->host);
+ return 0;
+ }
+
+ if(!oper_p->rsa_pubkey)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
+ "is not enabled for your oper{} block.", me.name, parv[0]);
+ return 0;
+ }
+
+ if(!generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey))
+ {
+ char *chal = challenge;
+ source_p->localClient->chal_time = CurrentTime;
+ for(;;)
+ {
+ cnt = strlcpy(chal_line, chal, CHALLENGE_WIDTH);
+ sendto_one(source_p, form_str(RPL_RSACHALLENGE2), me.name, source_p->name, chal_line);
+ if(cnt > CHALLENGE_WIDTH)
+ chal += CHALLENGE_WIDTH - 1;
+ else
+ break;
+
+ }
+ sendto_one(source_p, form_str(RPL_ENDOFRSACHALLENGE2),
+ me.name, source_p->name);
+ MyFree(challenge);
+ DupString(source_p->localClient->opername, oper_p->name);
+ }
+ else
+ sendto_one_notice(source_p, ":Failed to generate challenge.");
+
+ return 0;
+}
+
+static int
+get_randomness(unsigned char *buf, int length)
+{
+ /* Seed OpenSSL PRNG with EGD enthropy pool -kre */
+ if(ConfigFileEntry.use_egd && (ConfigFileEntry.egdpool_path != NULL))
+ {
+ if(RAND_egd(ConfigFileEntry.egdpool_path) == -1)
+ return -1;
+ }
+
+ if(RAND_status())
+ {
+ if(RAND_bytes(buf, length) > 0)
+ return 1;
+ }
+ else {
+ if(RAND_pseudo_bytes(buf, length) >= 0)
+ return 1;
+ }
+ return 0;
+}
+
+static int
+generate_challenge(char **r_challenge, char **r_response, RSA * rsa)
+{
+ SHA_CTX ctx;
+ unsigned char secret[CHALLENGE_SECRET_LENGTH], *tmp;
+ unsigned long length;
+ unsigned long e = 0;
+ unsigned long cnt = 0;
+ int ret;
+
+ if(!rsa)
+ return -1;
+ if(get_randomness(secret, CHALLENGE_SECRET_LENGTH))
+ {
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, (u_int8_t *)secret, CHALLENGE_SECRET_LENGTH);
+ *r_response = MyMalloc(SHA_DIGEST_LENGTH);
+ SHA1_Final((u_int8_t *)*r_response, &ctx);
+
+ length = RSA_size(rsa);
+ tmp = MyMalloc(length);
+ ret = RSA_public_encrypt(CHALLENGE_SECRET_LENGTH, secret, tmp, rsa, RSA_PKCS1_OAEP_PADDING);
+
+ if (ret >= 0)
+ {
+ *r_challenge = (char *)ircd_base64_encode(tmp, ret);
+ MyFree(tmp);
+ return 0;
+ }
+ MyFree(tmp);
+ MyFree(*r_response);
+ *r_response = NULL;
+ }
+
+ ERR_load_crypto_strings();
+ while ((cnt < 100) && (e = ERR_get_error()))
+ {
+ ilog(L_MAIN, "SSL error: %s", ERR_error_string(e, 0));
+ cnt++;
+ }
+
+ return (-1);
+}
+
+#endif /* HAVE_LIBCRYPTO */
--- /dev/null
+/*
+ * Copyright (c) 2005 William Pitcock <nenolod -at- nenolod.net>
+ * and Jilles Tjoelker <jilles -at- stack.nl>
+ * All rights reserved.
+ *
+ * Redistribution in both source and binary forms are permitted
+ * provided that the above copyright notice remains unchanged.
+ *
+ * m_chghost.c: A module for handling spoofing dynamically.
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_serv.h"
+#include "s_user.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+#include "whowas.h"
+#include "monitor.h"
+
+static int me_realhost(struct Client *, struct Client *, int, const char **);
+static int ms_chghost(struct Client *, struct Client *, int, const char **);
+static int me_chghost(struct Client *, struct Client *, int, const char **);
+static int mo_chghost(struct Client *, struct Client *, int, const char **);
+
+struct Message realhost_msgtab = {
+ "REALHOST", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_realhost, 2}, mg_ignore}
+};
+
+struct Message chghost_msgtab = {
+ "CHGHOST", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, {ms_chghost, 3}, {ms_chghost, 3}, {me_chghost, 3}, {mo_chghost, 3}}
+};
+
+mapi_clist_av1 chghost_clist[] = { &chghost_msgtab, &realhost_msgtab, NULL };
+
+DECLARE_MODULE_AV1(chghost, NULL, NULL, chghost_clist, NULL, NULL, "$Revision: 1865 $");
+
+/* clean_host()
+ *
+ * input - host to check
+ * output - 0 if erroneous, else 0
+ * side effects -
+ */
+static int
+clean_host(const char *host)
+{
+ int len = 0;
+
+ for(; *host; host++)
+ {
+ len++;
+
+ if(!IsHostChar(*host))
+ return 0;
+ }
+
+ if(len > HOSTLEN)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * me_realhost
+ * parv[0] = origin
+ * parv[1] = real host
+ *
+ * Yes this contains a little race condition if someone does a whois
+ * in between the UID and REALHOST and use_whois_actually is enabled.
+ * I don't think that's a big problem as the whole thing is a
+ * race condition.
+ */
+static int
+me_realhost(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ if (!IsPerson(source_p))
+ return 0;
+
+ del_from_hostname_hash(source_p->orighost, source_p);
+ strlcpy(source_p->orighost, parv[1], HOSTLEN);
+ if (irccmp(source_p->host, source_p->orighost))
+ SetDynSpoof(source_p);
+ else
+ ClearDynSpoof(source_p);
+ add_to_hostname_hash(source_p->orighost, source_p);
+ return 0;
+}
+
+static int
+do_chghost(struct Client *source_p, struct Client *target_p,
+ const char *newhost, int is_encap)
+{
+ if (!clean_host(newhost))
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_encap ? L_ALL : L_NETWIDE, "%s attempted to change hostname for %s to %s (invalid)",
+ IsServer(source_p) ? source_p->name : get_oper_name(source_p),
+ target_p->name, newhost);
+ /* sending this remotely may disclose important
+ * routing information -- jilles */
+ if (is_encap ? MyClient(target_p) : !ConfigServerHide.flatten_links)
+ sendto_one_notice(target_p, ":*** Notice -- %s attempted to change your hostname to %s (invalid)",
+ source_p->name, newhost);
+ return 0;
+ }
+ change_nick_user_host(target_p, target_p->name, target_p->username, newhost, 0, "Changing host");
+ if (irccmp(target_p->host, target_p->orighost))
+ {
+ SetDynSpoof(target_p);
+ if (MyClient(target_p))
+ sendto_one_numeric(target_p, RPL_HOSTHIDDEN, "%s :is now your hidden host (set by %s)", target_p->host, source_p->name);
+ }
+ else
+ {
+ ClearDynSpoof(target_p);
+ if (MyClient(target_p))
+ sendto_one_numeric(target_p, RPL_HOSTHIDDEN, "%s :hostname reset by %s", target_p->host, source_p->name);
+ }
+ if (MyClient(source_p))
+ sendto_one_notice(source_p, ":Changed hostname for %s to %s", target_p->name, target_p->host);
+ if (!IsServer(source_p) && !IsService(source_p))
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s changed hostname for %s to %s", get_oper_name(source_p), target_p->name, target_p->host);
+ return 1;
+}
+
+/*
+ * ms_chghost
+ * parv[0] = origin
+ * parv[1] = target
+ * parv[2] = host
+ */
+static int
+ms_chghost(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ if (!(target_p = find_person(parv[1])))
+ return -1;
+
+ if (do_chghost(source_p, target_p, parv[2], 0))
+ {
+ sendto_server(client_p, NULL,
+ CAP_EUID | CAP_TS6, NOCAPS, ":%s CHGHOST %s %s",
+ use_id(source_p), use_id(target_p), parv[2]);
+ sendto_server(client_p, NULL,
+ CAP_TS6, CAP_EUID, ":%s ENCAP * CHGHOST %s :%s",
+ use_id(source_p), use_id(target_p), parv[2]);
+ sendto_server(client_p, NULL,
+ NOCAPS, CAP_TS6, ":%s ENCAP * CHGHOST %s :%s",
+ source_p->name, target_p->name, parv[2]);
+ }
+
+ return 0;
+}
+
+/*
+ * me_chghost
+ * parv[0] = origin
+ * parv[1] = target
+ * parv[2] = host
+ */
+static int
+me_chghost(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ if (!(target_p = find_person(parv[1])))
+ return -1;
+
+ do_chghost(source_p, target_p, parv[2], 1);
+
+ return 0;
+}
+
+/*
+ * mo_chghost
+ * parv[0] = origin
+ * parv[1] = target
+ * parv[2] = host
+ */
+/* Disable this because of the abuse potential -- jilles
+ * No, make it toggleable via ./configure. --nenolod
+ */
+static int
+mo_chghost(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+#ifdef ENABLE_OPER_CHGHOST
+ struct Client *target_p;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ if (!(target_p = find_named_person(parv[1])))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), parv[1]);
+ return 0;
+ }
+
+ if (!clean_host(parv[2]))
+ {
+ sendto_one_notice(source_p, ":Hostname %s is invalid", parv[2]);
+ return 0;
+ }
+
+ do_chghost(source_p, target_p, parv[2], 0);
+
+ sendto_server(NULL, NULL,
+ CAP_EUID | CAP_TS6, NOCAPS, ":%s CHGHOST %s %s",
+ use_id(source_p), use_id(target_p), parv[2]);
+ sendto_server(NULL, NULL,
+ CAP_TS6, CAP_EUID, ":%s ENCAP * CHGHOST %s :%s",
+ use_id(source_p), use_id(target_p), parv[2]);
+ sendto_server(NULL, NULL,
+ NOCAPS, CAP_TS6, ":%s ENCAP * CHGHOST %s :%s",
+ source_p->name, target_p->name, parv[2]);
+#else
+ sendto_one_notice(source_p, ":CHGHOST is disabled");
+#endif
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_close.c: Closes all unregistered connections.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_close.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_close(struct Client *, struct Client *, int, const char **);
+
+struct Message close_msgtab = {
+ "CLOSE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_close, 0}}
+};
+
+mapi_clist_av1 close_clist[] = { &close_msgtab, NULL };
+DECLARE_MODULE_AV1(close, NULL, NULL, close_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * mo_close - CLOSE message handler
+ * - added by Darren Reed Jul 13 1992.
+ */
+static int
+mo_close(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *ptr_next;
+ int closed = 0;
+
+ DLINK_FOREACH_SAFE(ptr, ptr_next, unknown_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(source_p, form_str(RPL_CLOSING), me.name, source_p->name,
+ get_client_name(target_p, SHOW_IP), target_p->status);
+
+ (void) exit_client(target_p, target_p, target_p, "Oper Closing");
+ closed++;
+ }
+
+ sendto_one(source_p, form_str(RPL_CLOSEEND), me.name, source_p->name, closed);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * m_cmessage.c: Handles CPRIVMSG/CNOTICE, target change limitation free
+ * PRIVMSG/NOTICE implementations.
+ *
+ * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_cmessage.c 1543 2006-06-01 18:18:28Z jilles $
+ */
+#include "stdinc.h"
+#include "client.h"
+#include "channel.h"
+#include "numeric.h"
+#include "msg.h"
+#include "modules.h"
+#include "hash.h"
+#include "send.h"
+#include "s_conf.h"
+#include "packet.h"
+
+static int m_cmessage(int, const char *, struct Client *, struct Client *, int, const char **);
+static int m_cprivmsg(struct Client *, struct Client *, int, const char **);
+static int m_cnotice(struct Client *, struct Client *, int, const char **);
+
+struct Message cprivmsg_msgtab = {
+ "CPRIVMSG", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, {m_cprivmsg, 4}, mg_ignore, mg_ignore, mg_ignore, {m_cprivmsg, 4}}
+};
+struct Message cnotice_msgtab = {
+ "CNOTICE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, {m_cnotice, 4}, mg_ignore, mg_ignore, mg_ignore, {m_cnotice, 4}}
+};
+
+mapi_clist_av1 cmessage_clist[] = { &cprivmsg_msgtab, &cnotice_msgtab, NULL };
+DECLARE_MODULE_AV1(cmessage, NULL, NULL, cmessage_clist, NULL, NULL, "$Revision: 1543 $");
+
+#define PRIVMSG 0
+#define NOTICE 1
+
+static int
+m_cprivmsg(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ return m_cmessage(PRIVMSG, "PRIVMSG", client_p, source_p, parc, parv);
+}
+
+static int
+m_cnotice(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ return m_cmessage(NOTICE, "NOTICE", client_p, source_p, parc, parv);
+}
+
+static int
+m_cmessage(int p_or_n, const char *command,
+ struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+
+ if(!IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ if((target_p = find_named_person(parv[1])) == NULL)
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), parv[1]);
+ return 0;
+ }
+
+ if((chptr = find_channel(parv[2])) == NULL)
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[2]);
+ return 0;
+ }
+
+ if((msptr = find_channel_membership(chptr, source_p)) == NULL)
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL),
+ chptr->chname);
+ return 0;
+ }
+
+ if(!is_chanop_voiced(msptr))
+ {
+ if(p_or_n != NOTICE)
+ sendto_one(source_p, form_str(ERR_VOICENEEDED),
+ me.name, source_p->name, chptr->chname);
+ return 0;
+ }
+
+ if(!IsMember(target_p, chptr))
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL),
+ target_p->name, chptr->chname);
+ return 0;
+ }
+
+ if(MyClient(target_p) && (IsSetCallerId(target_p) || (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])) &&
+ !accept_message(source_p, target_p) && !IsOper(source_p))
+ {
+ if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])
+ {
+ if (p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_NONONREG,
+ form_str(ERR_NONONREG),
+ target_p->name);
+ return 0;
+ }
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, ERR_TARGUMODEG,
+ form_str(ERR_TARGUMODEG), target_p->name);
+
+ if((target_p->localClient->last_caller_id_time +
+ ConfigFileEntry.caller_id_wait) < CurrentTime)
+ {
+ if(p_or_n != NOTICE)
+ sendto_one_numeric(source_p, RPL_TARGNOTIFY,
+ form_str(RPL_TARGNOTIFY),
+ target_p->name);
+
+ sendto_one(target_p, form_str(RPL_UMODEGMSG),
+ me.name, target_p->name, source_p->name,
+ source_p->username, source_p->host);
+
+ target_p->localClient->last_caller_id_time = CurrentTime;
+ }
+
+ return 0;
+ }
+
+ if(p_or_n != NOTICE)
+ source_p->localClient->last = CurrentTime;
+
+ sendto_anywhere(target_p, source_p, command, ":%s", parv[3]);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_connect.c: Connects to a remote IRC server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_connect.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "hash.h"
+#include "modules.h"
+
+static int mo_connect(struct Client *, struct Client *, int, const char **);
+static int ms_connect(struct Client *, struct Client *, int, const char **);
+
+struct Message connect_msgtab = {
+ "CONNECT", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_connect, 4}, {ms_connect, 4}, mg_ignore, {mo_connect, 2}}
+};
+
+mapi_clist_av1 connect_clist[] = { &connect_msgtab, NULL };
+DECLARE_MODULE_AV1(connect, NULL, NULL, connect_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * mo_connect - CONNECT command handler
+ *
+ * Added by Jto 11 Feb 1989
+ *
+ * m_connect
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ * parv[2] = port number
+ * parv[3] = remote server
+ */
+static int
+mo_connect(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int port;
+ int tmpport;
+ struct server_conf *server_p;
+ struct Client *target_p;
+
+ /* always privileged with handlers */
+
+ if(MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remote");
+ return 0;
+ }
+
+ if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ if((target_p = find_server(source_p, parv[1])))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Connect: Server %s already exists from %s.",
+ me.name, parv[0], parv[1], target_p->from->name);
+ return 0;
+ }
+
+ /*
+ * try to find the name, then host, if both fail notify ops and bail
+ */
+ if((server_p = find_server_conf(parv[1])) == NULL)
+ {
+ sendto_one(source_p,
+ "NOTICE %s :Connect: Host %s not listed in ircd.conf",
+ parv[0], parv[1]);
+ return 0;
+ }
+
+ /*
+ * Get port number from user, if given. If not specified,
+ * use the default form configuration structure. If missing
+ * from there, then use the precompiled default.
+ */
+ tmpport = port = server_p->port;
+ if(parc > 2 && !EmptyString(parv[2]))
+ {
+ if((port = atoi(parv[2])) <= 0)
+ {
+ sendto_one(source_p, "NOTICE %s :Connect: Illegal port number", parv[0]);
+ return 0;
+ }
+ }
+ else if(port <= 0 && (port = PORTNUM) <= 0)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
+ me.name, parv[0]);
+ return 0;
+ }
+ /*
+ * Notify all operators about remote connect requests
+ */
+
+ ilog(L_SERVER, "CONNECT From %s : %s %s", parv[0], parv[1], parc > 2 ? parv[2] : "");
+
+ server_p->port = port;
+ /*
+ * at this point we should be calling connect_server with a valid
+ * C:line and a valid port in the C:line
+ */
+ if(serv_connect(server_p, source_p))
+ {
+#ifndef HIDE_SERVERS_IPS
+ sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
+ me.name, parv[0], server_p->host, server_p->name, server_p->port);
+#else
+ sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
+ me.name, parv[0], server_p->name, server_p->port);
+#endif
+
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
+ me.name, parv[0], server_p->name, server_p->port);
+
+ }
+
+ /*
+ * client is either connecting with all the data it needs or has been
+ * destroyed
+ */
+ server_p->port = tmpport;
+ return 0;
+}
+
+/*
+ * ms_connect - CONNECT command handler
+ *
+ * Added by Jto 11 Feb 1989
+ *
+ * m_connect
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ * parv[2] = port number
+ * parv[3] = remote server
+ */
+static int
+ms_connect(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int port;
+ int tmpport;
+ struct server_conf *server_p;
+ struct Client *target_p;
+
+ if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ if((target_p = find_server(NULL, parv[1])))
+ {
+ sendto_one_notice(source_p, ":Connect: Server %s already exists from %s.",
+ parv[1], target_p->from->name);
+ return 0;
+ }
+
+ /*
+ * try to find the name, then host, if both fail notify ops and bail
+ */
+ if((server_p = find_server_conf(parv[1])) == NULL)
+ {
+ sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf",
+ parv[1]);
+ return 0;
+ }
+
+ /*
+ * Get port number from user, if given. If not specified,
+ * use the default form configuration structure. If missing
+ * from there, then use the precompiled default.
+ */
+ tmpport = server_p->port;
+
+ port = atoi(parv[2]);
+
+ /* if someone sends port 0, and we have a config port.. use it */
+ if(port == 0 && server_p->port)
+ port = server_p->port;
+ else if(port <= 0)
+ {
+ sendto_one_notice(source_p, ":Connect: Illegal port number");
+ return 0;
+ }
+
+ /*
+ * Notify all operators about remote connect requests
+ */
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "Remote CONNECT %s %d from %s",
+ parv[1], port, source_p->name);
+ sendto_server(NULL, NULL, CAP_TS6, NOCAPS,
+ ":%s WALLOPS :Remote CONNECT %s %d from %s",
+ me.id, parv[1], port, source_p->name);
+ sendto_server(NULL, NULL, NOCAPS, CAP_TS6,
+ ":%s WALLOPS :Remote CONNECT %s %d from %s",
+ me.name, parv[1], port, source_p->name);
+
+ ilog(L_SERVER, "CONNECT From %s : %s %d", source_p->name, parv[1], port);
+
+ server_p->port = port;
+ /*
+ * at this point we should be calling connect_server with a valid
+ * C:line and a valid port in the C:line
+ */
+ if(serv_connect(server_p, source_p))
+ sendto_one_notice(source_p, ":*** Connecting to %s.%d",
+ server_p->name, server_p->port);
+ else
+ sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d",
+ server_p->name, server_p->port);
+ /*
+ * client is either connecting with all the data it needs or has been
+ * destroyed
+ */
+ server_p->port = tmpport;
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_dline.c: Bans/unbans a user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_dline.c 3051 2006-12-27 00:02:32Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "send.h"
+#include "hash.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_dline(struct Client *, struct Client *, int, const char **);
+static int mo_undline(struct Client *, struct Client *, int, const char **);
+
+struct Message dline_msgtab = {
+ "DLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_dline, 2}}
+};
+struct Message undline_msgtab = {
+ "UNDLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_undline, 2}}
+};
+
+mapi_clist_av1 dline_clist[] = { &dline_msgtab, &undline_msgtab, NULL };
+DECLARE_MODULE_AV1(dline, NULL, NULL, dline_clist, NULL, NULL, "$Revision: 3051 $");
+
+static int valid_comment(char *comment);
+static int flush_write(struct Client *, FILE *, char *, char *);
+static int remove_temp_dline(const char *);
+
+/* mo_dline()
+ *
+ * parv[1] - dline to add
+ * parv[2] - reason
+ */
+static int
+mo_dline(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ char def[] = "No Reason";
+ const char *dlhost;
+ char *oper_reason;
+ char *reason = def;
+ struct irc_sockaddr_storage daddr;
+ char cidr_form_host[HOSTLEN + 1];
+ struct ConfItem *aconf;
+ int bits;
+ char dlbuffer[IRCD_BUFSIZE];
+ const char *current_date;
+ int tdline_time = 0;
+ int loc = 1;
+
+ if(!IsOperK(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "kline");
+ return 0;
+ }
+
+ if((tdline_time = valid_temp_time(parv[loc])) >= 0)
+ loc++;
+
+ if(parc < loc + 1)
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "DLINE");
+ return 0;
+ }
+
+ dlhost = parv[loc];
+ strlcpy(cidr_form_host, dlhost, sizeof(cidr_form_host));
+
+ if(!parse_netmask(dlhost, NULL, &bits))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid D-Line",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ loc++;
+
+ if(parc >= loc + 1) /* host :reason */
+ {
+ if(!EmptyString(parv[loc]))
+ reason = LOCAL_COPY(parv[loc]);
+
+ if(!valid_comment(reason))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Invalid character '\"' in comment",
+ me.name, source_p->name);
+ return 0;
+ }
+ }
+
+ if(IsOperAdmin(source_p))
+ {
+ if(bits < 8)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
+ me.name, parv[0]);
+ return 0;
+ }
+ }
+ else
+ {
+ if(bits < 16)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Dline bitmasks less than 16 are for admins only.",
+ me.name, parv[0]);
+ return 0;
+ }
+ }
+
+ if(ConfigFileEntry.non_redundant_klines)
+ {
+ const char *creason;
+ int t = AF_INET, ty, b;
+ ty = parse_netmask(dlhost, (struct sockaddr *)&daddr, &b);
+#ifdef IPV6
+ if(ty == HM_IPV6)
+ t = AF_INET6;
+ else
+#endif
+ t = AF_INET;
+
+ if((aconf = find_dline((struct sockaddr *)&daddr, t)) != NULL)
+ {
+ int bx;
+ parse_netmask(aconf->host, NULL, &bx);
+ if(b >= bx)
+ {
+ creason = aconf->passwd ? aconf->passwd : "<No Reason>";
+ if(IsConfExemptKline(aconf))
+ sendto_one(source_p,
+ ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
+ me.name, parv[0], dlhost, aconf->host, creason);
+ else
+ sendto_one(source_p,
+ ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
+ me.name, parv[0], dlhost, aconf->host, creason);
+ return 0;
+ }
+ }
+ }
+
+ set_time();
+ current_date = smalldate();
+
+ aconf = make_conf();
+ aconf->status = CONF_DLINE;
+ DupString(aconf->host, dlhost);
+
+ /* Look for an oper reason */
+ if((oper_reason = strchr(reason, '|')) != NULL)
+ {
+ *oper_reason = '\0';
+ oper_reason++;
+
+ if(!EmptyString(oper_reason))
+ DupString(aconf->spasswd, oper_reason);
+ }
+
+ if(tdline_time > 0)
+ {
+ ircsnprintf(dlbuffer, sizeof(dlbuffer),
+ "Temporary D-line %d min. - %s (%s)",
+ (int) (tdline_time / 60), reason, current_date);
+ DupString(aconf->passwd, dlbuffer);
+ aconf->hold = CurrentTime + tdline_time;
+ add_temp_dline(aconf);
+
+ if(EmptyString(oper_reason))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. D-Line for [%s] [%s]",
+ get_oper_name(source_p), tdline_time / 60,
+ aconf->host, reason);
+ ilog(L_KLINE, "D %s %d %s %s",
+ get_oper_name(source_p), tdline_time / 60,
+ aconf->host, reason);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. D-Line for [%s] [%s|%s]",
+ get_oper_name(source_p), tdline_time / 60,
+ aconf->host, reason, oper_reason);
+ ilog(L_KLINE, "D %s %d %s %s|%s",
+ get_oper_name(source_p), tdline_time / 60,
+ aconf->host, reason, oper_reason);
+ }
+
+ sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line for [%s]",
+ me.name, source_p->name, tdline_time / 60, aconf->host);
+ }
+ else
+ {
+ ircsnprintf(dlbuffer, sizeof(dlbuffer), "%s (%s)", reason, current_date);
+ DupString(aconf->passwd, dlbuffer);
+ add_conf_by_address(aconf->host, CONF_DLINE, NULL, aconf);
+ write_confitem(DLINE_TYPE, source_p, NULL, aconf->host, reason,
+ oper_reason, current_date, 0);
+ }
+
+ check_dlines();
+ return 0;
+}
+
+/* mo_undline()
+ *
+ * parv[1] = dline to remove
+ */
+static int
+mo_undline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ FILE *in;
+ FILE *out;
+ char buf[BUFSIZE], buff[BUFSIZE], temppath[BUFSIZE], *p;
+ const char *filename, *found_cidr;
+ const char *cidr;
+ int pairme = NO, error_on_write = NO;
+ mode_t oldumask;
+
+ ircsnprintf(temppath, sizeof(temppath), "%s.tmp", ConfigFileEntry.dlinefile);
+
+ if(!IsOperUnkline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "unkline");
+ return 0;
+ }
+
+ cidr = parv[1];
+
+ if(parse_netmask(cidr, NULL, NULL) == HM_HOST)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid D-Line",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ if(remove_temp_dline(cidr))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Un-dlined [%s] from temporary D-lines",
+ me.name, parv[0], cidr);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the temporary D-Line for: [%s]",
+ get_oper_name(source_p), cidr);
+ ilog(L_KLINE, "UD %s %s", get_oper_name(source_p), cidr);
+ return 0;
+ }
+
+ filename = get_conf_name(DLINE_TYPE);
+
+ if((in = fopen(filename, "r")) == 0)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, parv[0], filename);
+ return 0;
+ }
+
+ oldumask = umask(0);
+ if((out = fopen(temppath, "w")) == 0)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, parv[0], temppath);
+ fclose(in);
+ umask(oldumask);
+ return 0;
+ }
+
+ umask(oldumask);
+
+ while (fgets(buf, sizeof(buf), in))
+ {
+ strlcpy(buff, buf, sizeof(buff));
+
+ if((p = strchr(buff, '\n')) != NULL)
+ *p = '\0';
+
+ if((*buff == '\0') || (*buff == '#'))
+ {
+ if(!error_on_write)
+ flush_write(source_p, out, buf, temppath);
+ continue;
+ }
+
+ if((found_cidr = getfield(buff)) == NULL)
+ {
+ if(!error_on_write)
+ flush_write(source_p, out, buf, temppath);
+ continue;
+ }
+
+ if(irccmp(found_cidr, cidr) == 0)
+ {
+ pairme++;
+ }
+ else
+ {
+ if(!error_on_write)
+ flush_write(source_p, out, buf, temppath);
+ continue;
+ }
+ }
+
+ fclose(in);
+ if (fclose(out))
+ error_on_write = YES;
+
+ if(error_on_write)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Couldn't write D-line file, aborted",
+ me.name, parv[0]);
+ return 0;
+ }
+ else if(!pairme)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :No D-Line for %s",
+ me.name, parv[0], cidr);
+
+ if(temppath != NULL)
+ (void) unlink(temppath);
+
+ return 0;
+ }
+
+ if (rename(temppath, filename))
+ {
+ sendto_one_notice(source_p, ":Couldn't rename temp file, aborted");
+ return 0;
+ }
+ rehash_bans(0);
+
+
+ sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", me.name, parv[0], cidr);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the D-Line for: [%s]", get_oper_name(source_p), cidr);
+ ilog(L_KLINE, "UD %s %s", get_oper_name(source_p), cidr);
+
+ return 0;
+}
+
+/*
+ * valid_comment
+ * inputs - pointer to client
+ * - pointer to comment
+ * output - 0 if no valid comment, 1 if valid
+ * side effects - NONE
+ */
+static int
+valid_comment(char *comment)
+{
+ if(strchr(comment, '"'))
+ return 0;
+
+ if(strlen(comment) > REASONLEN)
+ comment[REASONLEN] = '\0';
+
+ return 1;
+}
+
+/*
+ * flush_write()
+ *
+ * inputs - pointer to client structure of oper requesting unkline
+ * - out is the file descriptor
+ * - buf is the buffer to write
+ * - ntowrite is the expected number of character to be written
+ * - temppath is the temporary file name to be written
+ * output - YES for error on write
+ * - NO for success
+ * side effects - if successful, the buf is written to output file
+ * if a write failure happesn, and the file pointed to
+ * by temppath, if its non NULL, is removed.
+ *
+ * The idea here is, to be as robust as possible when writing to the
+ * kline file.
+ *
+ * -Dianora
+ */
+static int
+flush_write(struct Client *source_p, FILE * out, char *buf, char *temppath)
+{
+ int error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+
+ if(error_on_write)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Unable to write to %s",
+ me.name, source_p->name, temppath);
+ fclose(out);
+ if(temppath != NULL)
+ (void) unlink(temppath);
+ }
+ return (error_on_write);
+}
+
+/* remove_temp_dline()
+ *
+ * inputs - hostname to undline
+ * outputs -
+ * side effects - tries to undline anything that matches
+ */
+static int
+remove_temp_dline(const char *host)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ struct irc_sockaddr_storage addr, caddr;
+ int bits, cbits;
+ int i;
+
+ parse_netmask(host, (struct sockaddr *)&addr, &bits);
+
+ for (i = 0; i < LAST_TEMP_TYPE; i++)
+ {
+ DLINK_FOREACH(ptr, temp_dlines[i].head)
+ {
+ aconf = ptr->data;
+
+ parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
+
+ if(comp_with_mask_sock((struct sockaddr *)&addr, (struct sockaddr *)&caddr, bits) && bits == cbits)
+ {
+ dlinkDestroy(ptr, &temp_dlines[i]);
+ delete_one_address_conf(aconf->host, aconf);
+ return YES;
+ }
+ }
+ }
+
+ return NO;
+}
--- /dev/null
+/* modules/m_encap.c
+ * Copyright (C) 2003-2005 ircd-ratbox development team
+ * Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_encap.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+
+static int ms_encap(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message encap_msgtab = {
+ "ENCAP", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, {ms_encap, 3}, {ms_encap, 3}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 encap_clist[] = { &encap_msgtab, NULL };
+DECLARE_MODULE_AV1(encap, NULL, NULL, encap_clist, NULL, NULL, "$Revision: 254 $");
+
+/* ms_encap()
+ *
+ * parv[1] - destination server
+ * parv[2] - subcommand
+ * parv[3] - parameters
+ */
+static int
+ms_encap(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char buffer[BUFSIZE];
+ char *ptr;
+ int cur_len = 0;
+ int len;
+ int i;
+
+ ptr = buffer;
+
+ for(i = 1; i < parc - 1; i++)
+ {
+ len = strlen(parv[i]) + 1;
+
+ /* ugh, not even at the last parameter, just bail --fl */
+ if((size_t)(cur_len + len) >= sizeof(buffer))
+ return 0;
+
+ ircsnprintf(ptr, sizeof(buffer) - cur_len, "%s ", parv[i]);
+ cur_len += len;
+ ptr += len;
+ }
+
+ len = strlen(parv[i]);
+
+ /* if its a command without parameters, dont prepend a ':' */
+ if(parc == 3)
+ ircsnprintf(ptr, sizeof(buffer) - cur_len, "%s", parv[2]);
+ else
+ ircsnprintf(ptr, sizeof(buffer) - cur_len, ":%s", parv[parc-1]);
+
+ /* add a trailing \0 if it was too long */
+ if((cur_len + len) >= BUFSIZE)
+ buffer[BUFSIZE-1] = '\0';
+
+ sendto_match_servs(source_p, parv[1], CAP_ENCAP, NOCAPS,
+ "ENCAP %s", buffer);
+
+ /* if it matches us, find a matching handler and call it */
+ if(match(parv[1], me.name))
+ handle_encap(client_p, source_p, parv[2], parc - 2, parv + 2);
+
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * m_etrace.c: Gives local opers a trace output with added info.
+ *
+ * Copyright (C) 2002-2003 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_etrace.c 2775 2006-11-27 11:45:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "class.h"
+#include "hook.h"
+#include "client.h"
+#include "hash.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_etrace(struct Client *, struct Client *, int, const char **);
+static int me_etrace(struct Client *, struct Client *, int, const char **);
+static int mo_chantrace(struct Client *, struct Client *, int, const char **);
+static int mo_masktrace(struct Client *, struct Client *, int, const char **);
+
+struct Message etrace_msgtab = {
+ "ETRACE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, mg_ignore, mg_ignore, {me_etrace, 0}, {mo_etrace, 0}}
+};
+struct Message chantrace_msgtab = {
+ "CHANTRACE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_chantrace, 2}}
+};
+struct Message masktrace_msgtab = {
+ "MASKTRACE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_masktrace, 2}}
+};
+
+mapi_clist_av1 etrace_clist[] = { &etrace_msgtab, &chantrace_msgtab, &masktrace_msgtab, NULL };
+DECLARE_MODULE_AV1(etrace, NULL, NULL, etrace_clist, NULL, NULL, "$Revision: 2775 $");
+
+static void do_etrace(struct Client *source_p, int ipv4, int ipv6);
+static void do_etrace_full(struct Client *source_p);
+static void do_single_etrace(struct Client *source_p, struct Client *target_p);
+
+static const char *empty_sockhost = "255.255.255.255";
+static const char *spoofed_sockhost = "0";
+
+/*
+ * m_etrace
+ * parv[0] = sender prefix
+ * parv[1] = options [or target]
+ * parv[2] = [target]
+ */
+static int
+mo_etrace(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc > 1 && !EmptyString(parv[1]))
+ {
+ if(!irccmp(parv[1], "-full"))
+ do_etrace_full(source_p);
+#ifdef IPV6
+ else if(!irccmp(parv[1], "-v6"))
+ do_etrace(source_p, 0, 1);
+ else if(!irccmp(parv[1], "-v4"))
+ do_etrace(source_p, 1, 0);
+#endif
+ else
+ {
+ struct Client *target_p = find_named_person(parv[1]);
+
+ if(target_p)
+ {
+ if(!MyClient(target_p))
+ sendto_one(target_p, ":%s ENCAP %s ETRACE %s",
+ get_id(source_p, target_p),
+ target_p->user->server,
+ get_id(target_p, target_p));
+ else
+ do_single_etrace(source_p, target_p);
+ }
+ else
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), parv[1]);
+ }
+ }
+ else
+ do_etrace(source_p, 1, 1);
+
+ return 0;
+}
+
+static int
+me_etrace(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ if(!IsOper(source_p) || parc < 2 || EmptyString(parv[1]))
+ return 0;
+
+ /* we cant etrace remote clients.. we shouldnt even get sent them */
+ if((target_p = find_person(parv[1])) && MyClient(target_p))
+ do_single_etrace(source_p, target_p);
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE),
+ target_p ? target_p->name : parv[1]);
+
+ return 0;
+}
+
+static void
+do_etrace(struct Client *source_p, int ipv4, int ipv6)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ /* report all direct connections */
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+#ifdef IPV6
+ if((!ipv4 && target_p->localClient->ip.ss_family == AF_INET) ||
+ (!ipv6 && target_p->localClient->ip.ss_family == AF_INET6))
+ continue;
+#endif
+
+ sendto_one(source_p, form_str(RPL_ETRACE),
+ me.name, source_p->name,
+ IsOper(target_p) ? "Oper" : "User",
+ get_client_class(target_p),
+ target_p->name, target_p->username, target_p->host,
+ show_ip(source_p, target_p) ? target_p->sockhost : "255.255.255.255",
+ target_p->info);
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
+}
+
+static void
+do_etrace_full(struct Client *source_p)
+{
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ do_single_etrace(source_p, ptr->data);
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
+}
+
+/*
+ * do_single_etrace - searches local clients and displays those matching
+ * a pattern
+ * input - source client, target client
+ * output - etrace results
+ * side effects - etrace results are displayed
+ */
+static void
+do_single_etrace(struct Client *source_p, struct Client *target_p)
+{
+ /* note, we hide fullcaps for spoofed users, as mirc can often
+ * advertise its internal ip address in the field --fl
+ */
+ if(!show_ip(source_p, target_p))
+ sendto_one(source_p, form_str(RPL_ETRACEFULL),
+ me.name, source_p->name,
+ IsOper(target_p) ? "Oper" : "User",
+ get_client_class(target_p),
+ target_p->name, target_p->username, target_p->host,
+ "255.255.255.255", "<hidden> <hidden>", target_p->info);
+ else
+ sendto_one(source_p, form_str(RPL_ETRACEFULL),
+ me.name, source_p->name,
+ IsOper(target_p) ? "Oper" : "User",
+ get_client_class(target_p),
+ target_p->name, target_p->username,
+ target_p->host, target_p->sockhost,
+ target_p->localClient->fullcaps, target_p->info);
+}
+
+static int
+mo_chantrace(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+ const char *sockhost;
+ const char *name;
+ dlink_node *ptr;
+ int operspy = 0;
+
+ name = parv[1];
+
+ if(IsOperSpy(source_p) && parv[1][0] == '!')
+ {
+ name++;
+ operspy = 1;
+
+ if(EmptyString(name))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "CHANTRACE");
+ return 0;
+ }
+ }
+
+ if((chptr = find_channel(name)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL),
+ name);
+ return 0;
+ }
+
+ /* dont report operspys for nonexistant channels. */
+ if(operspy)
+ report_operspy(source_p, "CHANTRACE", chptr->chname);
+
+ if(!operspy && !IsMember(client_p, chptr))
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL),
+ chptr->chname);
+ return 0;
+ }
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(EmptyString(target_p->sockhost))
+ sockhost = empty_sockhost;
+ else if(!show_ip(source_p, target_p))
+ sockhost = spoofed_sockhost;
+ else
+ sockhost = target_p->sockhost;
+
+ sendto_one(source_p, form_str(RPL_ETRACE),
+ me.name, source_p->name,
+ IsOper(target_p) ? "Oper" : "User",
+ /* class field -- pretend its server.. */
+ target_p->servptr->name,
+ target_p->name, target_p->username, target_p->host,
+ sockhost, target_p->info);
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
+ return 0;
+}
+
+static void
+match_masktrace(struct Client *source_p, dlink_list *list,
+ const char *username, const char *hostname, const char *name,
+ const char *gecos)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ const char *sockhost;
+ char *mangle_gecos = NULL;
+
+ if(gecos != NULL)
+ {
+ if(strstr(gecos, "\\s"))
+ {
+ char *tmp = LOCAL_COPY(gecos);
+ char *orig = tmp;
+ char *new = tmp;
+ while(*orig)
+ {
+ if(*orig == '\\' && *(orig + 1) != '\0')
+ {
+ if(*(orig + 1) == 's')
+ {
+ *new++ = ' ';
+ orig += 2;
+ }
+ /* otherwise skip that and the escaped
+ * character after it, so we dont mistake
+ * \\s as \s --fl
+ */
+ else
+ {
+ *new++ = *orig++;
+ *new++ = *orig++;
+ }
+ }
+ else
+ *new++ = *orig++;
+ }
+
+ *new = '\0';
+ mangle_gecos = LOCAL_COPY(tmp);
+ }
+ else
+ mangle_gecos = LOCAL_COPY(gecos);
+ }
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ target_p = ptr->data;
+ if(!IsPerson(target_p))
+ continue;
+
+ if(EmptyString(target_p->sockhost))
+ sockhost = empty_sockhost;
+ else if(!show_ip(source_p, target_p))
+ sockhost = spoofed_sockhost;
+ else
+ sockhost = target_p->sockhost;
+
+ if(match(username, target_p->username) &&
+ (match(hostname, target_p->host) ||
+ match(hostname, target_p->orighost) ||
+ match(hostname, sockhost) || match_ips(hostname, sockhost)))
+ {
+ if(name != NULL && !match(name, target_p->name))
+ continue;
+
+ if(mangle_gecos != NULL && !match_esc(mangle_gecos, target_p->info))
+ continue;
+
+ sendto_one(source_p, form_str(RPL_ETRACE),
+ me.name, source_p->name,
+ IsOper(target_p) ? "Oper" : "User",
+ /* class field -- pretend its server.. */
+ target_p->servptr->name,
+ target_p->name, target_p->username, target_p->host,
+ sockhost, target_p->info);
+ }
+ }
+}
+
+static int
+mo_masktrace(struct Client *client_p, struct Client *source_p, int parc,
+ const char *parv[])
+{
+ char *name, *username, *hostname, *gecos;
+ const char *mask;
+ int operspy = 0;
+
+ mask = parv[1];
+ name = LOCAL_COPY(parv[1]);
+ collapse(name);
+
+ if(IsOperSpy(source_p) && parv[1][0] == '!')
+ {
+ name++;
+ mask++;
+ operspy = 1;
+ }
+
+ if(parc > 2 && !EmptyString(parv[2]))
+ {
+ gecos = LOCAL_COPY(parv[2]);
+ collapse_esc(gecos);
+ } else
+ gecos = NULL;
+
+
+ if((hostname = strchr(name, '@')) == NULL)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters", me.name, source_p->name);
+ return 0;
+ }
+
+ *hostname++ = '\0';
+
+ if((username = strchr(name, '!')) == NULL)
+ {
+ username = name;
+ name = NULL;
+ } else
+ *username++ = '\0';
+
+ if(EmptyString(username) || EmptyString(hostname))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters", me.name, source_p->name);
+ return 0;
+ }
+
+ if(operspy) {
+ if (!ConfigFileEntry.operspy_dont_care_user_info)
+ {
+ char buf[512];
+ strlcpy(buf, mask, sizeof(buf));
+ if(!EmptyString(gecos)) {
+ strlcat(buf, " ", sizeof(buf));
+ strlcat(buf, gecos, sizeof(buf));
+ }
+
+ report_operspy(source_p, "MASKTRACE", buf);
+ }
+ match_masktrace(source_p, &global_client_list, username, hostname, name, gecos);
+ } else
+ match_masktrace(source_p, &lclient_list, username, hostname, name, gecos);
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_gline.c: Votes towards globally banning a mask.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_gline.c 1146 2006-04-07 22:52:35Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "s_gline.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "scache.h"
+#include "send.h"
+#include "msg.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_log.h"
+
+static int mo_gline(struct Client *, struct Client *, int, const char **);
+static int mc_gline(struct Client *, struct Client *, int, const char **);
+static int ms_gline(struct Client *, struct Client *, int, const char **);
+static int mo_ungline(struct Client *, struct Client *, int, const char **);
+
+struct Message gline_msgtab = {
+ "GLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {mc_gline, 3}, {ms_gline, 7}, mg_ignore, {mo_gline, 3}}
+};
+struct Message ungline_msgtab = {
+ "UNGLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_ungline, 2}}
+};
+
+mapi_clist_av1 gline_clist[] = { &gline_msgtab, &ungline_msgtab, NULL };
+DECLARE_MODULE_AV1(gline, NULL, NULL, gline_clist, NULL, NULL, "$Revision: 1146 $");
+
+static int majority_gline(struct Client *source_p, const char *user,
+ const char *host, const char *reason);
+static void set_local_gline(struct Client *source_p, const char *user,
+ const char *host, const char *reason);
+
+static int check_wild_gline(const char *, const char *);
+static int invalid_gline(struct Client *, const char *, const char *, char *);
+
+static int remove_temp_gline(const char *, const char *);
+
+
+/* mo_gline()
+ *
+ * inputs - The usual for a m_ function
+ * output -
+ * side effects - place a gline if 3 opers agree
+ */
+static int
+mo_gline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *user = NULL;
+ char *host = NULL; /* user and host of GLINE "victim" */
+ char *reason = NULL; /* reason for "victims" demise */
+ char splat[] = "*";
+ char *ptr;
+
+ if(!ConfigFileEntry.glines)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :GLINE disabled, perhaps you want a clustered or remote KLINE?",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ if(!IsOperGline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "gline");
+ return 0;
+ }
+
+ host = strchr(parv[1], '@');
+
+ /* specific user@host */
+ if(host != NULL)
+ {
+ user = parv[1];
+ *(host++) = '\0';
+
+ /* gline for "@host", use *@host */
+ if(*user == '\0')
+ user = splat;
+ }
+ /* just a host? */
+ else
+ {
+ /* ok, its not a host.. abort */
+ if(strchr(parv[1], '.') == NULL)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Invalid parameters",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ user = splat;
+ host = LOCAL_COPY(parv[1]);
+ }
+
+ reason = LOCAL_COPY(parv[2]);
+
+ if(invalid_gline(source_p, user, host, reason))
+ return 0;
+
+ /* Not enough non-wild characters were found, assume they are trying to gline *@*. */
+ if(check_wild_gline(user, host))
+ {
+ if(MyClient(source_p))
+ sendto_one(source_p,
+ ":%s NOTICE %s :Please include at least %d non-wildcard "
+ "characters with the user@host",
+ me.name, source_p->name,
+ ConfigFileEntry.min_nonwildcard);
+ return 0;
+ }
+
+ if((ptr = strchr(host, '/')) != NULL)
+ {
+ int bitlen;
+ bitlen = strtol(++ptr, NULL, 10);
+
+ /* ipv4? */
+ if(strchr(host, ':') == NULL)
+ {
+ if(bitlen < ConfigFileEntry.gline_min_cidr)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with cidr length < %d",
+ me.name, source_p->name,
+ ConfigFileEntry.gline_min_cidr);
+ return 0;
+ }
+ }
+ /* ipv6 */
+ else if(bitlen < ConfigFileEntry.gline_min_cidr6)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with cidr length < %d",
+ me.name, source_p->name,
+ ConfigFileEntry.gline_min_cidr6);
+ return 0;
+ }
+ }
+
+ /* inform users about the gline before we call majority_gline()
+ * so already voted comes below gline request --fl
+ */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
+ source_p->name, source_p->username,
+ source_p->host, me.name, user, host, reason);
+ ilog(L_GLINE, "R %s %s %s %s %s %s %s",
+ source_p->name, source_p->username, source_p->host,
+ source_p->user->server, user, host, reason);
+
+ /* If at least 3 opers agree this user should be G lined then do it */
+ majority_gline(source_p, user, host, reason);
+
+ /* 4 param version for hyb-7 servers */
+ sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
+ ":%s GLINE %s %s :%s",
+ use_id(source_p), user, host, reason);
+ sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
+ ":%s GLINE %s %s :%s",
+ source_p->name, user, host, reason);
+
+ /* 8 param for hyb-6 */
+ sendto_server(NULL, NULL, NOCAPS, CAP_GLN,
+ ":%s GLINE %s %s %s %s %s %s :%s",
+ me.name, source_p->name, source_p->username,
+ source_p->host, source_p->user->server,
+ user, host, reason);
+ return 0;
+}
+
+/* mc_gline()
+ */
+static int
+mc_gline(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *acptr;
+ const char *user;
+ const char *host;
+ char *reason;
+ char *ptr;
+
+ /* hyb6 allows empty gline reasons */
+ if(parc < 4 || EmptyString(parv[3]))
+ return 0;
+
+ acptr = source_p;
+
+ user = parv[1];
+ host = parv[2];
+ reason = LOCAL_COPY(parv[3]);
+
+ if(invalid_gline(acptr, user, host, reason))
+ return 0;
+
+ sendto_server(client_p, NULL, CAP_GLN|CAP_TS6, NOCAPS,
+ ":%s GLINE %s %s :%s",
+ use_id(acptr), user, host, reason);
+ sendto_server(client_p, NULL, CAP_GLN, CAP_TS6,
+ ":%s GLINE %s %s :%s",
+ acptr->name, user, host, reason);
+ sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
+ ":%s GLINE %s %s %s %s %s %s :%s",
+ acptr->user->server, acptr->name,
+ acptr->username, acptr->host,
+ acptr->user->server, user, host, reason);
+
+ if(!ConfigFileEntry.glines)
+ return 0;
+
+ /* check theres enough non-wildcard chars */
+ if(check_wild_gline(user, host))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s is requesting a gline without "
+ "%d non-wildcard characters for [%s@%s] [%s]",
+ acptr->name, acptr->username,
+ acptr->host, acptr->user->server,
+ ConfigFileEntry.min_nonwildcard,
+ user, host, reason);
+ return 0;
+ }
+
+ if((ptr = strchr(host, '/')) != NULL)
+ {
+ int bitlen;
+ bitlen = strtol(++ptr, NULL, 10);
+
+ /* ipv4? */
+ if(strchr(host, ':') == NULL)
+ {
+ if(bitlen < ConfigFileEntry.gline_min_cidr)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s!%s@%s on %s is requesting a "
+ "gline with a cidr mask < %d for [%s@%s] [%s]",
+ acptr->name, acptr->username, acptr->host,
+ acptr->user->server,
+ ConfigFileEntry.gline_min_cidr,
+ user, host, reason);
+ return 0;
+ }
+ }
+ /* ipv6 */
+ else if(bitlen < ConfigFileEntry.gline_min_cidr6)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s!%s@%s on %s is requesting a "
+ "gline with a cidr mask < %d for [%s@%s] [%s]",
+ acptr->name, acptr->username, acptr->host,
+ acptr->user->server,
+ ConfigFileEntry.gline_min_cidr6,
+ user, host, reason);
+ return 0;
+ }
+ }
+
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
+ acptr->name, acptr->username, acptr->host,
+ acptr->user->server, user, host, reason);
+
+ ilog(L_GLINE, "R %s %s %s %s %s %s %s",
+ source_p->name, source_p->username, source_p->host,
+ source_p->user->server, user, host, reason);
+
+ /* If at least 3 opers agree this user should be G lined then do it */
+ majority_gline(acptr, user, host, reason);
+
+ return 0;
+}
+
+
+/* ms_gline()
+ *
+ * inputs - The usual for a m_ function
+ * output -
+ * side effects - attempts to place a gline, if 3 opers agree
+ */
+static int
+ms_gline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *acptr;
+ const char *user;
+ const char *host;
+ char *reason;
+
+ /* hyb6 allows empty gline reasons */
+ if(parc < 8 || EmptyString(parv[7]))
+ return 0;
+
+ /* client doesnt exist.. someones messing */
+ if((acptr = find_client(parv[1])) == NULL)
+ return 0;
+
+ /* client that sent the gline, isnt on the server that sent
+ * the gline out. somethings fucked.
+ */
+ if(acptr->servptr != source_p)
+ return 0;
+
+ user = parv[5];
+ host = parv[6];
+ reason = LOCAL_COPY(parv[7]);
+
+ if(invalid_gline(acptr, user, host, reason))
+ return 0;
+
+ sendto_server(client_p, NULL, CAP_GLN|CAP_TS6, NOCAPS,
+ ":%s GLINE %s %s :%s",
+ use_id(acptr), user, host, reason);
+ sendto_server(client_p, NULL, CAP_GLN, CAP_TS6,
+ ":%s GLINE %s %s :%s",
+ acptr->name, user, host, reason);
+ sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
+ ":%s GLINE %s %s %s %s %s %s :%s",
+ acptr->user->server, acptr->name,
+ acptr->username, acptr->host,
+ acptr->user->server, user, host, reason);
+
+ if(!ConfigFileEntry.glines)
+ return 0;
+
+ /* check theres enough non-wildcard chars */
+ if(check_wild_gline(user, host))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s is requesting a gline without "
+ "%d non-wildcard characters for [%s@%s] [%s]",
+ acptr->name, acptr->username,
+ acptr->host, acptr->user->server,
+ ConfigFileEntry.min_nonwildcard,
+ user, host, reason);
+ return 0;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
+ acptr->name, acptr->username, acptr->host,
+ acptr->user->server, user, host, reason);
+
+ ilog(L_GLINE, "R %s %s %s %s %s %s %s",
+ acptr->name, acptr->username, acptr->host,
+ acptr->user->server, user, host, reason);
+
+ /* If at least 3 opers agree this user should be G lined then do it */
+ majority_gline(acptr, user, host, reason);
+
+ return 0;
+}
+
+/* mo_ungline()
+ *
+ * parv[0] = sender nick
+ * parv[1] = gline to remove
+ */
+static int
+mo_ungline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *user;
+ char *h = LOCAL_COPY(parv[1]);
+ char *host;
+ char splat[] = "*";
+
+ if(!ConfigFileEntry.glines)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :UNGLINE disabled, perhaps you want UNKLINE?", me.name, parv[0]);
+ return 0;
+ }
+
+ if(!IsOperUnkline(source_p) || !IsOperGline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "unkline");
+ return 0;
+ }
+
+ if((host = strchr(h, '@')) || *h == '*')
+ {
+ /* Explicit user@host mask given */
+
+ if(host)
+ {
+ *host++ = '\0';
+
+ /* check for @host */
+ if(*h)
+ user = h;
+ else
+ user = splat;
+
+ if(!*host)
+ host = splat;
+ }
+ else
+ {
+ user = splat;
+ host = h;
+ }
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters", me.name, parv[0]);
+ return 0;
+ }
+
+ if(remove_temp_gline(user, host))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Un-glined [%s@%s]",
+ me.name, parv[0], user, host);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the G-Line for: [%s@%s]",
+ get_oper_name(source_p), user, host);
+ ilog(L_GLINE, "U %s %s %s %s %s %s",
+ source_p->name, source_p->username, source_p->host,
+ source_p->user->server, user, host);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :No G-Line for %s@%s",
+ me.name, parv[0], user, host);
+ }
+
+ return 0;
+}
+
+/*
+ * check_wild_gline
+ *
+ * inputs - user, host of gline
+ * output - 1 if not enough non-wildchar char's, 0 if ok
+ * side effects - NONE
+ */
+static int
+check_wild_gline(const char *user, const char *host)
+{
+ const char *p;
+ char tmpch;
+ int nonwild;
+
+ nonwild = 0;
+ p = user;
+
+ while ((tmpch = *p++))
+ {
+ if(!IsKWildChar(tmpch))
+ {
+ /* enough of them, break */
+ if(++nonwild >= ConfigFileEntry.min_nonwildcard)
+ break;
+ }
+ }
+
+ if(nonwild < ConfigFileEntry.min_nonwildcard)
+ {
+ /* user doesnt, try host */
+ p = host;
+ while ((tmpch = *p++))
+ {
+ if(!IsKWildChar(tmpch))
+ if(++nonwild >= ConfigFileEntry.min_nonwildcard)
+ break;
+ }
+ }
+
+ if(nonwild < ConfigFileEntry.min_nonwildcard)
+ return 1;
+ else
+ return 0;
+}
+
+/* invalid_gline
+ *
+ * inputs - pointer to source client, ident, host and reason
+ * outputs - 1 if invalid, 0 if valid
+ * side effects -
+ */
+static int
+invalid_gline(struct Client *source_p, const char *luser,
+ const char *lhost, char *lreason)
+{
+ if(strchr(luser, '!'))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid character '!' in gline",
+ me.name, source_p->name);
+ return 1;
+ }
+
+ if(strlen(lreason) > REASONLEN)
+ lreason[REASONLEN] = '\0';
+
+ return 0;
+}
+
+/*
+ * set_local_gline
+ *
+ * inputs - pointer to oper nick/username/host/server,
+ * victim user/host and reason
+ * output - NONE
+ * side effects -
+ */
+static void
+set_local_gline(struct Client *source_p, const char *user,
+ const char *host, const char *reason)
+{
+ char buffer[IRCD_BUFSIZE];
+ struct ConfItem *aconf;
+ const char *current_date;
+ char *my_reason;
+ char *oper_reason;
+
+ current_date = smalldate();
+
+ my_reason = LOCAL_COPY(reason);
+
+ aconf = make_conf();
+ aconf->status = CONF_GLINE;
+ aconf->flags |= CONF_FLAGS_TEMPORARY;
+
+ if(strlen(my_reason) > REASONLEN)
+ my_reason[REASONLEN-1] = '\0';
+
+ if((oper_reason = strchr(my_reason, '|')) != NULL)
+ {
+ *oper_reason = '\0';
+ oper_reason++;
+
+ if(!EmptyString(oper_reason))
+ DupString(aconf->spasswd, oper_reason);
+ }
+
+ ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
+
+ DupString(aconf->passwd, buffer);
+ DupString(aconf->user, user);
+ DupString(aconf->host, host);
+ aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
+ add_gline(aconf);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s on %s has triggered gline for [%s@%s] [%s]",
+ source_p->name, source_p->username,
+ source_p->host, source_p->user->server,
+ user, host, reason);
+ ilog(L_GLINE, "T %s %s %s %s %s %s %s",
+ source_p->name, source_p->username, source_p->host,
+ source_p->user->server, user, host, reason);
+
+ check_glines();
+}
+
+/* majority_gline()
+ *
+ * input - client doing gline, user, host and reason of gline
+ * output - YES if there are 3 different opers/servers agree, else NO
+ * side effects -
+ */
+static int
+majority_gline(struct Client *source_p, const char *user,
+ const char *host, const char *reason)
+{
+ dlink_node *pending_node;
+ struct gline_pending *pending;
+
+ /* to avoid desync.. --fl */
+ cleanup_glines(NULL);
+
+ /* if its already glined, why bother? :) -- fl_ */
+ if(find_is_glined(host, user))
+ return NO;
+
+ DLINK_FOREACH(pending_node, pending_glines.head)
+ {
+ pending = pending_node->data;
+
+ if((irccmp(pending->user, user) == 0) &&
+ (irccmp(pending->host, host) == 0))
+ {
+ /* check oper or server hasnt already voted */
+ if(((irccmp(pending->oper_user1, source_p->username) == 0) ||
+ (irccmp(pending->oper_host1, source_p->host) == 0)))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "oper has already voted");
+ return NO;
+ }
+ else if(irccmp(pending->oper_server1, source_p->user->server) == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "server has already voted");
+ return NO;
+ }
+
+ if(pending->oper_user2[0] != '\0')
+ {
+ /* if two other opers on two different servers have voted yes */
+ if(((irccmp(pending->oper_user2, source_p->username) == 0) ||
+ (irccmp(pending->oper_host2, source_p->host) == 0)))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "oper has already voted");
+ return NO;
+ }
+ else if(irccmp(pending->oper_server2, source_p->user->server) == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "server has already voted");
+ return NO;
+ }
+
+ /* trigger the gline using the original reason --fl */
+ set_local_gline(source_p, user, host,
+ pending->reason1);
+
+ cleanup_glines(NULL);
+ return YES;
+ }
+ else
+ {
+ strlcpy(pending->oper_nick2, source_p->name,
+ sizeof(pending->oper_nick2));
+ strlcpy(pending->oper_user2, source_p->username,
+ sizeof(pending->oper_user2));
+ strlcpy(pending->oper_host2, source_p->host,
+ sizeof(pending->oper_host2));
+ DupString(pending->reason2, reason);
+ pending->oper_server2 = find_or_add(source_p->user->server);
+ pending->last_gline_time = CurrentTime;
+ pending->time_request2 = CurrentTime;
+ return NO;
+ }
+ }
+ }
+
+ /* no pending gline, create a new one */
+ pending = (struct gline_pending *)
+ MyMalloc(sizeof(struct gline_pending));
+
+ strlcpy(pending->oper_nick1, source_p->name,
+ sizeof(pending->oper_nick1));
+ strlcpy(pending->oper_user1, source_p->username,
+ sizeof(pending->oper_user1));
+ strlcpy(pending->oper_host1, source_p->host,
+ sizeof(pending->oper_host1));
+
+ pending->oper_server1 = find_or_add(source_p->user->server);
+
+ strlcpy(pending->user, user, sizeof(pending->user));
+ strlcpy(pending->host, host, sizeof(pending->host));
+ DupString(pending->reason1, reason);
+ pending->reason2 = NULL;
+
+ pending->last_gline_time = CurrentTime;
+ pending->time_request1 = CurrentTime;
+
+ dlinkAddAlloc(pending, &pending_glines);
+
+ return NO;
+}
+
+/* remove_temp_gline()
+ *
+ * inputs - username, hostname to ungline
+ * outputs -
+ * side effects - tries to ungline anything that matches
+ */
+static int
+remove_temp_gline(const char *user, const char *host)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ struct irc_sockaddr_storage addr, caddr;
+ int bits, cbits;
+ int mtype, gtype;
+
+ mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits);
+
+ DLINK_FOREACH(ptr, glines.head)
+ {
+ aconf = ptr->data;
+
+ gtype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
+
+ if(gtype != mtype || (user && irccmp(user, aconf->user)))
+ continue;
+
+ if(gtype == HM_HOST)
+ {
+ if(irccmp(aconf->host, host))
+ continue;
+ }
+ else if(bits != cbits ||
+ !comp_with_mask_sock((struct sockaddr *)&addr,
+ (struct sockaddr *)&caddr, bits))
+ continue;
+
+ dlinkDestroy(ptr, &glines);
+ delete_one_address_conf(aconf->host, aconf);
+ return YES;
+ }
+
+ return NO;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_help.c: Provides help information to a user/operator.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_help.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "msg.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "parse.h"
+#include "modules.h"
+#include "hash.h"
+#include "cache.h"
+
+static int m_help(struct Client *, struct Client *, int, const char **);
+static int mo_help(struct Client *, struct Client *, int, const char **);
+static int mo_uhelp(struct Client *, struct Client *, int, const char **);
+static void dohelp(struct Client *, int, const char *);
+
+struct Message help_msgtab = {
+ "HELP", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_help, 0}, mg_ignore, mg_ignore, mg_ignore, {mo_help, 0}}
+};
+struct Message uhelp_msgtab = {
+ "UHELP", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_help, 0}, mg_ignore, mg_ignore, mg_ignore, {mo_uhelp, 0}}
+};
+
+mapi_clist_av1 help_clist[] = { &help_msgtab, &uhelp_msgtab, NULL };
+DECLARE_MODULE_AV1(help, NULL, NULL, help_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_help - HELP message handler
+ * parv[0] = sender prefix
+ */
+static int
+m_help(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+
+ /* HELP is always local */
+ if((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "HELP");
+ sendto_one(source_p, form_str(RPL_ENDOFHELP),
+ me.name, source_p->name,
+ (parc > 1 && !EmptyString(parv[1])) ? parv[1] : "index");
+ return 0;
+ }
+ else
+ {
+ last_used = CurrentTime;
+ }
+
+ dohelp(source_p, HELP_USER, parc > 1 ? parv[1] : NULL);
+
+ return 0;
+}
+
+/*
+ * mo_help - HELP message handler
+ * parv[0] = sender prefix
+ */
+static int
+mo_help(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ dohelp(source_p, HELP_OPER, parc > 1 ? parv[1] : NULL);
+ return 0;
+}
+
+/*
+ * mo_uhelp - HELP message handler
+ * This is used so that opers can view the user help file without deopering
+ * parv[0] = sender prefix
+ */
+static int
+mo_uhelp(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ dohelp(source_p, HELP_USER, parc > 1 ? parv[1] : NULL);
+ return 0;
+}
+
+static void
+dohelp(struct Client *source_p, int flags, const char *topic)
+{
+ static const char ntopic[] = "index";
+ struct cachefile *hptr;
+ struct cacheline *lineptr;
+ dlink_node *ptr;
+ dlink_node *fptr;
+
+ if(EmptyString(topic))
+ topic = ntopic;
+
+ hptr = hash_find_help(topic, flags);
+
+ if(hptr == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_HELPNOTFOUND),
+ me.name, source_p->name, topic);
+ return;
+ }
+
+ fptr = hptr->contents.head;
+ lineptr = fptr->data;
+
+ /* first line cant be empty */
+ sendto_one(source_p, form_str(RPL_HELPSTART),
+ me.name, source_p->name, topic, lineptr->data);
+
+ DLINK_FOREACH(ptr, fptr->next)
+ {
+ lineptr = ptr->data;
+
+ sendto_one(source_p, form_str(RPL_HELPTXT),
+ me.name, source_p->name, topic, lineptr->data);
+ }
+
+ sendto_one(source_p, form_str(RPL_ENDOFHELP),
+ me.name, source_p->name, topic);
+ return;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_info.c: Sends information about the server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_info.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "m_info.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "hook.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_user.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static void send_conf_options(struct Client *source_p);
+static void send_birthdate_online_time(struct Client *source_p);
+static void send_info_text(struct Client *source_p);
+static void info_spy(struct Client *);
+
+static int m_info(struct Client *, struct Client *, int, const char **);
+static int mo_info(struct Client *, struct Client *, int, const char **);
+
+struct Message info_msgtab = {
+ "INFO", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_info, 0}, {mo_info, 0}, mg_ignore, mg_ignore, {mo_info, 0}}
+};
+
+int doing_info_hook;
+
+mapi_clist_av1 info_clist[] = { &info_msgtab, NULL };
+mapi_hlist_av1 info_hlist[] = {
+ { "doing_info", &doing_info_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(info, NULL, NULL, info_clist, info_hlist, NULL, "$Revision: 3131 $");
+
+/*
+ * jdc -- Structure for our configuration value table
+ */
+struct InfoStruct
+{
+ const char *name; /* Displayed variable name */
+ unsigned int output_type; /* See below #defines */
+ void *option; /* Pointer reference to the value */
+ const char *desc; /* ASCII description of the variable */
+};
+/* Types for output_type in InfoStruct */
+#define OUTPUT_STRING 0x0001 /* Output option as %s w/ dereference */
+#define OUTPUT_STRING_PTR 0x0002 /* Output option as %s w/out deference */
+#define OUTPUT_DECIMAL 0x0004 /* Output option as decimal (%d) */
+#define OUTPUT_BOOLEAN 0x0008 /* Output option as "ON" or "OFF" */
+#define OUTPUT_BOOLEAN_YN 0x0010 /* Output option as "YES" or "NO" */
+#define OUTPUT_BOOLEAN2 0x0020 /* Output option as "YES/NO/MASKED" */
+
+/* *INDENT-OFF* */
+static struct InfoStruct info_table[] = {
+ /* --[ START OF TABLE ]-------------------------------------------- */
+ {
+ "opers_see_all_users",
+ OUTPUT_BOOLEAN_YN,
+ &opers_see_all_users,
+ "Farconnect notices available or operspy accountability limited"
+ },
+ {
+ "anti_nick_flood",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.anti_nick_flood,
+ "NICK flood protection"
+ },
+ {
+ "anti_spam_exit_message_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.anti_spam_exit_message_time,
+ "Duration a client must be connected for to have an exit message"
+ },
+ {
+ "caller_id_wait",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.caller_id_wait,
+ "Minimum delay between notifying UMODE +g users of messages"
+ },
+ {
+ "client_exit",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.client_exit,
+ "Prepend 'Client Exit:' to user QUIT messages"
+ },
+ {
+ "client_flood",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.client_flood,
+ "Number of lines before a client Excess Flood's",
+ },
+ {
+ "connect_timeout",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.connect_timeout,
+ "Connect timeout for connections to servers"
+ },
+ {
+ "default_floodcount",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.default_floodcount,
+ "Startup value of FLOODCOUNT",
+ },
+ {
+ "default_adminstring",
+ OUTPUT_STRING,
+ &ConfigFileEntry.default_adminstring,
+ "Default adminstring at startup.",
+ },
+ {
+ "default_operstring",
+ OUTPUT_STRING,
+ &ConfigFileEntry.default_operstring,
+ "Default operstring at startup.",
+ },
+ {
+ "servicestring",
+ OUTPUT_STRING,
+ &ConfigFileEntry.servicestring,
+ "String shown in whois for opered services.",
+ },
+ {
+ "disable_auth",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.disable_auth,
+ "Controls whether auth checking is disabled or not"
+ },
+ {
+ "disable_fake_channels",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.disable_fake_channels,
+ "Controls whether bold etc are disabled for JOIN"
+ },
+ {
+ "dot_in_ip6_addr",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.dot_in_ip6_addr,
+ "Suffix a . to ip6 addresses",
+ },
+ {
+ "dots_in_ident",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.dots_in_ident,
+ "Number of permissable dots in an ident"
+ },
+ {
+ "failed_oper_notice",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.failed_oper_notice,
+ "Inform opers if someone /oper's with the wrong password"
+ },
+ {
+ "fname_userlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_userlog,
+ "User log file"
+ },
+ {
+ "fname_fuserlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_fuserlog,
+ "Failed user log file"
+ },
+
+ {
+ "fname_operlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_operlog,
+ "Operator log file"
+ },
+ {
+ "fname_foperlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_foperlog,
+ "Failed operator log file"
+ },
+ {
+ "fname_serverlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_serverlog,
+ "Server connect/disconnect log file"
+ },
+ {
+ "fname_klinelog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_klinelog,
+ "KLINE etc log file"
+ },
+ {
+ "fname_glinelog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_glinelog,
+ "GLINE log file"
+ },
+ {
+ "fname_operspylog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_operspylog,
+ "Oper spy log file"
+ },
+ {
+ "fname_ioerrorlog",
+ OUTPUT_STRING,
+ &ConfigFileEntry.fname_ioerrorlog,
+ "IO error log file"
+ },
+ {
+ "glines",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.glines,
+ "G-line (network-wide K-line) support"
+ },
+ {
+ "gline_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_time,
+ "Expiry time for G-lines"
+ },
+ {
+ "gline_min_cidr",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_min_cidr,
+ "Minimum CIDR bitlen for ipv4 glines"
+ },
+ {
+ "gline_min_cidr6",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.gline_min_cidr6,
+ "Minimum CIDR bitlen for ipv6 glines"
+ },
+ {
+ "global_snotices",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.global_snotices,
+ "Send out certain server notices globally"
+ },
+ {
+ "hide_error_messages",
+ OUTPUT_BOOLEAN2,
+ &ConfigFileEntry.hide_error_messages,
+ "Hide ERROR messages coming from servers"
+ },
+ {
+ "hide_spoof_ips",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.hide_spoof_ips,
+ "Hide IPs of spoofed users"
+ },
+ {
+ "hub",
+ OUTPUT_BOOLEAN_YN,
+ &ServerInfo.hub,
+ "Server is a hub"
+ },
+ {
+ "idletime",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.idletime,
+ "Number of minutes before a client is considered idle"
+ },
+ {
+ "kline_delay",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.kline_delay,
+ "Duration of time to delay kline checking"
+ },
+ {
+ "kline_reason",
+ OUTPUT_STRING,
+ &ConfigFileEntry.kline_reason,
+ "K-lined clients sign off with this reason"
+ },
+ {
+ "dline_with_reason",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.dline_with_reason,
+ "Display D-line reason to client on disconnect"
+ },
+ {
+ "kline_with_reason",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.kline_with_reason,
+ "Display K-line reason to client on disconnect"
+ },
+ {
+ "max_accept",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_accept,
+ "Maximum nicknames on accept list",
+ },
+ {
+ "max_nick_changes",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_nick_changes,
+ "NICK change threshhold setting"
+ },
+ {
+ "max_nick_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_nick_time,
+ "NICK flood protection time interval"
+ },
+ {
+ "max_targets",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.max_targets,
+ "The maximum number of PRIVMSG/NOTICE targets"
+ },
+ {
+ "min_nonwildcard",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.min_nonwildcard,
+ "Minimum non-wildcard chars in K/G lines",
+ },
+ {
+ "min_nonwildcard_simple",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.min_nonwildcard_simple,
+ "Minimum non-wildcard chars in xlines/resvs",
+ },
+ {
+ "network_name",
+ OUTPUT_STRING,
+ &ServerInfo.network_name,
+ "Network name"
+ },
+ {
+ "network_desc",
+ OUTPUT_STRING,
+ &ServerInfo.network_desc,
+ "Network description"
+ },
+ {
+ "nick_delay",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.nick_delay,
+ "Delay nicks are locked for on split",
+ },
+ {
+ "no_oper_flood",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.no_oper_flood,
+ "Disable flood control for operators",
+ },
+ {
+ "non_redundant_klines",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.non_redundant_klines,
+ "Check for and disallow redundant K-lines"
+ },
+ {
+ "operspy_admin_only",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.operspy_admin_only,
+ "Send +Z operspy notices to admins only"
+ },
+ {
+ "operspy_dont_care_user_info",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.operspy_dont_care_user_info,
+ "Remove accountability and some '!' requirement from non-channel operspy"
+ },
+ {
+ "pace_wait",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.pace_wait,
+ "Minimum delay between uses of certain commands"
+ },
+ {
+ "pace_wait_simple",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.pace_wait_simple,
+ "Minimum delay between less intensive commands"
+ },
+ {
+ "ping_cookie",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.ping_cookie,
+ "Require ping cookies to connect",
+ },
+ {
+ "reject_after_count",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.reject_after_count,
+ "Client rejection threshold setting",
+ },
+ {
+ "reject_ban_time",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.reject_ban_time,
+ "Client rejection time interval",
+ },
+ {
+ "reject_duration",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.reject_duration,
+ "Client rejection cache duration",
+ },
+ {
+ "short_motd",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.short_motd,
+ "Do not show MOTD; only tell clients they should read it"
+ },
+ {
+ "stats_e_disabled",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_e_disabled,
+ "STATS e output is disabled",
+ },
+ {
+ "stats_c_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_c_oper_only,
+ "STATS C output is only shown to operators",
+ },
+ {
+ "stats_h_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_h_oper_only,
+ "STATS H output is only shown to operators",
+ },
+ {
+ "stats_i_oper_only",
+ OUTPUT_BOOLEAN2,
+ &ConfigFileEntry.stats_i_oper_only,
+ "STATS I output is only shown to operators",
+ },
+ {
+ "stats_k_oper_only",
+ OUTPUT_BOOLEAN2,
+ &ConfigFileEntry.stats_k_oper_only,
+ "STATS K output is only shown to operators",
+ },
+ {
+ "stats_o_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_o_oper_only,
+ "STATS O output is only shown to operators",
+ },
+ {
+ "stats_P_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_P_oper_only,
+ "STATS P is only shown to operators",
+ },
+ {
+ "stats_y_oper_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigFileEntry.stats_y_oper_only,
+ "STATS Y is only shown to operators",
+ },
+ {
+ "tkline_expire_notices",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.tkline_expire_notices,
+ "Notices given to opers when tklines expire"
+ },
+ {
+ "ts_max_delta",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.ts_max_delta,
+ "Maximum permitted TS delta from another server"
+ },
+ {
+ "ts_warn_delta",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.ts_warn_delta,
+ "Maximum permitted TS delta before displaying a warning"
+ },
+ {
+ "warn_no_nline",
+ OUTPUT_BOOLEAN,
+ &ConfigFileEntry.warn_no_nline,
+ "Display warning if connecting server lacks N-line"
+ },
+ {
+ "default_split_server_count",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.default_split_server_count,
+ "Startup value of SPLITNUM",
+ },
+ {
+ "default_split_user_count",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.default_split_user_count,
+ "Startup value of SPLITUSERS",
+ },
+ {
+ "knock_delay",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.knock_delay,
+ "Delay between a users KNOCK attempts"
+ },
+ {
+ "knock_delay_channel",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.knock_delay_channel,
+ "Delay between KNOCK attempts to a channel",
+ },
+ {
+ "invite_ops_only",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.invite_ops_only,
+ "INVITE is restricted to channelops only"
+ },
+ {
+ "kick_on_split_riding",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.kick_on_split_riding,
+ "Kick users riding splits to join +i or +k channels"
+ },
+ {
+ "max_bans",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_bans,
+ "Total +b/e/I/q modes allowed in a channel",
+ },
+ {
+ "max_bans_large",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_bans_large,
+ "Total +b/e/I/q modes allowed in a +L channel",
+ },
+ {
+ "max_chans_per_user",
+ OUTPUT_DECIMAL,
+ &ConfigChannel.max_chans_per_user,
+ "Maximum number of channels a user can join",
+ },
+ {
+ "no_create_on_split",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.no_create_on_split,
+ "Disallow creation of channels when split",
+ },
+ {
+ "no_join_on_split",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.no_join_on_split,
+ "Disallow joining channels when split",
+ },
+ {
+ "use_except",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.use_except,
+ "Enable chanmode +e (ban exceptions)",
+ },
+ {
+ "use_invex",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.use_invex,
+ "Enable chanmode +I (invite exceptions)",
+ },
+ {
+ "use_forward",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.use_forward,
+ "Enable chanmode +f (channel forwarding)",
+ },
+ {
+ "use_knock",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.use_knock,
+ "Enable /KNOCK",
+ },
+ {
+ "disable_hidden",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.disable_hidden,
+ "Prevent servers from hiding themselves from a flattened /links",
+ },
+ {
+ "flatten_links",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.flatten_links,
+ "Flatten /links list",
+ },
+ {
+ "hidden",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigServerHide.hidden,
+ "Hide this server from a flattened /links on remote servers",
+ },
+ {
+ "links_delay",
+ OUTPUT_DECIMAL,
+ &ConfigServerHide.links_delay,
+ "Links rehash delay"
+ },
+ /* --[ END OF TABLE ]---------------------------------------------- */
+ { (char *) 0, (unsigned int) 0, (void *) 0, (char *) 0}
+};
+/* *INDENT-ON* */
+
+/*
+** m_info
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static int
+m_info(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "INFO");
+ sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ info_spy(source_p);
+
+ send_info_text(source_p);
+ send_birthdate_online_time(source_p);
+
+ sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
+ return 0;
+}
+
+/*
+** mo_info
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static int
+mo_info(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) == HUNTED_ISME)
+ {
+ info_spy(source_p);
+
+ send_info_text(source_p);
+
+ if(IsOper(source_p))
+ send_conf_options(source_p);
+
+ send_birthdate_online_time(source_p);
+
+ sendto_one_numeric(source_p, RPL_ENDOFINFO, form_str(RPL_ENDOFINFO));
+ }
+
+ return 0;
+}
+
+/*
+ * send_info_text
+ *
+ * inputs - client pointer to send info text to
+ * output - none
+ * side effects - info text is sent to client
+ */
+static void
+send_info_text(struct Client *source_p)
+{
+ const char **text = infotext;
+
+ while (*text)
+ {
+ sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), *text++);
+ }
+
+ sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
+}
+
+/*
+ * send_birthdate_online_time
+ *
+ * inputs - client pointer to send to
+ * output - none
+ * side effects - birthdate and online time are sent
+ */
+static void
+send_birthdate_online_time(struct Client *source_p)
+{
+ sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p), creation, generation);
+
+ sendto_one(source_p, ":%s %d %s :On-line since %s",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p), myctime(startup_time));
+}
+
+/*
+ * send_conf_options
+ *
+ * inputs - client pointer to send to
+ * output - none
+ * side effects - send config options to client
+ */
+static void
+send_conf_options(struct Client *source_p)
+{
+ Info *infoptr;
+ int i = 0;
+
+ /*
+ * Now send them a list of all our configuration options
+ * (mostly from config.h)
+ */
+ for (infoptr = MyInformation; infoptr->name; infoptr++)
+ {
+ if(infoptr->intvalue)
+ {
+ sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ infoptr->name, infoptr->intvalue,
+ infoptr->desc);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ infoptr->name, infoptr->strvalue,
+ infoptr->desc);
+ }
+ }
+
+ /*
+ * Parse the info_table[] and do the magic.
+ */
+ for (i = 0; info_table[i].name; i++)
+ {
+ switch (info_table[i].output_type)
+ {
+ /*
+ * For "char *" references
+ */
+ case OUTPUT_STRING:
+ {
+ char *option = *((char **) info_table[i].option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ info_table[i].name,
+ option ? option : "NONE",
+ info_table[i].desc ? info_table[i].desc : "<none>");
+
+ break;
+ }
+ /*
+ * For "char foo[]" references
+ */
+ case OUTPUT_STRING_PTR:
+ {
+ char *option = (char *) info_table[i].option;
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ info_table[i].name,
+ EmptyString(option) ? "NONE" : option,
+ info_table[i].desc ? info_table[i].desc : "<none>");
+
+ break;
+ }
+ /*
+ * Output info_table[i].option as a decimal value.
+ */
+ case OUTPUT_DECIMAL:
+ {
+ int option = *((int *) info_table[i].option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ info_table[i].name,
+ option,
+ info_table[i].desc ? info_table[i].desc : "<none>");
+
+ break;
+ }
+
+ /*
+ * Output info_table[i].option as "ON" or "OFF"
+ */
+ case OUTPUT_BOOLEAN:
+ {
+ int option = *((int *) info_table[i].option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ info_table[i].name,
+ option ? "ON" : "OFF",
+ info_table[i].desc ? info_table[i].desc : "<none>");
+
+ break;
+ }
+ /*
+ * Output info_table[i].option as "YES" or "NO"
+ */
+ case OUTPUT_BOOLEAN_YN:
+ {
+ int option = *((int *) info_table[i].option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ get_id(&me, source_p), RPL_INFO,
+ get_id(source_p, source_p),
+ info_table[i].name,
+ option ? "YES" : "NO",
+ info_table[i].desc ? info_table[i].desc : "<none>");
+
+ break;
+ }
+
+ case OUTPUT_BOOLEAN2:
+ {
+ int option = *((int *) info_table[i].option);
+
+ sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
+ me.name, RPL_INFO, source_p->name,
+ info_table[i].name,
+ option ? ((option == 1) ? "MASK" : "YES") : "NO",
+ info_table[i].desc ? info_table[i].desc : "<none>");
+ } /* switch (info_table[i].output_type) */
+ }
+ } /* forloop */
+
+
+ /* Don't send oper_only_umodes...it's a bit mask, we will have to decode it
+ ** in order for it to show up properly to opers who issue INFO
+ */
+
+ sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
+}
+
+/* info_spy()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - hook doing_info is called
+ */
+static void
+info_spy(struct Client *source_p)
+{
+ hook_data hd;
+
+ hd.client = source_p;
+ hd.arg1 = hd.arg2 = NULL;
+
+ call_hook(doing_info_hook, &hd);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_invite.c: Invites the user to join a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_invite.c 718 2006-02-08 20:26:58Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "common.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static int m_invite(struct Client *, struct Client *, int, const char **);
+
+struct Message invite_msgtab = {
+ "INVITE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_invite, 3}, {m_invite, 3}, mg_ignore, mg_ignore, {m_invite, 3}}
+};
+mapi_clist_av1 invite_clist[] = { &invite_msgtab, NULL };
+DECLARE_MODULE_AV1(invite, NULL, NULL, invite_clist, NULL, NULL, "$Revision: 718 $");
+
+static void add_invite(struct Channel *, struct Client *);
+
+/* m_invite()
+ * parv[0] - sender prefix
+ * parv[1] - user to invite
+ * parv[2] - channel name
+ */
+static int
+m_invite(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+ int store_invite = 0;
+
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ if((target_p = find_person(parv[1])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK),
+ IsDigit(parv[1][0]) ? "*" : parv[1]);
+ return 0;
+ }
+
+ if(check_channel_name(parv[2]) == 0)
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME),
+ parv[2]);
+ return 0;
+ }
+
+ if(!IsChannelName(parv[2]))
+ {
+ if(MyClient(source_p))
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[2]);
+ return 0;
+ }
+
+ /* Do not send local channel invites to users if they are not on the
+ * same server as the person sending the INVITE message.
+ */
+ if(parv[2][0] == '&' && !MyConnect(target_p))
+ {
+ sendto_one(source_p, form_str(ERR_USERNOTONSERV),
+ me.name, source_p->name, target_p->name);
+ return 0;
+ }
+
+ if((chptr = find_channel(parv[2])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[2]);
+ return 0;
+ }
+
+ msptr = find_channel_membership(chptr, source_p);
+ if(MyClient(source_p) && (msptr == NULL))
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL), parv[2]);
+ return 0;
+ }
+
+ if(IsMember(target_p, chptr))
+ {
+ sendto_one_numeric(source_p, ERR_USERONCHANNEL,
+ form_str(ERR_USERONCHANNEL),
+ target_p->name, parv[2]);
+ return 0;
+ }
+
+ /* only store invites for +i channels */
+ /* if the invite could allow someone to join who otherwise could not,
+ * unconditionally require ops, unless the channel is +g */
+ if(ConfigChannel.invite_ops_only || (chptr->mode.mode & MODE_INVITEONLY))
+ {
+ /* treat remote clients as chanops */
+ if(MyClient(source_p) && !is_chanop(msptr) &&
+ !(chptr->mode.mode & MODE_FREEINVITE))
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, parv[2]);
+ return 0;
+ }
+
+ if(chptr->mode.mode & MODE_INVITEONLY)
+ store_invite = 1;
+ }
+
+ if(MyConnect(source_p))
+ {
+ sendto_one(source_p, form_str(RPL_INVITING),
+ me.name, source_p->name,
+ target_p->name, parv[2]);
+ if(target_p->user->away)
+ sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY),
+ target_p->name, target_p->user->away);
+ }
+ /* invite timestamp */
+ else if(parc > 3 && !EmptyString(parv[3]))
+ {
+ /* this should never be less than */
+ if(atol(parv[3]) > chptr->channelts)
+ return 0;
+ }
+
+ if(MyConnect(target_p))
+ {
+ sendto_one(target_p, ":%s!%s@%s INVITE %s :%s",
+ source_p->name, source_p->username, source_p->host,
+ target_p->name, chptr->chname);
+
+ if(store_invite)
+ add_invite(chptr, target_p);
+ }
+ else if(target_p->from != client_p)
+ {
+ sendto_one_prefix(target_p, source_p, "INVITE", "%s %lu",
+ chptr->chname, (unsigned long) chptr->channelts);
+ }
+
+ return 0;
+}
+
+/* add_invite()
+ *
+ * input - channel to add invite to, client to add
+ * output -
+ * side effects - client is added to invite list.
+ */
+static void
+add_invite(struct Channel *chptr, struct Client *who)
+{
+ dlink_node *ptr;
+
+ /* already invited? */
+ DLINK_FOREACH(ptr, who->user->invited.head)
+ {
+ if(ptr->data == chptr)
+ return;
+ }
+
+ /* ok, if their invite list is too long, remove the tail */
+ if((int)dlink_list_length(&who->user->invited) >=
+ ConfigChannel.max_chans_per_user)
+ {
+ ptr = who->user->invited.tail;
+ del_invite(ptr->data, who);
+ }
+
+ /* add user to channel invite list */
+ dlinkAddAlloc(who, &chptr->invites);
+
+ /* add channel to user invite list */
+ dlinkAddAlloc(chptr, &who->user->invited);
+}
+
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_ison.c: Provides a single line answer of whether a user is online.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_ison.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h" /* ConfigFileEntry */
+#include "s_serv.h" /* uplink/IsCapable */
+#include "hash.h"
+
+#include <string.h>
+
+static int m_ison(struct Client *, struct Client *, int, const char **);
+
+struct Message ison_msgtab = {
+ "ISON", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_ison, 2}, mg_ignore, mg_ignore, mg_ignore, {m_ison, 2}}
+};
+
+mapi_clist_av1 ison_clist[] = { &ison_msgtab, NULL };
+DECLARE_MODULE_AV1(ison, NULL, NULL, ison_clist, NULL, NULL, "$Revision: 254 $");
+
+static char buf[BUFSIZE];
+static char buf2[BUFSIZE];
+
+
+/*
+ * m_ison added by Darren Reed 13/8/91 to act as an efficent user indicator
+ * with respect to cpu/bandwidth used. Implemented for NOTIFY feature in
+ * clients. Designed to reduce number of whois requests. Can process
+ * nicknames in batches as long as the maximum buffer length.
+ *
+ * format:
+ * ISON :nicklist
+ */
+static int
+m_ison(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ char *nick;
+ char *p;
+ char *current_insert_point, *current_insert_point2;
+ int len;
+ int i;
+ int done = 0;
+
+ current_insert_point2 = buf2;
+ *buf2 = '\0';
+
+ ircsprintf(buf, form_str(RPL_ISON), me.name, source_p->name);
+ len = strlen(buf);
+ current_insert_point = buf + len;
+
+ /* rfc1489 is ambigious about how to handle ISON
+ * this should handle both interpretations.
+ */
+ for (i = 1; i < parc; i++)
+ {
+ char *cs = LOCAL_COPY(parv[i]);
+ for (nick = strtoken(&p, cs, " "); nick; nick = strtoken(&p, NULL, " "))
+ {
+ target_p = find_named_client(nick);
+
+ if(target_p != NULL)
+ {
+ len = strlen(target_p->name);
+ if((current_insert_point + (len + 5)) < (buf + sizeof(buf)))
+ {
+ memcpy((void *) current_insert_point,
+ (void *) target_p->name, len);
+ current_insert_point += len;
+ *current_insert_point++ = ' ';
+ }
+ else
+ {
+ done = 1;
+ break;
+ }
+ }
+ }
+ if(done)
+ break;
+ }
+
+ /* current_insert_point--;
+ * Do NOT take out the trailing space, it breaks ircII
+ * --Rodder */
+
+ *current_insert_point = '\0';
+ *current_insert_point2 = '\0';
+
+ sendto_one(source_p, "%s", buf);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_kline.c: Bans/unbans a user.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_kline.c 3063 2006-12-27 00:47:45Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "send.h"
+#include "hash.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "event.h"
+
+static int mo_kline(struct Client *, struct Client *, int, const char **);
+static int ms_kline(struct Client *, struct Client *, int, const char **);
+static int me_kline(struct Client *, struct Client *, int, const char **);
+static int mo_unkline(struct Client *, struct Client *, int, const char **);
+static int ms_unkline(struct Client *, struct Client *, int, const char **);
+static int me_unkline(struct Client *, struct Client *, int, const char **);
+
+struct Message kline_msgtab = {
+ "KLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_kline, 5}, {ms_kline, 5}, {me_kline, 5}, {mo_kline, 3}}
+};
+
+struct Message unkline_msgtab = {
+ "UNKLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_unkline, 4}, {ms_unkline, 4}, {me_unkline, 3}, {mo_unkline, 2}}
+};
+
+mapi_clist_av1 kline_clist[] = { &kline_msgtab, &unkline_msgtab, NULL };
+DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision: 3063 $");
+
+/* Local function prototypes */
+static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host);
+static int valid_comment(struct Client *source_p, char *comment);
+static int valid_user_host(struct Client *source_p, const char *user, const char *host);
+static int valid_wild_card(struct Client *source_p, const char *user, const char *host);
+
+static void handle_remote_kline(struct Client *source_p, int tkline_time,
+ const char *user, const char *host, const char *reason);
+static void apply_kline(struct Client *source_p, struct ConfItem *aconf,
+ const char *reason, const char *oper_reason, const char *current_date);
+static void apply_tkline(struct Client *source_p, struct ConfItem *aconf,
+ const char *, const char *, const char *, int);
+static int already_placed_kline(struct Client *, const char *, const char *, int);
+
+static void handle_remote_unkline(struct Client *source_p,
+ const char *user, const char *host);
+static void remove_permkline_match(struct Client *, const char *, const char *);
+static int flush_write(struct Client *, FILE *, const char *, const char *);
+static int remove_temp_kline(const char *, const char *);
+
+/* mo_kline()
+ *
+ * parv[1] - temp time or user@host
+ * parv[2] - user@host, "ON", or reason
+ * parv[3] - "ON", reason, or server to target
+ * parv[4] - server to target, or reason
+ * parv[5] - reason
+ */
+static int
+mo_kline(struct Client *client_p, struct Client *source_p,
+ int parc, const char **parv)
+{
+ char def[] = "No Reason";
+ char user[USERLEN + 2];
+ char host[HOSTLEN + 2];
+ char buffer[IRCD_BUFSIZE];
+ char *reason = def;
+ char *oper_reason;
+ const char *current_date;
+ const char *target_server = NULL;
+ struct ConfItem *aconf;
+ int tkline_time = 0;
+ int loc = 1;
+
+ if(!IsOperK(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "kline");
+ return 0;
+ }
+
+ if((tkline_time = valid_temp_time(parv[loc])) >= 0)
+ loc++;
+ /* we just set tkline_time to -1! */
+ else
+ tkline_time = 0;
+
+ if(find_user_host(source_p, parv[loc], user, host) == 0)
+ return 0;
+
+ loc++;
+
+ if(parc >= loc+2 && !irccmp(parv[loc], "ON"))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ target_server = parv[loc+1];
+ loc += 2;
+ }
+
+ if(parc <= loc || EmptyString(parv[loc]))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "KLINE");
+ return 0;
+ }
+
+ reason = LOCAL_COPY(parv[loc]);
+
+ if(target_server != NULL)
+ {
+ propagate_generic(source_p, "KLINE", target_server, CAP_KLN,
+ "%d %s %s :%s",
+ tkline_time, user, host, reason);
+
+ /* If we are sending it somewhere that doesnt include us, stop */
+ if(!match(target_server, me.name))
+ return 0;
+ }
+ /* if we have cluster servers, send it to them.. */
+ else if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_generic(source_p, "KLINE",
+ (tkline_time > 0) ? SHARED_TKLINE : SHARED_PKLINE, CAP_KLN,
+ "%lu %s %s :%s",
+ tkline_time, user, host, reason);
+
+ if(!valid_user_host(source_p, user, host) ||
+ !valid_wild_card(source_p, user, host) ||
+ !valid_comment(source_p, reason))
+ return 0;
+
+ if(already_placed_kline(source_p, user, host, tkline_time))
+ return 0;
+
+ set_time();
+ current_date = smalldate();
+ aconf = make_conf();
+ aconf->status = CONF_KILL;
+ DupString(aconf->host, host);
+ DupString(aconf->user, user);
+ aconf->port = 0;
+
+ /* Look for an oper reason */
+ if((oper_reason = strchr(reason, '|')) != NULL)
+ {
+ *oper_reason = '\0';
+ oper_reason++;
+
+ if(!EmptyString(oper_reason))
+ DupString(aconf->spasswd, oper_reason);
+ }
+
+ if(tkline_time > 0)
+ {
+ ircsnprintf(buffer, sizeof(buffer),
+ "Temporary K-line %d min. - %s (%s)",
+ (int) (tkline_time / 60), reason, current_date);
+ DupString(aconf->passwd, buffer);
+ apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
+ }
+ else
+ {
+ ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
+ DupString(aconf->passwd, buffer);
+ apply_kline(source_p, aconf, reason, oper_reason, current_date);
+ }
+
+ if(ConfigFileEntry.kline_delay)
+ {
+ if(kline_queued == 0)
+ {
+ eventAddOnce("check_klines", check_klines_event, NULL,
+ ConfigFileEntry.kline_delay);
+ kline_queued = 1;
+ }
+ }
+ else
+ check_klines();
+
+ return 0;
+}
+
+/* ms_kline()
+ *
+ * parv[1] - server targeted at
+ * parv[2] - tkline time (0 if perm)
+ * parv[3] - user
+ * parv[4] - host
+ * parv[5] - reason
+ */
+static int
+ms_kline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int tkline_time = atoi(parv[2]);
+
+ /* 1.5-3 and earlier contains a bug that allows remote klines to be
+ * sent with an empty reason field. This is a protocol violation,
+ * but its not worth dropping the link over.. --anfl
+ */
+ if(parc < 6 || EmptyString(parv[5]))
+ return 0;
+
+ propagate_generic(source_p, "KLINE", parv[1], CAP_KLN,
+ "%d %s %s :%s",
+ tkline_time, parv[3], parv[4], parv[5]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_kline(source_p, tkline_time, parv[3], parv[4], parv[5]);
+ return 0;
+}
+
+static int
+me_kline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* <tkline_time> <user> <host> :<reason> */
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_kline(source_p, atoi(parv[1]), parv[2], parv[3], parv[4]);
+ return 0;
+}
+
+static void
+handle_remote_kline(struct Client *source_p, int tkline_time,
+ const char *user, const char *host, const char *kreason)
+{
+ char buffer[BUFSIZE];
+ const char *current_date;
+ char *reason = LOCAL_COPY(kreason);
+ struct ConfItem *aconf = NULL;
+ char *oper_reason;
+
+ if(!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server,
+ (tkline_time > 0) ? SHARED_TKLINE : SHARED_PKLINE))
+ return;
+
+ if(!valid_user_host(source_p, user, host) ||
+ !valid_wild_card(source_p, user, host) ||
+ !valid_comment(source_p, reason))
+ return;
+
+ if(already_placed_kline(source_p, user, host, tkline_time))
+ return;
+
+ aconf = make_conf();
+
+ aconf->status = CONF_KILL;
+ DupString(aconf->user, user);
+ DupString(aconf->host, host);
+
+ /* Look for an oper reason */
+ if((oper_reason = strchr(reason, '|')) != NULL)
+ {
+ *oper_reason = '\0';
+ oper_reason++;
+
+ if(!EmptyString(oper_reason))
+ DupString(aconf->spasswd, oper_reason);
+ }
+
+ current_date = smalldate();
+
+ if(tkline_time > 0)
+ {
+ ircsnprintf(buffer, sizeof(buffer),
+ "Temporary K-line %d min. - %s (%s)",
+ (int) (tkline_time / 60), reason, current_date);
+ DupString(aconf->passwd, buffer);
+ apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
+ }
+ else
+ {
+ ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
+ DupString(aconf->passwd, buffer);
+ apply_kline(source_p, aconf, reason, oper_reason, current_date);
+ }
+
+ if(ConfigFileEntry.kline_delay)
+ {
+ if(kline_queued == 0)
+ {
+ eventAddOnce("check_klines", check_klines_event, NULL,
+ ConfigFileEntry.kline_delay);
+ kline_queued = 1;
+ }
+ }
+ else
+ check_klines();
+
+ return;
+}
+
+/* mo_unkline()
+ *
+ * parv[1] - kline to remove
+ * parv[2] - optional "ON"
+ * parv[3] - optional target server
+ */
+static int
+mo_unkline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *user;
+ char *host;
+ char splat[] = "*";
+ char *h = LOCAL_COPY(parv[1]);
+
+ if(!IsOperUnkline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "unkline");
+ return 0;
+ }
+
+ if((host = strchr(h, '@')) || *h == '*' || strchr(h, '.') || strchr(h, ':'))
+ {
+ /* Explicit user@host mask given */
+
+ if(host) /* Found user@host */
+ {
+ *host++ = '\0';
+
+ /* check for @host */
+ if(*h)
+ user = h;
+ else
+ user = splat;
+
+ /* check for user@ */
+ if(!*host)
+ host = splat;
+ }
+ else
+ {
+ user = splat; /* no @ found, assume its *@somehost */
+ host = h;
+ }
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters", me.name, source_p->name);
+ return 0;
+ }
+
+ /* possible remote kline.. */
+ if((parc > 3) && (irccmp(parv[2], "ON") == 0))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ propagate_generic(source_p, "UNKLINE", parv[3], CAP_UNKLN,
+ "%s %s", user, host);
+
+ if(match(parv[3], me.name) == 0)
+ return 0;
+ }
+ else if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_generic(source_p, "UNKLINE", SHARED_UNKLINE, CAP_UNKLN,
+ "%s %s", user, host);
+
+ if(remove_temp_kline(user, host))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Un-klined [%s@%s] from temporary k-lines",
+ me.name, parv[0], user, host);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the temporary K-Line for: [%s@%s]",
+ get_oper_name(source_p), user, host);
+ ilog(L_KLINE, "UK %s %s %s",
+ get_oper_name(source_p), user, host);
+ return 0;
+ }
+
+ remove_permkline_match(source_p, host, user);
+
+ return 0;
+}
+
+/* ms_unkline()
+ *
+ * parv[1] - target server
+ * parv[2] - user to unkline
+ * parv[3] - host to unkline
+ */
+static int
+ms_unkline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2] parv[3]
+ * oper target server user host */
+ propagate_generic(source_p, "UNKLINE", parv[1], CAP_UNKLN,
+ "%s %s", parv[2], parv[3]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unkline(source_p, parv[2], parv[3]);
+ return 0;
+}
+
+static int
+me_unkline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* user host */
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unkline(source_p, parv[1], parv[2]);
+ return 0;
+}
+
+static void
+handle_remote_unkline(struct Client *source_p, const char *user, const char *host)
+{
+ if(!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server, SHARED_UNKLINE))
+ return;
+
+ if(remove_temp_kline(user, host))
+ {
+ sendto_one_notice(source_p,
+ ":Un-klined [%s@%s] from temporary k-lines",
+ user, host);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the temporary K-Line for: [%s@%s]",
+ get_oper_name(source_p), user, host);
+
+ ilog(L_KLINE, "UK %s %s %s",
+ get_oper_name(source_p), user, host);
+ return;
+ }
+
+ remove_permkline_match(source_p, host, user);
+}
+
+/* apply_kline()
+ *
+ * inputs -
+ * output - NONE
+ * side effects - kline as given, is added to the hashtable
+ * and conf file
+ */
+static void
+apply_kline(struct Client *source_p, struct ConfItem *aconf,
+ const char *reason, const char *oper_reason, const char *current_date)
+{
+ add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf);
+ write_confitem(KLINE_TYPE, source_p, aconf->user, aconf->host,
+ reason, oper_reason, current_date, 0);
+}
+
+/* apply_tkline()
+ *
+ * inputs -
+ * output - NONE
+ * side effects - tkline as given is placed
+ */
+static void
+apply_tkline(struct Client *source_p, struct ConfItem *aconf,
+ const char *reason, const char *oper_reason, const char *current_date, int tkline_time)
+{
+ aconf->hold = CurrentTime + tkline_time;
+ add_temp_kline(aconf);
+
+ /* no oper reason.. */
+ if(EmptyString(oper_reason))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. K-Line for [%s@%s] [%s]",
+ get_oper_name(source_p), tkline_time / 60,
+ aconf->user, aconf->host, reason);
+ ilog(L_KLINE, "K %s %d %s %s %s",
+ get_oper_name(source_p), tkline_time / 60,
+ aconf->user, aconf->host, reason);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. K-Line for [%s@%s] [%s|%s]",
+ get_oper_name(source_p), tkline_time / 60,
+ aconf->user, aconf->host, reason, oper_reason);
+ ilog(L_KLINE, "K %s %d %s %s %s|%s",
+ get_oper_name(source_p), tkline_time / 60,
+ aconf->user, aconf->host, reason, oper_reason);
+ }
+
+ sendto_one_notice(source_p, ":Added temporary %d min. K-Line [%s@%s]",
+ tkline_time / 60, aconf->user, aconf->host);
+}
+
+/* find_user_host()
+ *
+ * inputs - client placing kline, user@host, user buffer, host buffer
+ * output - 0 if not ok to kline, 1 to kline i.e. if valid user host
+ * side effects -
+ */
+static int
+find_user_host(struct Client *source_p, const char *userhost, char *luser, char *lhost)
+{
+ char *hostp;
+
+ hostp = strchr(userhost, '@');
+
+ if(hostp != NULL) /* I'm a little user@host */
+ {
+ *(hostp++) = '\0'; /* short and squat */
+ if(*userhost)
+ strlcpy(luser, userhost, USERLEN + 1); /* here is my user */
+ else
+ strcpy(luser, "*");
+ if(*hostp)
+ strlcpy(lhost, hostp, HOSTLEN + 1); /* here is my host */
+ else
+ strcpy(lhost, "*");
+ }
+ else
+ {
+ /* no '@', no '.', so its not a user@host or host, therefore
+ * its a nick, which support was removed for.
+ */
+ if(strchr(userhost, '.') == NULL && strchr(userhost, ':') == NULL)
+ return 0;
+
+ luser[0] = '*'; /* no @ found, assume its *@somehost */
+ luser[1] = '\0';
+ strlcpy(lhost, userhost, HOSTLEN + 1);
+ }
+
+ return 1;
+}
+
+/* valid_user_host()
+ *
+ * inputs - user buffer, host buffer
+ * output - 0 if invalid, 1 if valid
+ * side effects -
+ */
+static int
+valid_user_host(struct Client *source_p, const char *luser, const char *lhost)
+{
+ /* # is invalid, as is '!' (n!u@h kline) */
+ if(strchr(lhost, '#') || strchr(luser, '#') || strchr(luser, '!'))
+ {
+ sendto_one_notice(source_p, ":Invalid K-Line");
+ return 0;
+ }
+
+ return 1;
+}
+
+/* valid_wild_card()
+ *
+ * input - user buffer, host buffer
+ * output - 0 if invalid, 1 if valid
+ * side effects -
+ */
+static int
+valid_wild_card(struct Client *source_p, const char *luser, const char *lhost)
+{
+ const char *p;
+ char tmpch;
+ int nonwild = 0;
+
+ /* check there are enough non wildcard chars */
+ p = luser;
+ while ((tmpch = *p++))
+ {
+ if(!IsKWildChar(tmpch))
+ {
+ /* found enough chars, return */
+ if(++nonwild >= ConfigFileEntry.min_nonwildcard)
+ return 1;
+ }
+ }
+
+ /* try host, as user didnt contain enough */
+ p = lhost;
+ while ((tmpch = *p++))
+ {
+ if(!IsKWildChar(tmpch))
+ if(++nonwild >= ConfigFileEntry.min_nonwildcard)
+ return 1;
+ }
+
+ sendto_one_notice(source_p,
+ ":Please include at least %d non-wildcard "
+ "characters with the user@host",
+ ConfigFileEntry.min_nonwildcard);
+ return 0;
+}
+
+/*
+ * valid_comment
+ * inputs - pointer to client
+ * - pointer to comment
+ * output - 0 if no valid comment, 1 if valid
+ * side effects - NONE
+ */
+static int
+valid_comment(struct Client *source_p, char *comment)
+{
+ if(strchr(comment, '"'))
+ {
+ sendto_one_notice(source_p, ":Invalid character '\"' in comment");
+ return 0;
+ }
+
+ if(strlen(comment) > REASONLEN)
+ comment[REASONLEN] = '\0';
+
+ return 1;
+}
+
+/* already_placed_kline()
+ *
+ * inputs - source to notify, user@host to check, tkline time
+ * outputs - 1 if a perm kline or a tkline when a tkline is being
+ * set exists, else 0
+ * side effects - notifies source_p kline exists
+ */
+/* Note: This currently works if the new K-line is a special case of an
+ * existing K-line, but not the other way round. To do that we would
+ * have to walk the hash and check every existing K-line. -A1kmm.
+ */
+static int
+already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int tkline)
+{
+ const char *reason;
+ struct irc_sockaddr_storage iphost, *piphost;
+ struct ConfItem *aconf;
+ int t;
+ if(ConfigFileEntry.non_redundant_klines)
+ {
+ if((t = parse_netmask(lhost, (struct sockaddr *)&iphost, NULL)) != HM_HOST)
+ {
+#ifdef IPV6
+ if(t == HM_IPV6)
+ t = AF_INET6;
+ else
+#endif
+ t = AF_INET;
+
+ piphost = &iphost;
+ }
+ else
+ piphost = NULL;
+
+ if((aconf = find_conf_by_address(lhost, NULL, NULL, (struct sockaddr *)piphost, CONF_KILL, t, luser)))
+ {
+ /* setting a tkline, or existing one is perm */
+ if(tkline || ((aconf->flags & CONF_FLAGS_TEMPORARY) == 0))
+ {
+ reason = aconf->passwd ? aconf->passwd : "<No Reason>";
+
+ sendto_one_notice(source_p,
+ ":[%s@%s] already K-Lined by [%s@%s] - %s",
+ luser, lhost, aconf->user,
+ aconf->host, reason);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* remove_permkline_match()
+ *
+ * hunts for a permanent kline, and removes it.
+ */
+static void
+remove_permkline_match(struct Client *source_p, const char *host, const char *user)
+{
+ FILE *in, *out;
+ int pairme = 0;
+ int error_on_write = NO;
+ char buf[BUFSIZE];
+ char matchbuf[BUFSIZE];
+ char temppath[BUFSIZE];
+ const char *filename;
+ mode_t oldumask;
+ int matchlen;
+
+ ircsnprintf(temppath, sizeof(temppath),
+ "%s.tmp", ConfigFileEntry.klinefile);
+
+ filename = get_conf_name(KLINE_TYPE);
+
+ if((in = fopen(filename, "r")) == 0)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", filename);
+ return;
+ }
+
+ oldumask = umask(0);
+ if((out = fopen(temppath, "w")) == 0)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", temppath);
+ fclose(in);
+ umask(oldumask);
+ return;
+ }
+
+ umask(oldumask);
+
+ snprintf(matchbuf, sizeof(matchbuf), "\"%s\",\"%s\"", user, host);
+ matchlen = strlen(matchbuf);
+
+ while (fgets(buf, sizeof(buf), in))
+ {
+ if(error_on_write)
+ break;
+
+ if(!strncasecmp(buf, matchbuf, matchlen))
+ {
+ pairme++;
+ break;
+ }
+ else
+ error_on_write = flush_write(source_p, out, buf, temppath);
+ }
+
+ /* we dropped out of the loop early because we found a match,
+ * to drop into this somewhat faster loop as we presume we'll never
+ * have two matching klines --anfl
+ */
+ if(pairme && !error_on_write)
+ {
+ while(fgets(buf, sizeof(buf), in))
+ {
+ if(error_on_write)
+ break;
+
+ error_on_write = flush_write(source_p, out, buf, temppath);
+ }
+ }
+
+ fclose(in);
+ if (fclose(out))
+ error_on_write = YES;
+
+ /* The result of the rename should be checked too... oh well */
+ /* If there was an error on a write above, then its been reported
+ * and I am not going to trash the original kline /conf file
+ */
+ if(error_on_write)
+ {
+ sendto_one_notice(source_p, ":Couldn't write temp kline file, aborted");
+ return;
+ }
+ else if(!pairme)
+ {
+ sendto_one_notice(source_p, ":No K-Line for %s@%s",
+ user, host);
+
+ if(temppath != NULL)
+ (void) unlink(temppath);
+
+ return;
+ }
+
+ if (rename(temppath, filename))
+ {
+ sendto_one_notice(source_p, ":Couldn't rename temp file, aborted");
+ return;
+ }
+ rehash_bans(0);
+
+ sendto_one_notice(source_p, ":K-Line for [%s@%s] is removed",
+ user, host);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the K-Line for: [%s@%s]",
+ get_oper_name(source_p), user, host);
+
+ ilog(L_KLINE, "UK %s %s %s",
+ get_oper_name(source_p), user, host);
+ return;
+}
+
+/*
+ * flush_write()
+ *
+ * inputs - pointer to client structure of oper requesting unkline
+ * - out is the file descriptor
+ * - buf is the buffer to write
+ * - ntowrite is the expected number of character to be written
+ * - temppath is the temporary file name to be written
+ * output - YES for error on write
+ * - NO for success
+ * side effects - if successful, the buf is written to output file
+ * if a write failure happesn, and the file pointed to
+ * by temppath, if its non NULL, is removed.
+ *
+ * The idea here is, to be as robust as possible when writing to the
+ * kline file.
+ *
+ * -Dianora
+ */
+
+static int
+flush_write(struct Client *source_p, FILE * out, const char *buf, const char *temppath)
+{
+ int error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+
+ if(error_on_write)
+ {
+ sendto_one_notice(source_p, ":Unable to write to %s",
+ temppath);
+ if(temppath != NULL)
+ (void) unlink(temppath);
+ }
+ return (error_on_write);
+}
+
+/* remove_temp_kline()
+ *
+ * inputs - username, hostname to unkline
+ * outputs -
+ * side effects - tries to unkline anything that matches
+ */
+static int
+remove_temp_kline(const char *user, const char *host)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ struct irc_sockaddr_storage addr, caddr;
+ int bits, cbits;
+ int mtype, ktype;
+ int i;
+
+ mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits);
+
+ for (i = 0; i < LAST_TEMP_TYPE; i++)
+ {
+ DLINK_FOREACH(ptr, temp_klines[i].head)
+ {
+ aconf = ptr->data;
+
+ ktype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
+
+ if(ktype != mtype || (user && irccmp(user, aconf->user)))
+ continue;
+
+ if(ktype == HM_HOST)
+ {
+ if(irccmp(aconf->host, host))
+ continue;
+ }
+ else if(bits != cbits ||
+ !comp_with_mask_sock((struct sockaddr *)&addr,
+ (struct sockaddr *)&caddr, bits))
+ continue;
+
+ dlinkDestroy(ptr, &temp_klines[i]);
+ delete_one_address_conf(aconf->host, aconf);
+ return YES;
+ }
+ }
+
+ return NO;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_knock.c: Requests to be invited to a channel.
+ *
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_knock.c 752 2006-02-11 20:55:03Z jilles $
+ */
+
+#include "stdinc.h"
+#include "sprintf_irc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+
+static int m_knock(struct Client *, struct Client *, int, const char **);
+
+struct Message knock_msgtab = {
+ "KNOCK", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_knock, 2}, {m_knock, 2}, mg_ignore, mg_ignore, {m_knock, 2}}
+};
+
+mapi_clist_av1 knock_clist[] = { &knock_msgtab, NULL };
+DECLARE_MODULE_AV1(knock, NULL, NULL, knock_clist, NULL, NULL, "$Revision: 752 $");
+
+/* m_knock
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ *
+ * The KNOCK command has the following syntax:
+ * :<sender> KNOCK <channel>
+ *
+ * If a user is not banned from the channel they can use the KNOCK
+ * command to have the server NOTICE the channel operators notifying
+ * they would like to join. Helpful if the channel is invite-only, the
+ * key is forgotten, or the channel is full (INVITE can bypass each one
+ * of these conditions. Concept by Dianora <db@db.net> and written by
+ * <anonymous>
+ */
+static int
+m_knock(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ char *p, *name;
+
+ if(MyClient(source_p) && ConfigChannel.use_knock == 0)
+ {
+ sendto_one(source_p, form_str(ERR_KNOCKDISABLED),
+ me.name, source_p->name);
+ return 0;
+ }
+
+ name = LOCAL_COPY(parv[1]);
+
+ /* dont allow one knock to multiple chans */
+ if((p = strchr(name, ',')))
+ *p = '\0';
+
+ if(!IsChannelName(name))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), name);
+ return 0;
+ }
+
+ if((chptr = find_channel(name)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), name);
+ return 0;
+ }
+
+ if(IsMember(source_p, chptr))
+ {
+ if(MyClient(source_p))
+ sendto_one(source_p, form_str(ERR_KNOCKONCHAN),
+ me.name, source_p->name, name);
+ return 0;
+ }
+
+ if(!((chptr->mode.mode & MODE_INVITEONLY) || (*chptr->mode.key) ||
+ (chptr->mode.limit &&
+ dlink_list_length(&chptr->members) >= (unsigned long)chptr->mode.limit)))
+ {
+ sendto_one_numeric(source_p, ERR_CHANOPEN,
+ form_str(ERR_CHANOPEN), name);
+ return 0;
+ }
+
+ /* cant knock to a +p channel */
+ if(HiddenChannel(chptr))
+ {
+ sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+ form_str(ERR_CANNOTSENDTOCHAN), name);
+ return 0;
+ }
+
+
+ if(MyClient(source_p))
+ {
+ /* don't allow a knock if the user is banned */
+ if(is_banned(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN ||
+ is_quieted(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN)
+ {
+ sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+ form_str(ERR_CANNOTSENDTOCHAN), name);
+ return 0;
+ }
+
+ /* local flood protection:
+ * allow one knock per user per knock_delay
+ * allow one knock per channel per knock_delay_channel
+ */
+ if(!IsOper(source_p) &&
+ (source_p->localClient->last_knock + ConfigChannel.knock_delay) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
+ me.name, source_p->name, name, "user");
+ return 0;
+ }
+ else if((chptr->last_knock + ConfigChannel.knock_delay_channel) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
+ me.name, source_p->name, name, "channel");
+ return 0;
+ }
+
+ /* ok, we actually can send the knock, tell client */
+ source_p->localClient->last_knock = CurrentTime;
+
+ sendto_one(source_p, form_str(RPL_KNOCKDLVR),
+ me.name, source_p->name, name);
+ }
+
+ chptr->last_knock = CurrentTime;
+
+ if(ConfigChannel.use_knock)
+ sendto_channel_local(ONLY_CHANOPS, chptr, form_str(RPL_KNOCK),
+ me.name, name, name, source_p->name,
+ source_p->username, source_p->host);
+
+ sendto_server(client_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS,
+ ":%s KNOCK %s", use_id(source_p), name);
+ sendto_server(client_p, chptr, CAP_KNOCK, CAP_TS6,
+ ":%s KNOCK %s", source_p->name, name);
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_links.c: Shows what servers are currently connected.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_links.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "hook.h"
+#include "cache.h"
+
+static int m_links(struct Client *, struct Client *, int, const char **);
+static int mo_links(struct Client *, struct Client *, int, const char **);
+
+struct Message links_msgtab = {
+ "LINKS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_links, 0}, {mo_links, 0}, mg_ignore, mg_ignore, {mo_links, 0}}
+};
+
+int doing_links_hook;
+
+mapi_clist_av1 links_clist[] = { &links_msgtab, NULL };
+mapi_hlist_av1 links_hlist[] = {
+ { "doing_links", &doing_links_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(links, NULL, NULL, links_clist, links_hlist, NULL, "$Revision: 254 $");
+
+static void send_links_cache(struct Client *source_p);
+
+/*
+ * m_links - LINKS message handler
+ * parv[0] = sender prefix
+ * parv[1] = servername mask
+ * or
+ * parv[0] = sender prefix
+ * parv[1] = server to query
+ * parv[2] = servername mask
+ */
+static int
+m_links(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(ConfigServerHide.flatten_links && !IsExemptShide(source_p))
+ send_links_cache(source_p);
+ else
+ mo_links(client_p, source_p, parc, parv);
+
+ return 0;
+}
+
+static int
+mo_links(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *mask = "";
+ struct Client *target_p;
+ char clean_mask[2 * HOSTLEN + 4];
+ hook_data hd;
+
+ dlink_node *ptr;
+
+ if(parc > 2)
+ {
+ if(hunt_server(client_p, source_p, ":%s LINKS %s :%s", 1, parc, parv)
+ != HUNTED_ISME)
+ return 0;
+
+ mask = parv[2];
+ }
+ else if(parc == 2)
+ mask = parv[1];
+
+ if(*mask) /* only necessary if there is a mask */
+ mask = collapse(clean_string
+ (clean_mask, (const unsigned char *) mask, 2 * HOSTLEN));
+
+ hd.client = source_p;
+ hd.arg1 = mask;
+ hd.arg2 = NULL;
+
+ call_hook(doing_links_hook, &hd);
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(*mask && !match(mask, target_p->name))
+ continue;
+
+ /* We just send the reply, as if theyre here theres either no SHIDE,
+ * or theyre an oper..
+ */
+ sendto_one_numeric(source_p, RPL_LINKS, form_str(RPL_LINKS),
+ target_p->name, target_p->serv->up,
+ target_p->hopcount,
+ target_p->info[0] ? target_p->info : "(Unknown Location)");
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFLINKS, form_str(RPL_ENDOFLINKS),
+ EmptyString(mask) ? "*" : mask);
+
+ return 0;
+}
+
+/* send_links_cache()
+ *
+ * inputs - client to send to
+ * outputs - the cached links, us, and RPL_ENDOFLINKS
+ * side effects -
+ */
+static void
+send_links_cache(struct Client *source_p)
+{
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, links_cache_list.head)
+ {
+ sendto_one(source_p, ":%s 364 %s %s",
+ me.name, source_p->name, (const char *)ptr->data);
+ }
+
+ sendto_one_numeric(source_p, RPL_LINKS, form_str(RPL_LINKS),
+ me.name, me.name, 0, me.info);
+
+ sendto_one_numeric(source_p, RPL_ENDOFLINKS, form_str(RPL_ENDOFLINKS), "*");
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_list.c: Shows what servers are currently connected.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_list_ratbox.c 722 2006-02-08 21:51:28Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "linebuf.h"
+
+static int m_list(struct Client *, struct Client *, int, const char **);
+static int mo_list(struct Client *, struct Client *, int, const char **);
+
+struct Message list_msgtab = {
+ "LIST", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_list, 0}, mg_ignore, mg_ignore, mg_ignore, {mo_list, 0}}
+};
+
+mapi_clist_av1 list_clist[] = { &list_msgtab, NULL };
+DECLARE_MODULE_AV1(list, NULL, NULL, list_clist, NULL, NULL, "$Revision: 722 $");
+
+static void list_all_channels(struct Client *source_p);
+static void list_limit_channels(struct Client *source_p, const char *param);
+static void list_named_channel(struct Client *source_p, const char *name);
+
+/* m_list()
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ */
+static int
+m_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ /* pace this due to the sheer traffic involved */
+ if(((last_used + ConfigFileEntry.pace_wait) > CurrentTime))
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "LIST");
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ /* If no arg, do all channels *whee*, else just one channel */
+ if(parc < 2 || EmptyString(parv[1]))
+ list_all_channels(source_p);
+ else if(IsChannelName(parv[1]))
+ list_named_channel(source_p, parv[1]);
+ else
+ list_limit_channels(source_p, parv[1]);
+
+ return 0;
+}
+
+/* mo_list()
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ */
+static int
+mo_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* If no arg, do all channels *whee*, else just one channel */
+ if(parc < 2 || EmptyString(parv[1]))
+ list_all_channels(source_p);
+ else if(IsChannelName(parv[1]))
+ list_named_channel(source_p, parv[1]);
+ else
+ list_limit_channels(source_p, parv[1]);
+
+ return 0;
+}
+
+/* list_all_channels()
+ *
+ * inputs - pointer to client requesting list
+ * output -
+ * side effects - list all channels to source_p
+ */
+static void
+list_all_channels(struct Client *source_p)
+{
+ struct Channel *chptr;
+ dlink_node *ptr;
+ int sendq_limit;
+
+ /* give them an output limit of 90% of their sendq. --fl */
+ sendq_limit = (int) get_sendq(source_p);
+ sendq_limit /= 10;
+ sendq_limit *= 9;
+
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+
+ /* if theyre overflowing their sendq, stop. --fl */
+ if(linebuf_len(&source_p->localClient->buf_sendq) > sendq_limit)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYMATCHES),
+ me.name, source_p->name, "LIST");
+ break;
+ }
+
+ if(SecretChannel(chptr) && !IsMember(source_p, chptr))
+ continue;
+
+ sendto_one(source_p, form_str(RPL_LIST),
+ me.name, source_p->name, chptr->chname,
+ dlink_list_length(&chptr->members),
+ chptr->topic == NULL ? "" : chptr->topic);
+ }
+
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+}
+
+static void
+list_limit_channels(struct Client *source_p, const char *param)
+{
+ struct Channel *chptr;
+ char *args;
+ char *p;
+ dlink_node *ptr;
+ unsigned int sendq_limit;
+ int max = INT_MAX;
+ int min = 0;
+ int i;
+
+ args = LOCAL_COPY(param);
+
+ for(i = 0; i < 2; i++)
+ {
+ if((p = strchr(args, ',')) != NULL)
+ *p++ = '\0';
+
+ if(*args == '<')
+ {
+ args++;
+ if((max = atoi(args)) <= 0)
+ max = INT_MAX;
+ }
+ else if(*args == '>')
+ {
+ args++;
+ if((min = atoi(args)) < 0)
+ min = 0;
+ }
+
+ if(EmptyString(p))
+ break;
+ else
+ args = p;
+ }
+
+ /* give them an output limit of 90% of their sendq. --fl */
+ sendq_limit = (unsigned int) get_sendq(source_p);
+ sendq_limit /= 10;
+ sendq_limit *= 9;
+
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+
+ /* if theyre overflowing their sendq, stop. --fl */
+ if(linebuf_len(&source_p->localClient->buf_sendq) > sendq_limit)
+ {
+ sendto_one(source_p, form_str(ERR_TOOMANYMATCHES),
+ me.name, source_p->name, "LIST");
+ break;
+ }
+
+ if(dlink_list_length(&chptr->members) >= max ||
+ dlink_list_length(&chptr->members) <= min)
+ continue;
+
+ if(SecretChannel(chptr) && !IsMember(source_p, chptr))
+ continue;
+
+ sendto_one(source_p, form_str(RPL_LIST),
+ me.name, source_p->name, chptr->chname,
+ dlink_list_length(&chptr->members),
+ chptr->topic == NULL ? "" : chptr->topic);
+ }
+
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+}
+
+
+/* list_named_channel()
+ *
+ * inputs - pointer to client requesting list
+ * output -
+ * side effects - list single channel to source
+ */
+static void
+list_named_channel(struct Client *source_p, const char *name)
+{
+ struct Channel *chptr;
+ char *p;
+ char *n = LOCAL_COPY(name);
+
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ if((p = strchr(n, ',')))
+ *p = '\0';
+
+ if(*n == '\0')
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), name);
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+ }
+
+ chptr = find_channel(n);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), n);
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+ }
+
+ if(ShowChannel(source_p, chptr))
+ sendto_one(source_p, form_str(RPL_LIST),
+ me.name, source_p->name, chptr->chname,
+ dlink_list_length(&chptr->members),
+ chptr->topic == NULL ? "" : chptr->topic);
+
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+}
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * m_list_safelist.c: Version of /list that uses the safelist code.
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_list_safelist.c 1393 2006-05-20 19:28:16Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "event.h"
+
+static dlink_list safelisting_clients = { NULL, NULL, 0 };
+
+static int _modinit(void);
+static void _moddeinit(void);
+
+static int m_list(struct Client *, struct Client *, int, const char **);
+static int mo_list(struct Client *, struct Client *, int, const char **);
+
+static void safelist_check_cliexit(hook_data_client_exit * hdata);
+static void safelist_client_instantiate(struct Client *, struct ListClient *);
+static void safelist_client_release(struct Client *);
+static void safelist_one_channel(struct Client *source_p, struct Channel *chptr);
+static void safelist_iterate_client(struct Client *source_p);
+static void safelist_iterate_clients(void *unused);
+static void safelist_channel_named(struct Client *source_p, const char *name);
+
+struct Message list_msgtab = {
+ "LIST", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_list, 0}, mg_ignore, mg_ignore, mg_ignore, {mo_list, 0}}
+};
+
+mapi_clist_av1 list_clist[] = { &list_msgtab, NULL };
+
+mapi_hfn_list_av1 list_hfnlist[] = {
+ {"client_exit", (hookfn) safelist_check_cliexit},
+ {NULL, NULL}
+};
+
+DECLARE_MODULE_AV1(list, _modinit, _moddeinit, list_clist, NULL, list_hfnlist, "$Revision: 1393 $");
+
+static int _modinit(void)
+{
+ eventAdd("safelist_iterate_clients", safelist_iterate_clients, NULL, 3);
+
+ return 0;
+}
+
+static void _moddeinit(void)
+{
+ eventDelete(safelist_iterate_clients, NULL);
+}
+
+static void safelist_check_cliexit(hook_data_client_exit * hdata)
+{
+ /* Cancel the safelist request if we are disconnecting
+ * from the server. That way it doesn't core. :P --nenolod
+ */
+ if (MyClient(hdata->target) && hdata->target->localClient->safelist_data != NULL)
+ {
+ safelist_client_release(hdata->target);
+ }
+}
+
+/* m_list()
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ *
+ * XXX - With SAFELIST, do we really need to continue pacing?
+ * In theory, the server cannot be lagged by this. --nenolod
+ */
+static int m_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ if (source_p->localClient->safelist_data != NULL)
+ {
+ sendto_one_notice(source_p, ":/LIST aborted");
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ safelist_client_release(source_p);
+ return 0;
+ }
+
+ if (parc < 2 || !IsChannelName(parv[1]))
+ {
+ /* pace this due to the sheer traffic involved */
+ if (((last_used + ConfigFileEntry.pace_wait) > CurrentTime))
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "LIST");
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ return mo_list(client_p, source_p, parc, parv);
+}
+
+/* mo_list()
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ */
+static int mo_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct ListClient params;
+ char *p, *args;
+ int i;
+
+ if (source_p->localClient->safelist_data != NULL)
+ {
+ sendto_one_notice(source_p, ":/LIST aborted");
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ safelist_client_release(source_p);
+ return 0;
+ }
+
+ /* XXX rather arbitrary -- jilles */
+ params.users_min = 3;
+ params.users_max = INT_MAX;
+
+ if (parc > 1 && parv[1] != NULL && !IsChannelName(parv[1]))
+ {
+ args = LOCAL_COPY(parv[1]);
+ /* Make any specification cancel out defaults */
+ if (*args == '<')
+ params.users_min = 0;
+
+ for (i = 0; i < 2; i++)
+ {
+ if ((p = strchr(args, ',')) != NULL)
+ *p++ = '\0';
+
+ if (*args == '<')
+ {
+ args++;
+ if (IsDigit(*args))
+ {
+ params.users_max = atoi(args);
+ if (params.users_max == 0)
+ params.users_max = INT_MAX;
+ else
+ params.users_max--;
+ }
+ else
+ params.users_max = INT_MAX;
+ }
+ else if (*args == '>')
+ {
+ args++;
+ if (IsDigit(*args))
+ params.users_min = atoi(args) + 1;
+ else
+ params.users_min = 0;
+ }
+
+ if (EmptyString(p))
+ break;
+ else
+ args = p;
+ }
+ }
+ else if (parc > 1 && IsChannelName(parv[1]))
+ {
+ safelist_channel_named(source_p, parv[1]);
+ return 0;
+ }
+
+ safelist_client_instantiate(source_p, ¶ms);
+
+ return 0;
+}
+
+/*
+ * safelist_sendq_exceeded()
+ *
+ * inputs - pointer to client that needs checking
+ * outputs - 1 if a client has exceeded the reserved
+ * sendq limit, 0 if not
+ * side effects - none
+ *
+ * When safelisting, we only use half of the SendQ at any
+ * given time.
+ */
+static int safelist_sendq_exceeded(struct Client *client_p)
+{
+ if (linebuf_len(&client_p->localClient->buf_sendq) > (get_sendq(client_p) / 2))
+ return YES;
+ else
+ return NO;
+}
+
+/*
+ * safelist_client_instantiate()
+ *
+ * inputs - pointer to Client to be listed,
+ * struct ListClient to copy for params
+ * outputs - none
+ * side effects - the safelist process begins for a
+ * client.
+ *
+ * Please do not ever call this on a non-local client.
+ * If you do, you will get SIGSEGV.
+ */
+static void safelist_client_instantiate(struct Client *client_p, struct ListClient *params)
+{
+ struct ListClient *self;
+
+ s_assert(MyClient(client_p));
+ s_assert(params != NULL);
+
+ self = MyMalloc(sizeof(struct ListClient));
+
+ self->hash_indice = 0;
+ self->users_min = params->users_min;
+ self->users_max = params->users_max;
+
+ client_p->localClient->safelist_data = self;
+
+ sendto_one(client_p, form_str(RPL_LISTSTART), me.name, client_p->name);
+
+ /* pop the client onto the queue for processing */
+ dlinkAddAlloc(client_p, &safelisting_clients);
+
+ /* give the user some initial data to work with */
+ safelist_iterate_client(client_p);
+}
+
+/*
+ * safelist_client_release()
+ *
+ * inputs - pointer to Client being listed on
+ * outputs - none
+ * side effects - the client is no longer being
+ * listed
+ *
+ * Please do not ever call this on a non-local client.
+ * If you do, you will get SIGSEGV.
+ */
+static void safelist_client_release(struct Client *client_p)
+{
+ s_assert(MyClient(client_p));
+
+ dlinkFindDestroy(client_p, &safelisting_clients);
+
+ MyFree(client_p->localClient->safelist_data);
+
+ client_p->localClient->safelist_data = NULL;
+
+ sendto_one(client_p, form_str(RPL_LISTEND), me.name, client_p->name);
+}
+
+/*
+ * safelist_channel_named()
+ *
+ * inputs - client pointer, channel name
+ * outputs - none
+ * side effects - a named channel is listed
+ */
+static void safelist_channel_named(struct Client *source_p, const char *name)
+{
+ struct Channel *chptr;
+ char *p;
+ char *n = LOCAL_COPY(name);
+
+ sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
+
+ if ((p = strchr(n, ',')))
+ *p = '\0';
+
+ if (*n == '\0')
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), name);
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+ }
+
+ chptr = find_channel(n);
+
+ if (chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), n);
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+ }
+
+ if (ShowChannel(source_p, chptr))
+ sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname,
+ dlink_list_length(&chptr->members),
+ chptr->topic == NULL ? "" : chptr->topic);
+
+ sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
+ return;
+}
+
+/*
+ * safelist_one_channel()
+ *
+ * inputs - client pointer and channel pointer
+ * outputs - none
+ * side effects - a channel is listed if it meets the
+ * requirements
+ */
+static void safelist_one_channel(struct Client *source_p, struct Channel *chptr)
+{
+ struct ListClient *safelist_data = source_p->localClient->safelist_data;
+
+ if (SecretChannel(chptr) && !IsMember(source_p, chptr))
+ return;
+
+ if ((unsigned int)chptr->members.length < safelist_data->users_min
+ || (unsigned int)chptr->members.length > safelist_data->users_max)
+ return;
+
+ sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname,
+ chptr->members.length, chptr->topic == NULL ? "" : chptr->topic);
+}
+
+/*
+ * safelist_iterate_client()
+ *
+ * inputs - client pointer
+ * outputs - none
+ * side effects - the client's sendq is filled up again
+ */
+static void safelist_iterate_client(struct Client *source_p)
+{
+ dlink_node *ptr;
+ int iter;
+
+ for (iter = source_p->localClient->safelist_data->hash_indice; iter < CH_MAX; iter++)
+ {
+ if (safelist_sendq_exceeded(source_p->from) == YES)
+ {
+ source_p->localClient->safelist_data->hash_indice = iter;
+ return;
+ }
+
+ DLINK_FOREACH(ptr, channelTable[iter].head)
+ safelist_one_channel(source_p, (struct Channel *) ptr->data);
+ }
+
+ safelist_client_release(source_p);
+}
+
+static void safelist_iterate_clients(void *unused)
+{
+ dlink_node *n, *n2;
+
+ DLINK_FOREACH_SAFE(n, n2, safelisting_clients.head)
+ safelist_iterate_client((struct Client *)n->data);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_locops.c: Sends a message to all operators on the local server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_locops.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+
+static int m_locops(struct Client *, struct Client *, int, const char **);
+static int ms_locops(struct Client *, struct Client *, int, const char **);
+static int me_locops(struct Client *, struct Client *, int, const char **);
+
+struct Message locops_msgtab = {
+ "LOCOPS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_locops, 3}, mg_ignore, {me_locops, 2}, {m_locops, 2}}
+};
+
+mapi_clist_av1 locops_clist[] = { &locops_msgtab, NULL };
+DECLARE_MODULE_AV1(locops, NULL, NULL, locops_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_locops - LOCOPS message handler
+ * (write to *all* local opers currently online)
+ * parv[0] = sender prefix
+ * parv[1] = message text
+ */
+static int
+m_locops(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_wallops_flags(UMODE_LOCOPS, source_p, "LOCOPS - %s", parv[1]);
+
+ if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_generic(source_p, "LOCOPS", SHARED_LOCOPS, CAP_CLUSTER,
+ ":%s", parv[1]);
+
+ return 0;
+}
+
+static int
+ms_locops(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2]
+ * oper target serv message
+ */
+ propagate_generic(source_p, "LOCOPS", parv[1], CAP_CLUSTER,
+ ":%s", parv[2]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(find_shared_conf("*", "*", source_p->user->server, SHARED_LOCOPS))
+ sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[2]);
+
+ return 0;
+}
+
+static int
+me_locops(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ if(!IsPerson(source_p))
+ return 0;
+
+ if(find_shared_conf("*", "*", source_p->user->server, SHARED_LOCOPS))
+ sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[1]);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_lusers.c: Sends user statistics.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_lusers.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h" /* hunt_server */
+#include "s_user.h" /* show_lusers */
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int m_lusers(struct Client *, struct Client *, int, const char **);
+static int ms_lusers(struct Client *, struct Client *, int, const char **);
+
+struct Message lusers_msgtab = {
+ "LUSERS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_lusers, 0}, {ms_lusers, 0}, mg_ignore, mg_ignore, {ms_lusers, 0}}
+};
+
+mapi_clist_av1 lusers_clist[] = { &lusers_msgtab, NULL };
+DECLARE_MODULE_AV1(lusers, NULL, NULL, lusers_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_lusers - LUSERS message handler
+ * parv[0] = sender
+ * parv[1] = host/server mask.
+ * parv[2] = server to query
+ *
+ * 199970918 JRL hacked to ignore parv[1] completely and require parc > 3
+ * to cause a force
+ */
+static int
+m_lusers(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+
+ if (parc > 2)
+ {
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "LUSERS");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ if(hunt_server(client_p, source_p, ":%s LUSERS %s :%s", 2, parc, parv) !=
+ HUNTED_ISME)
+ return 0;
+ }
+
+ show_lusers(source_p);
+
+ return 0;
+}
+
+/*
+ * ms_lusers - LUSERS message handler for servers and opers
+ * parv[0] = sender
+ * parv[1] = host/server mask.
+ * parv[2] = server to query
+ *
+ * 199970918 JRL hacked to ignore parv[1] completely and require parc > 3
+ * to cause a force
+ */
+static int
+ms_lusers(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc > 2)
+ {
+ if(hunt_server(client_p, source_p, ":%s LUSERS %s :%s", 2, parc, parv)
+ != HUNTED_ISME)
+ return 0;
+ }
+
+ show_lusers(source_p);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_map.c: Sends an Undernet compatible map to a user.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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
+ *
+ * $Id: m_map.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "modules.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "sprintf_irc.h"
+
+#define USER_COL 50 /* display | Users: %d at col 50 */
+
+static int m_map(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int mo_map(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message map_msgtab = {
+ "MAP", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_map, 0}, mg_ignore, mg_ignore, mg_ignore, {mo_map, 0}}
+};
+
+mapi_clist_av1 map_clist[] = { &map_msgtab, NULL };
+DECLARE_MODULE_AV1(map, NULL, NULL, map_clist, NULL, NULL, "$Revision: 254 $");
+
+static void dump_map(struct Client *client_p, struct Client *root, char *pbuf);
+
+static char buf[BUFSIZE];
+
+/* m_map
+** parv[0] = sender prefix
+*/
+static int
+m_map(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if((!IsExemptShide(source_p) && ConfigServerHide.flatten_links) ||
+ ConfigFileEntry.map_oper_only)
+ {
+ m_not_oper(client_p, source_p, parc, parv);
+ return 0;
+ }
+
+ dump_map(client_p, &me, buf);
+ sendto_one(client_p, form_str(RPL_MAPEND), me.name, client_p->name);
+ return 0;
+}
+
+/*
+** mo_map
+** parv[0] = sender prefix
+*/
+static int
+mo_map(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ dump_map(client_p, &me, buf);
+ sendto_one(client_p, form_str(RPL_MAPEND), me.name, client_p->name);
+
+ return 0;
+}
+
+/*
+** dump_map
+** dumps server map, called recursively.
+*/
+static void
+dump_map(struct Client *client_p, struct Client *root_p, char *pbuf)
+{
+ int cnt = 0, i = 0, len;
+ struct Client *server_p;
+ dlink_node *ptr;
+ *pbuf = '\0';
+
+ strlcat(pbuf, root_p->name, BUFSIZE);
+ if (has_id(root_p))
+ {
+ strlcat(pbuf, "[", BUFSIZE);
+ strlcat(pbuf, root_p->id, BUFSIZE);
+ strlcat(pbuf, "]", BUFSIZE);
+ }
+ len = strlen(buf);
+ buf[len] = ' ';
+
+ if(len < USER_COL)
+ {
+ for (i = len + 1; i < USER_COL; i++)
+ {
+ buf[i] = '-';
+ }
+ }
+
+ ircsnprintf(buf + USER_COL, BUFSIZE - USER_COL,
+ " | Users: %5lu (%4.1f%%)", dlink_list_length(&root_p->serv->users),
+ 100 * (float) dlink_list_length(&root_p->serv->users) / (float) Count.total);
+
+ sendto_one(client_p, form_str(RPL_MAP), me.name, client_p->name, buf);
+
+ if(root_p->serv->servers.head != NULL)
+ {
+ cnt += dlink_list_length(&root_p->serv->servers);
+
+ if(cnt)
+ {
+ if(pbuf > buf + 3)
+ {
+ pbuf[-2] = ' ';
+ if(pbuf[-3] == '`')
+ pbuf[-3] = ' ';
+ }
+ }
+ }
+ i = 1;
+ DLINK_FOREACH(ptr, root_p->serv->servers.head)
+ {
+ server_p = ptr->data;
+ *pbuf = ' ';
+ if(i < cnt)
+ *(pbuf + 1) = '|';
+ else
+ *(pbuf + 1) = '`';
+
+ *(pbuf + 2) = '-';
+ *(pbuf + 3) = ' ';
+ dump_map(client_p, server_p, pbuf + 4);
+
+ i++;
+ }
+}
--- /dev/null
+/* modules/m_monitor.c
+ *
+ * Copyright (C) 2005 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_monitor.c 312 2005-11-07 10:47:33Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "monitor.h"
+#include "numeric.h"
+#include "s_conf.h"
+
+static int m_monitor(struct Client *, struct Client *, int, const char **);
+
+struct Message monitor_msgtab = {
+ "MONITOR", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_monitor, 2}, mg_ignore, mg_ignore, mg_ignore, {m_monitor, 2}}
+};
+
+mapi_clist_av1 monitor_clist[] = { &monitor_msgtab, NULL };
+DECLARE_MODULE_AV1(monitor, NULL, NULL, monitor_clist, NULL, NULL, "$Revision: 312 $");
+
+static void
+add_monitor(struct Client *client_p, const char *nicks)
+{
+ char onbuf[BUFSIZE], offbuf[BUFSIZE];
+ struct Client *target_p;
+ struct monitor *monptr;
+ const char *name;
+ char *tmp;
+ char *p;
+ char *onptr, *offptr;
+ int mlen, arglen;
+ int cur_onlen, cur_offlen;
+
+ /* these two are same length, just diff numeric */
+ cur_offlen = cur_onlen = mlen = sprintf(onbuf, form_str(RPL_MONONLINE),
+ me.name, client_p->name, "");
+ sprintf(offbuf, form_str(RPL_MONOFFLINE),
+ me.name, client_p->name, "");
+
+ onptr = onbuf + mlen;
+ offptr = offbuf + mlen;
+
+ tmp = LOCAL_COPY(nicks);
+
+ for(name = strtoken(&p, tmp, ","); name; name = strtoken(&p, NULL, ","))
+ {
+ if(EmptyString(name) || strlen(name) > NICKLEN-1)
+ continue;
+
+ if(dlink_list_length(&client_p->localClient->monitor_list) >=
+ ConfigFileEntry.max_monitor)
+ {
+ char buf[100];
+
+ if(cur_onlen != mlen)
+ sendto_one(client_p, "%s", onbuf);
+ if(cur_offlen != mlen)
+ sendto_one(client_p, "%s", offbuf);
+
+ if(p)
+ snprintf(buf, sizeof(buf), "%s,%s", name, p);
+ else
+ snprintf(buf, sizeof(buf), "%s", name);
+
+ sendto_one(client_p, form_str(ERR_MONLISTFULL),
+ me.name, client_p->name,
+ ConfigFileEntry.max_monitor, buf);
+ return;
+ }
+
+ monptr = find_monitor(name, 1);
+
+ /* already monitoring this nick */
+ if(dlinkFind(client_p, &monptr->users))
+ continue;
+
+ dlinkAddAlloc(client_p, &monptr->users);
+ dlinkAddAlloc(monptr, &client_p->localClient->monitor_list);
+
+ if((target_p = find_named_person(name)) != NULL)
+ {
+ if(cur_onlen + strlen(target_p->name) +
+ strlen(target_p->username) + strlen(target_p->host) + 3 >= BUFSIZE-3)
+ {
+ sendto_one(client_p, "%s", onbuf);
+ cur_onlen = mlen;
+ onptr = onbuf + mlen;
+ }
+
+ if(cur_onlen != mlen)
+ {
+ *onptr++ = ',';
+ cur_onlen++;
+ }
+
+ arglen = sprintf(onptr, "%s!%s@%s",
+ target_p->name, target_p->username,
+ target_p->host);
+ onptr += arglen;
+ cur_onlen += arglen;
+ }
+ else
+ {
+ if(cur_offlen + strlen(name) + 1 >= BUFSIZE-3)
+ {
+ sendto_one(client_p, "%s", offbuf);
+ cur_offlen = mlen;
+ offptr = offbuf + mlen;
+ }
+
+ if(cur_offlen != mlen)
+ {
+ *offptr++ = ',';
+ cur_offlen++;
+ }
+
+ arglen = sprintf(offptr, "%s", name);
+ offptr += arglen;
+ cur_offlen += arglen;
+ }
+ }
+
+ if(cur_onlen != mlen)
+ sendto_one(client_p, "%s", onbuf);
+ if(cur_offlen != mlen)
+ sendto_one(client_p, "%s", offbuf);
+}
+
+static void
+del_monitor(struct Client *client_p, const char *nicks)
+{
+ struct monitor *monptr;
+ const char *name;
+ char *tmp;
+ char *p;
+
+ if(!dlink_list_length(&client_p->localClient->monitor_list))
+ return;
+
+ tmp = LOCAL_COPY(nicks);
+
+ for(name = strtoken(&p, tmp, ","); name; name = strtoken(&p, NULL, ","))
+ {
+ if(EmptyString(name))
+ continue;
+
+ /* not monitored */
+ if((monptr = find_monitor(name, 0)) == NULL)
+ continue;
+
+ dlinkFindDestroy(client_p, &monptr->users);
+ dlinkFindDestroy(monptr, &client_p->localClient->monitor_list);
+ }
+}
+
+static void
+list_monitor(struct Client *client_p)
+{
+ char buf[BUFSIZE];
+ struct monitor *monptr;
+ char *nbuf;
+ dlink_node *ptr;
+ int mlen, arglen, cur_len;
+
+ if(!dlink_list_length(&client_p->localClient->monitor_list))
+ {
+ sendto_one(client_p, form_str(RPL_ENDOFMONLIST),
+ me.name, client_p->name);
+ return;
+ }
+
+ cur_len = mlen = sprintf(buf, form_str(RPL_MONLIST),
+ me.name, client_p->name, "");
+ nbuf = buf + mlen;
+
+ DLINK_FOREACH(ptr, client_p->localClient->monitor_list.head)
+ {
+ monptr = ptr->data;
+
+ if(cur_len + strlen(monptr->name) + 1 >= BUFSIZE-3)
+ {
+ sendto_one(client_p, "%s", buf);
+ nbuf = buf + mlen;
+ cur_len = mlen;
+ }
+
+ if(cur_len != mlen)
+ {
+ *nbuf++ = ',';
+ cur_len++;
+ }
+
+ arglen = sprintf(nbuf, "%s", monptr->name);
+ cur_len += arglen;
+ nbuf += arglen;
+ }
+
+ sendto_one(client_p, "%s", buf);
+ sendto_one(client_p, form_str(RPL_ENDOFMONLIST),
+ me.name, client_p->name);
+}
+
+static void
+show_monitor_status(struct Client *client_p)
+{
+ char onbuf[BUFSIZE], offbuf[BUFSIZE];
+ struct Client *target_p;
+ struct monitor *monptr;
+ char *onptr, *offptr;
+ int cur_onlen, cur_offlen;
+ int mlen, arglen;
+ dlink_node *ptr;
+
+ mlen = cur_onlen = sprintf(onbuf, form_str(RPL_MONONLINE),
+ me.name, client_p->name, "");
+ cur_offlen = sprintf(offbuf, form_str(RPL_MONOFFLINE),
+ me.name, client_p->name, "");
+
+ onptr = onbuf + mlen;
+ offptr = offbuf + mlen;
+
+ DLINK_FOREACH(ptr, client_p->localClient->monitor_list.head)
+ {
+ monptr = ptr->data;
+
+ if((target_p = find_named_person(monptr->name)) != NULL)
+ {
+ if(cur_onlen + strlen(target_p->name) +
+ strlen(target_p->username) + strlen(target_p->host) + 3 >= BUFSIZE-3)
+ {
+ sendto_one(client_p, "%s", onbuf);
+ cur_onlen = mlen;
+ onptr = onbuf + mlen;
+ }
+
+ if(cur_onlen != mlen)
+ {
+ *onptr++ = ',';
+ cur_onlen++;
+ }
+
+ arglen = sprintf(onptr, "%s!%s@%s",
+ target_p->name, target_p->username,
+ target_p->host);
+ onptr += arglen;
+ cur_onlen += arglen;
+ }
+ else
+ {
+ if(cur_offlen + strlen(monptr->name) + 1 >= BUFSIZE-3)
+ {
+ sendto_one(client_p, "%s", offbuf);
+ cur_offlen = mlen;
+ offptr = offbuf + mlen;
+ }
+
+ if(cur_offlen != mlen)
+ {
+ *offptr++ = ',';
+ cur_offlen++;
+ }
+
+ arglen = sprintf(offptr, "%s", monptr->name);
+ offptr += arglen;
+ cur_offlen += arglen;
+ }
+ }
+
+ if(cur_onlen != mlen)
+ sendto_one(client_p, "%s", onbuf);
+ if(cur_offlen != mlen)
+ sendto_one(client_p, "%s", offbuf);
+}
+
+static int
+m_monitor(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ switch(parv[1][0])
+ {
+ case '+':
+ if(parc < 3 || EmptyString(parv[2]))
+ {
+ sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "MONITOR");
+ return 0;
+ }
+
+ add_monitor(source_p, parv[2]);
+ break;
+ case '-':
+ if(parc < 3 || EmptyString(parv[2]))
+ {
+ sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "MONITOR");
+ return 0;
+ }
+
+ del_monitor(source_p, parv[2]);
+ break;
+
+ case 'C':
+ case 'c':
+ clear_monitor(source_p);
+ break;
+
+ case 'L':
+ case 'l':
+ list_monitor(source_p);
+ break;
+
+ case 'S':
+ case 's':
+ show_monitor_status(source_p);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_motd.c: Shows the current message of the day.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_motd.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "tools.h"
+#include "ircd.h"
+#include "send.h"
+#include "numeric.h"
+#include "hook.h"
+#include "msg.h"
+#include "s_serv.h" /* hunt_server */
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "cache.h"
+
+static int m_motd(struct Client *, struct Client *, int, const char **);
+static int mo_motd(struct Client *, struct Client *, int, const char **);
+
+struct Message motd_msgtab = {
+ "MOTD", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_motd, 0}, {mo_motd, 0}, mg_ignore, mg_ignore, {mo_motd, 0}}
+};
+
+int doing_motd_hook;
+
+mapi_clist_av1 motd_clist[] = { &motd_msgtab, NULL };
+mapi_hlist_av1 motd_hlist[] = {
+ { "doing_motd", &doing_motd_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(motd, NULL, NULL, motd_clist, motd_hlist, NULL, "$Revision: 254 $");
+
+static void motd_spy(struct Client *);
+
+/*
+** m_motd
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static int
+m_motd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "MOTD");
+ sendto_one(source_p, form_str(RPL_ENDOFMOTD),
+ me.name, source_p->name);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ if(hunt_server(client_p, source_p, ":%s MOTD :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ motd_spy(source_p);
+ send_user_motd(source_p);
+
+ return 0;
+}
+
+/*
+** mo_motd
+** parv[0] = sender prefix
+** parv[1] = servername
+*/
+static int
+mo_motd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(hunt_server(client_p, source_p, ":%s MOTD :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ motd_spy(source_p);
+ send_user_motd(source_p);
+
+ return 0;
+}
+
+/* motd_spy()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - hook doing_motd is called
+ */
+static void
+motd_spy(struct Client *source_p)
+{
+ hook_data data;
+
+ data.client = source_p;
+ data.arg1 = data.arg2 = NULL;
+
+ call_hook(doing_motd_hook, &data);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_names.c: Shows the users who are online.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_names.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "sprintf_irc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int m_names(struct Client *, struct Client *, int, const char **);
+
+struct Message names_msgtab = {
+ "NAMES", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_names, 0}, mg_ignore, mg_ignore, mg_ignore, {m_names, 0}}
+};
+
+mapi_clist_av1 names_clist[] = { &names_msgtab, NULL };
+DECLARE_MODULE_AV1(names, NULL, NULL, names_clist, NULL, NULL, "$Revision: 254 $");
+
+static void names_global(struct Client *source_p);
+
+/************************************************************************
+ * m_names() - Added by Jto 27 Apr 1989
+ ************************************************************************/
+
+/*
+ * m_names
+ * parv[0] = sender prefix
+ * parv[1] = channel
+ */
+static int
+m_names(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+ struct Channel *chptr = NULL;
+ char *s;
+
+ if(parc > 1 && !EmptyString(parv[1]))
+ {
+ char *p = LOCAL_COPY(parv[1]);
+ if((s = strchr(p, ',')))
+ *s = '\0';
+
+ if(!check_channel_name(p))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME),
+ (unsigned char *) p);
+ return 0;
+ }
+
+ if((chptr = find_channel(p)) != NULL)
+ channel_member_names(chptr, source_p, 1);
+ else
+ sendto_one(source_p, form_str(RPL_ENDOFNAMES),
+ me.name, source_p->name, p);
+ }
+ else
+ {
+ if(!IsOper(source_p))
+ {
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "NAMES");
+ sendto_one(source_p, form_str(RPL_ENDOFNAMES),
+ me.name, source_p->name, "*");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ names_global(source_p);
+ sendto_one(source_p, form_str(RPL_ENDOFNAMES),
+ me.name, source_p->name, "*");
+ }
+
+ return 0;
+}
+
+/*
+ * names_global
+ *
+ * inputs - pointer to client struct requesting names
+ * output - none
+ * side effects - lists all non public non secret channels
+ */
+static void
+names_global(struct Client *source_p)
+{
+ int mlen;
+ int tlen;
+ int cur_len;
+ int dont_show = NO;
+ dlink_node *lp, *ptr;
+ struct Client *target_p;
+ struct Channel *chptr = NULL;
+ struct membership *msptr;
+ char buf[BUFSIZE];
+ char *t;
+
+ /* first do all visible channels */
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+ channel_member_names(chptr, source_p, 0);
+ }
+ cur_len = mlen = ircsprintf(buf, form_str(RPL_NAMREPLY),
+ me.name, source_p->name, "*", "*");
+ t = buf + mlen;
+
+ /* Second, do all clients in one big sweep */
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+ dont_show = NO;
+
+ if(!IsPerson(target_p) || IsInvisible(target_p))
+ continue;
+
+ /* we want to show -i clients that are either:
+ * a) not on any channels
+ * b) only on +p channels
+ *
+ * both were missed out above. if the target is on a
+ * common channel with source, its already been shown.
+ */
+ DLINK_FOREACH(lp, target_p->user->channel.head)
+ {
+ msptr = lp->data;
+ chptr = msptr->chptr;
+
+ if(PubChannel(chptr) || IsMember(source_p, chptr) ||
+ SecretChannel(chptr))
+ {
+ dont_show = YES;
+ break;
+ }
+ }
+
+ if(dont_show)
+ continue;
+
+ if((cur_len + NICKLEN + 2) > (BUFSIZE - 3))
+ {
+ sendto_one(source_p, "%s", buf);
+ cur_len = mlen;
+ t = buf + mlen;
+ }
+
+ tlen = ircsprintf(t, "%s ", target_p->name);
+ cur_len += tlen;
+ t += tlen;
+ }
+
+ if(cur_len > mlen)
+ sendto_one(source_p, "%s", buf);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_oper.c: Makes a user an IRC Operator.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_oper.c 1483 2006-05-27 18:58:12Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "s_user.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+#include "cache.h"
+
+static int m_oper(struct Client *, struct Client *, int, const char **);
+
+struct Message oper_msgtab = {
+ "OPER", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_oper, 3}, mg_ignore, mg_ignore, mg_ignore, {m_oper, 3}}
+};
+
+mapi_clist_av1 oper_clist[] = { &oper_msgtab, NULL };
+DECLARE_MODULE_AV1(oper, NULL, NULL, oper_clist, NULL, NULL, "$Revision: 1483 $");
+
+static int match_oper_password(const char *password, struct oper_conf *oper_p);
+extern char *crypt();
+
+/*
+ * m_oper
+ * parv[0] = sender prefix
+ * parv[1] = oper name
+ * parv[2] = oper password
+ */
+static int
+m_oper(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct oper_conf *oper_p;
+ const char *name;
+ const char *password;
+
+ name = parv[1];
+ password = parv[2];
+
+ if(IsOper(source_p))
+ {
+ sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
+ send_oper_motd(source_p);
+ return 0;
+ }
+
+ /* end the grace period */
+ if(!IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ oper_p = find_oper_conf(source_p->username, source_p->orighost,
+ source_p->sockhost, name);
+
+ if(oper_p == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
+ ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
+ name, source_p->name,
+ source_p->username, source_p->host, source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Failed OPER attempt - host mismatch by %s (%s@%s)",
+ source_p->name, source_p->username, source_p->host);
+ }
+
+ return 0;
+ }
+
+ if(match_oper_password(password, oper_p))
+ {
+ oper_up(source_p, oper_p);
+
+ ilog(L_OPERED, "OPER %s by %s!%s@%s (%s)",
+ name, source_p->name, source_p->username, source_p->host,
+ source_p->sockhost);
+ return 0;
+ }
+ else
+ {
+ sendto_one(source_p, form_str(ERR_PASSWDMISMATCH),
+ me.name, source_p->name);
+
+ ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)",
+ name, source_p->name, source_p->username, source_p->host,
+ source_p->sockhost);
+
+ if(ConfigFileEntry.failed_oper_notice)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Failed OPER attempt by %s (%s@%s)",
+ source_p->name, source_p->username, source_p->host);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * match_oper_password
+ *
+ * inputs - pointer to given password
+ * - pointer to Conf
+ * output - YES or NO if match
+ * side effects - none
+ */
+static int
+match_oper_password(const char *password, struct oper_conf *oper_p)
+{
+ const char *encr;
+
+ /* passwd may be NULL pointer. Head it off at the pass... */
+ if(EmptyString(oper_p->passwd))
+ return NO;
+
+ if(IsOperConfEncrypted(oper_p))
+ {
+ /* use first two chars of the password they send in as salt */
+ /* If the password in the conf is MD5, and ircd is linked
+ * to scrypt on FreeBSD, or the standard crypt library on
+ * glibc Linux, then this code will work fine on generating
+ * the proper encrypted hash for comparison.
+ */
+ if(!EmptyString(password))
+ encr = crypt(password, oper_p->passwd);
+ else
+ encr = "";
+ }
+ else
+ encr = password;
+
+ if(strcmp(encr, oper_p->passwd) == 0)
+ return YES;
+ else
+ return NO;
+}
--- /dev/null
+/* modules/m_operspy.c
+ * Copyright (C) 2003-2005 ircd-ratbox development team
+ * Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_operspy.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+
+static int ms_operspy(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message operspy_msgtab = {
+ "OPERSPY", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {ms_operspy, 2}, mg_ignore}
+};
+
+mapi_clist_av1 operspy_clist[] = { &operspy_msgtab, NULL };
+DECLARE_MODULE_AV1(operspy, NULL, NULL, operspy_clist, NULL, NULL, "$Revision: 254 $");
+
+/* ms_operspy()
+ *
+ * parv[1] - operspy command
+ * parv[2] - optional params
+ */
+static int
+ms_operspy(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ static char buffer[BUFSIZE];
+ char *ptr;
+ int cur_len = 0;
+ int len, i;
+
+ if(parc < 4)
+ {
+ report_operspy(source_p, parv[1],
+ parc < 3 ? NULL : parv[2]);
+ }
+ /* buffer all remaining into one param */
+ else
+ {
+ ptr = buffer;
+ cur_len = 0;
+
+ for(i = 2; i < parc; i++)
+ {
+ len = strlen(parv[i]) + 1;
+
+ if((size_t)(cur_len + len) >= sizeof(buffer))
+ return 0;
+
+ ircsnprintf(ptr, sizeof(buffer) - cur_len, "%s ",
+ parv[i]);
+ ptr += len;
+ cur_len += len;
+ }
+
+ report_operspy(source_p, parv[1], buffer);
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_pass.c: Used to send a password for a server or client{} block.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_pass.c 1291 2006-05-05 19:00:19Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h" /* client struct */
+#include "irc_string.h"
+#include "send.h" /* sendto_one */
+#include "numeric.h" /* ERR_xxx */
+#include "ircd.h" /* me */
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "s_conf.h"
+
+static int mr_pass(struct Client *, struct Client *, int, const char **);
+
+struct Message pass_msgtab = {
+ "PASS", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_pass, 2}, mg_reg, mg_ignore, mg_ignore, mg_ignore, mg_reg}
+};
+
+mapi_clist_av1 pass_clist[] = { &pass_msgtab, NULL };
+DECLARE_MODULE_AV1(pass, NULL, NULL, pass_clist, NULL, NULL, "$Revision: 1291 $");
+
+/*
+ * m_pass() - Added Sat, 4 March 1989
+ *
+ *
+ * mr_pass - PASS message handler
+ * parv[0] = sender prefix
+ * parv[1] = password
+ * parv[2] = "TS" if this server supports TS.
+ * parv[3] = optional TS version field -- needed for TS6
+ */
+static int
+mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(client_p->localClient->passwd)
+ {
+ memset(client_p->localClient->passwd, 0,
+ strlen(client_p->localClient->passwd));
+ MyFree(client_p->localClient->passwd);
+ }
+
+ DupNString(client_p->localClient->passwd, parv[1], PASSWDLEN);
+
+ /* These are for servers only */
+ if(parc > 2 && client_p->user == NULL)
+ {
+ /*
+ * It looks to me as if orabidoo wanted to have more
+ * than one set of option strings possible here...
+ * i.e. ":AABBTS" as long as TS was the last two chars
+ * however, as we are now using CAPAB, I think we can
+ * safely assume if there is a ":TS" then its a TS server
+ * -Dianora
+ */
+ if(irccmp(parv[2], "TS") == 0 && client_p->tsinfo == 0)
+ client_p->tsinfo = TS_DOESTS;
+
+ /* kludge, if we're not using ts6, dont ever mark a server
+ * as TS6 capable, that way we'll never send them TS6 data.
+ */
+ if(ServerInfo.use_ts6 && parc == 5 && atoi(parv[3]) >= 6)
+ {
+ /* only mark as TS6 if the SID is valid.. */
+ if(IsDigit(parv[4][0]) && IsIdChar(parv[4][1]) &&
+ IsIdChar(parv[4][2]) && parv[4][3] == '\0' &&
+ EmptyString(client_p->id))
+ {
+ client_p->localClient->caps |= CAP_TS6;
+ strcpy(client_p->id, parv[4]);
+ }
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_ping.c: Requests that a PONG message be sent back.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_ping.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "irc_string.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "hash.h"
+#include "s_conf.h"
+#include "s_serv.h"
+
+static int m_ping(struct Client *, struct Client *, int, const char **);
+static int ms_ping(struct Client *, struct Client *, int, const char **);
+
+struct Message ping_msgtab = {
+ "PING", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_ping, 2}, {ms_ping, 2}, {ms_ping, 2}, mg_ignore, {m_ping, 2}}
+};
+
+mapi_clist_av1 ping_clist[] = { &ping_msgtab, NULL };
+DECLARE_MODULE_AV1(ping, NULL, NULL, ping_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+** m_ping
+** parv[0] = sender prefix
+** parv[1] = origin
+** parv[2] = destination
+*/
+static int
+m_ping(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *destination;
+
+ destination = parv[2]; /* Will get NULL or pointer (parc >= 2!!) */
+
+ if(!EmptyString(destination) && !match(destination, me.name))
+ {
+ if((target_p = find_server(source_p, destination)))
+ {
+ sendto_one(target_p, ":%s PING %s :%s",
+ get_id(source_p, target_p),
+ source_p->name, get_id(target_p, target_p));
+ }
+ else
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ destination);
+ return 0;
+ }
+ }
+ else
+ sendto_one(source_p, ":%s PONG %s :%s", me.name,
+ (destination) ? destination : me.name, parv[1]);
+
+ return 0;
+}
+
+static int
+ms_ping(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *destination;
+
+ destination = parv[2]; /* Will get NULL or pointer (parc >= 2!!) */
+
+ if(!EmptyString(destination) && irccmp(destination, me.name) &&
+ irccmp(destination, me.id))
+ {
+ if((target_p = find_client(destination)) && IsServer(target_p))
+ sendto_one(target_p, ":%s PING %s :%s",
+ get_id(source_p, target_p), source_p->name,
+ get_id(target_p, target_p));
+ /* not directed at an id.. */
+ else if(!IsDigit(*destination))
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ destination);
+ }
+ else
+ sendto_one(source_p, ":%s PONG %s :%s",
+ get_id(&me, source_p), me.name,
+ get_id(source_p, source_p));
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_pong.c: The reply to a ping message.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_pong.c 522 2006-01-15 20:55:27Z jilles $
+ */
+
+#include "stdinc.h"
+#include "ircd.h"
+#include "s_user.h"
+#include "client.h"
+#include "hash.h" /* for find_client() */
+#include "hook.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "send.h"
+#include "channel.h"
+#include "irc_string.h"
+#include "msg.h"
+#include "parse.h"
+#include "hash.h"
+#include "modules.h"
+
+static int mr_pong(struct Client *, struct Client *, int, const char **);
+static int ms_pong(struct Client *, struct Client *, int, const char **);
+
+struct Message pong_msgtab = {
+ "PONG", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_pong, 0}, mg_ignore, mg_ignore, {ms_pong, 2}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 pong_clist[] = { &pong_msgtab, NULL };
+DECLARE_MODULE_AV1(pong, NULL, NULL, pong_clist, NULL, NULL, "$Revision: 522 $");
+
+static int
+ms_pong(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ const char *destination;
+
+ destination = parv[2];
+ source_p->flags &= ~FLAGS_PINGSENT;
+
+ /* Now attempt to route the PONG, comstud pointed out routable PING
+ * is used for SPING. routable PING should also probably be left in
+ * -Dianora
+ * That being the case, we will route, but only for registered clients (a
+ * case can be made to allow them only from servers). -Shadowfax
+ */
+ if(!EmptyString(destination) && !match(destination, me.name) &&
+ irccmp(destination, me.id))
+ {
+ if((target_p = find_client(destination)) ||
+ (target_p = find_server(NULL, destination)))
+ sendto_one(target_p, ":%s PONG %s %s",
+ get_id(source_p, target_p), parv[1],
+ get_id(target_p, target_p));
+ else
+ {
+ if(!IsDigit(*destination))
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER), destination);
+ return 0;
+ }
+ }
+
+ /* destination is us, emulate EOB */
+ if(IsServer(source_p) && !HasSentEob(source_p))
+ {
+ if(MyConnect(source_p))
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "End of burst (emulated) from %s (%d seconds)",
+ source_p->name,
+ (signed int) (CurrentTime - source_p->localClient->firsttime));
+ SetEob(source_p);
+ eob_count++;
+ call_hook(h_server_eob, source_p);
+ }
+
+ return 0;
+}
+
+static int
+mr_pong(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(parc == 2 && !EmptyString(parv[1]))
+ {
+ if(ConfigFileEntry.ping_cookie && source_p->user && source_p->name[0])
+ {
+ unsigned long incoming_ping = strtoul(parv[1], NULL, 16);
+ if(incoming_ping)
+ {
+ if(source_p->localClient->random_ping == incoming_ping)
+ {
+ char buf[USERLEN + 1];
+ strlcpy(buf, source_p->username, sizeof(buf));
+ source_p->flags2 |= FLAGS2_PING_COOKIE;
+ register_local_user(client_p, source_p, buf);
+ }
+ else
+ {
+ sendto_one(source_p, form_str(ERR_WRONGPONG),
+ me.name, source_p->name,
+ source_p->localClient->random_ping);
+ return 0;
+ }
+ }
+ }
+
+ }
+ else
+ sendto_one(source_p, form_str(ERR_NOORIGIN), me.name, parv[0]);
+
+ source_p->flags &= ~FLAGS_PINGSENT;
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_post.c: Exits the user if unregistered, it is a web form.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_post.c 498 2006-01-15 16:40:33Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+
+static int mr_dumb_proxy(struct Client *, struct Client *, int, const char **);
+
+struct Message post_msgtab = {
+ "POST", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_dumb_proxy, 0}, mg_ignore, mg_ignore, mg_ignore, mg_ignore, mg_ignore}
+};
+struct Message get_msgtab = {
+ "GET", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_dumb_proxy, 0}, mg_ignore, mg_ignore, mg_ignore, mg_ignore, mg_ignore}
+};
+struct Message put_msgtab = {
+ "PUT", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {{mr_dumb_proxy, 0}, mg_ignore, mg_ignore, mg_ignore, mg_ignore, mg_ignore}
+};
+
+
+mapi_clist_av1 post_clist[] = {
+ &post_msgtab, &get_msgtab, &put_msgtab, NULL
+};
+DECLARE_MODULE_AV1(post, NULL, NULL, post_clist, NULL, NULL, "$Revision: 498 $");
+
+
+/*
+** mr_dumb_proxy
+** parv[0] = sender prefix
+** parv[1] = comment
+*/
+static int
+mr_dumb_proxy(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_realops_snomask(SNO_REJ, L_ALL,
+ "HTTP Proxy disconnected: [%s@%s]",
+ client_p->username, client_p->host);
+ exit_client(client_p, source_p, source_p, "Client Exit");
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_rehash.c: Re-reads the configuration file.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_rehash.c 932 2006-03-05 03:39:14Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "channel.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "s_gline.h"
+#include "s_serv.h"
+#include "numeric.h"
+#include "res.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "hostmask.h"
+#include "reject.h"
+#include "hash.h"
+#include "cache.h"
+
+static int mo_rehash(struct Client *, struct Client *, int, const char **);
+static int me_rehash(struct Client *, struct Client *, int, const char **);
+
+struct Message rehash_msgtab = {
+ "REHASH", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_rehash, 0}, {mo_rehash, 0}}
+};
+
+mapi_clist_av1 rehash_clist[] = { &rehash_msgtab, NULL };
+DECLARE_MODULE_AV1(rehash, NULL, NULL, rehash_clist, NULL, NULL, "$Revision: 932 $");
+
+struct hash_commands
+{
+ const char *cmd;
+ void (*handler) (struct Client * source_p);
+};
+
+static void
+rehash_bans_loc(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is rehashing bans",
+ get_oper_name(source_p));
+
+ rehash_bans(0);
+}
+
+static void
+rehash_dns(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is rehashing DNS",
+ get_oper_name(source_p));
+
+ /* reread /etc/resolv.conf and reopen res socket */
+ restart_resolver();
+}
+
+static void
+rehash_motd(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is forcing re-reading of MOTD file",
+ get_oper_name(source_p));
+
+ free_cachefile(user_motd);
+ user_motd = cache_file(MPATH, "ircd.motd", 0);
+}
+
+static void
+rehash_omotd(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is forcing re-reading of OPER MOTD file",
+ get_oper_name(source_p));
+
+ free_cachefile(oper_motd);
+ oper_motd = cache_file(OPATH, "opers.motd", 0);
+}
+
+static void
+rehash_glines(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr, *next_ptr;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing G-lines",
+ get_oper_name(source_p));
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, glines.head)
+ {
+ aconf = ptr->data;
+
+ delete_one_address_conf(aconf->host, aconf);
+ dlinkDestroy(ptr, &glines);
+ }
+}
+
+static void
+rehash_pglines(struct Client *source_p)
+{
+ struct gline_pending *glp_ptr;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing pending glines",
+ get_oper_name(source_p));
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, pending_glines.head)
+ {
+ glp_ptr = ptr->data;
+
+ MyFree(glp_ptr->reason1);
+ MyFree(glp_ptr->reason2);
+ MyFree(glp_ptr);
+ dlinkDestroy(ptr, &pending_glines);
+ }
+}
+
+static void
+rehash_tklines(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr, *next_ptr;
+ int i;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing temp klines",
+ get_oper_name(source_p));
+
+ for(i = 0; i < LAST_TEMP_TYPE; i++)
+ {
+ DLINK_FOREACH_SAFE(ptr, next_ptr, temp_klines[i].head)
+ {
+ aconf = ptr->data;
+
+ delete_one_address_conf(aconf->host, aconf);
+ dlinkDestroy(ptr, &temp_klines[i]);
+ }
+ }
+}
+
+static void
+rehash_tdlines(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr, *next_ptr;
+ int i;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing temp dlines",
+ get_oper_name(source_p));
+
+ for(i = 0; i < LAST_TEMP_TYPE; i++)
+ {
+ DLINK_FOREACH_SAFE(ptr, next_ptr, temp_dlines[i].head)
+ {
+ aconf = ptr->data;
+
+ delete_one_address_conf(aconf->host, aconf);
+ dlinkDestroy(ptr, &temp_dlines[i]);
+ }
+ }
+}
+
+static void
+rehash_txlines(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing temp xlines",
+ get_oper_name(source_p));
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(!aconf->hold)
+ continue;
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &xline_conf_list);
+ }
+}
+
+static void
+rehash_tresvs(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ int i;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing temp resvs",
+ get_oper_name(source_p));
+
+ HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
+ {
+ aconf = ptr->data;
+
+ if(!aconf->hold)
+ continue;
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &resvTable[i]);
+ }
+ HASH_WALK_END
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(!aconf->hold)
+ continue;
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &resv_conf_list);
+ }
+}
+
+static void
+rehash_rejectcache(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is clearing reject cache",
+ get_oper_name(source_p));
+ flush_reject();
+
+}
+
+static void
+rehash_help(struct Client *source_p)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is forcing re-reading of HELP files",
+ get_oper_name(source_p));
+ clear_help_hash();
+ load_help();
+}
+
+static void
+rehash_nickdelay(struct Client *source_p)
+{
+ struct nd_entry *nd;
+ dlink_node *ptr;
+ dlink_node *safe_ptr;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is clearing the nick delay table",
+ get_oper_name(source_p));
+
+ DLINK_FOREACH_SAFE(ptr, safe_ptr, nd_list.head)
+ {
+ nd = ptr->data;
+
+ free_nd_entry(nd);
+ }
+}
+
+/* *INDENT-OFF* */
+static struct hash_commands rehash_commands[] =
+{
+ {"BANS", rehash_bans_loc },
+ {"DNS", rehash_dns },
+ {"MOTD", rehash_motd },
+ {"OMOTD", rehash_omotd },
+ {"GLINES", rehash_glines },
+ {"PGLINES", rehash_pglines },
+ {"TKLINES", rehash_tklines },
+ {"TDLINES", rehash_tdlines },
+ {"TXLINES", rehash_txlines },
+ {"TRESVS", rehash_tresvs },
+ {"REJECTCACHE", rehash_rejectcache },
+ {"HELP", rehash_help },
+ {"NICKDELAY", rehash_nickdelay },
+ {NULL, NULL }
+};
+/* *INDENT-ON* */
+
+static void
+do_rehash(struct Client *source_p, const char *type)
+{
+ if (type != NULL)
+ {
+ int x;
+ char cmdbuf[100];
+
+ for (x = 0; rehash_commands[x].cmd != NULL && rehash_commands[x].handler != NULL;
+ x++)
+ {
+ if(irccmp(type, rehash_commands[x].cmd) == 0)
+ {
+ sendto_one(source_p, form_str(RPL_REHASHING), me.name,
+ source_p->name, rehash_commands[x].cmd);
+ rehash_commands[x].handler(source_p);
+ ilog(L_MAIN, "REHASH %s From %s[%s]", type,
+ get_oper_name(source_p), source_p->sockhost);
+ return;
+ }
+ }
+
+ /* We are still here..we didn't match */
+ cmdbuf[0] = '\0';
+ for (x = 0; rehash_commands[x].cmd != NULL && rehash_commands[x].handler != NULL;
+ x++)
+ {
+ strlcat(cmdbuf, " ", sizeof(cmdbuf));
+ strlcat(cmdbuf, rehash_commands[x].cmd, sizeof(cmdbuf));
+ }
+ sendto_one(source_p, ":%s NOTICE %s :rehash one of:%s", me.name, source_p->name,
+ cmdbuf);
+ }
+ else
+ {
+ sendto_one(source_p, form_str(RPL_REHASHING), me.name, source_p->name,
+ ConfigFileEntry.configfile);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is rehashing server config file", get_oper_name(source_p));
+ ilog(L_MAIN, "REHASH From %s[%s]", get_oper_name(source_p),
+ source_p->sockhost);
+ rehash(0);
+ }
+}
+
+/*
+ * mo_rehash - REHASH message handler
+ *
+ * parv[1] = rehash type or destination
+ * parv[2] = destination
+ */
+static int
+mo_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *type = NULL, *target_server = NULL;
+
+ if(!IsOperRehash(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "rehash");
+ return 0;
+ }
+
+ if (parc > 2)
+ type = parv[1], target_server = parv[2];
+ else if (parc > 1 && (strchr(parv[1], '.') || strchr(parv[1], '?') || strchr(parv[1], '*')))
+ type = NULL, target_server = parv[1];
+ else if (parc > 1)
+ type = parv[1], target_server = NULL;
+ else
+ type = NULL, target_server = NULL;
+
+ if (target_server != NULL)
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+ sendto_match_servs(source_p, target_server,
+ CAP_ENCAP, NOCAPS,
+ "ENCAP %s REHASH %s",
+ target_server, type != NULL ? type : "");
+ if (match(target_server, me.name) == 0)
+ return 0;
+ }
+
+ do_rehash(source_p, type);
+
+ return 0;
+}
+
+static int
+me_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+
+ if (!IsPerson(source_p))
+ return 0;
+
+ if (!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server, SHARED_REHASH))
+ return 0;
+
+ do_rehash(source_p, parc > 1 ? parv[1] : NULL);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_restart.c: Exits and re-runs ircd.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_restart.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "restart.h"
+#include "s_log.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_restart(struct Client *, struct Client *, int, const char **);
+
+struct Message restart_msgtab = {
+ "RESTART", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_restart, 0}}
+};
+
+mapi_clist_av1 restart_clist[] = { &restart_msgtab, NULL };
+DECLARE_MODULE_AV1(restart, NULL, NULL, restart_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * mo_restart
+ *
+ */
+static int
+mo_restart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ char buf[BUFSIZE];
+ dlink_node *ptr;
+ struct Client *target_p;
+
+ if(!IsOperDie(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "die");
+ return 0;
+ }
+
+ if(parc < 2 || EmptyString(parv[1]))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Need server name /restart %s",
+ me.name, source_p->name, me.name);
+ return 0;
+ }
+ else if(irccmp(parv[1], me.name))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Mismatch on /restart %s",
+ me.name, source_p->name, me.name);
+ return 0;
+ }
+
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p,
+ ":%s NOTICE %s :Server Restarting. %s",
+ me.name, target_p->name, get_client_name(source_p, HIDE_IP));
+ }
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p, ":%s ERROR :Restart by %s",
+ me.name, get_client_name(source_p, HIDE_IP));
+ }
+
+ ircsprintf(buf, "Server RESTART by %s", get_client_name(source_p, HIDE_IP));
+ restart(buf);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_resv.c: Reserves(jupes) a nickname or channel.
+ *
+ * Copyright (C) 2001-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_resv.c 3045 2006-12-26 23:16:57Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "channel.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "hash.h"
+#include "s_log.h"
+#include "sprintf_irc.h"
+
+static int mo_resv(struct Client *, struct Client *, int, const char **);
+static int ms_resv(struct Client *, struct Client *, int, const char **);
+static int me_resv(struct Client *, struct Client *, int, const char **);
+static int mo_unresv(struct Client *, struct Client *, int, const char **);
+static int ms_unresv(struct Client *, struct Client *, int, const char **);
+static int me_unresv(struct Client *, struct Client *, int, const char **);
+
+struct Message resv_msgtab = {
+ "RESV", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {mg_ignore, mg_not_oper, {ms_resv, 4}, {ms_resv, 4}, {me_resv, 5}, {mo_resv, 3}}
+};
+struct Message unresv_msgtab = {
+ "UNRESV", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
+ {mg_ignore, mg_not_oper, {ms_unresv, 3}, {ms_unresv, 3}, {me_unresv, 2}, {mo_unresv, 2}}
+};
+
+mapi_clist_av1 resv_clist[] = { &resv_msgtab, &unresv_msgtab, NULL };
+DECLARE_MODULE_AV1(resv, NULL, NULL, resv_clist, NULL, NULL, "$Revision: 3045 $");
+
+static void parse_resv(struct Client *source_p, const char *name,
+ const char *reason, int temp_time);
+static void propagate_resv(struct Client *source_p, const char *target,
+ int temp_time, const char *name, const char *reason);
+static void cluster_resv(struct Client *source_p, int temp_time,
+ const char *name, const char *reason);
+
+static void handle_remote_unresv(struct Client *source_p, const char *name);
+static void remove_resv(struct Client *source_p, const char *name);
+static int remove_temp_resv(struct Client *source_p, const char *name);
+
+/*
+ * mo_resv()
+ * parv[0] = sender prefix
+ * parv[1] = channel/nick to forbid
+ * parv[2] = reason
+ */
+static int
+mo_resv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *name;
+ const char *reason;
+ const char *target_server = NULL;
+ int temp_time;
+ int loc = 1;
+
+ /* RESV [time] <name> [ON <server>] :<reason> */
+
+ if((temp_time = valid_temp_time(parv[loc])) >= 0)
+ loc++;
+ /* we just set temp_time to -1! */
+ else
+ temp_time = 0;
+
+ name = parv[loc];
+ loc++;
+
+ if((parc >= loc+2) && (irccmp(parv[loc], "ON") == 0))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ target_server = parv[loc+1];
+ loc += 2;
+ }
+
+ if(parc <= loc || EmptyString(parv[loc]))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "RESV");
+ return 0;
+ }
+
+ reason = parv[loc];
+
+ /* remote resv.. */
+ if(target_server)
+ {
+ propagate_resv(source_p, target_server, temp_time, name, reason);
+
+ if(match(target_server, me.name) == 0)
+ return 0;
+ }
+ else if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_resv(source_p, temp_time, name, reason);
+
+ parse_resv(source_p, name, reason, temp_time);
+
+ return 0;
+}
+
+/* ms_resv()
+ * parv[0] = sender prefix
+ * parv[1] = target server
+ * parv[2] = channel/nick to forbid
+ * parv[3] = reason
+ */
+static int
+ms_resv(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2] parv[3]
+ * oper target server resv reason
+ */
+ propagate_resv(source_p, parv[1], 0, parv[2], parv[3]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ parse_resv(source_p, parv[2], parv[3], 0);
+ return 0;
+}
+
+static int
+me_resv(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ /* time name 0 :reason */
+ if(!IsPerson(source_p))
+ return 0;
+
+ parse_resv(source_p, parv[2], parv[4], atoi(parv[1]));
+ return 0;
+}
+
+/* parse_resv()
+ *
+ * inputs - source_p if error messages wanted
+ * - thing to resv
+ * - reason for resv
+ * outputs -
+ * side effects - will parse the resv and create it if valid
+ */
+static void
+parse_resv(struct Client *source_p, const char *name,
+ const char *reason, int temp_time)
+{
+ struct ConfItem *aconf;
+
+ if(!MyClient(source_p) &&
+ !find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server,
+ (temp_time > 0) ? SHARED_TRESV : SHARED_PRESV))
+ return;
+
+ if(IsChannelName(name))
+ {
+ if(hash_find_resv(name))
+ {
+ sendto_one_notice(source_p,
+ ":A RESV has already been placed on channel: %s",
+ name);
+ return;
+ }
+
+ if(strlen(name) > CHANNELLEN)
+ {
+ sendto_one_notice(source_p, ":Invalid RESV length: %s",
+ name);
+ return;
+ }
+
+ if(strchr(reason, '"'))
+ {
+ sendto_one_notice(source_p,
+ ":Invalid character '\"' in comment");
+ return;
+ }
+
+ aconf = make_conf();
+ aconf->status = CONF_RESV_CHANNEL;
+ aconf->port = 0;
+ DupString(aconf->name, name);
+ DupString(aconf->passwd, reason);
+ add_to_resv_hash(aconf->name, aconf);
+
+ if(temp_time > 0)
+ {
+ aconf->hold = CurrentTime + temp_time;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. RESV for [%s] [%s]",
+ get_oper_name(source_p), temp_time / 60,
+ name, reason);
+ ilog(L_KLINE, "R %s %d %s %s",
+ get_oper_name(source_p), temp_time / 60,
+ name, reason);
+ sendto_one_notice(source_p, ":Added temporary %d min. RESV [%s]",
+ temp_time / 60, name);
+ }
+ else
+ write_confitem(RESV_TYPE, source_p, NULL, aconf->name,
+ aconf->passwd, NULL, NULL, 0);
+ }
+ else if(clean_resv_nick(name))
+ {
+ if(strlen(name) > NICKLEN*2)
+ {
+ sendto_one_notice(source_p, ":Invalid RESV length: %s",
+ name);
+ return;
+ }
+
+ if(strchr(reason, '"'))
+ {
+ sendto_one_notice(source_p,
+ ":Invalid character '\"' in comment");
+ return;
+ }
+
+ if(!valid_wild_card_simple(name))
+ {
+ sendto_one_notice(source_p,
+ ":Please include at least %d non-wildcard "
+ "characters with the resv",
+ ConfigFileEntry.min_nonwildcard_simple);
+ return;
+ }
+
+ if(find_nick_resv(name))
+ {
+ sendto_one_notice(source_p,
+ ":A RESV has already been placed on nick: %s",
+ name);
+ return;
+ }
+
+ aconf = make_conf();
+ aconf->status = CONF_RESV_NICK;
+ aconf->port = 0;
+ DupString(aconf->name, name);
+ DupString(aconf->passwd, reason);
+ dlinkAddAlloc(aconf, &resv_conf_list);
+
+ if(temp_time > 0)
+ {
+ aconf->hold = CurrentTime + temp_time;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. RESV for [%s] [%s]",
+ get_oper_name(source_p), temp_time / 60,
+ name, reason);
+ ilog(L_KLINE, "R %s %d %s %s",
+ get_oper_name(source_p), temp_time / 60,
+ name, reason);
+ sendto_one_notice(source_p, ":Added temporary %d min. RESV [%s]",
+ temp_time / 60, name);
+ }
+ else
+ write_confitem(RESV_TYPE, source_p, NULL, aconf->name,
+ aconf->passwd, NULL, NULL, 0);
+ }
+ else
+ sendto_one_notice(source_p,
+ ":You have specified an invalid resv: [%s]",
+ name);
+}
+
+static void
+propagate_resv(struct Client *source_p, const char *target,
+ int temp_time, const char *name, const char *reason)
+{
+ if(!temp_time)
+ {
+ sendto_match_servs(source_p, target,
+ CAP_CLUSTER, NOCAPS,
+ "RESV %s %s :%s",
+ target, name, reason);
+ sendto_match_servs(source_p, target,
+ CAP_ENCAP, CAP_CLUSTER,
+ "ENCAP %s RESV %d %s 0 :%s",
+ target, temp_time, name, reason);
+ }
+ else
+ sendto_match_servs(source_p, target,
+ CAP_ENCAP, NOCAPS,
+ "ENCAP %s RESV %d %s 0 :%s",
+ target, temp_time, name, reason);
+}
+
+static void
+cluster_resv(struct Client *source_p, int temp_time, const char *name,
+ const char *reason)
+{
+ struct remote_conf *shared_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, cluster_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ /* old protocol cant handle temps, and we dont really want
+ * to convert them to perm.. --fl
+ */
+ if(!temp_time)
+ {
+ if(!(shared_p->flags & SHARED_PRESV))
+ continue;
+
+ sendto_match_servs(source_p, shared_p->server,
+ CAP_CLUSTER, NOCAPS,
+ "RESV %s %s :%s",
+ shared_p->server, name, reason);
+ sendto_match_servs(source_p, shared_p->server,
+ CAP_ENCAP, CAP_CLUSTER,
+ "ENCAP %s RESV 0 %s 0 :%s",
+ shared_p->server, name, reason);
+ }
+ else if(shared_p->flags & SHARED_TRESV)
+ sendto_match_servs(source_p, shared_p->server,
+ CAP_ENCAP, NOCAPS,
+ "ENCAP %s RESV %d %s 0 :%s",
+ shared_p->server, temp_time, name, reason);
+ }
+}
+
+
+/*
+ * mo_unresv()
+ * parv[0] = sender prefix
+ * parv[1] = channel/nick to unforbid
+ */
+static int
+mo_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if((parc == 4) && (irccmp(parv[2], "ON") == 0))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ propagate_generic(source_p, "UNRESV", parv[3], CAP_CLUSTER,
+ "%s", parv[1]);
+
+ if(match(parv[3], me.name) == 0)
+ return 0;
+ }
+ else if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_generic(source_p, "UNRESV", SHARED_UNRESV, CAP_CLUSTER,
+ "%s", parv[1]);
+
+ if(remove_temp_resv(source_p, parv[1]))
+ return 0;
+
+ remove_resv(source_p, parv[1]);
+ return 0;
+}
+
+/* ms_unresv()
+ * parv[0] = sender prefix
+ * parv[1] = target server
+ * parv[2] = resv to remove
+ */
+static int
+ms_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2]
+ * oper target server resv to remove
+ */
+ propagate_generic(source_p, "UNRESV", parv[1], CAP_CLUSTER,
+ "%s", parv[2]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unresv(source_p, parv[2]);
+ return 0;
+}
+
+static int
+me_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* name */
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unresv(source_p, parv[1]);
+ return 0;
+}
+
+static void
+handle_remote_unresv(struct Client *source_p, const char *name)
+{
+ if(!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server, SHARED_UNRESV))
+ return;
+
+ if(remove_temp_resv(source_p, name))
+ return;
+
+ remove_resv(source_p, name);
+
+ return;
+}
+
+static int
+remove_temp_resv(struct Client *source_p, const char *name)
+{
+ struct ConfItem *aconf = NULL;
+
+ if(IsChannelName(name))
+ {
+ if((aconf = hash_find_resv(name)) == NULL)
+ return 0;
+
+ /* its permanent, let remove_resv do it properly */
+ if(!aconf->hold)
+ return 0;
+
+ del_from_resv_hash(name, aconf);
+ free_conf(aconf);
+ }
+ else
+ {
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(irccmp(aconf->name, name))
+ aconf = NULL;
+ else
+ break;
+ }
+
+ if(aconf == NULL)
+ return 0;
+
+ /* permanent, remove_resv() needs to do it properly */
+ if(!aconf->hold)
+ return 0;
+
+ /* already have ptr from the loop above.. */
+ dlinkDestroy(ptr, &resv_conf_list);
+ free_conf(aconf);
+ }
+
+ sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the RESV for: [%s]",
+ get_oper_name(source_p), name);
+ ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
+
+ return 1;
+}
+
+/* remove_resv()
+ *
+ * inputs - client removing the resv
+ * - resv to remove
+ * outputs -
+ * side effects - resv if found, is removed
+ */
+static void
+remove_resv(struct Client *source_p, const char *name)
+{
+ FILE *in, *out;
+ char buf[BUFSIZE];
+ char buff[BUFSIZE];
+ char temppath[BUFSIZE];
+ const char *filename;
+ mode_t oldumask;
+ char *p;
+ int error_on_write = 0;
+ int found_resv = 0;
+
+ ircsprintf(temppath, "%s.tmp", ConfigFileEntry.resvfile);
+ filename = get_conf_name(RESV_TYPE);
+
+ if((in = fopen(filename, "r")) == NULL)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", filename);
+ return;
+ }
+
+ oldumask = umask(0);
+
+ if((out = fopen(temppath, "w")) == NULL)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", temppath);
+ fclose(in);
+ umask(oldumask);
+ return;
+ }
+
+ umask(oldumask);
+
+ while (fgets(buf, sizeof(buf), in))
+ {
+ const char *resv_name;
+
+ if(error_on_write)
+ {
+ if(temppath != NULL)
+ (void) unlink(temppath);
+
+ break;
+ }
+
+ strlcpy(buff, buf, sizeof(buff));
+
+ if((p = strchr(buff, '\n')) != NULL)
+ *p = '\0';
+
+ if((*buff == '\0') || (*buff == '#'))
+ {
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ continue;
+ }
+
+ if((resv_name = getfield(buff)) == NULL)
+ {
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ continue;
+ }
+
+ if(irccmp(resv_name, name) == 0)
+ {
+ found_resv++;
+ }
+ else
+ {
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ }
+ }
+
+ fclose(in);
+ if (fclose(out))
+ error_on_write = YES;
+
+ if(error_on_write)
+ {
+ sendto_one_notice(source_p, ":Couldn't write temp resv file, aborted");
+ return;
+ }
+ else if(!found_resv)
+ {
+ sendto_one_notice(source_p, ":No RESV for %s", name);
+
+ if(temppath != NULL)
+ (void) unlink(temppath);
+
+ return;
+ }
+
+ if (rename(temppath, filename))
+ {
+ sendto_one_notice(source_p, ":Couldn't rename temp file, aborted");
+ return;
+ }
+ rehash_bans(0);
+
+ sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the RESV for: [%s]", get_oper_name(source_p), name);
+ ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
+}
--- /dev/null
+/* modules/m_sasl.c
+ * Copyright (C) 2006 Michael Tharp <gxti@partiallystapled.com>
+ * Copyright (C) 2006 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_sasl.c 1409 2006-05-21 14:46:17Z jilles $
+ */
+
+#include "stdinc.h"
+
+#include "client.h"
+#include "hash.h"
+#include "send.h"
+#include "msg.h"
+#include "modules.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_stats.h"
+#include "string.h"
+
+static int mr_authenticate(struct Client *, struct Client *, int, const char **);
+static int me_sasl(struct Client *, struct Client *, int, const char **);
+
+static void abort_sasl(struct Client *);
+static void abort_sasl_exit(hook_data_client_exit *);
+
+struct Message authenticate_msgtab = {
+ "AUTHENTICATE", 0, 0, 0, MFLG_SLOW,
+ {{mr_authenticate, 2}, mg_reg, mg_ignore, mg_ignore, mg_ignore, mg_reg}
+};
+struct Message sasl_msgtab = {
+ "SASL", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_sasl, 5}, mg_ignore}
+};
+
+mapi_clist_av1 sasl_clist[] = {
+ &authenticate_msgtab, &sasl_msgtab, NULL
+};
+mapi_hfn_list_av1 sasl_hfnlist[] = {
+ { "new_local_user", (hookfn) abort_sasl },
+ { "client_exit", (hookfn) abort_sasl_exit },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(sasl, NULL, NULL, sasl_clist, NULL, sasl_hfnlist, "$Revision: 1409 $");
+
+static int
+mr_authenticate(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *agent_p = NULL;
+
+ /* They really should use CAP for their own sake. */
+ if(!IsCapable(source_p, CLICAP_SASL))
+ return 0;
+
+ if (strlen(client_p->id) == 3)
+ {
+ exit_client(client_p, client_p, client_p, "Mixing client and server protocol");
+ return 0;
+ }
+
+ if(source_p->preClient->sasl_complete)
+ {
+ sendto_one(source_p, form_str(ERR_SASLALREADY), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
+ return 0;
+ }
+
+ if(strlen(parv[1]) > 400)
+ {
+ sendto_one(source_p, form_str(ERR_SASLTOOLONG), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
+ return 0;
+ }
+
+ if(!*source_p->id)
+ {
+ /* Allocate a UID. */
+ strcpy(source_p->id, generate_uid());
+ add_to_id_hash(source_p->id, source_p);
+ }
+
+ if(*source_p->preClient->sasl_agent)
+ agent_p = find_id(source_p->preClient->sasl_agent);
+
+ if(agent_p == NULL)
+ sendto_server(NULL, NULL, CAP_TS6|CAP_ENCAP, NOCAPS, ":%s ENCAP * SASL %s * S %s", me.id,
+ source_p->id, parv[1]);
+ else
+ sendto_one(agent_p, ":%s ENCAP %s SASL %s %s C %s", me.id, agent_p->servptr->name,
+ source_p->id, agent_p->id, parv[1]);
+ source_p->preClient->sasl_out++;
+
+ return 0;
+}
+
+static int
+me_sasl(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p, *agent_p;
+
+ /* Let propagate if not addressed to us, or if broadcast.
+ * Only SASL agents can answer global requests.
+ */
+ if(strncmp(parv[2], me.id, 3))
+ return 0;
+
+ if((target_p = find_id(parv[2])) == NULL)
+ return 0;
+
+ if(target_p->preClient == NULL)
+ return 0;
+
+ if((agent_p = find_id(parv[1])) == NULL)
+ return 0;
+
+ if(source_p != agent_p->servptr) /* WTF?! */
+ return 0;
+
+ /* We only accept messages from SASL agents; these must have umode +S
+ * (so the server must be listed in a service{} block).
+ */
+ if(!IsService(agent_p))
+ return 0;
+
+ /* Reject if someone has already answered. */
+ if(*target_p->preClient->sasl_agent && strncmp(parv[1], target_p->preClient->sasl_agent, IDLEN))
+ return 0;
+ else if(!*target_p->preClient->sasl_agent)
+ strlcpy(target_p->preClient->sasl_agent, parv[1], IDLEN);
+
+ if(*parv[3] == 'C')
+ sendto_one(target_p, "AUTHENTICATE %s", parv[4]);
+ else if(*parv[3] == 'D')
+ {
+ if(*parv[4] == 'F')
+ sendto_one(target_p, form_str(ERR_SASLFAIL), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
+ else if(*parv[4] == 'S') {
+ sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
+ target_p->preClient->sasl_complete = 1;
+ ServerStats->is_ssuc++;
+ }
+ *target_p->preClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */
+ }
+
+ return 0;
+}
+
+/* If the client never finished authenticating but is
+ * registering anyway, abort the exchange.
+ */
+static void
+abort_sasl(struct Client *data)
+{
+ if(data->preClient->sasl_out == 0 || data->preClient->sasl_complete)
+ return;
+
+ data->preClient->sasl_out = data->preClient->sasl_complete = 0;
+ ServerStats->is_sbad++;
+
+ if(!IsClosing(data))
+ sendto_one(data, form_str(ERR_SASLABORTED), me.name, EmptyString(data->name) ? "*" : data->name);
+
+ if(*data->preClient->sasl_agent)
+ {
+ struct Client *agent_p = find_id(data->preClient->sasl_agent);
+ if(agent_p)
+ {
+ sendto_one(agent_p, ":%s ENCAP %s SASL %s %s D A", me.id, agent_p->servptr->name,
+ data->id, agent_p->id);
+ return;
+ }
+ }
+
+ sendto_server(NULL, NULL, CAP_TS6|CAP_ENCAP, NOCAPS, ":%s ENCAP * SASL %s * D A", me.id,
+ data->id);
+}
+
+static void
+abort_sasl_exit(hook_data_client_exit *data)
+{
+ if (data->target->preClient)
+ abort_sasl(data->target);
+}
+
--- /dev/null
+/*
+ * charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ * m_scan.c: Provides information about various targets on various topics
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod -at- nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_scan.c 1853 2006-08-24 18:30:52Z jilles $
+ */
+
+#include "stdinc.h"
+#include "class.h"
+#include "hook.h"
+#include "client.h"
+#include "hash.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_user.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_scan(struct Client *, struct Client *, int, const char **);
+static int scan_umodes(struct Client *, struct Client *, int, const char **);
+/*static int scan_cmodes(struct Client *, struct Client *, int, const char **);*/
+
+struct Message scan_msgtab = {
+ "SCAN", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_scan, 2}}
+};
+
+mapi_clist_av1 scan_clist[] = { &scan_msgtab, NULL };
+DECLARE_MODULE_AV1(scan, NULL, NULL, scan_clist, NULL, NULL, "$Revision: 1853 $");
+
+typedef int (*scan_handler)(struct Client *, struct Client *, int,
+ const char **);
+
+struct scan_cmd {
+ const char *name;
+ int operlevel;
+ scan_handler handler;
+} scan_cmds[] = {
+ {"UMODES", L_OPER, scan_umodes},
+ {NULL, 0, NULL}
+};
+
+static const char *empty_sockhost = "255.255.255.255";
+static const char *spoofed_sockhost = "0";
+
+/*
+ * m_scan
+ * parv[0] = sender prefix
+ * parv[1] = options [or target]
+ * parv[2] = [target]
+ */
+static int
+mo_scan(struct Client *client_p, struct Client *source_p, int parc,
+ const char *parv[])
+{
+ struct scan_cmd *sptr;
+
+ for (sptr = scan_cmds; sptr->name != NULL; sptr++)
+ {
+ if (!irccmp(sptr->name, parv[1]))
+ {
+ if (sptr->operlevel == L_ADMIN &&
+ !IsOperAdmin(source_p))
+ return -1;
+ else
+ return sptr->handler(client_p, source_p, parc, parv);
+ }
+ }
+
+ sendto_one_notice(source_p, ":*** %s is not an implemented SCAN target",
+ parv[1]);
+
+ return 0;
+}
+
+static int
+scan_umodes(struct Client *client_p, struct Client *source_p, int parc,
+ const char *parv[])
+{
+ unsigned int allowed_umodes = 0, disallowed_umodes = 0;
+ int what = MODE_ADD;
+ int mode;
+ int list_users = YES;
+ int list_max = 0;
+ int list_count = 0, count = 0;
+ const char *mask = NULL;
+ const char *c;
+ struct Client *target_p;
+ dlink_list *target_list = &lclient_list; /* local clients only by default */
+ dlink_node *tn;
+ int i;
+ const char *sockhost;
+ char buf[512];
+
+ if (parc < 3)
+ {
+ if (MyClient(source_p))
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "SCAN UMODES");
+
+ return -1;
+ }
+
+ for (c = parv[2]; *c; c++)
+ {
+ switch(*c)
+ {
+ case '+':
+ what = MODE_ADD;
+ break;
+ case '-':
+ what = MODE_DEL;
+ break;
+ default:
+ if ((mode = user_modes[(unsigned char) *c]) != 0)
+ {
+ if (what == MODE_ADD)
+ allowed_umodes |= mode;
+ else
+ disallowed_umodes |= mode;
+ }
+ }
+ }
+
+ for (i = 3; i < parc; i++)
+ {
+ if (!irccmp(parv[i], "no-list"))
+ list_users = NO;
+ else if (!irccmp(parv[i], "list"))
+ list_users = YES;
+ else if (!irccmp(parv[i], "global"))
+ target_list = &global_client_list;
+ else if (i < (parc - 1))
+ {
+ if (!irccmp(parv[i], "list-max"))
+ list_max = atoi(parv[++i]);
+ else if (!irccmp(parv[i], "mask"))
+ mask = parv[++i];
+ }
+ }
+ if (target_list == &global_client_list && (list_users || mask))
+ {
+ if (IsOperSpy(source_p))
+ {
+ if (!ConfigFileEntry.operspy_dont_care_user_info)
+ {
+ strlcpy(buf, "UMODES", sizeof buf);
+ for (i = 2; i < parc; i++)
+ {
+ strlcat(buf, " ", sizeof buf);
+ strlcat(buf, parv[i], sizeof buf);
+ }
+ report_operspy(source_p, "SCAN", buf);
+ }
+ }
+ else
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "oper_spy");
+ return -1;
+ }
+ }
+
+ DLINK_FOREACH(tn, target_list->head)
+ {
+ unsigned int working_umodes = 0;
+ char maskbuf[BUFSIZE];
+
+ target_p = tn->data;
+
+ if (!IsClient(target_p))
+ continue;
+
+ if(EmptyString(target_p->sockhost))
+ sockhost = empty_sockhost;
+ else if(!show_ip(source_p, target_p))
+ sockhost = spoofed_sockhost;
+ else
+ sockhost = target_p->sockhost;
+
+ working_umodes = target_p->umodes;
+
+ /* require that we have the allowed umodes... */
+ if ((working_umodes & allowed_umodes) != allowed_umodes)
+ continue;
+
+ /* require that we have NONE of the disallowed ones */
+ if ((working_umodes & disallowed_umodes) != 0)
+ continue;
+
+ if (mask != NULL)
+ {
+ ircsnprintf(maskbuf, BUFSIZE, "%s!%s@%s",
+ target_p->name, target_p->username, target_p->host);
+
+ if (!match(mask, maskbuf))
+ continue;
+ }
+
+ if (list_users && (!list_max || (list_count < list_max)))
+ {
+ char modebuf[BUFSIZE];
+ char *m = modebuf;
+
+ *m++ = '+';
+
+ for (i = 0; i < 128; i++)
+ {
+ if (target_p->umodes & user_modes[i])
+ *m++ = (char) i;
+ }
+
+ *m++ = '\0';
+
+ list_count++;
+
+ sendto_one_numeric(source_p, RPL_SCANUMODES,
+ form_str(RPL_SCANUMODES),
+ target_p->name, target_p->username,
+ target_p->host, sockhost,
+ target_p->servptr->name, modebuf,
+ target_p->info);
+ }
+ count++;
+ }
+
+ sendto_one_numeric(source_p, RPL_SCANMATCHED,
+ form_str(RPL_SCANMATCHED), count);
+
+ return 0;
+}
--- /dev/null
+/* modules/m_services.c
+ * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_services.c 1907 2006-08-29 19:18:15Z jilles $
+ */
+
+#include "stdinc.h"
+
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+#include "whowas.h"
+#include "monitor.h"
+
+static int me_su(struct Client *, struct Client *, int, const char **);
+static int me_login(struct Client *, struct Client *, int, const char **);
+static int me_rsfnc(struct Client *, struct Client *, int, const char **);
+static int me_nickdelay(struct Client *, struct Client *, int, const char **);
+
+static void h_svc_server_introduced(hook_data_client *);
+static void h_svc_whois(hook_data_client *);
+static void h_svc_stats(hook_data_int *);
+
+struct Message su_msgtab = {
+ "SU", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_su, 2}, mg_ignore}
+};
+struct Message login_msgtab = {
+ "LOGIN", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_login, 2}, mg_ignore}
+};
+struct Message rsfnc_msgtab = {
+ "RSFNC", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_rsfnc, 4}, mg_ignore}
+};
+struct Message nickdelay_msgtab = {
+ "NICKDELAY", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, mg_ignore, {me_nickdelay, 3}, mg_ignore}
+};
+
+mapi_clist_av1 services_clist[] = {
+ &su_msgtab, &login_msgtab, &rsfnc_msgtab, &nickdelay_msgtab, NULL
+};
+mapi_hfn_list_av1 services_hfnlist[] = {
+ { "doing_stats", (hookfn) h_svc_stats },
+ { "doing_whois", (hookfn) h_svc_whois },
+ { "doing_whois_global", (hookfn) h_svc_whois },
+ { "server_introduced", (hookfn) h_svc_server_introduced },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(services, NULL, NULL, services_clist, NULL, services_hfnlist, "$Revision: 1907 $");
+
+static int
+me_su(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ if(!(source_p->flags & FLAGS_SERVICE))
+ return 0;
+
+ if((target_p = find_client(parv[1])) == NULL)
+ return 0;
+
+ if(!target_p->user)
+ return 0;
+
+ if(EmptyString(parv[2]))
+ target_p->user->suser[0] = '\0';
+ else
+ strlcpy(target_p->user->suser, parv[2], sizeof(target_p->user->suser));
+
+ invalidate_bancache_user(target_p);
+
+ return 0;
+}
+
+static int
+me_login(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ if(!IsPerson(source_p))
+ return 0;
+
+ strlcpy(source_p->user->suser, parv[1], sizeof(source_p->user->suser));
+ return 0;
+}
+
+static int
+clean_nick(const char *nick)
+{
+ int len = 0;
+
+ if(EmptyString(nick) || *nick == '-' || IsDigit(*nick))
+ return 0;
+
+ for(; *nick; nick++)
+ {
+ len++;
+ if(!IsNickChar(*nick))
+ return 0;
+ }
+
+ if(len >= NICKLEN)
+ return 0;
+
+ return 1;
+}
+
+static int
+me_rsfnc(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Client *exist_p;
+ time_t newts, curts;
+
+ if(!(source_p->flags & FLAGS_SERVICE))
+ return 0;
+
+ if((target_p = find_person(parv[1])) == NULL)
+ return 0;
+
+ if(!MyClient(target_p))
+ return 0;
+
+ if(!clean_nick(parv[2]))
+ return 0;
+
+ curts = atol(parv[4]);
+
+ /* if tsinfo is different from what it was when services issued the
+ * RSFNC, then we ignore it. This can happen when a client changes
+ * nicknames before the RSFNC arrives.. --anfl
+ */
+ if(target_p->tsinfo != curts)
+ return 0;
+
+ if((exist_p = find_named_client(parv[2])))
+ {
+ char buf[BUFSIZE];
+
+ /* this would be one hell of a race condition to trigger
+ * this one given the tsinfo check above, but its here for
+ * safety --anfl
+ */
+ if(target_p == exist_p)
+ return 0;
+
+ if(MyClient(exist_p))
+ sendto_one(exist_p, ":%s KILL %s :(Nickname regained by services)",
+ me.name, exist_p->name);
+
+ exist_p->flags |= FLAGS_KILLED;
+ /* Do not send kills to servers for unknowns -- jilles */
+ if(IsClient(exist_p))
+ kill_client_serv_butone(NULL, exist_p, "%s (Nickname regained by services)",
+ me.name);
+
+ snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))",
+ me.name);
+ exit_client(NULL, exist_p, &me, buf);
+ }
+
+ newts = atol(parv[3]);
+
+ /* timestamp is older than 15mins, ignore it */
+ if(newts < (CurrentTime - 900))
+ newts = CurrentTime - 900;
+
+ target_p->tsinfo = newts;
+
+ monitor_signoff(target_p);
+
+ invalidate_bancache_user(target_p);
+
+ sendto_realops_snomask(SNO_NCHANGE, L_ALL,
+ "Nick change: From %s to %s [%s@%s]",
+ target_p->name, parv[2], target_p->username,
+ target_p->host);
+
+ sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s",
+ target_p->name, target_p->username,
+ target_p->host, parv[2]);
+
+ add_history(target_p, 1);
+ sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
+ use_id(target_p), parv[2], (long) target_p->tsinfo);
+ sendto_server(NULL, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld",
+ target_p->name, parv[2], (long) target_p->tsinfo);
+
+ del_from_client_hash(target_p->name, target_p);
+ strcpy(target_p->name, parv[2]);
+ add_to_client_hash(target_p->name, target_p);
+
+ monitor_signon(target_p);
+
+ del_all_accepts(target_p);
+
+ comm_note(target_p->localClient->fd, "Nick: %s", target_p->name);
+ return 0;
+}
+
+/*
+** me_nickdelay
+** parv[0] = sender prefix
+** parv[1] = duration in seconds (0 to remove)
+** parv[2] = nick
+*/
+static int
+me_nickdelay(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int duration;
+ struct nd_entry *nd;
+
+ if(!(source_p->flags & FLAGS_SERVICE))
+ return 0;
+
+ duration = atoi(parv[1]);
+ if (duration <= 0)
+ {
+ nd = hash_find_nd(parv[2]);
+ if (nd != NULL)
+ free_nd_entry(nd);
+ }
+ else
+ {
+ if (duration > 86400)
+ duration = 86400;
+ add_nd_entry(parv[2]);
+ nd = hash_find_nd(parv[2]);
+ if (nd != NULL)
+ nd->expire = CurrentTime + duration;
+ }
+
+ return 0;
+}
+
+static void
+h_svc_server_introduced(hook_data_client *hdata)
+{
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, service_list.head)
+ {
+ if(!irccmp((const char *) ptr->data, hdata->target->name))
+ {
+ hdata->target->flags |= FLAGS_SERVICE;
+ return;
+ }
+ }
+}
+
+static void
+h_svc_whois(hook_data_client *data)
+{
+ char *p = data->target->user->suser;
+ if(!EmptyString(p))
+ {
+ /* Try to strip off any leading digits as this may be used to
+ * store both an ID number and an account name in one field.
+ * If only digits are present, leave as is.
+ */
+ while(IsDigit(*p))
+ p++;
+ if(*p == '\0')
+ p = data->target->user->suser;
+
+ sendto_one(data->client, form_str(RPL_WHOISLOGGEDIN),
+ get_id(&me, data->client),
+ get_id(data->client, data->client),
+ data->target->name, p);
+ }
+}
+
+static void
+h_svc_stats(hook_data_int *data)
+{
+ char statchar = (char) data->arg2;
+ dlink_node *ptr;
+
+ if (statchar == 'U' && IsOper(data->client))
+ {
+ DLINK_FOREACH(ptr, service_list.head)
+ {
+ sendto_one_numeric(data->client, RPL_STATSULINE,
+ form_str(RPL_STATSULINE),
+ ptr->data, "*", "*", "s");
+ }
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_set.c: Sets a server parameter.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_set.c 494 2006-01-15 16:08:28Z jilles $
+ */
+
+/* rewritten by jdc */
+
+#include "stdinc.h"
+#include "client.h"
+#include "event.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "send.h"
+#include "common.h"
+#include "channel.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_set(struct Client *, struct Client *, int, const char **);
+
+struct Message set_msgtab = {
+ "SET", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_set, 0}}
+};
+
+mapi_clist_av1 set_clist[] = { &set_msgtab, NULL };
+DECLARE_MODULE_AV1(set, NULL, NULL, set_clist, NULL, NULL, "$Revision: 494 $");
+
+/* Structure used for the SET table itself */
+struct SetStruct
+{
+ const char *name;
+ void (*handler) ();
+ int wants_char; /* 1 if it expects (char *, [int]) */
+ int wants_int; /* 1 if it expects ([char *], int) */
+
+ /* eg: 0, 1 == only an int arg
+ * eg: 1, 1 == char and int args */
+};
+
+
+static void quote_adminstring(struct Client *, const char *);
+static void quote_autoconn(struct Client *, char *, int);
+static void quote_autoconnall(struct Client *, int);
+static void quote_floodcount(struct Client *, int);
+static void quote_identtimeout(struct Client *, int);
+static void quote_idletime(struct Client *, int);
+static void quote_max(struct Client *, int);
+static void quote_operstring(struct Client *, const char *);
+static void quote_spamnum(struct Client *, int);
+static void quote_spamtime(struct Client *, int);
+static void quote_splitmode(struct Client *, char *);
+static void quote_splitnum(struct Client *, int);
+static void quote_splitusers(struct Client *, int);
+static void list_quote_commands(struct Client *);
+
+
+/*
+ * If this ever needs to be expanded to more than one arg of each
+ * type, want_char/want_int could be the count of the arguments,
+ * instead of just a boolean flag...
+ *
+ * -davidt
+ */
+
+static struct SetStruct set_cmd_table[] = {
+ /* name function string arg int arg */
+ /* -------------------------------------------------------- */
+ {"ADMINSTRING", quote_adminstring, 1, 0 },
+ {"AUTOCONN", quote_autoconn, 1, 1 },
+ {"AUTOCONNALL", quote_autoconnall, 0, 1 },
+ {"FLOODCOUNT", quote_floodcount, 0, 1 },
+ {"IDENTTIMEOUT", quote_identtimeout, 0, 1 },
+ {"IDLETIME", quote_idletime, 0, 1 },
+ {"MAX", quote_max, 0, 1 },
+ {"MAXCLIENTS", quote_max, 0, 1 },
+ {"OPERSTRING", quote_operstring, 1, 0 },
+ {"SPAMNUM", quote_spamnum, 0, 1 },
+ {"SPAMTIME", quote_spamtime, 0, 1 },
+ {"SPLITMODE", quote_splitmode, 1, 0 },
+ {"SPLITNUM", quote_splitnum, 0, 1 },
+ {"SPLITUSERS", quote_splitusers, 0, 1 },
+ /* -------------------------------------------------------- */
+ {(char *) 0, (void (*)()) 0, 0, 0}
+};
+
+
+/*
+ * list_quote_commands() sends the client all the available commands.
+ * Four to a line for now.
+ */
+static void
+list_quote_commands(struct Client *source_p)
+{
+ int i;
+ int j = 0;
+ const char *names[4];
+
+ sendto_one(source_p, ":%s NOTICE %s :Available QUOTE SET commands:",
+ me.name, source_p->name);
+
+ names[0] = names[1] = names[2] = names[3] = "";
+
+ for (i = 0; set_cmd_table[i].handler; i++)
+ {
+ names[j++] = set_cmd_table[i].name;
+
+ if(j > 3)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
+ me.name, source_p->name, names[0], names[1], names[2], names[3]);
+ j = 0;
+ names[0] = names[1] = names[2] = names[3] = "";
+ }
+
+ }
+ if(j)
+ sendto_one(source_p, ":%s NOTICE %s :%s %s %s %s",
+ me.name, source_p->name, names[0], names[1], names[2], names[3]);
+}
+
+/* SET AUTOCONN */
+static void
+quote_autoconn(struct Client *source_p, char *arg, int newval)
+{
+ set_server_conf_autoconn(source_p, arg, newval);
+}
+
+/* SET AUTOCONNALL */
+static void
+quote_autoconnall(struct Client *source_p, int newval)
+{
+ if(newval >= 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed AUTOCONNALL to %i",
+ source_p->name, newval);
+
+ GlobalSetOptions.autoconn = newval;
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :AUTOCONNALL is currently %i",
+ me.name, source_p->name, GlobalSetOptions.autoconn);
+ }
+}
+
+
+/* SET FLOODCOUNT */
+static void
+quote_floodcount(struct Client *source_p, int newval)
+{
+ if(newval >= 0)
+ {
+ GlobalSetOptions.floodcount = newval;
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed FLOODCOUNT to %i", source_p->name,
+ GlobalSetOptions.floodcount);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :FLOODCOUNT is currently %i",
+ me.name, source_p->name, GlobalSetOptions.floodcount);
+ }
+}
+
+/* SET IDENTTIMEOUT */
+static void
+quote_identtimeout(struct Client *source_p, int newval)
+{
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return;
+ }
+
+ if(newval > 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed IDENTTIMEOUT to %d",
+ get_oper_name(source_p), newval);
+ GlobalSetOptions.ident_timeout = newval;
+ }
+ else
+ sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d",
+ me.name, source_p->name, GlobalSetOptions.ident_timeout);
+}
+
+/* SET IDLETIME */
+static void
+quote_idletime(struct Client *source_p, int newval)
+{
+ if(newval >= 0)
+ {
+ if(newval == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has disabled idletime checking", source_p->name);
+ GlobalSetOptions.idletime = 0;
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed IDLETIME to %i",
+ source_p->name, newval);
+ GlobalSetOptions.idletime = (newval * 60);
+ }
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :IDLETIME is currently %i",
+ me.name, source_p->name, GlobalSetOptions.idletime / 60);
+ }
+}
+
+/* SET MAX */
+static void
+quote_max(struct Client *source_p, int newval)
+{
+ if(newval > 0)
+ {
+ if(newval > MASTER_MAX)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You cannot set MAXCLIENTS to > MASTER_MAX (%d)",
+ me.name, source_p->name, MASTER_MAX);
+ return;
+ }
+
+ if(newval < 32)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :You cannot set MAXCLIENTS to < 32 (%d:%d)",
+ me.name, source_p->name, GlobalSetOptions.maxclients,
+ highest_fd);
+ return;
+ }
+
+ GlobalSetOptions.maxclients = newval;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s!%s@%s set new MAXCLIENTS to %d (%lu current)",
+ source_p->name, source_p->username, source_p->host,
+ GlobalSetOptions.maxclients,
+ dlink_list_length(&lclient_list));
+
+ return;
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Current Maxclients = %d (%lu)",
+ me.name, source_p->name, GlobalSetOptions.maxclients,
+ dlink_list_length(&lclient_list));
+ }
+}
+
+/* SET OPERSTRING */
+static void
+quote_operstring(struct Client *source_p, const char *arg)
+{
+ if(EmptyString(arg))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :OPERSTRING is currently '%s'",
+ me.name, source_p->name, GlobalSetOptions.operstring);
+ }
+ else
+ {
+ strlcpy(GlobalSetOptions.operstring, arg,
+ sizeof(GlobalSetOptions.operstring));
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed OPERSTRING to '%s'",
+ get_oper_name(source_p), arg);
+ }
+}
+
+/* SET ADMINSTRING */
+static void
+quote_adminstring(struct Client *source_p, const char *arg)
+{
+ if(EmptyString(arg))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :ADMINSTRING is currently '%s'",
+ me.name, source_p->name, GlobalSetOptions.adminstring);
+ }
+ else
+ {
+ strlcpy(GlobalSetOptions.adminstring, arg,
+ sizeof(GlobalSetOptions.adminstring));
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed ADMINSTRING to '%s'",
+ get_oper_name(source_p), arg);
+ }
+}
+
+/* SET SPAMNUM */
+static void
+quote_spamnum(struct Client *source_p, int newval)
+{
+ if(newval > 0)
+ {
+ if(newval == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has disabled ANTI_SPAMBOT", source_p->name);
+ GlobalSetOptions.spam_num = newval;
+ return;
+ }
+ if(newval < MIN_SPAM_NUM)
+ {
+ GlobalSetOptions.spam_num = MIN_SPAM_NUM;
+ }
+ else /* if (newval < MIN_SPAM_NUM) */
+ {
+ GlobalSetOptions.spam_num = newval;
+ }
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed SPAMNUM to %i",
+ source_p->name, GlobalSetOptions.spam_num);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :SPAMNUM is currently %i",
+ me.name, source_p->name, GlobalSetOptions.spam_num);
+ }
+}
+
+/* SET SPAMTIME */
+static void
+quote_spamtime(struct Client *source_p, int newval)
+{
+ if(newval > 0)
+ {
+ if(newval < MIN_SPAM_TIME)
+ {
+ GlobalSetOptions.spam_time = MIN_SPAM_TIME;
+ }
+ else /* if (newval < MIN_SPAM_TIME) */
+ {
+ GlobalSetOptions.spam_time = newval;
+ }
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed SPAMTIME to %i",
+ source_p->name, GlobalSetOptions.spam_time);
+ }
+ else
+ {
+ sendto_one(source_p, ":%s NOTICE %s :SPAMTIME is currently %i",
+ me.name, source_p->name, GlobalSetOptions.spam_time);
+ }
+}
+
+/* this table is what splitmode may be set to */
+static const char *splitmode_values[] = {
+ "OFF",
+ "ON",
+ "AUTO",
+ NULL
+};
+
+/* this table is what splitmode may be */
+static const char *splitmode_status[] = {
+ "OFF",
+ "AUTO (OFF)",
+ "ON",
+ "AUTO (ON)",
+ NULL
+};
+
+/* SET SPLITMODE */
+static void
+quote_splitmode(struct Client *source_p, char *charval)
+{
+ if(charval)
+ {
+ int newval;
+
+ for (newval = 0; splitmode_values[newval]; newval++)
+ {
+ if(!irccmp(splitmode_values[newval], charval))
+ break;
+ }
+
+ /* OFF */
+ if(newval == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is disabling splitmode", get_oper_name(source_p));
+
+ splitmode = 0;
+ splitchecking = 0;
+
+ eventDelete(check_splitmode, NULL);
+ }
+ /* ON */
+ else if(newval == 1)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is enabling and activating splitmode",
+ get_oper_name(source_p));
+
+ splitmode = 1;
+ splitchecking = 0;
+
+ /* we might be deactivating an automatic splitmode, so pull the event */
+ eventDelete(check_splitmode, NULL);
+ }
+ /* AUTO */
+ else if(newval == 2)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s is enabling automatic splitmode",
+ get_oper_name(source_p));
+
+ splitchecking = 1;
+ check_splitmode(NULL);
+ }
+ }
+ else
+ /* if we add splitchecking to splitmode*2 we get a unique table to
+ * pull values back out of, splitmode can be four states - but you can
+ * only set to three, which means we cant use the same table --fl_
+ */
+ sendto_one(source_p, ":%s NOTICE %s :SPLITMODE is currently %s",
+ me.name, source_p->name,
+ splitmode_status[(splitchecking + (splitmode * 2))]);
+}
+
+/* SET SPLITNUM */
+static void
+quote_splitnum(struct Client *source_p, int newval)
+{
+ if(newval >= 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed SPLITNUM to %i", source_p->name, newval);
+ split_servers = newval;
+
+ if(splitchecking)
+ check_splitmode(NULL);
+ }
+ else
+ sendto_one(source_p, ":%s NOTICE %s :SPLITNUM is currently %i",
+ me.name, source_p->name, split_servers);
+}
+
+/* SET SPLITUSERS */
+static void
+quote_splitusers(struct Client *source_p, int newval)
+{
+ if(newval >= 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed SPLITUSERS to %i", source_p->name, newval);
+ split_users = newval;
+
+ if(splitchecking)
+ check_splitmode(NULL);
+ }
+ else
+ sendto_one(source_p, ":%s NOTICE %s :SPLITUSERS is currently %i",
+ me.name, source_p->name, split_users);
+}
+
+/*
+ * mo_set - SET command handler
+ * set options while running
+ */
+static int
+mo_set(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int newval;
+ int i, n;
+ const char *arg = NULL;
+ const char *intarg = NULL;
+
+ if(parc > 1)
+ {
+ /*
+ * Go through all the commands in set_cmd_table, until one is
+ * matched. I realize strcmp() is more intensive than a numeric
+ * lookup, but at least it's better than a big-ass switch/case
+ * statement.
+ */
+ for (i = 0; set_cmd_table[i].handler; i++)
+ {
+ if(!irccmp(set_cmd_table[i].name, parv[1]))
+ {
+ /*
+ * Command found; now execute the code
+ */
+ n = 2;
+
+ if(set_cmd_table[i].wants_char)
+ {
+ arg = parv[n++];
+ }
+
+ if(set_cmd_table[i].wants_int)
+ {
+ intarg = parv[n++];
+ }
+
+ if((n - 1) > parc)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :SET %s expects (\"%s%s\") args",
+ me.name, source_p->name,
+ set_cmd_table[i].name,
+ (set_cmd_table[i].
+ wants_char ? "string, " : ""),
+ (set_cmd_table[i].
+ wants_char ? "int" : ""));
+ return 0;
+ }
+
+ if(parc <= 2)
+ {
+ arg = NULL;
+ intarg = NULL;
+ }
+
+ if(set_cmd_table[i].wants_int && (parc > 2))
+ {
+ if(intarg)
+ {
+ if(!irccmp(intarg, "yes") || !irccmp(intarg, "on"))
+ newval = 1;
+ else if(!irccmp(intarg, "no")
+ || !irccmp(intarg, "off"))
+ newval = 0;
+ else
+ newval = atoi(intarg);
+ }
+ else
+ {
+ newval = -1;
+ }
+
+ if(newval < 0)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Value less than 0 illegal for %s",
+ me.name, source_p->name,
+ set_cmd_table[i].name);
+
+ return 0;
+ }
+ }
+ else
+ newval = -1;
+
+ if(set_cmd_table[i].wants_char)
+ {
+ if(set_cmd_table[i].wants_int)
+ set_cmd_table[i].handler(source_p, arg, newval);
+ else
+ set_cmd_table[i].handler(source_p, arg);
+ return 0;
+ }
+ else
+ {
+ if(set_cmd_table[i].wants_int)
+ set_cmd_table[i].handler(source_p, newval);
+ else
+ /* Just in case someone actually wants a
+ * set function that takes no args.. *shrug* */
+ set_cmd_table[i].handler(source_p);
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * Code here will be executed when a /QUOTE SET command is not
+ * found within set_cmd_table.
+ */
+ sendto_one(source_p, ":%s NOTICE %s :Variable not found.", me.name, parv[0]);
+ return 0;
+ }
+
+ list_quote_commands(source_p);
+
+ return 0;
+}
--- /dev/null
+/* modules/m_signon.c
+ * Copyright (C) 2006 Michael Tharp <gxti@partiallystapled.com>
+ * Copyright (C) 2006 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_signon.c 1192 2006-04-21 16:21:02Z jilles $
+ */
+
+#include "stdinc.h"
+
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+#include "whowas.h"
+#include "monitor.h"
+#include "s_stats.h"
+#include "snomask.h"
+#include "irc_string.h"
+#include "s_user.h"
+
+static int me_svslogin(struct Client *, struct Client *, int, const char **);
+static int ms_signon(struct Client *, struct Client *, int, const char **);
+
+static void send_signon(struct Client *, struct Client *, const char *, const char *, const char *, unsigned int, const char *);
+
+struct Message svslogin_msgtab = {
+ "SVSLOGIN", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_svslogin, 6}, mg_ignore}
+};
+struct Message signon_msgtab = {
+ "SIGNON", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, {ms_signon, 6}, mg_ignore, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 signon_clist[] = {
+ &svslogin_msgtab, &signon_msgtab, NULL
+};
+
+DECLARE_MODULE_AV1(signon, NULL, NULL, signon_clist, NULL, NULL, "$Revision: 1192 $");
+
+#define NICK_VALID 1
+#define USER_VALID 2
+#define HOST_VALID 4
+
+static int
+clean_nick(const char *nick)
+{
+ int len = 0;
+
+ if(*nick == '-')
+ return 0;
+
+ /* This is used to check logins, which are often
+ * numeric. Don't check for leading digits, if
+ * services wants to set someone's nick to something
+ * starting with a number, let it try.
+ * --gxti
+ */
+
+ for (; *nick; nick++)
+ {
+ len++;
+ if(!IsNickChar(*nick))
+ return 0;
+ }
+
+ /* nicklen is +1 */
+ if(len >= NICKLEN)
+ return 0;
+
+ return 1;
+}
+
+static int
+clean_username(const char *username)
+{
+ int len = 0;
+
+ for (; *username; username++)
+ {
+ len++;
+
+ if(!IsUserChar(*username))
+ return 0;
+ }
+
+ if(len > USERLEN)
+ return 0;
+
+ return 1;
+}
+
+static int
+clean_host(const char *host)
+{
+ int len = 0;
+
+ for (; *host; host++)
+ {
+ len++;
+
+ if(!IsHostChar(*host))
+ return 0;
+ }
+
+ if(len > HOSTLEN)
+ return 0;
+
+ return 1;
+}
+
+static int
+me_svslogin(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p, *exist_p;
+ char nick[NICKLEN+1], login[NICKLEN+1];
+ char user[USERLEN+1], host[HOSTLEN+1];
+ int valid = 0;
+
+ if(!(source_p->flags & FLAGS_SERVICE))
+ return 0;
+
+ if((target_p = find_client(parv[1])) == NULL)
+ return 0;
+
+ if(!MyClient(target_p) && !IsUnknown(target_p))
+ return 0;
+
+ if(clean_nick(parv[2]))
+ {
+ strlcpy(nick, parv[2], NICKLEN + 1);
+ valid |= NICK_VALID;
+ }
+ else if(*target_p->name)
+ strlcpy(nick, target_p->name, NICKLEN + 1);
+ else
+ strcpy(nick, "*");
+
+ if(clean_username(parv[3]))
+ {
+ strlcpy(user, parv[3], USERLEN + 1);
+ valid |= USER_VALID;
+ }
+ else
+ strlcpy(user, target_p->username, USERLEN + 1);
+
+ if(clean_host(parv[4]))
+ {
+ strlcpy(host, parv[4], HOSTLEN + 1);
+ valid |= HOST_VALID;
+ }
+ else
+ strlcpy(host, target_p->host, HOSTLEN + 1);
+
+ if(*parv[5] == '*')
+ {
+ if(target_p->user)
+ strlcpy(login, target_p->user->suser, NICKLEN + 1);
+ else
+ login[0] = '\0';
+ }
+ else if(!strcmp(parv[5], "0"))
+ login[0] = '\0';
+ else
+ strlcpy(login, parv[5], NICKLEN + 1);
+
+ /* Login (mostly) follows nick rules. */
+ if(*login && !clean_nick(login))
+ return 0;
+
+ if((exist_p = find_person(nick)) && target_p != exist_p)
+ {
+ char buf[BUFSIZE];
+
+ if(MyClient(exist_p))
+ sendto_one(exist_p, ":%s KILL %s :(Nickname regained by services)",
+ me.name, exist_p->name);
+
+ exist_p->flags |= FLAGS_KILLED;
+ kill_client_serv_butone(NULL, exist_p, "%s (Nickname regained by services)",
+ me.name);
+
+ snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))",
+ me.name);
+ exit_client(NULL, exist_p, &me, buf);
+ }else if((exist_p = find_client(nick)) && IsUnknown(exist_p) && exist_p != target_p) {
+ exit_client(NULL, exist_p, &me, "Overridden");
+ }
+
+ if(*login)
+ {
+ /* Strip leading digits, unless it's purely numeric. */
+ const char *p = login;
+ while(IsDigit(*p))
+ p++;
+ if(!*p)
+ p = login;
+
+ sendto_one(target_p, form_str(RPL_LOGGEDIN), me.name, EmptyString(target_p->name) ? "*" : target_p->name,
+ nick, user, host, p, p);
+ }
+ else
+ sendto_one(target_p, form_str(RPL_LOGGEDOUT), me.name, EmptyString(target_p->name) ? "*" : target_p->name,
+ nick, user, host);
+
+ if(IsUnknown(target_p))
+ {
+ struct User *user_p = make_user(target_p);
+
+ if(valid & NICK_VALID)
+ strcpy(target_p->preClient->spoofnick, nick);
+
+ if(valid & USER_VALID)
+ strcpy(target_p->preClient->spoofuser, user);
+
+ if(valid & HOST_VALID)
+ strcpy(target_p->preClient->spoofhost, host);
+
+ strlcpy(user_p->suser, login, NICKLEN + 1);
+ }
+ else
+ {
+ send_signon(NULL, target_p, nick, user, host, CurrentTime, login);
+ comm_note(target_p->localClient->fd, "Nick: %s", target_p->name);
+ }
+
+ return 0;
+}
+
+static int
+ms_signon(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+ int newts, sameuser;
+ char login[NICKLEN+1];
+
+ if(!clean_nick(parv[1]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad Nick from SIGNON: %s From: %s(via %s)",
+ parv[1], source_p->servptr->name, client_p->name);
+ /* if source_p has an id, kill_client_serv_butone() will
+ * send a kill to client_p, otherwise do it here */
+ if (!has_id(source_p))
+ sendto_one(client_p, ":%s KILL %s :%s (Bad nickname from SIGNON)",
+ get_id(&me, client_p), parv[1], me.name);
+ kill_client_serv_butone(client_p, source_p, "%s (Bad nickname from SIGNON)",
+ me.name);
+ source_p->flags |= FLAGS_KILLED;
+ exit_client(NULL, source_p, &me, "Bad nickname from SIGNON");
+ return 0;
+ }
+
+ if(!clean_username(parv[2]) || !clean_host(parv[3]))
+ {
+ ServerStats->is_kill++;
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Bad user@host from SIGNON: %s@%s From: %s(via %s)",
+ parv[2], parv[3], source_p->servptr->name, client_p->name);
+ /* if source_p has an id, kill_client_serv_butone() will
+ * send a kill to client_p, otherwise do it here */
+ if (!has_id(source_p))
+ sendto_one(client_p, ":%s KILL %s :%s (Bad user@host from SIGNON)",
+ get_id(&me, client_p), parv[1], me.name);
+ kill_client_serv_butone(client_p, source_p, "%s (Bad user@host from SIGNON)",
+ me.name);
+ source_p->flags |= FLAGS_KILLED;
+ exit_client(NULL, source_p, &me, "Bad user@host from SIGNON");
+ return 0;
+ }
+
+ newts = atol(parv[4]);
+
+ if(!strcmp(parv[5], "0"))
+ login[0] = '\0';
+ else if(*parv[5] != '*')
+ {
+ if (clean_nick(parv[5]))
+ strlcpy(login, parv[5], NICKLEN + 1);
+ else
+ return 0;
+ }
+
+ target_p = find_named_client(parv[1]);
+ if(target_p != NULL && target_p != source_p)
+ {
+ /* In case of collision, follow NICK rules. */
+ /* XXX this is duplicated code and does not do SAVE */
+ if(IsUnknown(target_p))
+ exit_client(NULL, target_p, &me, "Overridden");
+ else
+ {
+ if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from SIGNON from %s to %s(%s <- %s)(both killed)",
+ source_p->name, target_p->name, target_p->from->name,
+ client_p->name);
+
+ ServerStats->is_kill++;
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);
+
+ ServerStats->is_kill++;
+
+ kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);
+
+ target_p->flags |= FLAGS_KILLED;
+ exit_client(NULL, target_p, &me, "Nick collision(new)");
+ source_p->flags |= FLAGS_KILLED;
+ exit_client(client_p, source_p, &me, "Nick collision(old)");
+ return 0;
+ }
+ else
+ {
+ sameuser = !irccmp(target_p->username, source_p->username) &&
+ !irccmp(target_p->host, source_p->host);
+
+ if((sameuser && newts < target_p->tsinfo) ||
+ (!sameuser && newts > target_p->tsinfo))
+ {
+ if(sameuser)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from SIGNON from %s to %s(%s <- %s)(older killed)",
+ source_p->name, target_p->name,
+ target_p->from->name, client_p->name);
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick change collision from SIGNON from %s to %s(%s <- %s)(newer killed)",
+ source_p->name, target_p->name,
+ target_p->from->name, client_p->name);
+
+ ServerStats->is_kill++;
+
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* kill the client issuing the nickchange */
+ kill_client_serv_butone(client_p, source_p,
+ "%s (Nick change collision)", me.name);
+
+ source_p->flags |= FLAGS_KILLED;
+
+ if(sameuser)
+ exit_client(client_p, source_p, &me, "Nick collision(old)");
+ else
+ exit_client(client_p, source_p, &me, "Nick collision(new)");
+ return 0;
+ }
+ else
+ {
+ if(sameuser)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision from SIGNON on %s(%s <- %s)(older killed)",
+ target_p->name, target_p->from->name,
+ client_p->name);
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Nick collision from SIGNON on %s(%s <- %s)(newer killed)",
+ target_p->name, target_p->from->name,
+ client_p->name);
+
+ sendto_one_numeric(target_p, ERR_NICKCOLLISION,
+ form_str(ERR_NICKCOLLISION), target_p->name);
+
+ /* kill the client who existed before hand */
+ kill_client_serv_butone(client_p, target_p,
+ "%s (Nick collision)", me.name);
+
+ ServerStats->is_kill++;
+
+ target_p->flags |= FLAGS_KILLED;
+ (void) exit_client(client_p, target_p, &me, "Nick collision");
+ }
+ }
+
+ }
+ }
+
+ send_signon(client_p, source_p, parv[1], parv[2], parv[3], newts, login);
+ return 0;
+}
+
+static void
+send_signon(struct Client *client_p, struct Client *target_p,
+ const char *nick, const char *user, const char *host,
+ unsigned int newts, const char *login)
+{
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s SIGNON %s %s %s %ld %s",
+ use_id(target_p), nick, user, host,
+ (long) target_p->tsinfo, *login ? login : "0");
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s SIGNON %s %s %s %ld %s",
+ target_p->name, nick, user, host,
+ (long) target_p->tsinfo, *login ? login : "0");
+
+ strcpy(target_p->user->suser, login);
+
+ change_nick_user_host(target_p, nick, user, host, newts, "Signing %s (%s)", *login ? "in" : "out", nick);
+}
+
--- /dev/null
+/*
+ * charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ * m_snote.c: Server notice listener
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod -at- nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_snote.c 623 2006-01-29 13:47:35Z jilles $
+ */
+
+#include "stdinc.h"
+#include "class.h"
+#include "hook.h"
+#include "client.h"
+#include "hash.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_user.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int me_snote(struct Client *, struct Client *, int, const char **);
+
+struct Message snote_msgtab = {
+ "SNOTE", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_not_oper, mg_ignore, mg_ignore, {me_snote, 3}, mg_ignore}
+};
+
+mapi_clist_av1 snote_clist[] = { &snote_msgtab, NULL };
+DECLARE_MODULE_AV1(snote, NULL, NULL, snote_clist, NULL, NULL, "$Revision: 623 $");
+
+/*
+ * me_snote
+ * parv[0] = sender prefix
+ * parv[1] = snomask letter
+ * parv[2] = message
+ */
+static int
+me_snote(struct Client *client_p, struct Client *source_p, int parc,
+ const char *parv[])
+{
+ /* if there's more than just two params, this is a protocol
+ * violation, but it seems stupid to drop servers over it,
+ * shit happens afterall -nenolod
+ */
+ if (parc > 3)
+ return 0;
+ if (!IsServer(source_p))
+ return 0;
+
+ sendto_realops_snomask_from(snomask_modes[(unsigned char) *parv[1]],
+ L_ALL, source_p, "%s", parv[2]);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * m_stats.c: Sends the user statistics or config information.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_stats.c 1608 2006-06-04 02:11:40Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h" /* dlink_node/dlink_list */
+#include "class.h" /* report_classes */
+#include "client.h" /* Client */
+#include "common.h" /* TRUE/FALSE */
+#include "irc_string.h"
+#include "ircd.h" /* me */
+#include "listener.h" /* show_ports */
+#include "s_gline.h"
+#include "msg.h" /* Message */
+#include "hostmask.h" /* report_mtrie_conf_links */
+#include "numeric.h" /* ERR_xxx */
+#include "scache.h" /* list_scache */
+#include "send.h" /* sendto_one */
+#include "commio.h" /* highest_fd */
+#include "s_conf.h" /* ConfItem */
+#include "s_serv.h" /* hunt_server */
+#include "s_stats.h" /* tstats */
+#include "s_user.h" /* show_opers */
+#include "event.h" /* events */
+#include "blacklist.h" /* dnsbl stuff */
+#include "linebuf.h"
+#include "parse.h"
+#include "modules.h"
+#include "hook.h"
+#include "s_newconf.h"
+#include "hash.h"
+
+static int m_stats (struct Client *, struct Client *, int, const char **);
+
+struct Message stats_msgtab = {
+ "STATS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_stats, 2}, {m_stats, 3}, mg_ignore, mg_ignore, {m_stats, 2}}
+};
+
+int doing_stats_hook;
+int doing_stats_p_hook;
+
+mapi_clist_av1 stats_clist[] = { &stats_msgtab, NULL };
+mapi_hlist_av1 stats_hlist[] = {
+ { "doing_stats", &doing_stats_hook },
+ { "doing_stats_p", &doing_stats_p_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(stats, NULL, NULL, stats_clist, stats_hlist, NULL, "$Revision: 1608 $");
+
+const char *Lformat = "%s %u %u %u %u %u :%u %u %s";
+
+static void stats_l_list(struct Client *s, const char *, int, int, dlink_list *, char);
+static void stats_l_client(struct Client *source_p, struct Client *target_p,
+ char statchar);
+
+static void stats_spy(struct Client *, char, const char *);
+static void stats_p_spy(struct Client *);
+
+/* Heres our struct for the stats table */
+struct StatsStruct
+{
+ char letter;
+ void (*handler) ();
+ int need_oper;
+ int need_admin;
+};
+
+static void stats_dns_servers (struct Client *);
+static void stats_delay(struct Client *);
+static void stats_hash(struct Client *);
+static void stats_connect(struct Client *);
+static void stats_tdeny(struct Client *);
+static void stats_deny(struct Client *);
+static void stats_exempt(struct Client *);
+static void stats_events(struct Client *);
+static void stats_glines(struct Client *);
+static void stats_pending_glines(struct Client *);
+static void stats_hubleaf(struct Client *);
+static void stats_auth(struct Client *);
+static void stats_tklines(struct Client *);
+static void stats_klines(struct Client *);
+static void stats_messages(struct Client *);
+static void stats_dnsbl(struct Client *);
+static void stats_oper(struct Client *);
+static void stats_operedup(struct Client *);
+static void stats_ports(struct Client *);
+static void stats_tresv(struct Client *);
+static void stats_resv(struct Client *);
+static void stats_usage(struct Client *);
+static void stats_tstats(struct Client *);
+static void stats_uptime(struct Client *);
+static void stats_shared(struct Client *);
+static void stats_servers(struct Client *);
+static void stats_tgecos(struct Client *);
+static void stats_gecos(struct Client *);
+static void stats_class(struct Client *);
+static void stats_memory(struct Client *);
+static void stats_servlinks(struct Client *);
+static void stats_ltrace(struct Client *, int, const char **);
+static void stats_ziplinks(struct Client *);
+
+/* This table contains the possible stats items, in order:
+ * stats letter, function to call, operonly? adminonly?
+ * case only matters in the stats letter column.. -- fl_
+ */
+static struct StatsStruct stats_cmd_table[] = {
+ /* letter function need_oper need_admin */
+ {'a', stats_dns_servers, 1, 1, },
+ {'A', stats_dns_servers, 1, 1, },
+ {'b', stats_delay, 1, 1, },
+ {'B', stats_hash, 1, 1, },
+ {'c', stats_connect, 0, 0, },
+ {'C', stats_connect, 0, 0, },
+ {'d', stats_tdeny, 1, 0, },
+ {'D', stats_deny, 1, 0, },
+ {'e', stats_exempt, 1, 0, },
+ {'E', stats_events, 1, 1, },
+ {'f', comm_dump, 1, 1, },
+ {'F', comm_dump, 1, 1, },
+ {'g', stats_pending_glines, 1, 0, },
+ {'G', stats_glines, 1, 0, },
+ {'h', stats_hubleaf, 0, 0, },
+ {'H', stats_hubleaf, 0, 0, },
+ {'i', stats_auth, 0, 0, },
+ {'I', stats_auth, 0, 0, },
+ {'k', stats_tklines, 0, 0, },
+ {'K', stats_klines, 0, 0, },
+ {'l', stats_ltrace, 0, 0, },
+ {'L', stats_ltrace, 0, 0, },
+ {'m', stats_messages, 0, 0, },
+ {'M', stats_messages, 0, 0, },
+ {'n', stats_dnsbl, 0, 0, },
+ {'o', stats_oper, 0, 0, },
+ {'O', stats_oper, 0, 0, },
+ {'p', stats_operedup, 0, 0, },
+ {'P', stats_ports, 0, 0, },
+ {'q', stats_tresv, 1, 0, },
+ {'Q', stats_resv, 1, 0, },
+ {'r', stats_usage, 1, 0, },
+ {'R', stats_usage, 1, 0, },
+ {'t', stats_tstats, 1, 0, },
+ {'T', stats_tstats, 1, 0, },
+ {'u', stats_uptime, 0, 0, },
+ {'U', stats_shared, 1, 0, },
+ {'v', stats_servers, 0, 0, },
+ {'V', stats_servers, 0, 0, },
+ {'x', stats_tgecos, 1, 0, },
+ {'X', stats_gecos, 1, 0, },
+ {'y', stats_class, 0, 0, },
+ {'Y', stats_class, 0, 0, },
+ {'z', stats_memory, 1, 0, },
+ {'Z', stats_ziplinks, 1, 0, },
+ {'?', stats_servlinks, 0, 0, },
+ {(char) 0, (void (*)()) 0, 0, 0, }
+};
+
+/*
+ * m_stats by fl_
+ * parv[0] = sender prefix
+ * parv[1] = stat letter/command
+ * parv[2] = (if present) server/mask in stats L, or target
+ *
+ * This will search the tables for the appropriate stats letter,
+ * if found execute it.
+ */
+static int
+m_stats(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+ int i;
+ char statchar;
+
+ statchar = parv[1][0];
+
+ if(MyClient(source_p) && !IsOper(source_p))
+ {
+ /* Check the user is actually allowed to do /stats, and isnt flooding */
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "STATS");
+ sendto_one_numeric(source_p, RPL_ENDOFSTATS,
+ form_str(RPL_ENDOFSTATS), statchar);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ if(hunt_server (client_p, source_p, ":%s STATS %s :%s", 2, parc, parv) != HUNTED_ISME)
+ return 0;
+
+ if((statchar != 'L') && (statchar != 'l'))
+ stats_spy(source_p, statchar, NULL);
+
+ for (i = 0; stats_cmd_table[i].handler; i++)
+ {
+ if(stats_cmd_table[i].letter == statchar)
+ {
+ /* The stats table says what privs are needed, so check --fl_ */
+ /* Called for remote clients and for local opers, so check need_admin
+ * and need_oper
+ */
+ if((stats_cmd_table[i].need_admin && !IsOperAdmin (source_p)) ||
+ (stats_cmd_table[i].need_oper && !IsOper (source_p)))
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ break;
+ }
+
+ /* Blah, stats L needs the parameters, none of the others do.. */
+ if(statchar == 'L' || statchar == 'l')
+ stats_cmd_table[i].handler (source_p, parc, parv);
+ else
+ stats_cmd_table[i].handler (source_p);
+ }
+ }
+
+ /* Send the end of stats notice, and the stats_spy */
+ sendto_one_numeric(source_p, RPL_ENDOFSTATS,
+ form_str(RPL_ENDOFSTATS), statchar);
+
+ return 0;
+}
+
+static void
+stats_dns_servers (struct Client *source_p)
+{
+ report_dns_servers (source_p);
+}
+
+static void
+stats_delay(struct Client *source_p)
+{
+ struct nd_entry *nd;
+ dlink_node *ptr;
+ int i;
+
+ HASH_WALK(i, U_MAX, ptr, ndTable)
+ {
+ nd = ptr->data;
+ sendto_one_notice(source_p, "Delaying: %s for %ld",
+ nd->name, (long) nd->expire);
+ }
+ HASH_WALK_END
+}
+
+static void
+stats_hash(struct Client *source_p)
+{
+ hash_stats(source_p);
+}
+
+static void
+stats_connect(struct Client *source_p)
+{
+ static char buf[5];
+ struct server_conf *server_p;
+ char *s;
+ dlink_node *ptr;
+
+ if((ConfigFileEntry.stats_c_oper_only ||
+ (ConfigServerHide.flatten_links && !IsExemptShide(source_p))) &&
+ !IsOper(source_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str(ERR_NOPRIVILEGES));
+ return;
+ }
+
+ DLINK_FOREACH(ptr, server_conf_list.head)
+ {
+ server_p = ptr->data;
+
+ if(ServerConfIllegal(server_p))
+ continue;
+
+ buf[0] = '\0';
+ s = buf;
+
+ if(IsOper(source_p))
+ {
+ if(ServerConfAutoconn(server_p))
+ *s++ = 'A';
+ if(ServerConfTb(server_p))
+ *s++ = 'T';
+ if(ServerConfCompressed(server_p))
+ *s++ = 'Z';
+ }
+
+ if(!buf[0])
+ *s++ = '*';
+
+ *s = '\0';
+
+ sendto_one_numeric(source_p, RPL_STATSCLINE,
+ form_str(RPL_STATSCLINE),
+#ifndef HIDE_SERVERS_IPS
+ server_p->host,
+#else
+ "*@127.0.0.1",
+#endif
+ buf, server_p->name,
+ server_p->port, server_p->class_name);
+ }
+}
+
+/* stats_tdeny()
+ *
+ * input - client to report to
+ * output - none
+ * side effects - client is given temp dline list.
+ */
+static void
+stats_tdeny (struct Client *source_p)
+{
+ char *host, *pass, *user, *oper_reason;
+ struct AddressRec *arec;
+ struct ConfItem *aconf;
+ int i;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ for (arec = atable[i]; arec; arec = arec->next)
+ {
+ if(arec->type == CONF_DLINE)
+ {
+ aconf = arec->aconf;
+
+ if(!(aconf->flags & CONF_FLAGS_TEMPORARY))
+ continue;
+
+ get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
+
+ sendto_one_numeric(source_p, RPL_STATSDLINE,
+ form_str (RPL_STATSDLINE),
+ 'd', host, pass,
+ oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ }
+ }
+}
+
+/* stats_deny()
+ *
+ * input - client to report to
+ * output - none
+ * side effects - client is given dline list.
+ */
+static void
+stats_deny (struct Client *source_p)
+{
+ char *host, *pass, *user, *oper_reason;
+ struct AddressRec *arec;
+ struct ConfItem *aconf;
+ int i;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ for (arec = atable[i]; arec; arec = arec->next)
+ {
+ if(arec->type == CONF_DLINE)
+ {
+ aconf = arec->aconf;
+
+ if(aconf->flags & CONF_FLAGS_TEMPORARY)
+ continue;
+
+ get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
+
+ sendto_one_numeric(source_p, RPL_STATSDLINE,
+ form_str (RPL_STATSDLINE),
+ 'D', host, pass,
+ oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ }
+ }
+}
+
+
+/* stats_exempt()
+ *
+ * input - client to report to
+ * output - none
+ * side effects - client is given list of exempt blocks
+ */
+static void
+stats_exempt(struct Client *source_p)
+{
+ char *name, *host, *pass, *user, *classname;
+ struct AddressRec *arec;
+ struct ConfItem *aconf;
+ int i, port;
+
+ if(ConfigFileEntry.stats_e_disabled)
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ return;
+ }
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ for (arec = atable[i]; arec; arec = arec->next)
+ {
+ if(arec->type == CONF_EXEMPTDLINE)
+ {
+ aconf = arec->aconf;
+ get_printable_conf (aconf, &name, &host, &pass,
+ &user, &port, &classname);
+
+ sendto_one_numeric(source_p, RPL_STATSDLINE,
+ form_str(RPL_STATSDLINE),
+ 'e', host, pass, "", "");
+ }
+ }
+ }}
+
+
+static void
+stats_events (struct Client *source_p)
+{
+ show_events (source_p);
+}
+
+/* stats_pending_glines()
+ *
+ * input - client pointer
+ * output - none
+ * side effects - client is shown list of pending glines
+ */
+static void
+stats_pending_glines (struct Client *source_p)
+{
+ if(ConfigFileEntry.glines)
+ {
+ dlink_node *pending_node;
+ struct gline_pending *glp_ptr;
+ char timebuffer[MAX_DATE_STRING];
+ struct tm *tmptr;
+
+ DLINK_FOREACH (pending_node, pending_glines.head)
+ {
+ glp_ptr = pending_node->data;
+
+ tmptr = localtime (&glp_ptr->time_request1);
+ strftime (timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
+
+ sendto_one_notice(source_p,
+ ":1) %s!%s@%s on %s requested gline at %s for %s@%s [%s]",
+ glp_ptr->oper_nick1,
+ glp_ptr->oper_user1, glp_ptr->oper_host1,
+ glp_ptr->oper_server1, timebuffer,
+ glp_ptr->user, glp_ptr->host, glp_ptr->reason1);
+
+ if(glp_ptr->oper_nick2[0])
+ {
+ tmptr = localtime (&glp_ptr->time_request2);
+ strftime (timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
+ sendto_one_notice(source_p,
+ ":2) %s!%s@%s on %s requested gline at %s for %s@%s [%s]",
+ glp_ptr->oper_nick2,
+ glp_ptr->oper_user2, glp_ptr->oper_host2,
+ glp_ptr->oper_server2, timebuffer,
+ glp_ptr->user, glp_ptr->host, glp_ptr->reason2);
+ }
+ }
+
+ if(dlink_list_length (&pending_glines) > 0)
+ sendto_one_notice(source_p, ":End of Pending G-lines");
+ }
+ else
+ sendto_one_notice(source_p, ":This server does not support G-Lines");
+
+}
+
+/* stats_glines()
+ *
+ * input - client pointer
+ * output - none
+ * side effects - client is shown list of glines
+ */
+static void
+stats_glines (struct Client *source_p)
+{
+ if(ConfigFileEntry.glines)
+ {
+ dlink_node *gline_node;
+ struct ConfItem *kill_ptr;
+
+ DLINK_FOREACH_PREV (gline_node, glines.tail)
+ {
+ kill_ptr = gline_node->data;
+
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE), 'G',
+ kill_ptr->host ? kill_ptr->host : "*",
+ kill_ptr->user ? kill_ptr->user : "*",
+ kill_ptr->passwd ? kill_ptr->passwd : "No Reason",
+ kill_ptr->spasswd ? "|" : "",
+ kill_ptr->spasswd ? kill_ptr->spasswd : "");
+ }
+ }
+ else
+ sendto_one_notice(source_p, ":This server does not support G-Lines");
+}
+
+
+static void
+stats_hubleaf(struct Client *source_p)
+{
+ struct remote_conf *hub_p;
+ dlink_node *ptr;
+
+ if((ConfigFileEntry.stats_h_oper_only ||
+ (ConfigServerHide.flatten_links && !IsExemptShide(source_p))) &&
+ !IsOper(source_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ return;
+ }
+
+ DLINK_FOREACH(ptr, hubleaf_conf_list.head)
+ {
+ hub_p = ptr->data;
+
+ if(hub_p->flags & CONF_HUB)
+ sendto_one_numeric(source_p, RPL_STATSHLINE,
+ form_str(RPL_STATSHLINE),
+ hub_p->host, hub_p->server);
+ else
+ sendto_one_numeric(source_p, RPL_STATSLLINE,
+ form_str(RPL_STATSLLINE),
+ hub_p->host, hub_p->server);
+ }
+}
+
+
+static void
+stats_auth (struct Client *source_p)
+{
+ /* Oper only, if unopered, return ERR_NOPRIVS */
+ if((ConfigFileEntry.stats_i_oper_only == 2) && !IsOper (source_p))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+
+ /* If unopered, Only return matching auth blocks */
+ else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOper (source_p))
+ {
+ struct ConfItem *aconf;
+ char *name, *host, *pass, *user, *classname;
+ int port;
+
+ if(MyConnect (source_p))
+ aconf = find_conf_by_address (source_p->host, source_p->sockhost, NULL,
+ (struct sockaddr *)&source_p->localClient->ip,
+ CONF_CLIENT,
+ source_p->localClient->ip.ss_family,
+ source_p->username);
+ else
+ aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_CLIENT,
+ 0, source_p->username);
+
+ if(aconf == NULL)
+ return;
+
+ get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname);
+
+ sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
+ name, show_iline_prefix(source_p, aconf, user),
+ host, port, classname);
+ }
+
+ /* Theyre opered, or allowed to see all auth blocks */
+ else
+ report_auth (source_p);
+}
+
+
+static void
+stats_tklines(struct Client *source_p)
+{
+ /* Oper only, if unopered, return ERR_NOPRIVS */
+ if((ConfigFileEntry.stats_k_oper_only == 2) && !IsOper (source_p))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+
+ /* If unopered, Only return matching klines */
+ else if((ConfigFileEntry.stats_k_oper_only == 1) && !IsOper (source_p))
+ {
+ struct ConfItem *aconf;
+ char *host, *pass, *user, *oper_reason;
+
+ if(MyConnect (source_p))
+ aconf = find_conf_by_address (source_p->host, source_p->sockhost, NULL,
+ (struct sockaddr *)&source_p->localClient->ip,
+ CONF_KILL,
+ source_p->localClient->ip.ss_family,
+ source_p->username);
+ else
+ aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_KILL,
+ 0, source_p->username);
+
+ if(aconf == NULL)
+ return;
+
+ /* dont report a permanent kline as a tkline */
+ if((aconf->flags & CONF_FLAGS_TEMPORARY) == 0)
+ return;
+
+ get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
+
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE), 'k',
+ user, pass, oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ /* Theyre opered, or allowed to see all klines */
+ else
+ {
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ int i;
+ char *user, *host, *pass, *oper_reason;
+
+ for(i = 0; i < LAST_TEMP_TYPE; i++)
+ {
+ DLINK_FOREACH(ptr, temp_klines[i].head)
+ {
+ aconf = ptr->data;
+
+ get_printable_kline(source_p, aconf, &host, &pass,
+ &user, &oper_reason);
+
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE),
+ 'k', host, user, pass,
+ oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ }
+ }
+}
+
+static void
+stats_klines(struct Client *source_p)
+{
+ /* Oper only, if unopered, return ERR_NOPRIVS */
+ if((ConfigFileEntry.stats_k_oper_only == 2) && !IsOper (source_p))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+
+ /* If unopered, Only return matching klines */
+ else if((ConfigFileEntry.stats_k_oper_only == 1) && !IsOper (source_p))
+ {
+ struct ConfItem *aconf;
+ char *host, *pass, *user, *oper_reason;
+
+ /* search for a kline */
+ if(MyConnect (source_p))
+ aconf = find_conf_by_address (source_p->host, source_p->sockhost, NULL,
+ (struct sockaddr *)&source_p->localClient->ip,
+ CONF_KILL,
+ source_p->localClient->ip.ss_family,
+ source_p->username);
+ else
+ aconf = find_conf_by_address (source_p->host, NULL, NULL, NULL, CONF_KILL,
+ 0, source_p->username);
+
+ if(aconf == NULL)
+ return;
+
+ /* dont report a tkline as a kline */
+ if(aconf->flags & CONF_FLAGS_TEMPORARY)
+ return;
+
+ get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
+
+ sendto_one_numeric(source_p, RPL_STATSKLINE, form_str(RPL_STATSKLINE),
+ 'K', host, user, pass, oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ /* Theyre opered, or allowed to see all klines */
+ else
+ report_Klines (source_p);
+}
+
+static void
+stats_messages(struct Client *source_p)
+{
+ report_messages(source_p);
+}
+
+static void
+stats_dnsbl(struct Client *source_p)
+{
+ dlink_node *ptr;
+ struct Blacklist *blptr;
+
+ DLINK_FOREACH(ptr, blacklist_list.head)
+ {
+ blptr = ptr->data;
+
+ /* use RPL_STATSDEBUG for now -- jilles */
+ sendto_one_numeric(source_p, RPL_STATSDEBUG, "n :%d %s %s (%d)",
+ blptr->hits,
+ blptr->host,
+ blptr->status & CONF_ILLEGAL ? "disabled" : "active",
+ blptr->refcount);
+ }
+}
+
+static void
+stats_oper(struct Client *source_p)
+{
+ struct oper_conf *oper_p;
+ dlink_node *ptr;
+
+ if(!IsOper(source_p) && ConfigFileEntry.stats_o_oper_only)
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ return;
+ }
+
+ DLINK_FOREACH(ptr, oper_conf_list.head)
+ {
+ oper_p = ptr->data;
+
+ sendto_one_numeric(source_p, RPL_STATSOLINE,
+ form_str(RPL_STATSOLINE),
+ oper_p->username, oper_p->host, oper_p->name,
+ IsOper(source_p) ? get_oper_privs(oper_p->flags) : "0", "-1");
+ }
+}
+
+
+/* stats_operedup()
+ *
+ * input - client pointer
+ * output - none
+ * side effects - client is shown a list of active opers
+ */
+static void
+stats_operedup (struct Client *source_p)
+{
+ struct Client *target_p;
+ dlink_node *oper_ptr;
+ unsigned int count = 0;
+
+ DLINK_FOREACH (oper_ptr, oper_list.head)
+ {
+ target_p = oper_ptr->data;
+
+ if(IsOperInvis(target_p) && !IsOper(source_p))
+ continue;
+
+ if(target_p->user->away)
+ continue;
+
+ count++;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "p :%s (%s@%s)",
+ target_p->name, target_p->username,
+ target_p->host);
+ }
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "p :%u staff members", count);
+
+ stats_p_spy (source_p);
+}
+
+static void
+stats_ports (struct Client *source_p)
+{
+ if(!IsOper (source_p) && ConfigFileEntry.stats_P_oper_only)
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ else
+ show_ports (source_p);
+}
+
+static void
+stats_tresv(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ int i;
+
+ DLINK_FOREACH(ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+ if(aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSQLINE,
+ form_str(RPL_STATSQLINE),
+ 'q', aconf->port, aconf->name, aconf->passwd);
+ }
+
+ HASH_WALK(i, R_MAX, ptr, resvTable)
+ {
+ aconf = ptr->data;
+ if(aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSQLINE,
+ form_str(RPL_STATSQLINE),
+ 'q', aconf->port, aconf->name, aconf->passwd);
+ }
+ HASH_WALK_END
+}
+
+
+static void
+stats_resv(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ int i;
+
+ DLINK_FOREACH(ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+ if(!aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSQLINE,
+ form_str(RPL_STATSQLINE),
+ 'Q', aconf->port, aconf->name, aconf->passwd);
+ }
+
+ HASH_WALK(i, R_MAX, ptr, resvTable)
+ {
+ aconf = ptr->data;
+ if(!aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSQLINE,
+ form_str(RPL_STATSQLINE),
+ 'Q', aconf->port, aconf->name, aconf->passwd);
+ }
+ HASH_WALK_END
+}
+
+static void
+stats_usage (struct Client *source_p)
+{
+ struct rusage rus;
+ time_t secs;
+ time_t rup;
+#ifdef hz
+# define hzz hz
+#else
+# ifdef HZ
+# define hzz HZ
+# else
+ int hzz = 1;
+# endif
+#endif
+
+ if(getrusage(RUSAGE_SELF, &rus) == -1)
+ {
+ sendto_one_notice(source_p, ":Getruseage error: %s.",
+ strerror(errno));
+ return;
+ }
+ secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
+ if(0 == secs)
+ secs = 1;
+
+ rup = (CurrentTime - startup_time) * hzz;
+ if(0 == rup)
+ rup = 1;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :CPU Secs %d:%d User %d:%d System %d:%d",
+ (int) (secs / 60), (int) (secs % 60),
+ (int) (rus.ru_utime.tv_sec / 60),
+ (int) (rus.ru_utime.tv_sec % 60),
+ (int) (rus.ru_stime.tv_sec / 60),
+ (int) (rus.ru_stime.tv_sec % 60));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :RSS %ld ShMem %ld Data %ld Stack %ld",
+ rus.ru_maxrss, (rus.ru_ixrss / rup),
+ (rus.ru_idrss / rup), (rus.ru_isrss / rup));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :Swaps %d Reclaims %d Faults %d",
+ (int) rus.ru_nswap, (int) rus.ru_minflt, (int) rus.ru_majflt);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :Block in %d out %d",
+ (int) rus.ru_inblock, (int) rus.ru_oublock);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :Msg Rcv %d Send %d",
+ (int) rus.ru_msgrcv, (int) rus.ru_msgsnd);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "R :Signals %d Context Vol. %d Invol %d",
+ (int) rus.ru_nsignals, (int) rus.ru_nvcsw,
+ (int) rus.ru_nivcsw);
+}
+
+static void
+stats_tstats (struct Client *source_p)
+{
+ tstats (source_p);
+}
+
+static void
+stats_uptime (struct Client *source_p)
+{
+ time_t now;
+
+ now = CurrentTime - startup_time;
+ sendto_one_numeric(source_p, RPL_STATSUPTIME,
+ form_str (RPL_STATSUPTIME),
+ now / 86400, (now / 3600) % 24,
+ (now / 60) % 60, now % 60);
+ sendto_one_numeric(source_p, RPL_STATSCONN,
+ form_str (RPL_STATSCONN),
+ MaxConnectionCount, MaxClientCount,
+ Count.totalrestartcount);
+}
+
+struct shared_flags
+{
+ int flag;
+ char letter;
+};
+static struct shared_flags shared_flagtable[] =
+{
+ { SHARED_PKLINE, 'K' },
+ { SHARED_TKLINE, 'k' },
+ { SHARED_UNKLINE, 'U' },
+ { SHARED_PXLINE, 'X' },
+ { SHARED_TXLINE, 'x' },
+ { SHARED_UNXLINE, 'Y' },
+ { SHARED_PRESV, 'Q' },
+ { SHARED_TRESV, 'q' },
+ { SHARED_UNRESV, 'R' },
+ { SHARED_LOCOPS, 'L' },
+ { SHARED_REHASH, 'H' },
+ { 0, '\0'}
+};
+
+
+static void
+stats_shared (struct Client *source_p)
+{
+ struct remote_conf *shared_p;
+ dlink_node *ptr;
+ char buf[15];
+ char *p;
+ int i;
+
+ DLINK_FOREACH(ptr, shared_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ p = buf;
+
+ *p++ = 'c';
+
+ for(i = 0; shared_flagtable[i].flag != 0; i++)
+ {
+ if(shared_p->flags & shared_flagtable[i].flag)
+ *p++ = shared_flagtable[i].letter;
+ }
+
+ *p = '\0';
+
+ sendto_one_numeric(source_p, RPL_STATSULINE,
+ form_str(RPL_STATSULINE),
+ shared_p->server, shared_p->username,
+ shared_p->host, buf);
+ }
+
+ DLINK_FOREACH(ptr, cluster_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ p = buf;
+
+ *p++ = 'C';
+
+ for(i = 0; shared_flagtable[i].flag != 0; i++)
+ {
+ if(shared_p->flags & shared_flagtable[i].flag)
+ *p++ = shared_flagtable[i].letter;
+ }
+
+ *p = '\0';
+
+ sendto_one_numeric(source_p, RPL_STATSULINE,
+ form_str(RPL_STATSULINE),
+ shared_p->server, "*", "*", buf);
+ }
+}
+
+/* stats_servers()
+ *
+ * input - client pointer
+ * output - none
+ * side effects - client is shown lists of who connected servers
+ */
+static void
+stats_servers (struct Client *source_p)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ time_t seconds;
+ int days, hours, minutes;
+ int j = 0;
+
+ if(ConfigServerHide.flatten_links && !IsOper(source_p) &&
+ !IsExemptShide(source_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ return;
+ }
+
+ DLINK_FOREACH (ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ j++;
+ seconds = CurrentTime - target_p->localClient->firsttime;
+
+ days = (int) (seconds / 86400);
+ seconds %= 86400;
+ hours = (int) (seconds / 3600);
+ seconds %= 3600;
+ minutes = (int) (seconds / 60);
+ seconds %= 60;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "V :%s (%s!*@*) Idle: %d SendQ: %d "
+ "Connected: %d day%s, %d:%02d:%02d",
+ target_p->name,
+ (target_p->serv->by[0] ? target_p->serv->by : "Remote."),
+ (int) (CurrentTime - target_p->localClient->lasttime),
+ (int) linebuf_len (&target_p->localClient->buf_sendq),
+ days, (days == 1) ? "" : "s", hours, minutes,
+ (int) seconds);
+ }
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "V :%d Server(s)", j);
+}
+
+static void
+stats_tgecos(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSXLINE,
+ form_str(RPL_STATSXLINE),
+ 'x', aconf->port, aconf->name,
+ aconf->passwd);
+ }
+}
+
+static void
+stats_gecos(struct Client *source_p)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(!aconf->hold)
+ sendto_one_numeric(source_p, RPL_STATSXLINE,
+ form_str(RPL_STATSXLINE),
+ 'X', aconf->port, aconf->name,
+ aconf->passwd);
+ }
+}
+
+static void
+stats_class(struct Client *source_p)
+{
+ if(ConfigFileEntry.stats_y_oper_only && !IsOper(source_p))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ else
+ report_classes(source_p);
+}
+
+static void
+stats_memory (struct Client *source_p)
+{
+ count_memory (source_p);
+}
+
+static void
+stats_ziplinks (struct Client *source_p)
+{
+ dlink_node *ptr;
+ struct Client *target_p;
+ int sent_data = 0;
+
+ DLINK_FOREACH (ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+ if(IsCapable (target_p, CAP_ZIP))
+ {
+ /* we use memcpy(3) and a local copy of the structure to
+ * work around a register use bug on GCC on the SPARC.
+ * -jmallett, 04/27/2002
+ */
+ struct ZipStats zipstats;
+ memcpy (&zipstats, &target_p->localClient->zipstats,
+ sizeof (struct ZipStats));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "Z :ZipLinks stats for %s send[%.2f%% compression "
+ "(%lu kB data/%lu kB wire)] recv[%.2f%% compression "
+ "(%lu kB data/%lu kB wire)]",
+ target_p->name,
+ zipstats.out_ratio, zipstats.outK, zipstats.outK_wire,
+ zipstats.in_ratio, zipstats.inK, zipstats.inK_wire);
+ sent_data++;
+ }
+ }
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "Z :%u ziplink(s)", sent_data);
+}
+
+static void
+stats_servlinks (struct Client *source_p)
+{
+ static char Sformat[] = ":%s %d %s %s %u %u %u %u %u :%u %u %s";
+ long uptime, sendK, receiveK;
+ struct Client *target_p;
+ dlink_node *ptr;
+ int j = 0;
+
+ if(ConfigServerHide.flatten_links && !IsOper (source_p) &&
+ !IsExemptShide(source_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES,
+ form_str (ERR_NOPRIVILEGES));
+ return;
+ }
+
+ sendK = receiveK = 0;
+
+ DLINK_FOREACH (ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ j++;
+ sendK += target_p->localClient->sendK;
+ receiveK += target_p->localClient->receiveK;
+
+ sendto_one(source_p, Sformat,
+ get_id(&me, source_p), RPL_STATSLINKINFO, get_id(source_p, source_p),
+ get_server_name(target_p, SHOW_IP),
+ (int) linebuf_len (&target_p->localClient->buf_sendq),
+ (int) target_p->localClient->sendM,
+ (int) target_p->localClient->sendK,
+ (int) target_p->localClient->receiveM,
+ (int) target_p->localClient->receiveK,
+ CurrentTime - target_p->localClient->firsttime,
+ (CurrentTime > target_p->localClient->lasttime) ?
+ (CurrentTime - target_p->localClient->lasttime) : 0,
+ IsOper (source_p) ? show_capabilities (target_p) : "TS");
+ }
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "? :%u total server(s)", j);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "? :Sent total : %7.2f %s",
+ _GMKv (sendK), _GMKs (sendK));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "? :Recv total : %7.2f %s",
+ _GMKv (receiveK), _GMKs (receiveK));
+
+ uptime = (CurrentTime - startup_time);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "? :Server send: %7.2f %s (%4.1f K/s)",
+ _GMKv (me.localClient->sendK),
+ _GMKs (me.localClient->sendK),
+ (float) ((float) me.localClient->sendK / (float) uptime));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "? :Server recv: %7.2f %s (%4.1f K/s)",
+ _GMKv (me.localClient->receiveK),
+ _GMKs (me.localClient->receiveK),
+ (float) ((float) me.localClient->receiveK / (float) uptime));
+}
+
+static void
+stats_ltrace(struct Client *source_p, int parc, const char *parv[])
+{
+ int doall = 0;
+ int wilds = 0;
+ const char *name;
+ char statchar = parv[1][0];
+
+ /* this is def targeted at us somehow.. */
+ if(parc > 2 && !EmptyString(parv[2]))
+ {
+ /* directed at us generically? */
+ if(match(parv[2], me.name) ||
+ (!MyClient(source_p) && !irccmp(parv[2], me.id)))
+ {
+ name = me.name;
+ doall = 1;
+ }
+ else
+ {
+ name = parv[2];
+ wilds = strchr(name, '*') || strchr(name, '?');
+ }
+
+ /* must be directed at a specific person thats not us */
+ if(!doall && !wilds)
+ {
+ struct Client *target_p;
+
+ if(MyClient(source_p))
+ target_p = find_named_person(name);
+ else
+ target_p = find_person(name);
+
+ if(target_p != NULL)
+ {
+ stats_spy(source_p, statchar, target_p->name);
+ stats_l_client(source_p, target_p, statchar);
+ }
+ else
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ name);
+
+ return;
+ }
+ }
+ else
+ {
+ name = me.name;
+ doall = 1;
+ }
+
+ stats_spy(source_p, statchar, name);
+
+ if(doall)
+ {
+ /* local opers get everyone */
+ if(MyOper(source_p))
+ {
+ stats_l_list(source_p, name, doall, wilds, &unknown_list, statchar);
+ stats_l_list(source_p, name, doall, wilds, &lclient_list, statchar);
+ }
+ else
+ {
+ /* they still need themselves if theyre local.. */
+ if(MyClient(source_p))
+ stats_l_client(source_p, source_p, statchar);
+
+ stats_l_list(source_p, name, doall, wilds, &local_oper_list, statchar);
+ }
+
+ if (!ConfigServerHide.flatten_links || IsOper(source_p) ||
+ IsExemptShide(source_p))
+ stats_l_list(source_p, name, doall, wilds, &serv_list, statchar);
+
+ return;
+ }
+
+ /* ok, at this point theyre looking for a specific client whos on
+ * our server.. but it contains a wildcard. --fl
+ */
+ stats_l_list(source_p, name, doall, wilds, &lclient_list, statchar);
+
+ return;
+}
+
+
+static void
+stats_l_list(struct Client *source_p, const char *name, int doall, int wilds,
+ dlink_list * list, char statchar)
+{
+ dlink_node *ptr;
+ struct Client *target_p;
+
+ /* send information about connections which match. note, we
+ * dont need tests for IsInvisible(), because non-opers will
+ * never get here for normal clients --fl
+ */
+ DLINK_FOREACH(ptr, list->head)
+ {
+ target_p = ptr->data;
+
+ if(!doall && wilds && !match(name, target_p->name))
+ continue;
+
+ stats_l_client(source_p, target_p, statchar);
+ }
+}
+
+void
+stats_l_client(struct Client *source_p, struct Client *target_p,
+ char statchar)
+{
+ if(IsAnyServer(target_p))
+ {
+ sendto_one_numeric(source_p, RPL_STATSLINKINFO, Lformat,
+ get_server_name(target_p, SHOW_IP),
+ (int) linebuf_len(&target_p->localClient->buf_sendq),
+ (int) target_p->localClient->sendM,
+ (int) target_p->localClient->sendK,
+ (int) target_p->localClient->receiveM,
+ (int) target_p->localClient->receiveK,
+ CurrentTime - target_p->localClient->firsttime,
+ (CurrentTime > target_p->localClient->lasttime) ?
+ (CurrentTime - target_p->localClient->lasttime) : 0,
+ IsOper(source_p) ? show_capabilities(target_p) : "-");
+ }
+
+ else
+ {
+ sendto_one_numeric(source_p, RPL_STATSLINKINFO, Lformat,
+ show_ip(source_p, target_p) ?
+ (IsUpper(statchar) ?
+ get_client_name(target_p, SHOW_IP) :
+ get_client_name(target_p, HIDE_IP)) :
+ get_client_name(target_p, MASK_IP),
+ (int) linebuf_len(&target_p->localClient->buf_sendq),
+ (int) target_p->localClient->sendM,
+ (int) target_p->localClient->sendK,
+ (int) target_p->localClient->receiveM,
+ (int) target_p->localClient->receiveK,
+ CurrentTime - target_p->localClient->firsttime,
+ (CurrentTime > target_p->localClient->lasttime) ?
+ (CurrentTime - target_p->localClient->lasttime) : 0,
+ "-");
+ }
+}
+
+/*
+ * stats_spy
+ *
+ * inputs - pointer to client doing the /stats
+ * - char letter they are doing /stats on
+ * output - none
+ * side effects -
+ * This little helper function reports to opers if configured.
+ * personally, I don't see why opers need to see stats requests
+ * at all. They are just "noise" to an oper, and users can't do
+ * any damage with stats requests now anyway. So, why show them?
+ * -Dianora
+ */
+static void
+stats_spy(struct Client *source_p, char statchar, const char *name)
+{
+ hook_data_int data;
+
+ data.client = source_p;
+ data.arg1 = name;
+ data.arg2 = (int) statchar;
+
+ call_hook(doing_stats_hook, &data);
+}
+
+/* stats_p_spy()
+ *
+ * input - pointer to client doing stats
+ * ouput -
+ * side effects - call hook doing_stats_p
+ */
+static void
+stats_p_spy (struct Client *source_p)
+{
+ hook_data data;
+
+ data.client = source_p;
+ data.arg1 = data.arg2 = NULL;
+
+ call_hook(doing_stats_p_hook, &data);
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_svinfo.c: Sends TS information for clock & compatibility checks.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_svinfo.c 494 2006-01-15 16:08:28Z jilles $
+ */
+#include "stdinc.h"
+#include "client.h"
+#include "common.h" /* TRUE bleah */
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int ms_svinfo(struct Client *, struct Client *, int, const char **);
+
+struct Message svinfo_msgtab = {
+ "SVINFO", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, {ms_svinfo, 5}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 svinfo_clist[] = { &svinfo_msgtab, NULL };
+DECLARE_MODULE_AV1(svinfo, NULL, NULL, svinfo_clist, NULL, NULL, "$Revision: 494 $");
+
+/*
+ * ms_svinfo - SVINFO message handler
+ * parv[0] = sender prefix
+ * parv[1] = TS_CURRENT for the server
+ * parv[2] = TS_MIN for the server
+ * parv[3] = unused, send 0
+ * parv[4] = server's idea of UTC time
+ */
+static int
+ms_svinfo(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ signed int deltat;
+ time_t theirtime;
+
+ /* SVINFO isnt remote. */
+ if(source_p != client_p)
+ return 0;
+
+ if(TS_CURRENT < atoi(parv[2]) || atoi(parv[1]) < TS_MIN)
+ {
+ /* TS version is too low on one of the sides, drop the link */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s dropped, wrong TS protocol version (%s,%s)",
+ get_server_name(source_p, SHOW_IP), parv[1], parv[2]);
+ exit_client(source_p, source_p, source_p, "Incompatible TS version");
+ return 0;
+ }
+
+ /*
+ * since we're here, might as well set CurrentTime while we're at it
+ */
+ set_time();
+ theirtime = atol(parv[4]);
+ deltat = abs(theirtime - CurrentTime);
+
+ if(deltat > ConfigFileEntry.ts_max_delta)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s dropped, excessive TS delta"
+ " (my TS=%ld, their TS=%ld, delta=%d)",
+ get_server_name(source_p, SHOW_IP),
+ (long) CurrentTime, (long) theirtime, deltat);
+ ilog(L_SERVER,
+ "Link %s dropped, excessive TS delta"
+ " (my TS=%ld, their TS=%ld, delta=%d)",
+ log_client_name(source_p, SHOW_IP), (long) CurrentTime, (long) theirtime, deltat);
+ exit_client(source_p, source_p, source_p, "Excessive TS delta");
+ return 0;
+ }
+
+ if(deltat > ConfigFileEntry.ts_warn_delta)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link %s notable TS delta"
+ " (my TS=%ld, their TS=%ld, delta=%d)",
+ source_p->name, (long) CurrentTime, (long) theirtime, deltat);
+ }
+
+ return 0;
+}
+
--- /dev/null
+/* modules/m_tb.c
+ *
+ * Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2003-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_tb.c 1349 2006-05-17 17:37:46Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "modules.h"
+#include "hash.h"
+#include "s_serv.h"
+
+static int ms_tb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message tb_msgtab = {
+ "TB", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, {ms_tb, 4}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 tb_clist[] = { &tb_msgtab, NULL };
+DECLARE_MODULE_AV1(tb, NULL, NULL, tb_clist, NULL, NULL, "$Revision: 1349 $");
+
+/* m_tb()
+ *
+ * parv[1] - channel
+ * parv[2] - topic ts
+ * parv[3] - optional topicwho/topic
+ * parv[4] - topic
+ */
+static int
+ms_tb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ const char *newtopic;
+ const char *newtopicwho;
+ time_t newtopicts;
+ struct Client *fakesource_p;
+
+ chptr = find_channel(parv[1]);
+
+ if(chptr == NULL)
+ return 0;
+
+ newtopicts = atol(parv[2]);
+
+ /* Hide connecting server on netburst -- jilles */
+ if (ConfigServerHide.flatten_links && !HasSentEob(source_p))
+ fakesource_p = &me;
+ else
+ fakesource_p = source_p;
+
+ if(parc == 5)
+ {
+ newtopic = parv[4];
+ newtopicwho = parv[3];
+ }
+ else
+ {
+ newtopic = parv[3];
+ newtopicwho = fakesource_p->name;
+ }
+
+ if (EmptyString(newtopic))
+ return 0;
+
+ if(chptr->topic == NULL || chptr->topic_time > newtopicts)
+ {
+ /* its possible the topicts is a few seconds out on some
+ * servers, due to lag when propagating it, so if theyre the
+ * same topic just drop the message --fl
+ */
+ if(chptr->topic != NULL && strcmp(chptr->topic, newtopic) == 0)
+ return 0;
+
+ set_channel_topic(chptr, newtopic, newtopicwho, newtopicts);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
+ fakesource_p->name, chptr->chname, newtopic);
+ sendto_server(client_p, chptr, CAP_TB|CAP_TS6, NOCAPS,
+ ":%s TB %s %ld %s%s:%s",
+ use_id(source_p), chptr->chname, (long) chptr->topic_time,
+ ConfigChannel.burst_topicwho ? chptr->topic_info : "",
+ ConfigChannel.burst_topicwho ? " " : "", chptr->topic);
+ sendto_server(client_p, chptr, CAP_TB, CAP_TS6,
+ ":%s TB %s %ld %s%s:%s",
+ source_p->name, chptr->chname, (long) chptr->topic_time,
+ ConfigChannel.burst_topicwho ? chptr->topic_info : "",
+ ConfigChannel.burst_topicwho ? " " : "", chptr->topic);
+ }
+
+ return 0;
+}
--- /dev/null
+/* modules/m_testline.c
+ *
+ * Copyright (C) 2004 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2004-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_testline.c 2757 2006-11-10 22:58:15Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "client.h"
+#include "modules.h"
+#include "msg.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "sprintf_irc.h"
+
+static int mo_testline(struct Client *, struct Client *, int, const char **);
+static int mo_testgecos(struct Client *, struct Client *, int, const char **);
+
+struct Message testline_msgtab = {
+ "TESTLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, mg_ignore, mg_ignore, {mo_testline, 2}}
+};
+struct Message testgecos_msgtab = {
+ "TESTGECOS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, mg_ignore, mg_ignore, mg_ignore, {mo_testgecos, 2}}
+};
+
+mapi_clist_av1 testline_clist[] = { &testline_msgtab, &testgecos_msgtab, NULL };
+DECLARE_MODULE_AV1(testline, NULL, NULL, testline_clist, NULL, NULL, "$Revision: 2757 $");
+
+static int
+mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct ConfItem *aconf;
+ struct ConfItem *resv_p;
+ struct irc_sockaddr_storage ip;
+ char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1];
+ const char *name = NULL;
+ const char *username = NULL;
+ const char *host = NULL;
+ char *mask;
+ char *p;
+ int host_mask;
+ int type;
+
+ mask = LOCAL_COPY(parv[1]);
+
+ if((p = strchr(mask, '!')))
+ {
+ *p++ = '\0';
+ name = mask;
+ mask = p;
+
+ if(EmptyString(mask))
+ return 0;
+ }
+
+ if((p = strchr(mask, '@')))
+ {
+ *p++ = '\0';
+ username = mask;
+ host = p;
+
+ if(EmptyString(host))
+ return 0;
+ }
+ else
+ host = mask;
+
+ /* parses as an IP, check for a dline */
+ if((type = parse_netmask(host, (struct sockaddr *)&ip, &host_mask)) != HM_HOST)
+ {
+#ifdef IPV6
+ if(type == HM_IPV6)
+ aconf = find_dline((struct sockaddr *)&ip, AF_INET6);
+ else
+#endif
+ aconf = find_dline((struct sockaddr *)&ip, AF_INET);
+
+ if(aconf && aconf->status & CONF_DLINE)
+ {
+ sendto_one(source_p, form_str(RPL_TESTLINE),
+ me.name, source_p->name,
+ (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
+ (aconf->flags & CONF_FLAGS_TEMPORARY) ?
+ (long) ((aconf->hold - CurrentTime) / 60) : 0L,
+ aconf->host, aconf->passwd);
+
+ return 0;
+ }
+ }
+
+ if (username != NULL)
+ {
+ strlcpy(user_trunc, username, sizeof user_trunc);
+ strlcpy(notildeuser_trunc, *username == '~' ? username + 1 : username, sizeof notildeuser_trunc);
+ }
+ else
+ {
+ strlcpy(user_trunc, "dummy", sizeof user_trunc);
+ strlcpy(notildeuser_trunc, "dummy", sizeof notildeuser_trunc);
+ }
+ /* now look for a matching I/K/G */
+ if((aconf = find_address_conf(host, NULL, user_trunc, notildeuser_trunc,
+ (type != HM_HOST) ? (struct sockaddr *)&ip : NULL,
+ (type != HM_HOST) ? (
+#ifdef IPV6
+ (type == HM_IPV6) ? AF_INET6 :
+#endif
+ AF_INET) : 0)))
+ {
+ static char buf[HOSTLEN+USERLEN+2];
+
+ if(aconf->status & CONF_KILL)
+ {
+ ircsnprintf(buf, sizeof(buf), "%s@%s",
+ aconf->user, aconf->host);
+ sendto_one(source_p, form_str(RPL_TESTLINE),
+ me.name, source_p->name,
+ (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
+ (aconf->flags & CONF_FLAGS_TEMPORARY) ?
+ (long) ((aconf->hold - CurrentTime) / 60) : 0L,
+ buf, aconf->passwd);
+ return 0;
+ }
+ else if(aconf->status & CONF_GLINE)
+ {
+ ircsnprintf(buf, sizeof(buf), "%s@%s",
+ aconf->user, aconf->host);
+ sendto_one(source_p, form_str(RPL_TESTLINE),
+ me.name, source_p->name,
+ 'G', (long) ((aconf->hold - CurrentTime) / 60),
+ buf, aconf->passwd);
+ return 0;
+ }
+ }
+
+ /* they asked us to check a nick, so hunt for resvs.. */
+ if(name && (resv_p = find_nick_resv(name)))
+ {
+ sendto_one(source_p, form_str(RPL_TESTLINE),
+ me.name, source_p->name,
+ resv_p->hold ? 'q' : 'Q',
+ resv_p->hold ? (long) ((resv_p->hold - CurrentTime) / 60) : 0L,
+ resv_p->name, resv_p->passwd);
+
+ /* this is a false positive, so make sure it isn't counted in stats q
+ * --nenolod
+ */
+ resv_p->port--;
+ return 0;
+ }
+
+ /* no matching resv, we can print the I: if it exists */
+ if(aconf && aconf->status & CONF_CLIENT)
+ {
+ sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
+ aconf->name, show_iline_prefix(source_p, aconf, aconf->user),
+ aconf->host, aconf->port, aconf->className);
+ return 0;
+ }
+
+ /* nothing matches.. */
+ sendto_one(source_p, form_str(RPL_NOTESTLINE),
+ me.name, source_p->name, parv[1]);
+ return 0;
+}
+
+static int
+mo_testgecos(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct ConfItem *aconf;
+
+ if(!(aconf = find_xline(parv[1], 0)))
+ {
+ sendto_one(source_p, form_str(RPL_NOTESTLINE),
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ sendto_one(source_p, form_str(RPL_TESTLINE),
+ me.name, source_p->name,
+ aconf->hold ? 'x' : 'X',
+ aconf->hold ? (long) ((aconf->hold - CurrentTime) / 60) : 0L,
+ aconf->name, aconf->passwd);
+ return 0;
+}
--- /dev/null
+/*
+ * m_testmask.c: Shows the number of matching local and global clients
+ * for a user@host mask, helpful when setting GLINE's
+ *
+ * Copyright (C) 2003 by W. Campbell
+ * Coypright (C) 2004 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_testmask.c 2775 2006-11-27 11:45:31Z jilles $
+ *
+ */
+
+/* List of ircd includes from ../include/ */
+#include "stdinc.h"
+#include "client.h"
+#include "common.h" /* FALSE bleah */
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int mo_testmask(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message testmask_msgtab = {
+ "TESTMASK", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_testmask, 2}}
+};
+
+mapi_clist_av1 testmask_clist[] = { &testmask_msgtab, NULL };
+DECLARE_MODULE_AV1(testmask, NULL, NULL, testmask_clist, NULL, NULL, "$Revision: 2775 $");
+
+static const char *empty_sockhost = "255.255.255.255";
+static const char *spoofed_sockhost = "0";
+
+static int
+mo_testmask(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[])
+{
+ struct Client *target_p;
+ int lcount = 0;
+ int gcount = 0;
+ char *name, *username, *hostname;
+ const char *sockhost;
+ char *gecos = NULL, *mangle_gecos = NULL;
+ dlink_node *ptr;
+
+ name = LOCAL_COPY(parv[1]);
+ collapse(name);
+
+ /* username is required */
+ if((hostname = strchr(name, '@')) == NULL)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ *hostname++ = '\0';
+
+ /* nickname is optional */
+ if((username = strchr(name, '!')) == NULL)
+ {
+ username = name;
+ name = NULL;
+ }
+ else
+ *username++ = '\0';
+
+ if(EmptyString(username) || EmptyString(hostname))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Invalid parameters",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ if(parc > 2 && !EmptyString(parv[2]))
+ {
+ gecos = LOCAL_COPY(parv[2]);
+ collapse_esc(gecos);
+ if(strstr(gecos, "\\s"))
+ {
+ char *tmp = LOCAL_COPY(gecos);
+ char *orig = tmp;
+ char *new = tmp;
+ while(*orig)
+ {
+ if(*orig == '\\' && *(orig + 1) != '\0')
+ {
+ if(*(orig + 1) == 's')
+ {
+ *new++ = ' ';
+ orig += 2;
+ }
+ /* otherwise skip that and the escaped
+ * character after it, so we dont mistake
+ * \\s as \s --fl
+ */
+ else
+ {
+ *new++ = *orig++;
+ *new++ = *orig++;
+ }
+ }
+ else
+ *new++ = *orig++;
+ }
+
+ *new = '\0';
+ mangle_gecos = LOCAL_COPY(tmp);
+ } else
+ mangle_gecos = gecos;
+ }
+
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!IsPerson(target_p))
+ continue;
+
+ if(EmptyString(target_p->sockhost))
+ sockhost = empty_sockhost;
+ else if(!show_ip(source_p, target_p))
+ sockhost = spoofed_sockhost;
+ else
+ sockhost = target_p->sockhost;
+
+ if(match(username, target_p->username) &&
+ (match(hostname, target_p->host) ||
+ match(hostname, target_p->orighost) ||
+ match(hostname, sockhost) || match_ips(hostname, sockhost)))
+ {
+ if(name && !match(name, target_p->name))
+ continue;
+
+ if(mangle_gecos && !match_esc(mangle_gecos, target_p->info))
+ continue;
+
+ if(MyClient(target_p))
+ lcount++;
+ else
+ gcount++;
+ }
+ }
+
+ sendto_one(source_p, form_str(RPL_TESTMASKGECOS),
+ me.name, source_p->name,
+ lcount, gcount, name ? name : "*",
+ username, hostname, gecos ? gecos : "*");
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_time.c: Sends the current time on the server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_time.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+#include "sprintf_irc.h"
+
+static int m_time(struct Client *, struct Client *, int, const char **);
+static char *date(void);
+
+struct Message time_msgtab = {
+ "TIME", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_time, 0}, {m_time, 2}, mg_ignore, mg_ignore, {m_time, 0}}
+};
+
+mapi_clist_av1 time_clist[] = { &time_msgtab, NULL };
+DECLARE_MODULE_AV1(time, NULL, NULL, time_clist, NULL, NULL, "$Revision: 254 $");
+
+static const char *months[] = {
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December"
+};
+
+static const char *weekdays[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday"
+};
+
+/*
+ * m_time
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+m_time(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* this is not rate limited, so end the grace period */
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ if(hunt_server(client_p, source_p, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME)
+ sendto_one_numeric(source_p, RPL_TIME, form_str(RPL_TIME),
+ me.name, date());
+
+ return 0;
+}
+
+/* date()
+ *
+ * returns date in human readable form
+ */
+static char *
+date(void)
+{
+ static char buf[80];
+ char plus;
+ struct tm *lt;
+ struct tm *gm;
+ struct tm gmbuf;
+ time_t lclock;
+ int minswest;
+
+ lclock = CurrentTime;
+ gm = gmtime(&lclock);
+ memcpy((void *) &gmbuf, (void *) gm, sizeof(gmbuf));
+ gm = &gmbuf;
+ lt = localtime(&lclock);
+
+ if(lt->tm_yday == gm->tm_yday)
+ minswest = (gm->tm_hour - lt->tm_hour) * 60 + (gm->tm_min - lt->tm_min);
+ else if(lt->tm_yday > gm->tm_yday && lt->tm_year == gm->tm_year)
+ minswest = (gm->tm_hour - (lt->tm_hour + 24)) * 60;
+ else
+ minswest = ((gm->tm_hour + 24) - lt->tm_hour) * 60;
+
+ plus = (minswest > 0) ? '-' : '+';
+
+ if(minswest < 0)
+ minswest = -minswest;
+
+ ircsprintf(buf, "%s %s %d %d -- %02u:%02u:%02u %c%02u:%02u",
+ weekdays[lt->tm_wday], months[lt->tm_mon], lt->tm_mday,
+ lt->tm_year + 1900, lt->tm_hour, lt->tm_min, lt->tm_sec,
+ plus, minswest / 60, minswest % 60);
+
+ return buf;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_topic.c: Sets a channel topic.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_topic.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static int m_topic(struct Client *, struct Client *, int, const char **);
+static int ms_topic(struct Client *, struct Client *, int, const char **);
+
+struct Message topic_msgtab = {
+ "TOPIC", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_topic, 2}, {m_topic, 2}, {ms_topic, 5}, mg_ignore, {m_topic, 2}}
+};
+
+mapi_clist_av1 topic_clist[] = { &topic_msgtab, NULL };
+DECLARE_MODULE_AV1(topic, NULL, NULL, topic_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_topic
+ * parv[0] = sender prefix
+ * parv[1] = channel name
+ * parv[2] = new topic, if setting topic
+ */
+static int
+m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr = NULL;
+ struct membership *msptr;
+ char *p = NULL;
+
+ if((p = strchr(parv[1], ',')))
+ *p = '\0';
+
+ if(MyClient(source_p) && !IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ if(!IsChannelName(parv[1]))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ chptr = find_channel(parv[1]);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ /* setting topic */
+ if(parc > 2)
+ {
+ msptr = find_channel_membership(chptr, source_p);
+
+ if(msptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL), parv[1]);
+ return 0;
+ }
+
+ if((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chanop(msptr))
+ {
+ char topic_info[USERHOST_REPLYLEN];
+ ircsprintf(topic_info, "%s!%s@%s",
+ source_p->name, source_p->username, source_p->host);
+ set_channel_topic(chptr, parv[2], topic_info, CurrentTime);
+
+ sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
+ ":%s TOPIC %s :%s",
+ use_id(source_p), chptr->chname,
+ chptr->topic == NULL ? "" : chptr->topic);
+ sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
+ ":%s TOPIC %s :%s",
+ source_p->name, chptr->chname,
+ chptr->topic == NULL ? "" : chptr->topic);
+ sendto_channel_local(ALL_MEMBERS,
+ chptr, ":%s!%s@%s TOPIC %s :%s",
+ source_p->name, source_p->username,
+ source_p->host, chptr->chname,
+ chptr->topic == NULL ? "" : chptr->topic);
+ }
+ else
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, parv[1]);
+ }
+ else if(MyClient(source_p))
+ {
+ if(!IsMember(source_p, chptr) && SecretChannel(chptr))
+ {
+ sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
+ form_str(ERR_NOTONCHANNEL), parv[1]);
+ return 0;
+ }
+ if(chptr->topic == NULL)
+ sendto_one(source_p, form_str(RPL_NOTOPIC),
+ me.name, source_p->name, parv[1]);
+ else
+ {
+ sendto_one(source_p, form_str(RPL_TOPIC),
+ me.name, source_p->name, chptr->chname, chptr->topic);
+
+ sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
+ me.name, source_p->name, chptr->chname,
+ chptr->topic_info, chptr->topic_time);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * ms_topic
+ * parv[0] = sender prefix
+ * parv[1] = channel name
+ * parv[2] = topic_info
+ * parv[3] = topic_info time
+ * parv[4] = new channel topic
+ *
+ * Let servers always set a topic
+ */
+static int
+ms_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr = NULL;
+
+ if(IsChannelName(parv[1]))
+ {
+ if((chptr = find_channel(parv[1])) == NULL)
+ return 0;
+
+ set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
+ source_p->name, parv[1],
+ chptr->topic == NULL ? "" : chptr->topic);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_trace.c: Traces a path to a client/server.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_trace.c 609 2006-01-28 21:44:33Z jilles $
+ */
+
+#include "stdinc.h"
+#include "class.h"
+#include "hook.h"
+#include "client.h"
+#include "hash.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int m_trace(struct Client *, struct Client *, int, const char **);
+
+static void trace_spy(struct Client *, struct Client *);
+
+struct Message trace_msgtab = {
+ "TRACE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_trace, 0}, {m_trace, 0}, mg_ignore, mg_ignore, {m_trace, 0}}
+};
+
+int doing_trace_hook;
+
+mapi_clist_av1 trace_clist[] = { &trace_msgtab, NULL };
+mapi_hlist_av1 trace_hlist[] = {
+ { "doing_trace", &doing_trace_hook },
+ { NULL, NULL }
+};
+DECLARE_MODULE_AV1(trace, NULL, NULL, trace_clist, trace_hlist, NULL, "$Revision: 609 $");
+
+static void count_downlinks(struct Client *server_p, int *pservcount, int *pusercount);
+static int report_this_status(struct Client *source_p, struct Client *target_p, int dow);
+
+/*
+ * m_trace
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+m_trace(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p = NULL;
+ struct Class *cltmp;
+ const char *tname;
+ int doall = 0;
+ int cnt = 0, wilds, dow;
+ dlink_node *ptr;
+
+ if(parc > 1)
+ {
+ tname = parv[1];
+
+ if(parc > 2)
+ {
+ if(hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv) !=
+ HUNTED_ISME)
+ return 0;
+ }
+ }
+ else
+ tname = me.name;
+
+ /* if we have 3 parameters, then the command is directed at us. So
+ * we shouldnt be forwarding it anywhere.
+ */
+ if(parc < 3)
+ {
+ switch (hunt_server(client_p, source_p, ":%s TRACE :%s", 1, parc, parv))
+ {
+ case HUNTED_PASS: /* note: gets here only if parv[1] exists */
+ {
+ struct Client *ac2ptr;
+
+ if(MyClient(source_p))
+ ac2ptr = find_named_client(tname);
+ else
+ ac2ptr = find_client(tname);
+
+ if(ac2ptr == NULL)
+ {
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ ac2ptr = ptr->data;
+
+ if(match(tname, ac2ptr->name) || match(ac2ptr->name, tname))
+ break;
+ else
+ ac2ptr = NULL;
+ }
+ }
+
+ /* giving this out with flattened links defeats the
+ * object --fl
+ */
+ if(IsOper(source_p) || IsExemptShide(source_p) ||
+ !ConfigServerHide.flatten_links)
+ sendto_one_numeric(source_p, RPL_TRACELINK,
+ form_str(RPL_TRACELINK),
+ ircd_version,
+ ac2ptr ? ac2ptr->name : tname,
+ ac2ptr ? ac2ptr->from->name : "EEK!");
+
+ return 0;
+ }
+
+ case HUNTED_ISME:
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ if(match(tname, me.name))
+ {
+ doall = 1;
+ }
+ /* if theyre tracing our SID, we need to move tname to our name so
+ * we dont give the sid in ENDOFTRACE
+ */
+ else if(!MyClient(source_p) && !strcmp(tname, me.id))
+ {
+ doall = 1;
+ tname = me.name;
+ }
+
+ wilds = strchr(tname, '*') || strchr(tname, '?');
+ dow = wilds || doall;
+
+ /* specific trace */
+ if(dow == 0)
+ {
+ if(MyClient(source_p) || parc > 2)
+ target_p = find_named_person(tname);
+ else
+ target_p = find_person(tname);
+
+ /* tname could be pointing to an ID at this point, so reset
+ * it to target_p->name if we have a target --fl
+ */
+ if(target_p != NULL)
+ {
+ report_this_status(source_p, target_p, 0);
+ tname = target_p->name;
+ }
+
+ trace_spy(source_p, target_p);
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE,
+ form_str(RPL_ENDOFTRACE), tname);
+ return 0;
+ }
+
+ trace_spy(source_p, NULL);
+
+ /* give non-opers a limited trace output of themselves (if local),
+ * opers and servers (if no shide) --fl
+ */
+ if(!IsOper(source_p))
+ {
+ if(MyClient(source_p))
+ {
+ if(doall || (wilds && match(tname, source_p->name)))
+ report_this_status(source_p, source_p, 0);
+ }
+
+ DLINK_FOREACH(ptr, local_oper_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!doall && wilds && (match(tname, target_p->name) == 0))
+ continue;
+
+ report_this_status(source_p, target_p, 0);
+ }
+
+ if (IsExemptShide(source_p) || !ConfigServerHide.flatten_links)
+ {
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!doall && wilds && !match(tname, target_p->name))
+ continue;
+
+ report_this_status(source_p, target_p, 0);
+ }
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE,
+ form_str(RPL_ENDOFTRACE), tname);
+ return 0;
+ }
+
+ /* source_p is opered */
+
+ /* report all direct connections */
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ /* dont show invisible users to remote opers */
+ if(IsInvisible(target_p) && dow && !MyConnect(source_p) && !IsOper(target_p))
+ continue;
+
+ if(!doall && wilds && !match(tname, target_p->name))
+ continue;
+
+ cnt = report_this_status(source_p, target_p, dow);
+ }
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!doall && wilds && !match(tname, target_p->name))
+ continue;
+
+ cnt = report_this_status(source_p, target_p, dow);
+ }
+
+ if(MyConnect(source_p))
+ {
+ DLINK_FOREACH(ptr, unknown_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!doall && wilds && !match(tname, target_p->name))
+ continue;
+
+ cnt = report_this_status(source_p, target_p, dow);
+ }
+ }
+
+ if(!cnt)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER, form_str(ERR_NOSUCHSERVER),
+ tname);
+
+ /* let the user have some idea that its at the end of the
+ * trace
+ */
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE,
+ form_str(RPL_ENDOFTRACE), tname);
+ return 0;
+ }
+
+ if(doall)
+ {
+ DLINK_FOREACH(ptr, class_list.head)
+ {
+ cltmp = ptr->data;
+
+ if(CurrUsers(cltmp) > 0)
+ sendto_one_numeric(source_p, RPL_TRACECLASS,
+ form_str(RPL_TRACECLASS),
+ ClassName(cltmp), CurrUsers(cltmp));
+ }
+ }
+
+ sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), tname);
+
+ return 0;
+}
+
+/*
+ * count_downlinks
+ *
+ * inputs - pointer to server to count
+ * - pointers to server and user count
+ * output - NONE
+ * side effects - server and user counts are added to given values
+ */
+static void
+count_downlinks(struct Client *server_p, int *pservcount, int *pusercount)
+{
+ dlink_node *ptr;
+
+ (*pservcount)++;
+ *pusercount += dlink_list_length(&server_p->serv->users);
+ DLINK_FOREACH(ptr, server_p->serv->servers.head)
+ {
+ count_downlinks(ptr->data, pservcount, pusercount);
+ }
+}
+
+/*
+ * report_this_status
+ *
+ * inputs - pointer to client to report to
+ * - pointer to client to report about
+ * output - counter of number of hits
+ * side effects - NONE
+ */
+static int
+report_this_status(struct Client *source_p, struct Client *target_p,
+ int dow)
+{
+ const char *name;
+ const char *class_name;
+ char ip[HOSTIPLEN];
+ int cnt = 0;
+
+ /* sanity check - should never happen */
+ if(!MyConnect(target_p))
+ return 0;
+
+ inetntop_sock((struct sockaddr *)&target_p->localClient->ip, ip, sizeof(ip));
+ class_name = get_client_class(target_p);
+
+ if(IsAnyServer(target_p))
+ name = get_server_name(target_p, HIDE_IP);
+ else
+ name = get_client_name(target_p, HIDE_IP);
+
+ switch (target_p->status)
+ {
+ case STAT_CONNECTING:
+ sendto_one_numeric(source_p, RPL_TRACECONNECTING,
+ form_str(RPL_TRACECONNECTING),
+ class_name, name);
+ cnt++;
+ break;
+
+ case STAT_HANDSHAKE:
+ sendto_one_numeric(source_p, RPL_TRACEHANDSHAKE,
+ form_str(RPL_TRACEHANDSHAKE),
+ class_name, name);
+ cnt++;
+ break;
+
+ case STAT_ME:
+ break;
+
+ case STAT_UNKNOWN:
+ /* added time -Taner */
+ sendto_one_numeric(source_p, RPL_TRACEUNKNOWN,
+ form_str(RPL_TRACEUNKNOWN),
+ class_name, name, ip,
+ CurrentTime - target_p->localClient->firsttime);
+ cnt++;
+ break;
+
+ case STAT_CLIENT:
+ /* Only opers see users if there is a wildcard
+ * but anyone can see all the opers.
+ */
+ if((IsOper(source_p) &&
+ (MyClient(source_p) || !(dow && IsInvisible(target_p))))
+ || !dow || IsOper(target_p) || (source_p == target_p))
+ {
+ if(IsOper(target_p))
+ sendto_one_numeric(source_p, RPL_TRACEOPERATOR,
+ form_str(RPL_TRACEOPERATOR),
+ class_name, name,
+ show_ip(source_p, target_p) ? ip : "255.255.255.255",
+ CurrentTime - target_p->localClient->lasttime,
+ CurrentTime - target_p->localClient->last);
+
+ else
+ sendto_one_numeric(source_p, RPL_TRACEUSER,
+ form_str(RPL_TRACEUSER),
+ class_name, name,
+ show_ip(source_p, target_p) ? ip : "255.255.255.255",
+ CurrentTime - target_p->localClient->lasttime,
+ CurrentTime - target_p->localClient->last);
+ cnt++;
+ }
+ break;
+
+ case STAT_SERVER:
+ {
+ int usercount = 0;
+ int servcount = 0;
+
+ count_downlinks(target_p, &servcount, &usercount);
+
+ sendto_one_numeric(source_p, RPL_TRACESERVER, form_str(RPL_TRACESERVER),
+ class_name, servcount, usercount, name,
+ *(target_p->serv->by) ? target_p->serv->by : "*", "*",
+ me.name, CurrentTime - target_p->localClient->lasttime);
+ cnt++;
+
+ }
+ break;
+
+ default: /* ...we actually shouldn't come here... --msa */
+ sendto_one_numeric(source_p, RPL_TRACENEWTYPE,
+ form_str(RPL_TRACENEWTYPE),
+ me.name, source_p->name, name);
+ cnt++;
+ break;
+ }
+
+ return (cnt);
+}
+
+/* trace_spy()
+ *
+ * input - pointer to client
+ * output - none
+ * side effects - hook event doing_trace is called
+ */
+static void
+trace_spy(struct Client *source_p, struct Client *target_p)
+{
+ hook_data_client hdata;
+
+ hdata.client = source_p;
+ hdata.target = target_p;
+
+ call_hook(doing_trace_hook, &hdata);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_unreject.c: Removes an ip from the reject cache
+ *
+ * Copyright (C) 2004 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2004-2005 ircd-ratbox 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
+ *
+ * $Id: m_unreject.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "s_conf.h"
+#include "hostmask.h"
+#include "reject.h"
+#include "msg.h"
+#include "modules.h"
+#include "send.h"
+
+static int mo_unreject(struct Client *, struct Client *, int, const char **);
+
+struct Message unreject_msgtab = {
+ "UNREJECT", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_unreject, 2}}
+};
+
+mapi_clist_av1 unreject_clist[] = { &unreject_msgtab, NULL };
+DECLARE_MODULE_AV1(unreject, NULL, NULL, unreject_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * mo_unreject
+ *
+ */
+static int
+mo_unreject(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
+ ConfigFileEntry.reject_duration == 0)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Reject cache is disabled",
+ me.name, source_p->name);
+ return 0;
+ }
+
+ if(!parse_netmask(parv[1], NULL, NULL))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Unable to parse netmask %s",
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ if(remove_reject(parv[1]))
+ sendto_one(source_p, ":%s NOTICE %s :Removed reject for %s",
+ me.name, source_p->name, parv[1]);
+ else
+ sendto_one(source_p, ":%s NOTICE %s :Unable to remove reject for %s",
+ me.name, source_p->name, parv[1]);
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_user.c: Sends username information.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_user.c 1459 2006-05-26 20:50:41Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "sprintf_irc.h"
+#include "blacklist.h"
+
+#define UFLAGS (FLAGS_INVISIBLE|FLAGS_WALLOP|FLAGS_SERVNOTICE)
+
+static int mr_user(struct Client *, struct Client *, int, const char **);
+
+struct Message user_msgtab = {
+ "USER", 0, 0, 0, MFLG_SLOW,
+ {{mr_user, 5}, mg_reg, mg_ignore, mg_ignore, mg_ignore, mg_reg}
+};
+
+mapi_clist_av1 user_clist[] = { &user_msgtab, NULL };
+DECLARE_MODULE_AV1(user, NULL, NULL, user_clist, NULL, NULL, "$Revision: 1459 $");
+
+static int do_local_user(struct Client *client_p, struct Client *source_p,
+ const char *username, const char *realname);
+
+/* mr_user()
+ * parv[1] = username (login name, account)
+ * parv[2] = client host name (ignored)
+ * parv[3] = server host name (ignored)
+ * parv[4] = users gecos
+ */
+static int
+mr_user(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static char buf[BUFSIZE];
+ char *p;
+
+ if (strlen(client_p->id) == 3)
+ {
+ exit_client(client_p, client_p, client_p, "Mixing client and server protocol");
+ return 0;
+ }
+
+ if((p = strchr(parv[1], '@')))
+ *p = '\0';
+
+ ircsnprintf(buf, sizeof(buf), "%s %s", parv[2], parv[3]);
+ MyFree(source_p->localClient->fullcaps);
+ DupString(source_p->localClient->fullcaps, buf);
+
+ do_local_user(client_p, source_p, parv[1], parv[4]);
+ return 0;
+}
+
+static int
+do_local_user(struct Client *client_p, struct Client *source_p,
+ const char *username, const char *realname)
+{
+ struct User *user;
+
+ s_assert(NULL != source_p);
+ s_assert(source_p->username != username);
+
+ user = make_user(source_p);
+ user->server = me.name;
+
+ if (!(source_p->flags & FLAGS_SENTUSER))
+ {
+ lookup_blacklists(source_p);
+ source_p->flags |= FLAGS_SENTUSER;
+ }
+
+ strlcpy(source_p->info, realname, sizeof(source_p->info));
+
+ if(!IsGotId(source_p))
+ {
+ /* This is in this location for a reason..If there is no identd
+ * and ping cookies are enabled..we need to have a copy of this
+ */
+ strlcpy(source_p->username, username, sizeof(source_p->username));
+ }
+
+ if(source_p->name[0])
+ {
+ /* NICK already received, now I have USER... */
+ return register_local_user(client_p, source_p, username);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_userhost.c: Shows a user's host.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_userhost.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+
+static char buf[BUFSIZE];
+
+static int m_userhost(struct Client *, struct Client *, int, const char **);
+
+struct Message userhost_msgtab = {
+ "USERHOST", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_userhost, 2}, mg_ignore, mg_ignore, mg_ignore, {m_userhost, 2}}
+};
+
+mapi_clist_av1 userhost_clist[] = { &userhost_msgtab, NULL };
+DECLARE_MODULE_AV1(userhost, NULL, NULL, userhost_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_userhost added by Darren Reed 13/8/91 to aid clients and reduce
+ * the need for complicated requests like WHOIS. It returns user/host
+ * information only (no spurious AWAY labels or channels).
+ */
+static int
+m_userhost(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ char response[NICKLEN * 2 + USERLEN + HOSTLEN + 30];
+ char *t;
+ int i; /* loop counter */
+ int cur_len;
+ int rl;
+
+ cur_len = ircsprintf(buf, form_str(RPL_USERHOST), me.name, parv[0], "");
+ t = buf + cur_len;
+
+ for (i = 1; i <= 5; i++)
+ {
+ if(parc < i + 1)
+ break;
+
+ if((target_p = find_person(parv[i])) != NULL)
+ {
+ /*
+ * Show real IP for USERHOST on yourself.
+ * This is needed for things like mIRC, which do a server-based
+ * lookup (USERHOST) to figure out what the clients' local IP
+ * is. Useful for things like NAT, and dynamic dial-up users.
+ */
+ if(MyClient(target_p) && (target_p == source_p))
+ {
+ rl = ircsprintf(response, "%s%s=%c%s@%s ",
+ target_p->name,
+ IsOper(target_p) ? "*" : "",
+ (target_p->user->away) ? '-' : '+',
+ target_p->username,
+ target_p->sockhost);
+ }
+ else
+ {
+ rl = ircsprintf(response, "%s%s=%c%s@%s ",
+ target_p->name,
+ IsOper(target_p) ? "*" : "",
+ (target_p->user->away) ? '-' : '+',
+ target_p->username, target_p->host);
+ }
+
+ if((rl + cur_len) < (BUFSIZE - 10))
+ {
+ ircsprintf(t, "%s", response);
+ t += rl;
+ cur_len += rl;
+ }
+ else
+ break;
+ }
+ }
+
+ sendto_one(source_p, "%s", buf);
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_users.c: Gives some basic user statistics.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_users.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int m_users(struct Client *, struct Client *, int, const char **);
+
+struct Message users_msgtab = {
+ "USERS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_users, 0}, {m_users, 0}, mg_ignore, mg_ignore, {m_users, 0}}
+};
+
+mapi_clist_av1 users_clist[] = { &users_msgtab, NULL };
+DECLARE_MODULE_AV1(users, NULL, NULL, users_clist, NULL, NULL, "$Revision: 254 $");
+
+/*
+ * m_users
+ * parv[0] = sender prefix
+ * parv[1] = servername
+ */
+static int
+m_users(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(hunt_server(client_p, source_p, ":%s USERS :%s", 1, parc, parv) == HUNTED_ISME)
+ {
+ sendto_one_numeric(source_p, RPL_LOCALUSERS,
+ form_str(RPL_LOCALUSERS),
+ dlink_list_length(&lclient_list),
+ Count.max_loc,
+ dlink_list_length(&lclient_list),
+ Count.max_loc);
+
+ sendto_one_numeric(source_p, RPL_GLOBALUSERS,
+ form_str(RPL_GLOBALUSERS),
+ Count.total, Count.max_tot,
+ Count.total, Count.max_tot);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_version.c: Shows ircd version information.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_version.c 1887 2006-08-29 13:42:56Z jilles $
+ */
+
+#include <stdinc.h>
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "supported.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static char *confopts(struct Client *source_p);
+
+static int m_version(struct Client *, struct Client *, int, const char **);
+static int mo_version(struct Client *, struct Client *, int, const char **);
+
+struct Message version_msgtab = {
+ "VERSION", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_version, 0}, {mo_version, 0}, {mo_version, 0}, mg_ignore, {mo_version, 0}}
+};
+
+mapi_clist_av1 version_clist[] = { &version_msgtab, NULL };
+DECLARE_MODULE_AV1(version, NULL, NULL, version_clist, NULL, NULL, "$Revision: 1887 $");
+
+/*
+ * m_version - VERSION command handler
+ * parv[0] = sender prefix
+ * parv[1] = remote server
+ */
+static int
+m_version(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0L;
+
+ if(parc > 1)
+ {
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ /* safe enough to give this on a local connect only */
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "VERSION");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+
+ if(hunt_server(client_p, source_p, ":%s VERSION :%s", 1, parc, parv) != HUNTED_ISME)
+ return 0;
+ }
+
+ sendto_one_numeric(source_p, RPL_VERSION, form_str(RPL_VERSION),
+ ircd_version, serno,
+ me.name, confopts(source_p), TS_CURRENT,
+ ServerInfo.sid);
+
+ show_isupport(source_p);
+
+ return 0;
+}
+
+/*
+ * mo_version - VERSION command handler
+ * parv[0] = sender prefix
+ * parv[1] = remote server
+ */
+static int
+mo_version(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(hunt_server(client_p, source_p, ":%s VERSION :%s", 1, parc, parv) == HUNTED_ISME)
+ {
+ sendto_one_numeric(source_p, RPL_VERSION, form_str(RPL_VERSION),
+ ircd_version, serno,
+ me.name, confopts(source_p), TS_CURRENT,
+ ServerInfo.sid);
+ show_isupport(source_p);
+ }
+
+ return 0;
+}
+
+/* confopts()
+ * input - client pointer
+ * output - ircd.conf option string
+ * side effects - none
+ */
+static char *
+confopts(struct Client *source_p)
+{
+ static char result[15];
+ char *p;
+
+ result[0] = '\0';
+ p = result;
+
+ if(ConfigChannel.use_except)
+ *p++ = 'e';
+
+ if(ConfigFileEntry.glines)
+ *p++ = 'g';
+ *p++ = 'G';
+
+ /* might wanna hide this :P */
+ if(ServerInfo.hub)
+ *p++ = 'H';
+
+ if(ConfigChannel.use_invex)
+ *p++ = 'I';
+
+ if(ConfigChannel.use_knock)
+ *p++ = 'K';
+
+ *p++ = 'M';
+ *p++ = 'p';
+
+ if(opers_see_all_users || ConfigFileEntry.operspy_dont_care_user_info)
+ *p++ = 'S';
+#ifdef IGNORE_BOGUS_TS
+ *p++ = 'T';
+#endif
+
+#ifdef HAVE_LIBZ
+ *p++ = 'Z';
+#endif
+
+#ifdef IPV6
+ *p++ = '6';
+#endif
+
+ *p = '\0';
+
+ return result;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_wallops.c: Sends a message to all operators.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_wallops.c 1377 2006-05-20 13:48:37Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+
+static int mo_operwall(struct Client *, struct Client *, int, const char **);
+static int ms_operwall(struct Client *, struct Client *, int, const char **);
+static int ms_wallops(struct Client *, struct Client *, int, const char **);
+
+struct Message wallops_msgtab = {
+ "WALLOPS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_wallops, 2}, {ms_wallops, 2}, mg_ignore, {ms_wallops, 2}}
+};
+struct Message operwall_msgtab = {
+ "OPERWALL", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_operwall, 2}, mg_ignore, mg_ignore, {mo_operwall, 2}}
+};
+
+mapi_clist_av1 wallops_clist[] = { &wallops_msgtab, &operwall_msgtab, NULL };
+DECLARE_MODULE_AV1(wallops, NULL, NULL, wallops_clist, NULL, NULL, "$Revision: 1377 $");
+
+/*
+ * mo_operwall (write to *all* opers currently online)
+ * parv[1] = message text
+ */
+static int
+mo_operwall(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(!IsOperOperwall(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "operwall");
+ return 0;
+ }
+
+ sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", parv[1]);
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s OPERWALL :%s",
+ use_id(source_p), parv[1]);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s OPERWALL :%s",
+ source_p->name, parv[1]);
+
+ return 0;
+}
+
+/*
+ * ms_operwall - OPERWALL message handler
+ * (write to *all* local opers currently online)
+ * parv[0] = sender prefix
+ * parv[1] = message text
+ */
+static int
+ms_operwall(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s OPERWALL :%s",
+ use_id(source_p), parv[1]);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s OPERWALL :%s",
+ source_p->name, parv[1]);
+ sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", parv[1]);
+
+ return 0;
+}
+
+/*
+ * ms_wallops (write to *all* opers currently online)
+ * parv[1] = message text
+ */
+static int
+ms_wallops(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ const char *prefix = "";
+
+ if (IsPerson(source_p))
+ {
+ if (!strncmp(parv[1], "OPERWALL - ", 11) ||
+ !strncmp(parv[1], "LOCOPS - ", 9) ||
+ !strncmp(parv[1], "SLOCOPS - ", 10))
+ prefix = "WALLOPS - ";
+ }
+
+ sendto_wallops_flags(UMODE_WALLOP, source_p, "%s%s", prefix, parv[1]);
+
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s WALLOPS :%s",
+ use_id(source_p), parv[1]);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s WALLOPS :%s",
+ source_p->name, parv[1]);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_who.c: Shows who is on a channel.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_who.c 1853 2006-08-24 18:30:52Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "common.h"
+#include "client.h"
+#include "channel.h"
+#include "hash.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+#include "s_newconf.h"
+
+static int m_who(struct Client *, struct Client *, int, const char **);
+
+struct Message who_msgtab = {
+ "WHO", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_who, 2}, mg_ignore, mg_ignore, mg_ignore, {m_who, 2}}
+};
+
+mapi_clist_av1 who_clist[] = { &who_msgtab, NULL };
+DECLARE_MODULE_AV1(who, NULL, NULL, who_clist, NULL, NULL, "$Revision: 1853 $");
+
+static void do_who_on_channel(struct Client *source_p, struct Channel *chptr,
+ int server_oper, int member);
+
+static void who_global(struct Client *source_p, const char *mask, int server_oper, int operspy);
+
+static void do_who(struct Client *source_p,
+ struct Client *target_p, const char *chname, const char *op_flags);
+
+
+/*
+** m_who
+** parv[0] = sender prefix
+** parv[1] = nickname mask list
+** parv[2] = additional selection flag, only 'o' for now.
+*/
+static int
+m_who(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+ struct Client *target_p;
+ struct membership *msptr;
+ char *mask;
+ dlink_node *lp;
+ struct Channel *chptr = NULL;
+ int server_oper = parc > 2 ? (*parv[2] == 'o') : 0; /* Show OPERS only */
+ int member;
+ int operspy = 0;
+
+ mask = LOCAL_COPY(parv[1]);
+
+ collapse(mask);
+
+ /* '/who *' */
+ if((*(mask + 1) == '\0') && (*mask == '*'))
+ {
+ if(source_p->user == NULL)
+ return 0;
+
+ if((lp = source_p->user->channel.head) != NULL)
+ {
+ msptr = lp->data;
+ do_who_on_channel(source_p, msptr->chptr, server_oper, YES);
+ }
+
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, "*");
+ return 0;
+ }
+
+ if(IsOperSpy(source_p) && *mask == '!')
+ {
+ mask++;
+ operspy = 1;
+
+ if(EmptyString(mask))
+ {
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+ }
+
+ /* '/who #some_channel' */
+ if(IsChannelName(mask))
+ {
+ /* List all users on a given channel */
+ chptr = find_channel(mask);
+ if(chptr != NULL)
+ {
+ if(operspy)
+ report_operspy(source_p, "WHO", chptr->chname);
+
+ if(IsMember(source_p, chptr) || operspy)
+ do_who_on_channel(source_p, chptr, server_oper, YES);
+ else if(!SecretChannel(chptr))
+ do_who_on_channel(source_p, chptr, server_oper, NO);
+ }
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, mask);
+ return 0;
+ }
+
+ /* '/who nick' */
+
+ if(((target_p = find_named_person(mask)) != NULL) &&
+ (!server_oper || IsOper(target_p)))
+ {
+ int isinvis = 0;
+
+ isinvis = IsInvisible(target_p);
+ DLINK_FOREACH(lp, target_p->user->channel.head)
+ {
+ msptr = lp->data;
+ chptr = msptr->chptr;
+
+ member = IsMember(source_p, chptr);
+
+ if(isinvis && !member)
+ continue;
+
+ if(member || (!isinvis && PubChannel(chptr)))
+ break;
+ }
+
+ /* if we stopped midlist, lp->data is the membership for
+ * target_p of chptr
+ */
+ if(lp != NULL)
+ do_who(source_p, target_p, chptr->chname,
+ find_channel_status(lp->data, IsCapable(source_p, CLICAP_MULTI_PREFIX)));
+ else
+ do_who(source_p, target_p, NULL, "");
+
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, mask);
+ return 0;
+ }
+
+ if(!IsFloodDone(source_p))
+ flood_endgrace(source_p);
+
+ /* it has to be a global who at this point, limit it */
+ if(!IsOper(source_p))
+ {
+ if((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "WHO");
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, "*");
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ /* Note: operspy_dont_care_user_info does not apply to
+ * who on channels */
+ if(IsOperSpy(source_p) && ConfigFileEntry.operspy_dont_care_user_info)
+ operspy = 1;
+
+ /* '/who 0' for a global list. this forces clients to actually
+ * request a full list. I presume its because of too many typos
+ * with "/who" ;) --fl
+ */
+ if((*(mask + 1) == '\0') && (*mask == '0'))
+ who_global(source_p, NULL, server_oper, 0);
+ else
+ who_global(source_p, mask, server_oper, operspy);
+
+ sendto_one(source_p, form_str(RPL_ENDOFWHO),
+ me.name, source_p->name, mask);
+
+ return 0;
+}
+
+/* who_common_channel
+ * inputs - pointer to client requesting who
+ * - pointer to channel member chain.
+ * - char * mask to match
+ * - int if oper on a server or not
+ * - pointer to int maxmatches
+ * output - NONE
+ * side effects - lists matching invisible clients on specified channel,
+ * marks matched clients.
+ */
+static void
+who_common_channel(struct Client *source_p, struct Channel *chptr,
+ const char *mask, int server_oper, int *maxmatches)
+{
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(!IsInvisible(target_p) || IsMarked(target_p))
+ continue;
+
+ if(server_oper && !IsOper(target_p))
+ continue;
+
+ SetMark(target_p);
+
+ if(*maxmatches > 0)
+ {
+ if((mask == NULL) ||
+ match(mask, target_p->name) || match(mask, target_p->username) ||
+ match(mask, target_p->host) || match(mask, target_p->user->server) ||
+ (IsOper(source_p) && match(mask, target_p->orighost)) ||
+ match(mask, target_p->info))
+ {
+ do_who(source_p, target_p, NULL, "");
+ --(*maxmatches);
+ }
+ }
+ }
+}
+
+/*
+ * who_global
+ *
+ * inputs - pointer to client requesting who
+ * - char * mask to match
+ * - int if oper on a server or not
+ * output - NONE
+ * side effects - do a global scan of all clients looking for match
+ * this is slightly expensive on EFnet ...
+ * marks assumed cleared for all clients initially
+ * and will be left cleared on return
+ */
+static void
+who_global(struct Client *source_p, const char *mask, int server_oper, int operspy)
+{
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *lp, *ptr;
+ int maxmatches = 500;
+
+ /* first, list all matching INvisible clients on common channels
+ * if this is not an operspy who
+ */
+ if(!operspy)
+ {
+ DLINK_FOREACH(lp, source_p->user->channel.head)
+ {
+ msptr = lp->data;
+ who_common_channel(source_p, msptr->chptr, mask, server_oper, &maxmatches);
+ }
+ }
+ else if (!ConfigFileEntry.operspy_dont_care_user_info)
+ report_operspy(source_p, "WHO", mask);
+
+ /* second, list all matching visible clients and clear all marks
+ * on invisible clients
+ * if this is an operspy who, list all matching clients, no need
+ * to clear marks
+ */
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+ if(!IsPerson(target_p))
+ continue;
+
+ if(IsInvisible(target_p) && !operspy)
+ {
+ ClearMark(target_p);
+ continue;
+ }
+
+ if(server_oper && !IsOper(target_p))
+ continue;
+
+ if(maxmatches > 0)
+ {
+ if(!mask ||
+ match(mask, target_p->name) || match(mask, target_p->username) ||
+ match(mask, target_p->host) || match(mask, target_p->user->server) ||
+ (IsOper(source_p) && match(mask, target_p->orighost)) ||
+ match(mask, target_p->info))
+ {
+ do_who(source_p, target_p, NULL, "");
+ --maxmatches;
+ }
+ }
+ }
+
+ if (maxmatches <= 0)
+ sendto_one(source_p,
+ form_str(ERR_TOOMANYMATCHES),
+ me.name, source_p->name, "WHO");
+}
+
+/*
+ * do_who_on_channel
+ *
+ * inputs - pointer to client requesting who
+ * - pointer to channel to do who on
+ * - The "real name" of this channel
+ * - int if source_p is a server oper or not
+ * - int if client is member or not
+ * output - NONE
+ * side effects - do a who on given channel
+ */
+static void
+do_who_on_channel(struct Client *source_p, struct Channel *chptr,
+ int server_oper, int member)
+{
+ struct Client *target_p;
+ struct membership *msptr;
+ dlink_node *ptr;
+ int combine = IsCapable(source_p, CLICAP_MULTI_PREFIX);
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(server_oper && !IsOper(target_p))
+ continue;
+
+ if(member || !IsInvisible(target_p))
+ do_who(source_p, target_p, chptr->chname,
+ find_channel_status(msptr, combine));
+ }
+}
+
+/*
+ * do_who
+ *
+ * inputs - pointer to client requesting who
+ * - pointer to client to do who on
+ * - The reported name
+ * - channel flags
+ * output - NONE
+ * side effects - do a who on given person
+ */
+
+static void
+do_who(struct Client *source_p, struct Client *target_p, const char *chname, const char *op_flags)
+{
+ char status[5];
+
+ ircsprintf(status, "%c%s%s",
+ target_p->user->away ? 'G' : 'H', IsOper(target_p) ? "*" : "", op_flags);
+
+ sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name,
+ (chname) ? (chname) : "*",
+ target_p->username,
+ target_p->host, target_p->user->server, target_p->name,
+ status,
+ ConfigServerHide.flatten_links ? 0 : target_p->hopcount,
+ target_p->info);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_whois.c: Shows who a user is.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_whois.c 1879 2006-08-27 21:18:43Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "common.h"
+#include "client.h"
+#include "hash.h"
+#include "channel.h"
+#include "hash.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "hook.h"
+#include "s_newconf.h"
+
+static void do_whois(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static void single_whois(struct Client *source_p, struct Client *target_p, int operspy);
+
+static int m_whois(struct Client *, struct Client *, int, const char **);
+static int ms_whois(struct Client *, struct Client *, int, const char **);
+
+struct Message whois_msgtab = {
+ "WHOIS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_whois, 2}, {ms_whois, 2}, mg_ignore, mg_ignore, {m_whois, 2}}
+};
+
+int doing_whois_hook;
+int doing_whois_global_hook;
+
+mapi_clist_av1 whois_clist[] = { &whois_msgtab, NULL };
+mapi_hlist_av1 whois_hlist[] = {
+ { "doing_whois", &doing_whois_hook },
+ { "doing_whois_global", &doing_whois_global_hook },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(whois, NULL, NULL, whois_clist, whois_hlist, NULL, "$Revision: 1879 $");
+
+/*
+ * m_whois
+ * parv[0] = sender prefix
+ * parv[1] = nickname masklist
+ */
+static int
+m_whois(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ static time_t last_used = 0;
+
+ if(parc > 2)
+ {
+ if(EmptyString(parv[2]))
+ {
+ sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
+ me.name, source_p->name);
+ return 0;
+ }
+
+ if(!IsOper(source_p))
+ {
+ /* seeing as this is going across servers, we should limit it */
+ if((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "WHOIS");
+ sendto_one_numeric(source_p, RPL_ENDOFWHOIS,
+ form_str(RPL_ENDOFWHOIS), parv[1]);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+ if(hunt_server(client_p, source_p, ":%s WHOIS %s :%s", 1, parc, parv) !=
+ HUNTED_ISME)
+ return 0;
+
+ parv[1] = parv[2];
+
+ }
+ do_whois(client_p, source_p, parc, parv);
+
+ return 0;
+}
+
+/*
+ * ms_whois
+ * parv[0] = sender prefix
+ * parv[1] = server to reply
+ * parv[2] = nickname to whois
+ */
+static int
+ms_whois(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+
+ /* note: early versions of ratbox allowed users to issue a remote
+ * whois with a blank parv[2], so we cannot treat it as a protocol
+ * violation. --anfl
+ */
+ if(parc < 3 || EmptyString(parv[2]))
+ {
+ sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
+ me.name, source_p->name);
+ return 0;
+ }
+
+ /* check if parv[1] exists */
+ if((target_p = find_client(parv[1])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ IsDigit(parv[1][0]) ? "*" : parv[1]);
+ return 0;
+ }
+
+ /* if parv[1] isnt my client, or me, someone else is supposed
+ * to be handling the request.. so send it to them
+ */
+ if(!MyClient(target_p) && !IsMe(target_p))
+ {
+ sendto_one(target_p, ":%s WHOIS %s :%s",
+ get_id(source_p, target_p),
+ get_id(target_p, target_p), parv[2]);
+ return 0;
+ }
+
+ /* ok, the target is either us, or a client on our server, so perform the whois
+ * but first, parv[1] == server to perform the whois on, parv[2] == person
+ * to whois, so make parv[1] = parv[2] so do_whois is ok -- fl_
+ */
+ parv[1] = parv[2];
+ do_whois(client_p, source_p, parc, parv);
+
+ return 0;
+}
+
+/* do_whois
+ *
+ * inputs - pointer to
+ * output -
+ * side effects -
+ */
+static void
+do_whois(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ char *nick;
+ char *p = NULL;
+ int operspy = 0;
+
+ nick = LOCAL_COPY(parv[1]);
+ if((p = strchr(nick, ',')))
+ *p = '\0';
+
+ if(IsOperSpy(source_p) && *nick == '!')
+ {
+ operspy = 1;
+ nick++;
+ }
+
+ target_p = find_named_person(nick);
+
+ if(target_p != NULL)
+ {
+ if(operspy)
+ {
+ char buffer[BUFSIZE];
+
+ snprintf(buffer, sizeof(buffer), "%s!%s@%s %s",
+ target_p->name, target_p->username,
+ target_p->host, target_p->user->server);
+ report_operspy(source_p, "WHOIS", buffer);
+ }
+
+ single_whois(source_p, target_p, operspy);
+ }
+ else
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK),
+ IsDigit(*nick) ? "*" : nick);
+
+ sendto_one_numeric(source_p, RPL_ENDOFWHOIS,
+ form_str(RPL_ENDOFWHOIS), parv[1]);
+ return;
+}
+
+/*
+ * single_whois()
+ *
+ * Inputs - source_p client to report to
+ * - target_p client to report on
+ * Output - if found return 1
+ * Side Effects - do a single whois on given client
+ * writing results to source_p
+ */
+static void
+single_whois(struct Client *source_p, struct Client *target_p, int operspy)
+{
+ char buf[BUFSIZE];
+ dlink_node *ptr;
+ struct Client *a2client_p;
+ struct membership *msptr;
+ struct Channel *chptr;
+ int cur_len = 0;
+ int mlen;
+ char *t;
+ int tlen;
+ hook_data_client hdata;
+ char *name;
+ char quest[] = "?";
+ int visible;
+ int extra_space = 0;
+
+ if(target_p->name[0] == '\0')
+ name = quest;
+ else
+ name = target_p->name;
+
+ if(target_p->user == NULL)
+ {
+ s_assert(0);
+ return;
+ }
+
+ a2client_p = target_p->servptr;
+
+ sendto_one_numeric(source_p, RPL_WHOISUSER, form_str(RPL_WHOISUSER),
+ target_p->name, target_p->username,
+ target_p->host, target_p->info);
+
+ cur_len = mlen = ircsprintf(buf, form_str(RPL_WHOISCHANNELS),
+ get_id(&me, source_p), get_id(source_p, source_p),
+ target_p->name);
+
+ /* Make sure it won't overflow when sending it to the client
+ * in full names; note that serverhiding may require more space
+ * for a different server name (not done here) -- jilles
+ */
+ if (!MyConnect(source_p))
+ {
+ extra_space = strlen(source_p->name) - 9;
+ if (extra_space < 0)
+ extra_space = 0;
+ extra_space += strlen(me.name) - 2; /* make sure >= 0 */
+ cur_len += extra_space;
+ }
+
+ t = buf + mlen;
+
+ DLINK_FOREACH(ptr, target_p->user->channel.head)
+ {
+ msptr = ptr->data;
+ chptr = msptr->chptr;
+
+ visible = IsService(target_p) ? IsMember(source_p, chptr) : ShowChannel(source_p, chptr);
+
+ if(visible || operspy)
+ {
+ if((cur_len + strlen(chptr->chname) + 3) > (BUFSIZE - 5))
+ {
+ sendto_one(source_p, "%s", buf);
+ cur_len = mlen + extra_space;
+ t = buf + mlen;
+ }
+
+ tlen = ircsprintf(t, "%s%s%s ",
+ visible ? "" : "!",
+ find_channel_status(msptr, 1),
+ chptr->chname);
+ t += tlen;
+ cur_len += tlen;
+ }
+ }
+
+ if(cur_len > mlen + extra_space)
+ sendto_one(source_p, "%s", buf);
+
+ sendto_one_numeric(source_p, RPL_WHOISSERVER, form_str(RPL_WHOISSERVER),
+ target_p->name, target_p->user->server,
+ a2client_p ? a2client_p->info : "*Not On This Net*");
+
+ if(target_p->user->away)
+ sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY),
+ target_p->name, target_p->user->away);
+
+ if(IsOper(target_p))
+ {
+ sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR),
+ target_p->name,
+ IsService(target_p) ? ConfigFileEntry.servicestring :
+ (IsAdmin(target_p) ? GlobalSetOptions.adminstring :
+ GlobalSetOptions.operstring));
+ }
+
+ if(MyClient(target_p))
+ {
+ if (IsDynSpoof(target_p) && (IsOper(source_p) || source_p == target_p))
+ {
+ /* trick here: show a nonoper their own IP if
+ * dynamic spoofed but not if auth{} spoofed
+ * -- jilles */
+ ClearDynSpoof(target_p);
+ sendto_one_numeric(source_p, RPL_WHOISHOST,
+ form_str(RPL_WHOISHOST),
+ target_p->name, target_p->orighost,
+ show_ip(source_p, target_p) ? target_p->sockhost : "255.255.255.255");
+ SetDynSpoof(target_p);
+ }
+ else if(ConfigFileEntry.use_whois_actually && show_ip(source_p, target_p))
+ sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
+ form_str(RPL_WHOISACTUALLY),
+ target_p->name, target_p->sockhost);
+
+ sendto_one_numeric(source_p, RPL_WHOISIDLE, form_str(RPL_WHOISIDLE),
+ target_p->name,
+ CurrentTime - target_p->localClient->last,
+ target_p->localClient->firsttime);
+ }
+ else
+ {
+ if (IsDynSpoof(target_p) && (IsOper(source_p) || source_p == target_p))
+ {
+ ClearDynSpoof(target_p);
+ sendto_one_numeric(source_p, RPL_WHOISHOST,
+ form_str(RPL_WHOISHOST),
+ target_p->name, target_p->orighost,
+ show_ip(source_p, target_p) && !EmptyString(target_p->sockhost) && strcmp(target_p->sockhost, "0")? target_p->sockhost : "255.255.255.255");
+ SetDynSpoof(target_p);
+ }
+ else if(ConfigFileEntry.use_whois_actually && show_ip(source_p, target_p) &&
+ !EmptyString(target_p->sockhost) && strcmp(target_p->sockhost, "0"))
+ {
+ sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
+ form_str(RPL_WHOISACTUALLY),
+ target_p->name, target_p->sockhost);
+
+ }
+
+ }
+
+ hdata.client = source_p;
+ hdata.target = target_p;
+
+ /* doing_whois_hook must only be called for local clients,
+ * doing_whois_global_hook must only be called for local targets
+ */
+ /* it is important that these are called *before* RPL_ENDOFWHOIS is
+ * sent, services compatibility code depends on it. --anfl
+ */
+ if(MyClient(source_p))
+ call_hook(doing_whois_hook, &hdata);
+ else
+ call_hook(doing_whois_global_hook, &hdata);
+
+ return;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * m_whois.c: Shows who a user was.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: m_whowas.c 1717 2006-07-04 14:41:11Z jilles $
+ */
+
+#include "stdinc.h"
+#include "whowas.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "ircd_defs.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_user.h"
+#include "send.h"
+#include "s_conf.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static int m_whowas(struct Client *, struct Client *, int, const char **);
+
+struct Message whowas_msgtab = {
+ "WHOWAS", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, {m_whowas, 2}, mg_ignore, mg_ignore, mg_ignore, {m_whowas, 2}}
+};
+
+mapi_clist_av1 whowas_clist[] = { &whowas_msgtab, NULL };
+DECLARE_MODULE_AV1(whowas, NULL, NULL, whowas_clist, NULL, NULL, "$Revision: 1717 $");
+
+/*
+** m_whowas
+** parv[0] = sender prefix
+** parv[1] = nickname queried
+*/
+static int
+m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Whowas *temp;
+ int cur = 0;
+ int max = -1, found = 0;
+ char *p;
+ const char *nick;
+
+ static time_t last_used = 0L;
+
+ if(!IsOper(source_p))
+ {
+ if((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime)
+ {
+ sendto_one(source_p, form_str(RPL_LOAD2HI),
+ me.name, source_p->name, "WHOWAS");
+ sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+ else
+ last_used = CurrentTime;
+ }
+
+
+ if(parc > 2)
+ max = atoi(parv[2]);
+
+#if 0
+ if(parc > 3)
+ if(hunt_server(client_p, source_p, ":%s WHOWAS %s %s :%s", 3, parc, parv))
+ return 0;
+#endif
+
+ if((p = strchr(parv[1], ',')))
+ *p = '\0';
+
+ nick = parv[1];
+
+ temp = WHOWASHASH[hash_whowas_name(nick)];
+ found = 0;
+ for (; temp; temp = temp->next)
+ {
+ if(!irccmp(nick, temp->name))
+ {
+ sendto_one(source_p, form_str(RPL_WHOWASUSER),
+ me.name, source_p->name, temp->name,
+ temp->username, temp->hostname, temp->realname);
+ if (MyOper(source_p) && !EmptyString(temp->sockhost))
+#if 0
+ sendto_one(source_p, form_str(RPL_WHOWASREAL),
+ me.name, source_p->name, temp->name,
+ "<untracked>", temp->sockhost);
+#else
+ sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
+ form_str(RPL_WHOISACTUALLY),
+ temp->name, temp->sockhost);
+#endif
+ sendto_one_numeric(source_p, RPL_WHOISSERVER,
+ form_str(RPL_WHOISSERVER),
+ temp->name, temp->servername,
+ myctime(temp->logoff));
+ cur++;
+ found++;
+ }
+ if(max > 0 && cur >= max)
+ break;
+ }
+
+ if(!found)
+ sendto_one(source_p, form_str(ERR_WASNOSUCHNICK),
+ me.name, source_p->name, nick);
+
+ sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
+ me.name, source_p->name, parv[1]);
+ return 0;
+}
--- /dev/null
+/* modules/m_xline.c
+ *
+ * Copyright (C) 2002-2003 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_xline.c 3059 2006-12-27 00:36:54Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "class.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "memory.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "hash.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+
+static int mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int ms_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int me_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int ms_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int me_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+
+struct Message xline_msgtab = {
+ "XLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_xline, 5}, {ms_xline, 5}, {me_xline, 5}, {mo_xline, 3}}
+};
+struct Message unxline_msgtab = {
+ "UNXLINE", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, {ms_unxline, 3}, {ms_unxline, 3}, {me_unxline, 2}, {mo_unxline, 2}}
+};
+
+mapi_clist_av1 xline_clist[] = { &xline_msgtab, &unxline_msgtab, NULL };
+DECLARE_MODULE_AV1(xline, NULL, NULL, xline_clist, NULL, NULL, "$Revision: 3059 $");
+
+static int valid_xline(struct Client *, const char *, const char *);
+static void apply_xline(struct Client *client_p, const char *name,
+ const char *reason, int temp_time);
+static void write_xline(struct Client *source_p, struct ConfItem *aconf);
+static void propagate_xline(struct Client *source_p, const char *target,
+ int temp_time, const char *name,
+ const char *type, const char *reason);
+static void cluster_xline(struct Client *source_p, int temp_time,
+ const char *name, const char *reason);
+
+static void handle_remote_xline(struct Client *source_p, int temp_time,
+ const char *name, const char *reason);
+static void handle_remote_unxline(struct Client *source_p, const char *name);
+
+static int remove_temp_xline(struct Client *source_p, const char *name);
+static void remove_xline(struct Client *source_p, const char *gecos);
+
+
+/* m_xline()
+ *
+ * parv[1] - thing to xline
+ * parv[2] - optional type/reason
+ * parv[3] - reason
+ */
+static int
+mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct ConfItem *aconf;
+ const char *name;
+ const char *reason;
+ const char *target_server = NULL;
+ int temp_time;
+ int loc = 1;
+
+ if(!IsOperXline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "xline");
+ return 0;
+ }
+
+ if((temp_time = valid_temp_time(parv[loc])) >= 0)
+ loc++;
+ /* we just set temp_time to -1! */
+ else
+ temp_time = 0;
+
+ name = parv[loc];
+ loc++;
+
+ /* XLINE <gecos> ON <server> :<reason> */
+ if(parc >= loc+2 && !irccmp(parv[loc], "ON"))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ target_server = parv[loc+1];
+ loc += 2;
+ }
+
+ if(parc <= loc || EmptyString(parv[loc]))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name, source_p->name, "XLINE");
+ return 0;
+ }
+
+ reason = parv[loc];
+
+ if(target_server != NULL)
+ {
+ propagate_xline(source_p, target_server, temp_time,
+ name, "2", reason);
+
+ if(!match(target_server, me.name))
+ return 0;
+ }
+ else if(dlink_list_length(&cluster_conf_list) > 0)
+ cluster_xline(source_p, temp_time, name, reason);
+
+ if((aconf = find_xline(name, 0)) != NULL)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s",
+ me.name, source_p->name, parv[1], aconf->name, aconf->passwd);
+ return 0;
+ }
+
+ if(!valid_xline(source_p, name, reason))
+ return 0;
+
+ apply_xline(source_p, name, reason, temp_time);
+
+ return 0;
+}
+
+/* ms_xline()
+ *
+ * handles a remote xline
+ */
+static int
+ms_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2] parv[3] parv[4]
+ * oper target serv xline type reason
+ */
+ propagate_xline(source_p, parv[1], 0, parv[2], parv[3], parv[4]);
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ /* destined for me? */
+ if(!match(parv[1], me.name))
+ return 0;
+
+ handle_remote_xline(source_p, 0, parv[2], parv[4]);
+ return 0;
+}
+
+static int
+me_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* time name type :reason */
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_xline(source_p, atoi(parv[1]), parv[2], parv[4]);
+ return 0;
+}
+
+static void
+handle_remote_xline(struct Client *source_p, int temp_time,
+ const char *name, const char *reason)
+{
+ struct ConfItem *aconf;
+
+ if(!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server,
+ (temp_time > 0) ? SHARED_TXLINE : SHARED_PXLINE))
+ return;
+
+ if(!valid_xline(source_p, name, reason))
+ return;
+
+ /* already xlined */
+ if((aconf = find_xline(name, 0)) != NULL)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s",
+ me.name, source_p->name, name,
+ aconf->name, aconf->passwd);
+ return;
+ }
+
+ apply_xline(source_p, name, reason, temp_time);
+}
+
+/* valid_xline()
+ *
+ * inputs - client xlining, gecos, reason and whether to warn
+ * outputs -
+ * side effects - checks the xline for validity, erroring if needed
+ */
+static int
+valid_xline(struct Client *source_p, const char *gecos,
+ const char *reason)
+{
+ if(EmptyString(reason))
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+ get_id(&me, source_p),
+ get_id(source_p, source_p), "XLINE");
+ return 0;
+ }
+
+ if(strchr(reason, ':') != NULL)
+ {
+ sendto_one_notice(source_p,
+ ":Invalid character ':' in comment");
+ return 0;
+ }
+
+ if(strchr(reason, '"'))
+ {
+ sendto_one_notice(source_p,
+ ":Invalid character '\"' in comment");
+ return 0;
+ }
+
+ if(!valid_wild_card_simple(gecos))
+ {
+ sendto_one_notice(source_p,
+ ":Please include at least %d non-wildcard "
+ "characters with the xline",
+ ConfigFileEntry.min_nonwildcard_simple);
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+apply_xline(struct Client *source_p, const char *name, const char *reason,
+ int temp_time)
+{
+ struct ConfItem *aconf;
+
+ aconf = make_conf();
+ aconf->status = CONF_XLINE;
+
+ if(strstr(name, "\\s"))
+ {
+ char *tmp = LOCAL_COPY(name);
+ char *orig = tmp;
+ char *new = tmp;
+
+ while(*orig)
+ {
+ if(*orig == '\\' && *(orig + 1) != '\0')
+ {
+ if(*(orig + 1) == 's')
+ {
+ *new++ = ' ';
+ orig += 2;
+ }
+ /* otherwise skip that and the escaped
+ * character after it, so we dont mistake
+ * \\s as \s --fl
+ */
+ else
+ {
+ *new++ = *orig++;
+ *new++ = *orig++;
+ }
+ }
+ else
+ *new++ = *orig++;
+ }
+
+ *new = '\0';
+ DupString(aconf->name, tmp);
+ }
+ else
+ DupString(aconf->name, name);
+
+ DupString(aconf->passwd, reason);
+ collapse(aconf->name);
+
+ if(temp_time > 0)
+ {
+ aconf->hold = CurrentTime + temp_time;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added temporary %d min. X-Line for [%s] [%s]",
+ get_oper_name(source_p), temp_time / 60,
+ aconf->name, reason);
+ ilog(L_KLINE, "X %s %d %s %s",
+ get_oper_name(source_p), temp_time / 60,
+ name, reason);
+ sendto_one_notice(source_p, ":Added temporary %d min. X-Line [%s]",
+ temp_time / 60, aconf->name);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s added X-Line for [%s] [%s]",
+ get_oper_name(source_p),
+ aconf->name, aconf->passwd);
+ sendto_one_notice(source_p, ":Added X-Line for [%s] [%s]",
+ aconf->name, aconf->passwd);
+ write_xline(source_p, aconf);
+ ilog(L_KLINE, "X %s 0 %s %s",
+ get_oper_name(source_p), name, reason);
+ }
+
+ dlinkAddAlloc(aconf, &xline_conf_list);
+ check_xlines();
+}
+
+/* write_xline()
+ *
+ * inputs - gecos, reason, xline type
+ * outputs - writes an xline to the config
+ * side effects -
+ */
+static void
+write_xline(struct Client *source_p, struct ConfItem *aconf)
+{
+ char buffer[BUFSIZE * 2];
+ FILE *out;
+ const char *filename;
+
+ filename = ConfigFileEntry.xlinefile;
+
+ if((out = fopen(filename, "a")) == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem opening %s ", filename);
+ sendto_one_notice(source_p, ":*** Problem opening file, xline added temporarily only");
+ return;
+ }
+
+ ircsprintf(buffer, "\"%s\",\"0\",\"%s\",\"%s\",%ld\n",
+ aconf->name, aconf->passwd,
+ get_oper_name(source_p), CurrentTime);
+
+ if(fputs(buffer, out) == -1)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem writing to %s", filename);
+ sendto_one_notice(source_p, ":*** Problem writing to file, xline added temporarily only");
+ fclose(out);
+ return;
+ }
+
+ if(fclose(out))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem writing to %s", filename);
+ sendto_one_notice(source_p, ":*** Problem writing to file, xline added temporarily only");
+ return;
+ }
+}
+
+static void
+propagate_xline(struct Client *source_p, const char *target,
+ int temp_time, const char *name, const char *type,
+ const char *reason)
+{
+ if(!temp_time)
+ {
+ sendto_match_servs(source_p, target, CAP_CLUSTER, NOCAPS,
+ "XLINE %s %s %s :%s",
+ target, name, type, reason);
+ sendto_match_servs(source_p, target, CAP_ENCAP, CAP_CLUSTER,
+ "ENCAP %s XLINE %d %s 2 :%s",
+ target, temp_time, name, reason);
+ }
+ else
+ sendto_match_servs(source_p, target, CAP_ENCAP, NOCAPS,
+ "ENCAP %s XLINE %d %s %s :%s",
+ target, temp_time, name, type, reason);
+}
+
+static void
+cluster_xline(struct Client *source_p, int temp_time, const char *name,
+ const char *reason)
+{
+ struct remote_conf *shared_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, cluster_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ /* old protocol cant handle temps, and we dont really want
+ * to convert them to perm.. --fl
+ */
+ if(!temp_time)
+ {
+ if(!(shared_p->flags & SHARED_PXLINE))
+ continue;
+
+ sendto_match_servs(source_p, shared_p->server, CAP_CLUSTER, NOCAPS,
+ "XLINE %s %s 2 :%s",
+ shared_p->server, name, reason);
+ sendto_match_servs(source_p, shared_p->server, CAP_ENCAP, CAP_CLUSTER,
+ "ENCAP %s XLINE 0 %s 2 :%s",
+ shared_p->server, name, reason);
+ }
+ else if(shared_p->flags & SHARED_TXLINE)
+ sendto_match_servs(source_p, shared_p->server, CAP_ENCAP, NOCAPS,
+ "ENCAP %s XLINE %d %s 2 :%s",
+ shared_p->server, temp_time, name, reason);
+ }
+}
+
+/* mo_unxline()
+ *
+ * parv[1] - thing to unxline
+ */
+static int
+mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ if(!IsOperXline(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "xline");
+ return 0;
+ }
+
+ if(parc == 4 && !(irccmp(parv[2], "ON")))
+ {
+ if(!IsOperRemoteBan(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "remoteban");
+ return 0;
+ }
+
+ propagate_generic(source_p, "UNXLINE", parv[3], CAP_CLUSTER,
+ "%s", parv[1]);
+
+ if(match(parv[3], me.name) == 0)
+ return 0;
+ }
+ else if(dlink_list_length(&cluster_conf_list))
+ cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER,
+ "%s", parv[1]);
+
+ if(remove_temp_xline(source_p, parv[1]))
+ return 0;
+
+ remove_xline(source_p, parv[1]);
+
+ return 0;
+}
+
+/* ms_unxline()
+ *
+ * handles a remote unxline
+ */
+static int
+ms_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* parv[0] parv[1] parv[2]
+ * oper target server gecos
+ */
+ propagate_generic(source_p, "UNXLINE", parv[1], CAP_CLUSTER,
+ "%s", parv[2]);
+
+ if(!match(parv[1], me.name))
+ return 0;
+
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unxline(source_p, parv[2]);
+ return 0;
+}
+
+static int
+me_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* name */
+ if(!IsPerson(source_p))
+ return 0;
+
+ handle_remote_unxline(source_p, parv[1]);
+ return 0;
+}
+
+static void
+handle_remote_unxline(struct Client *source_p, const char *name)
+{
+ if(!find_shared_conf(source_p->username, source_p->host,
+ source_p->user->server, SHARED_UNXLINE))
+ return;
+
+ if(remove_temp_xline(source_p, name))
+ return;
+
+ remove_xline(source_p, name);
+
+ return;
+}
+
+static int
+remove_temp_xline(struct Client *source_p, const char *name)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ /* only want to check temp ones! */
+ if(!aconf->hold)
+ continue;
+
+ if(!irccmp(aconf->name, name))
+ {
+ sendto_one_notice(source_p,
+ ":X-Line for [%s] is removed",
+ name);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the temporary X-Line for: [%s]",
+ get_oper_name(source_p), name);
+ ilog(L_KLINE, "UX %s %s",
+ get_oper_name(source_p), name);
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &xline_conf_list);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* remove_xline()
+ *
+ * inputs - gecos to remove
+ * outputs -
+ * side effects - removes xline from conf, if exists
+ */
+static void
+remove_xline(struct Client *source_p, const char *huntgecos)
+{
+ FILE *in, *out;
+ char buf[BUFSIZE];
+ char buff[BUFSIZE];
+ char temppath[BUFSIZE];
+ const char *filename;
+ const char *gecos;
+ mode_t oldumask;
+ char *p;
+ int error_on_write = 0;
+ int found_xline = 0;
+
+ filename = ConfigFileEntry.xlinefile;
+ ircsnprintf(temppath, sizeof(temppath),
+ "%s.tmp", ConfigFileEntry.xlinefile);
+
+ if((in = fopen(filename, "r")) == NULL)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", filename);
+ return;
+ }
+
+ oldumask = umask(0);
+
+ if((out = fopen(temppath, "w")) == NULL)
+ {
+ sendto_one_notice(source_p, ":Cannot open %s", temppath);
+ fclose(in);
+ umask(oldumask);
+ return;
+ }
+
+ umask(oldumask);
+
+ while (fgets(buf, sizeof(buf), in))
+ {
+ if(error_on_write)
+ {
+ if(temppath != NULL)
+ (void) unlink(temppath);
+
+ break;
+ }
+
+ strlcpy(buff, buf, sizeof(buff));
+
+ if((p = strchr(buff, '\n')) != NULL)
+ *p = '\0';
+
+ if((*buff == '\0') || (*buff == '#'))
+ {
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ continue;
+ }
+
+ if((gecos = getfield(buff)) == NULL)
+ {
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ continue;
+ }
+
+ /* matching.. */
+ if(irccmp(gecos, huntgecos) == 0)
+ found_xline++;
+ else
+ error_on_write = (fputs(buf, out) < 0) ? YES : NO;
+ }
+
+ fclose(in);
+ if (fclose(out))
+ error_on_write = YES;
+
+ if(error_on_write)
+ {
+ sendto_one_notice(source_p,
+ ":Couldn't write temp xline file, aborted");
+ return;
+ }
+ else if(found_xline == 0)
+ {
+ sendto_one_notice(source_p, ":No X-Line for %s", huntgecos);
+
+ if(temppath != NULL)
+ (void) unlink(temppath);
+ return;
+ }
+
+ if (rename(temppath, filename))
+ {
+ sendto_one_notice(source_p, ":Couldn't rename temp file, aborted");
+ return;
+ }
+ rehash_bans(0);
+
+ sendto_one_notice(source_p, ":X-Line for [%s] is removed", huntgecos);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has removed the X-Line for: [%s]",
+ get_oper_name(source_p), huntgecos);
+ ilog(L_KLINE, "UX %s %s", get_oper_name(source_p), huntgecos);
+}
--- /dev/null
+/*
+ * charybdis: an advanced Internet Relay Chat Daemon(ircd).
+ * sno_routing.c: Shows notices about netjoins and netsplits
+ *
+ * Copyright (c) 2005-2006 Jilles Tjoelker <jilles-at-stack.nl>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: sno_routing.c 1172 2006-04-18 13:49:18Z jilles $
+ */
+
+#include "stdinc.h"
+#include "modules.h"
+#include "client.h"
+#include "hook.h"
+#include "ircd.h"
+#include "send.h"
+
+static void h_nn_server_eob(struct Client *);
+static void h_nn_client_exit(hook_data_client_exit *);
+
+mapi_hfn_list_av1 nn_hfnlist[] = {
+ { "server_eob", (hookfn) h_nn_server_eob },
+ { "client_exit", (hookfn) h_nn_client_exit },
+ { NULL, NULL }
+};
+
+DECLARE_MODULE_AV1(networknotice, NULL, NULL, NULL, NULL, nn_hfnlist, "$Revision: 1172 $");
+
+/*
+ * count_mark_downlinks
+ *
+ * inputs - pointer to server to count
+ * - pointers to server and user count
+ * output - NONE
+ * side effects - servers are marked
+ * - server and user counts are added to given values
+ */
+static void
+count_mark_downlinks(struct Client *server_p, int *pservcount, int *pusercount)
+{
+ dlink_node *ptr;
+
+ SetFloodDone(server_p);
+ (*pservcount)++;
+ *pusercount += dlink_list_length(&server_p->serv->users);
+ DLINK_FOREACH(ptr, server_p->serv->servers.head)
+ {
+ count_mark_downlinks(ptr->data, pservcount, pusercount);
+ }
+}
+
+static void
+h_nn_server_eob(struct Client *source_p)
+{
+ int s = 0, u = 0;
+
+ if (IsFloodDone(source_p))
+ return;
+ count_mark_downlinks(source_p, &s, &u);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Netjoin %s <-> %s (%dS %dC)",
+ source_p->servptr ? source_p->servptr->name : "?",
+ source_p->name, s, u);
+}
+
+static void
+h_nn_client_exit(hook_data_client_exit *hdata)
+{
+ struct Client *source_p;
+ int s = 0, u = 0;
+ char *fromnick;
+
+ source_p = hdata->target;
+ fromnick = IsClient(hdata->from) ? hdata->from->name : NULL;
+
+ if (!IsServer(source_p))
+ return;
+ if (HasSentEob(source_p))
+ {
+ count_mark_downlinks(source_p, &s, &u);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Netsplit %s <-> %s (%dS %dC) (%s%s%s%s)",
+ source_p->servptr ? source_p->servptr->name : "?",
+ source_p->name, s, u,
+ fromnick ? "by " : "",
+ fromnick ? fromnick : "",
+ fromnick ? ": " : "",
+ hdata->comment);
+ }
+ else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Netsplit %s <-> %s (during burst) (%s%s%s%s)",
+ source_p->servptr ? source_p->servptr->name : "?",
+ source_p->name,
+ fromnick ? "by " : "",
+ fromnick ? fromnick : "",
+ fromnick ? ": " : "",
+ hdata->comment);
+}
--- /dev/null
+#!/bin/sh
+# static_modules.c.SH: Generates our static module list
+# $Id: static_modules.c.SH 6 2005-09-10 01:02:21Z nenolod $
+#
+SYMS=`for x in $*; do basename $x .o|sed -es/^m_//; done`
+cat > static_modules.c <<EOF
+/*
+ * This file is automatically generated: do not modify
+ * ircd-ratbox: A slightly useful ircd
+ *
+ * Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2003-2005 ircd-ratbox 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 "stdinc.h"
+#include "modules.h"
+#include "hash.h"
+#include "s_log.h"
+
+EOF
+
+for x in $SYMS; do
+ echo extern struct mapi_header_av1 "$x"_mheader\;
+done >> static_modules.c
+
+
+echo static const struct mapi_header_av1 *mapi_headers[] = { >> static_modules.c
+for x in $SYMS; do
+ echo \&"$x"_mheader,
+done >> static_modules.c
+
+echo NULL }\; >> static_modules.c
+
+cat >> static_modules.c <<EOF
+void load_static_modules(void)
+{
+ int x;
+ int *mapi_version;
+ for(x = 0; mapi_headers[x] != NULL; x++)
+ {
+ mapi_version = (int *)mapi_headers[x];
+ if(MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
+ {
+ ilog(L_MAIN, "Error: linked in module without a MAPI header..giving up");
+ exit(70);
+ }
+ switch(MAPI_VERSION(*mapi_version))
+ {
+ case 1:
+ {
+ struct mapi_mheader_av1 *mheader = (struct mapi_mheader_av1*)mapi_version;
+ if (mheader->mapi_register && (mheader->mapi_register() == -1))
+ {
+ ilog(L_MAIN, "Error: linked in module failed loading..giving up");
+ exit(70);
+ }
+
+ if(mheader->mapi_command_list)
+ {
+ struct Message **m;
+ for(m = mheader->mapi_command_list; *m; ++m)
+ mod_add_cmd(*m);
+ }
+
+ if(mheader->mapi_hook_list)
+ {
+ mapi_hlist_av1 *m;
+ for(m = mheader->mapi_hook_list; m->hapi_name; ++m)
+ *m->hapi_id = register_hook(m->hapi_name);
+ }
+
+ if(mheader->mapi_hfn_list)
+ {
+ mapi_hfn_list_av1 *m;
+ for(m = mheader->mapi_hfn_list; m->hapi_name; ++m)
+ add_hook(m->hapi_name, m->fn);
+
+ }
+
+ break;
+
+ }
+ default:
+ {
+ ilog(L_MAIN, "Error: Unknown MAPI version in linked in module..giving up");
+ exit(70);
+ }
+ }
+ }
+}
+EOF
--- /dev/null
+Makefile
+setup.h
+servlink
--- /dev/null
+-i8 -bli0 -ut -nsai -l100 -npcs
\ No newline at end of file
--- /dev/null
+#
+# Makefile.in for servlink/src
+#
+# $Id: Makefile.in 1285 2006-05-05 15:03:53Z nenolod $
+#
+
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_BIN = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+RM = @RM@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+LDFLAGS = @LDFLAGS@
+MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
+MV = @MV@
+RM = @RM@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libexecdir = @libexecdir@
+confdir = @confdir@
+localstatedir = @localstatedir@
+
+ZIP_LIB = @ZLIB_LD@
+
+IRCDLIBS = @LIBS@ $(ZIP_LIB)
+
+INCLUDES = -I. -I../include $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+PROGS = servlink
+
+SOURCES = \
+ servlink.c \
+ io.c \
+ control.c
+
+
+OBJECTS = ${SOURCES:.c=.o}
+
+all: servlink
+
+build: all
+
+servlink: ${OBJECTS}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJECTS} ${IRCDLIBS}
+
+install: build
+ @echo "ircd: installing servlink ($(PROGS))"
+ @for i in $(PROGS); do \
+ if test -f $(DESTDIR)$(bindir)/$$i; then \
+ $(MV) $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.old; \
+ fi; \
+ $(INSTALL_BIN) $$i $(DESTDIR)$(bindir); \
+ done
+
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $<
+
+.PHONY: depend clean distclean
+depend:
+ @${MKDEP} ${CPPFLAGS} ${SOURCES} > .depend.tmp
+ @sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
+ @echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
+ @echo '# make depend needs it.' >>Makefile.depend
+ @cat .depend.tmp >>Makefile.depend
+ @mv Makefile.depend Makefile
+ @rm -f .depend.tmp
+
+clean:
+ ${RM} -f *.o *~ *.core core servlink
+
+lint:
+ lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(SOURCES) >>../lint.out
+
+distclean: clean
+ ${RM} -f Makefile
+
+# End of Makefile
--- /dev/null
+Servlink protocol documentation.
+$Id: README 1285 2006-05-05 15:03:53Z nenolod $
+--------------
+
+After negotiating an incoming/outgoing server connection, the ircd will
+fork, then execve servlink, with fd 0 as one end of a control pipe and
+fd 1 as one end of a data pipe. fd 2 will be the socket connected to
+the remote server.
+
+The data pipe is used by the ircd to send/receive normal, decrypted,
+uncompressed IRC commands to/from the remote server. The socket is used to
+send the (processed) data to the remote server, and receive the data from
+the remote server.
+
+The control pipe is used to activate encryption/compression and to set the
+encryption key/algorithm to be used.
+
+Format of control messages:
+
+<u8 command><optional data>
+
+data format:
+<u16 len><data>
+
+Commands:
+
+001 - SET_ZIP_OUT_LEVEL
+ data: yes
+ description:
+ set compression level (0 [use default, 6], or 1-9)
+
+002 - START_ZIP_OUT
+ data: no
+ description:
+ all data written to the data pipe will be compressed
+ prior to being sent to the remote server.
+
+003 - START_ZIP_IN
+ data: no
+ description:
+ all data not yet read from the slink program will be
+ decompressed before reading
+
+004 - INJECT_RECVQ
+ data: recvq
+
+ Used before INIT to inject any data read from the server fd which
+ should be pre-processed by servlink before being sent back
+ to the LOCAL_FD through the data fd.
+
+005 - INJECT_SENDQ
+ data: sendq
+
+ As above, but sent to remote server without processing.
+
+006 - INIT
+
+007 - ZIPSTATS
+ request to send ziplinks statistics reply.
+
+replies
+
+001 - ERROR
+ data: u32 len/char error[len]
+
+ fatal error message.
+
+002 - ZIPSTATS
+ data: u32 in/u32 in_wire/u32 out/u32 out_wire
+
+ ziplinks commpression statistics
--- /dev/null
+Servlink todo list
+$Id: TODO 6 2005-09-10 01:02:21Z nenolod $
+------------------
+
+Fix any bugs that come up
+
+Think of improvements :)
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/servlink.c
+ *
+ * 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.
+ *
+ * $Id: control.c 1285 2006-05-05 15:03:53Z nenolod $
+ */
+
+#include "setup.h"
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "servlink.h"
+#include "io.h"
+#include "control.h"
+
+static cmd_handler cmd_set_zip_out_level;
+static cmd_handler cmd_start_zip_out;
+static cmd_handler cmd_start_zip_in;
+static cmd_handler cmd_init;
+
+struct command_def command_table[] = {
+ {CMD_SET_ZIP_OUT_LEVEL, cmd_set_zip_out_level, COMMAND_FLAG_DATA},
+ {CMD_START_ZIP_OUT, cmd_start_zip_out, 0},
+ {CMD_START_ZIP_IN, cmd_start_zip_in, 0},
+ {CMD_INJECT_RECVQ, process_recvq, COMMAND_FLAG_DATA},
+ {CMD_INJECT_SENDQ, process_sendq, COMMAND_FLAG_DATA},
+ {CMD_INIT, cmd_init, 0},
+ {CMD_ZIPSTATS, send_zipstats, 0},
+ {0, 0, 0}
+};
+
+void
+cmd_set_zip_out_level(struct ctrl_command *cmd)
+{
+#ifdef HAVE_LIBZ
+ out_state.zip_state.level = *cmd->data;
+ if((out_state.zip_state.level < -1) || (out_state.zip_state.level > 9))
+ send_error("invalid compression level %d", out_state.zip_state.level);
+#else
+ send_error("can't set compression level - no libz support!");
+#endif
+}
+
+void
+cmd_start_zip_out(struct ctrl_command *cmd)
+{
+#ifdef HAVE_LIBZ
+ int ret;
+
+ if(out_state.zip)
+ send_error("can't start compression - already started!");
+
+ out_state.zip_state.z_stream.total_in = 0;
+ out_state.zip_state.z_stream.total_out = 0;
+ out_state.zip_state.z_stream.zalloc = (alloc_func) 0;
+ out_state.zip_state.z_stream.zfree = (free_func) 0;
+ out_state.zip_state.z_stream.data_type = Z_ASCII;
+
+ if(out_state.zip_state.level <= 0)
+ out_state.zip_state.level = Z_DEFAULT_COMPRESSION;
+
+ if((ret = deflateInit(&out_state.zip_state.z_stream, out_state.zip_state.level)) != Z_OK)
+ send_error("deflateInit failed: %s", zError(ret));
+
+ out_state.zip = 1;
+#else
+ send_error("can't start compression - no libz support!");
+#endif
+}
+
+void
+cmd_start_zip_in(struct ctrl_command *cmd)
+{
+#ifdef HAVE_LIBZ
+ int ret;
+
+ if(in_state.zip)
+ send_error("can't start decompression - already started!");
+
+ in_state.zip_state.z_stream.total_in = 0;
+ in_state.zip_state.z_stream.total_out = 0;
+ in_state.zip_state.z_stream.zalloc = (alloc_func) 0;
+ in_state.zip_state.z_stream.zfree = (free_func) 0;
+ in_state.zip_state.z_stream.data_type = Z_ASCII;
+ if((ret = inflateInit(&in_state.zip_state.z_stream)) != Z_OK)
+ send_error("inflateInit failed: %s", zError(ret));
+ in_state.zip = 1;
+#else
+ send_error("can't start decompression - no libz support!");
+#endif
+}
+
+
+void
+cmd_init(struct ctrl_command *cmd)
+{
+ if(in_state.active || out_state.active)
+ send_error("CMD_INIT sent twice!");
+
+ in_state.active = 1;
+ out_state.active = 1;
+ CONTROL.read_cb = read_ctrl;
+ CONTROL.write_cb = NULL;
+ LOCAL.read_cb = read_data;
+ LOCAL.write_cb = NULL;
+ REMOTE.read_cb = read_net;
+ REMOTE.write_cb = NULL;
+}
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/control.h
+ *
+ * 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.
+ *
+ * $Id: control.h 1285 2006-05-05 15:03:53Z nenolod $
+ */
+
+#ifndef INCLUDED_servlink_control_h
+#define INCLUDED_servlink_control_h
+
+#define CMD_SET_ZIP_OUT_LEVEL 1 /* data */
+#define CMD_START_ZIP_OUT 2
+#define CMD_START_ZIP_IN 3
+#define CMD_INJECT_RECVQ 4 /* data */
+#define CMD_INJECT_SENDQ 5 /* data */
+#define CMD_INIT 6
+#define CMD_ZIPSTATS 7
+
+#define RPL_ERROR 1 /* data */
+#define RPL_ZIPSTATS 2 /* data */
+
+/* flags */
+#define COMMAND_FLAG_DATA 0x0001 /* command has data
+ following */
+struct ctrl_command
+{
+ int command;
+ int datalen;
+ int gotdatalen;
+ int readdata;
+ unsigned char *data;
+};
+
+typedef void cmd_handler(struct ctrl_command *);
+
+struct command_def
+{
+ unsigned int commandid;
+ cmd_handler *handler;
+ unsigned int flags;
+};
+
+extern struct command_def command_table[];
+#endif /* INCLUDED_servlink_control_h */
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/io.c
+ *
+ * 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.
+ *
+ * $Id: io.c 1285 2006-05-05 15:03:53Z nenolod $
+ */
+
+#include "setup.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "servlink.h"
+#include "io.h"
+#include "control.h"
+
+static int check_error(int, int, int);
+
+static const char *
+fd_name(int fd)
+{
+ if(fd == CONTROL.fd)
+ return "control";
+ if(fd == LOCAL.fd)
+ return "data";
+ if(fd == REMOTE.fd)
+ return "network";
+
+ /* uh oh... */
+ return "unknown";
+}
+
+#if defined( HAVE_LIBZ )
+static unsigned char tmp_buf[BUFLEN];
+static unsigned char tmp2_buf[BUFLEN];
+#endif
+
+static unsigned char ctrl_buf[256] = "";
+static unsigned int ctrl_len = 0;
+static unsigned int ctrl_ofs = 0;
+
+void
+io_loop(int nfds)
+{
+ fd_set rfds;
+ fd_set wfds;
+ int i, ret;
+
+ /* loop forever */
+ for (;;)
+ {
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+
+ for (i = 0; i < 3; i++)
+ {
+ if(fds[i].read_cb)
+ FD_SET(fds[i].fd, &rfds);
+ if(fds[i].write_cb)
+ FD_SET(fds[i].fd, &wfds);
+ }
+
+ /* we have <3 fds ever, so I don't think select is too painful */
+ ret = select(nfds, &rfds, &wfds, NULL, NULL);
+
+ if(ret < 0)
+ {
+ check_error(ret, IO_SELECT, -1); /* exit on fatal errors */
+ }
+ else if(ret > 0)
+ {
+ /* call any callbacks */
+ for (i = 0; i < 3; i++)
+ {
+ if(FD_ISSET(fds[i].fd, &rfds) && fds[i].read_cb)
+ (*fds[i].read_cb) ();
+ if(FD_ISSET(fds[i].fd, &wfds) && fds[i].write_cb)
+ (*fds[i].write_cb) ();
+ }
+ }
+ }
+}
+
+void
+send_data_blocking(int fd, unsigned char *data, int datalen)
+{
+ int ret;
+ fd_set wfds;
+
+ while (1)
+ {
+ ret = write(fd, data, datalen);
+
+ if(ret == datalen)
+ return;
+ else if(ret > 0)
+ {
+ data += ret;
+ datalen -= ret;
+ }
+
+ ret = check_error(ret, IO_WRITE, fd);
+
+ FD_ZERO(&wfds);
+ FD_SET(fd, &wfds);
+
+ /* sleep until we can write to the fd */
+ while (1)
+ {
+ ret = select(fd + 1, NULL, &wfds, NULL, NULL);
+
+ if(ret > 0) /* break out so we can write */
+ break;
+
+ if(ret < 0) /* error ? */
+ check_error(ret, IO_SELECT, fd); /* exit on fatal errors */
+
+ /* loop on non-fatal errors */
+ }
+ }
+}
+
+/*
+ * process_sendq:
+ *
+ * used before CMD_INIT to pass contents of SendQ from ircd
+ * to servlink. This data must _not_ be encrypted/compressed.
+ */
+void
+process_sendq(struct ctrl_command *cmd)
+{
+ send_data_blocking(REMOTE.fd, cmd->data, cmd->datalen);
+}
+
+/*
+ * process_recvq:
+ *
+ * used before CMD_INIT to pass contents of RecvQ from ircd
+ * to servlink. This data must be decrypted/decopmressed before
+ * sending back to the ircd.
+ */
+void
+process_recvq(struct ctrl_command *cmd)
+{
+ int ret;
+ unsigned char *buf;
+ int blen;
+ unsigned char *data = cmd->data;
+ unsigned int datalen = cmd->datalen;
+
+ buf = data;
+ blen = datalen;
+ ret = -1;
+ if(datalen > READLEN)
+ send_error("Error processing INJECT_RECVQ - buffer too long (%d > %d)",
+ datalen, READLEN);
+
+#ifdef HAVE_LIBZ
+ if(in_state.zip)
+ {
+ /* decompress data */
+ in_state.zip_state.z_stream.next_in = buf;
+ in_state.zip_state.z_stream.avail_in = blen;
+ in_state.zip_state.z_stream.next_out = tmp2_buf;
+ in_state.zip_state.z_stream.avail_out = BUFLEN;
+
+ buf = tmp2_buf;
+ while (in_state.zip_state.z_stream.avail_in)
+ {
+ if((ret = inflate(&in_state.zip_state.z_stream, Z_NO_FLUSH)) != Z_OK)
+ {
+ if(!strncmp("ERROR ", (char *)in_state.zip_state.z_stream.next_in, 6))
+ send_error("Received uncompressed ERROR");
+ else
+ send_error("Inflate failed: %s", zError(ret));
+ }
+ blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
+
+ if(in_state.zip_state.z_stream.avail_in)
+ {
+ send_data_blocking(LOCAL.fd, buf, blen);
+ blen = 0;
+ in_state.zip_state.z_stream.next_out = buf;
+ in_state.zip_state.z_stream.avail_out = BUFLEN;
+ }
+ }
+
+ if(!blen)
+ return;
+ }
+#endif
+
+ send_data_blocking(LOCAL.fd, buf, blen);
+}
+
+void
+send_zipstats(struct ctrl_command *unused)
+{
+#ifdef HAVE_LIBZ
+ int i = 0;
+ int ret;
+ u_int32_t len;
+ if(!in_state.active || !out_state.active)
+ send_error("Error processing CMD_ZIPSTATS - link is not active!");
+ if(!in_state.zip || !out_state.zip)
+ send_error("Error processing CMD_ZIPSTATS - link is not compressed!");
+
+ ctrl_buf[i++] = RPL_ZIPSTATS;
+ ctrl_buf[i++] = 0;
+ ctrl_buf[i++] = 16;
+
+ len = (u_int32_t) in_state.zip_state.z_stream.total_out;
+ ctrl_buf[i++] = ((len >> 24) & 0xFF);
+ ctrl_buf[i++] = ((len >> 16) & 0xFF);
+ ctrl_buf[i++] = ((len >> 8) & 0xFF);
+ ctrl_buf[i++] = ((len) & 0xFF);
+
+ len = (u_int32_t) in_state.zip_state.z_stream.total_in;
+ ctrl_buf[i++] = ((len >> 24) & 0xFF);
+ ctrl_buf[i++] = ((len >> 16) & 0xFF);
+ ctrl_buf[i++] = ((len >> 8) & 0xFF);
+ ctrl_buf[i++] = ((len) & 0xFF);
+
+ len = (u_int32_t) out_state.zip_state.z_stream.total_in;
+ ctrl_buf[i++] = ((len >> 24) & 0xFF);
+ ctrl_buf[i++] = ((len >> 16) & 0xFF);
+ ctrl_buf[i++] = ((len >> 8) & 0xFF);
+ ctrl_buf[i++] = ((len) & 0xFF);
+
+ len = (u_int32_t) out_state.zip_state.z_stream.total_out;
+ ctrl_buf[i++] = ((len >> 24) & 0xFF);
+ ctrl_buf[i++] = ((len >> 16) & 0xFF);
+ ctrl_buf[i++] = ((len >> 8) & 0xFF);
+ ctrl_buf[i++] = ((len) & 0xFF);
+
+ in_state.zip_state.z_stream.total_in = 0;
+ in_state.zip_state.z_stream.total_out = 0;
+ out_state.zip_state.z_stream.total_in = 0;
+ out_state.zip_state.z_stream.total_out = 0;
+
+ ret = check_error(write(CONTROL.fd, ctrl_buf, i), IO_WRITE, CONTROL.fd);
+ if(ret < i)
+ {
+ /* write incomplete, register write cb */
+ CONTROL.write_cb = write_ctrl;
+ /* deregister read_cb */
+ CONTROL.read_cb = NULL;
+ ctrl_ofs = ret;
+ ctrl_len = i - ret;
+ return;
+ }
+#else
+ send_error("can't send_zipstats -- no zlib support!");
+#endif
+}
+
+/* send_error
+ * - we ran into some problem, make a last ditch effort to
+ * flush the control fd sendq, then (blocking) send an
+ * error message over the control fd.
+ */
+void
+send_error(const char *message, ...)
+{
+ va_list args;
+ static int sending_error = 0;
+ struct linger linger_opt = { 1, 30 }; /* wait 30 seconds */
+ int len;
+
+ if(sending_error)
+ exit(1); /* we did _try_ */
+
+ sending_error = 1;
+
+ if(ctrl_len) /* attempt to flush any data we have... */
+ {
+ send_data_blocking(CONTROL.fd, (ctrl_buf + ctrl_ofs), ctrl_len);
+ }
+
+ /* prepare the message, in in_buf, since we won't be using it again.. */
+ in_state.buf[0] = RPL_ERROR;
+ in_state.buf[1] = 0;
+ in_state.buf[2] = 0;
+
+ va_start(args, message);
+ len = vsprintf((char *) in_state.buf + 3, message, args);
+ va_end(args);
+
+ in_state.buf[3 + len++] = '\0';
+ in_state.buf[1] = len >> 8;
+ in_state.buf[2] = len & 0xFF;
+ len += 3;
+
+ send_data_blocking(CONTROL.fd, in_state.buf, len);
+
+ /* XXX - is this portable?
+ * this obviously will fail on a non socket.. */
+ setsockopt(CONTROL.fd, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(struct linger));
+
+ /* well, we've tried... */
+ exit(1); /* now abort */
+}
+
+/* read_ctrl
+ * called when a command is waiting on the control pipe
+ */
+void
+read_ctrl(void)
+{
+ int ret;
+ unsigned char tmp[2];
+ unsigned char *len;
+ struct command_def *cdef;
+ static struct ctrl_command cmd = { 0, 0, 0, 0, NULL };
+
+ if(cmd.command == 0) /* we don't have a command yet */
+ {
+ cmd.gotdatalen = 0;
+ cmd.datalen = 0;
+ cmd.readdata = 0;
+ cmd.data = NULL;
+
+ /* read the command */
+ if(!(ret = check_error(read(CONTROL.fd, tmp, 1), IO_READ, CONTROL.fd)))
+ return;
+
+ cmd.command = tmp[0];
+ }
+
+ for (cdef = command_table; cdef->commandid; cdef++)
+ {
+ if((int)cdef->commandid == cmd.command)
+ break;
+ }
+
+ if(!cdef->commandid)
+ {
+ send_error("Unsupported command (servlink/ircd out of sync?): %d", cmd.command);
+ /* NOTREACHED */
+ }
+
+ /* read datalen for commands including data */
+ if(cdef->flags & COMMAND_FLAG_DATA)
+ {
+ if(cmd.gotdatalen < 2)
+ {
+ len = tmp;
+ if(!(ret = check_error(read(CONTROL.fd, len,
+ (2 - cmd.gotdatalen)), IO_READ, CONTROL.fd)))
+ return;
+
+ if(cmd.gotdatalen == 0)
+ {
+ cmd.datalen = len[0] << 8;
+ cmd.gotdatalen++;
+ ret--;
+ len++;
+ }
+ if(ret && (cmd.gotdatalen == 1))
+ {
+ cmd.datalen |= len[0];
+ cmd.gotdatalen++;
+ if(cmd.datalen > 0)
+ cmd.data = calloc(cmd.datalen, 1);
+ }
+ }
+ }
+
+ if(cmd.readdata < cmd.datalen) /* try to get any remaining data */
+ {
+ if(!(ret = check_error(read(CONTROL.fd,
+ (cmd.data + cmd.readdata),
+ cmd.datalen - cmd.readdata), IO_READ, CONTROL.fd)))
+ return;
+
+ cmd.readdata += ret;
+ if(cmd.readdata < cmd.datalen)
+ return;
+ }
+
+ /* we now have the command and any data */
+ (*cdef->handler) (&cmd);
+
+ if(cmd.datalen > 0)
+ free(cmd.data);
+ cmd.command = 0;
+}
+
+void
+write_ctrl(void)
+{
+ int ret;
+
+ assert(ctrl_len);
+
+ if(!(ret = check_error(write(CONTROL.fd, (ctrl_buf + ctrl_ofs),
+ ctrl_len), IO_WRITE, CONTROL.fd)))
+ return; /* no data waiting */
+
+ ctrl_len -= ret;
+
+ if(!ctrl_len)
+ {
+ /* write completed, de-register write cb */
+ CONTROL.write_cb = NULL;
+ /* reregister read_cb */
+ CONTROL.read_cb = read_ctrl;
+ ctrl_ofs = 0;
+ }
+ else
+ ctrl_ofs += ret;
+}
+
+void
+read_data(void)
+{
+ int ret, ret2;
+ unsigned char *buf = out_state.buf;
+ int blen;
+ ret2 = -1;
+ assert(!out_state.len);
+
+#if defined(HAVE_LIBZ)
+ if(out_state.zip || out_state.crypt)
+ buf = tmp_buf;
+#endif
+
+ while ((ret = check_error(read(LOCAL.fd, buf, READLEN), IO_READ, LOCAL.fd)))
+ {
+ blen = ret;
+#ifdef HAVE_LIBZ
+ if(out_state.zip)
+ {
+ out_state.zip_state.z_stream.next_in = buf;
+ out_state.zip_state.z_stream.avail_in = ret;
+
+ buf = out_state.buf;
+ out_state.zip_state.z_stream.next_out = buf;
+ out_state.zip_state.z_stream.avail_out = BUFLEN;
+ if(!(ret2 = deflate(&out_state.zip_state.z_stream,
+ Z_PARTIAL_FLUSH)) == Z_OK)
+ send_error("error compressing outgoing data - deflate returned: %s",
+ zError(ret2));
+
+ if(!out_state.zip_state.z_stream.avail_out)
+ send_error("error compressing outgoing data - avail_out == 0");
+ if(out_state.zip_state.z_stream.avail_in)
+ send_error("error compressing outgoing data - avail_in != 0");
+
+ blen = BUFLEN - out_state.zip_state.z_stream.avail_out;
+ }
+#endif
+
+
+ ret = check_error(write(REMOTE.fd, out_state.buf, blen), IO_WRITE, REMOTE.fd);
+ if(ret < blen)
+ {
+ /* write incomplete, register write cb */
+ REMOTE.write_cb = write_net;
+ /* deregister read_cb */
+ LOCAL.read_cb = NULL;
+ out_state.ofs = ret;
+ out_state.len = blen - ret;
+ return;
+ }
+#if defined(HAVE_LIBZ)
+ if(out_state.zip)
+ buf = tmp_buf;
+#endif
+ }
+
+}
+
+void
+write_net(void)
+{
+ int ret;
+
+ assert(out_state.len);
+
+ if(!(ret = check_error(write(REMOTE.fd,
+ (out_state.buf + out_state.ofs),
+ out_state.len), IO_WRITE, REMOTE.fd)))
+ return; /* no data waiting */
+
+ out_state.len -= ret;
+
+ if(!out_state.len)
+ {
+ /* write completed, de-register write cb */
+ REMOTE.write_cb = NULL;
+ /* reregister read_cb */
+ LOCAL.read_cb = read_data;
+ out_state.ofs = 0;
+ }
+ else
+ out_state.ofs += ret;
+}
+
+void
+read_net(void)
+{
+ int ret;
+ int ret2;
+ unsigned char *buf = in_state.buf;
+ int blen;
+ ret2 = -1;
+ assert(!in_state.len);
+
+#if defined(HAVE_LIBZ)
+ if(in_state.zip)
+ buf = tmp_buf;
+#endif
+
+ while ((ret = check_error(read(REMOTE.fd, buf, READLEN), IO_READ, REMOTE.fd)))
+ {
+ blen = ret;
+#ifdef HAVE_LIBZ
+ if(in_state.zip)
+ {
+ /* decompress data */
+ in_state.zip_state.z_stream.next_in = buf;
+ in_state.zip_state.z_stream.avail_in = ret;
+ in_state.zip_state.z_stream.next_out = in_state.buf;
+ in_state.zip_state.z_stream.avail_out = BUFLEN;
+
+ while (in_state.zip_state.z_stream.avail_in)
+ {
+ if((ret2 = inflate(&in_state.zip_state.z_stream,
+ Z_NO_FLUSH)) != Z_OK)
+ {
+ if(!strncmp("ERROR ", (char *)buf, 6))
+ send_error("Received uncompressed ERROR");
+ send_error("Inflate failed: %s", zError(ret2));
+ }
+ blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
+
+ if(in_state.zip_state.z_stream.avail_in)
+ {
+ if(blen)
+ {
+ send_data_blocking(LOCAL.fd, in_state.buf, blen);
+ blen = 0;
+ }
+
+ in_state.zip_state.z_stream.next_out = in_state.buf;
+ in_state.zip_state.z_stream.avail_out = BUFLEN;
+ }
+ }
+
+ if(!blen)
+ return; /* that didn't generate any decompressed input.. */
+ }
+#endif
+
+ ret = check_error(write(LOCAL.fd, in_state.buf, blen), IO_WRITE, LOCAL.fd);
+
+ if(ret < blen)
+ {
+ in_state.ofs = ret;
+ in_state.len = blen - ret;
+ /* write incomplete, register write cb */
+ LOCAL.write_cb = write_data;
+ /* deregister read_cb */
+ REMOTE.read_cb = NULL;
+ return;
+ }
+#if defined(HAVE_LIBZ)
+ if(in_state.zip)
+ buf = tmp_buf;
+#endif
+ }
+}
+
+void
+write_data(void)
+{
+ int ret;
+
+ assert(in_state.len);
+
+ if(!(ret = check_error(write(LOCAL.fd,
+ (in_state.buf + in_state.ofs),
+ in_state.len), IO_WRITE, LOCAL.fd)))
+ return;
+
+ in_state.len -= ret;
+
+ if(!in_state.len)
+ {
+ /* write completed, de-register write cb */
+ LOCAL.write_cb = NULL;
+ /* reregister read_cb */
+ REMOTE.read_cb = read_net;
+ in_state.ofs = 0;
+ }
+ else
+ in_state.ofs += ret;
+}
+
+int
+check_error(int ret, int io, int fd)
+{
+ if(ret > 0) /* no error */
+ return ret;
+ if(ret == 0) /* EOF */
+ {
+ send_error("%s failed on %s: EOF", IO_TYPE(io), FD_NAME(fd));
+ exit(1); /* NOTREACHED */
+ }
+
+ /* ret == -1.. */
+ switch (errno)
+ {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+ case EALREADY:
+ case EINTR:
+#ifdef ERESTART
+ case ERESTART:
+#endif
+ /* non-fatal error, 0 bytes read */
+ return 0;
+ }
+
+ /* fatal error */
+ send_error("%s failed on %s: %s", IO_TYPE(io), FD_NAME(fd), strerror(errno));
+ exit(1); /* NOTREACHED */
+}
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/io.h
+ *
+ * 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.
+ *
+ * $Id: io.h 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#ifndef INCLUDED_servlink_io_h
+#define INCLUDED_servlink_io_h
+
+#include "control.h"
+
+#define IO_READ 0
+#define IO_WRITE 1
+#define IO_SELECT 2
+
+#define IO_TYPE(io) ((io==IO_SELECT)?"select": \
+ ((io==IO_WRITE)?"write":"read"))
+
+#define FD_NAME(fd) (fd_name(fd))
+
+extern void io_loop(int nfds);
+extern void write_data(void);
+extern void read_data(void);
+extern void write_ctrl(void);
+extern void read_ctrl(void);
+extern void write_net(void);
+extern void read_net(void);
+extern void send_error(const char *, ...);
+extern void send_data_blocking(int fd, unsigned char *data, int datalen);
+extern cmd_handler process_recvq;
+extern cmd_handler process_sendq;
+extern cmd_handler send_zipstats;
+
+#endif /* INCLUDED_servlink_io_h */
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/servlink.c
+ *
+ * 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.
+ *
+ * $Id: servlink.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "setup.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "servlink.h"
+#include "io.h"
+#include "control.h"
+
+static void usage(void);
+
+struct slink_state in_state;
+struct slink_state out_state;
+
+struct fd_table fds[3] = {
+ {0, read_ctrl, NULL}, /* ctrl */
+ {0, NULL, NULL}, /* data */
+ {0, NULL, NULL}, /* net */
+};
+
+/* usage();
+ *
+ * Display usage message
+ */
+static void
+usage(void)
+{
+ fprintf(stderr, "ircd-ratbox server link v1.2\n");
+ fprintf(stderr, "2004-03-02\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "This program is called by the ircd-ratbox ircd.\n");
+ fprintf(stderr, "It cannot be used on its own.\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int max_fd = 0;
+ int i, x;
+#ifdef SERVLINK_DEBUG
+ int GDBAttached = 0;
+
+ while (!GDBAttached)
+ sleep(1);
+#endif
+
+ /* Make sure we are running under ircd.. */
+
+ if(argc != 4 || strcmp(argv[0], "-slink"))
+ usage(); /* exits */
+
+
+ for (i = 0; i < 3; i++)
+ {
+ fds[i].fd = atoi(argv[i + 1]);
+ if(fds[i].fd < 0)
+ exit(1);
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ /* XXX: Hack alert...we need to do dup2() here for some dumb
+ * platforms (Solaris) that don't like select using fds > 255
+ */
+
+ if(fds[i].fd >= 255)
+ {
+ for(x = 0; x < 255; x++)
+ {
+ if(x != fds[0].fd && x != fds[1].fd && x != fds[2].fd)
+ {
+ if(dup2(fds[i].fd, x) < 0)
+ exit(1);
+ close(fds[i].fd);
+ fds[i].fd = x;
+ break;
+ }
+ }
+ }
+ fcntl(fds[i].fd, F_SETFL, O_NONBLOCK);
+ if(fds[i].fd > max_fd)
+ max_fd = fds[i].fd;
+ }
+
+ /* enter io loop */
+ io_loop(max_fd + 1);
+
+ /* NOTREACHED */
+ return (0);
+} /* main() */
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, servlink/servlink.h
+ *
+ * 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.
+ *
+ * $Id: servlink.h 1285 2006-05-05 15:03:53Z nenolod $
+ */
+
+#ifndef INCLUDED_servlink_servlink_h
+#define INCLUDED_servlink_servlink_h
+
+#include "setup.h"
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+/* do not use stdin/out/err, as it seems to break on solaris */
+#define CONTROL fds[0]
+#define LOCAL fds[1]
+#define REMOTE fds[2]
+
+#undef SERVLINK_DEBUG
+
+#define READLEN 16384
+
+#ifdef HAVE_LIBZ
+#define BUFLEN READLEN * 6 /* allow for decompression */
+#else
+#define BUFLEN READLEN
+#endif
+
+
+#ifdef HAVE_LIBZ
+struct zip_state
+{
+ z_stream z_stream;
+ int level; /* compression level */
+};
+#endif
+
+struct slink_state
+{
+ unsigned int crypt:1;
+ unsigned int zip:1;
+ unsigned int active:1;
+
+ unsigned char buf[BUFLEN * 2];
+ unsigned int ofs;
+ unsigned int len;
+
+#ifdef HAVE_LIBZ
+ struct zip_state zip_state;
+#endif
+};
+
+
+typedef void (io_callback) (void);
+
+struct fd_table
+{
+ int fd;
+ io_callback *read_cb;
+ io_callback *write_cb;
+};
+
+extern struct slink_state in_state;
+extern struct slink_state out_state;
+extern struct fd_table fds[3];
+
+#endif /* INCLUDED_servlink_servlink_h */
--- /dev/null
+Makefile
+y.tab.*
+lex.yy.c
+ircd
+version.c.last
+version.c
--- /dev/null
+cache.o: cache.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/common.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../libcharybdis/tools.h ../include/client.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/event.h ../include/hash.h ../include/cache.h \
+ ../include/sprintf_irc.h
+channel.o: channel.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/hash.h \
+ ../include/hook.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/whowas.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../libcharybdis/event.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h ../include/s_log.h
+chmode.o: chmode.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/hash.h \
+ ../include/hook.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/numeric.h ../include/s_serv.h \
+ ../include/s_user.h ../include/send.h ../include/whowas.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../libcharybdis/event.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h ../include/s_log.h
+class.o: class.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../libcharybdis/tools.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_conf.h ../include/class.h \
+ ../include/patricia.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/send.h ../include/irc_string.h ../libcharybdis/memory.h \
+ ../include/patricia.h
+client.o: client.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../libcharybdis/tools.h ../include/client.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/class.h ../include/common.h \
+ ../libcharybdis/event.h ../include/hash.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../include/s_gline.h \
+ ../include/numeric.h ../include/packet.h ../include/s_auth.h \
+ ../libcharybdis/commio.h ../include/s_conf.h ../include/class.h \
+ ../include/patricia.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_log.h ../include/s_serv.h ../include/s_stats.h \
+ ../include/send.h ../include/whowas.h ../include/s_user.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/memory.h \
+ ../include/hostmask.h ../libcharybdis/balloc.h ../include/listener.h \
+ ../include/hook.h ../include/msg.h ../include/monitor.h
+getopt.o: getopt.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_getopt.h
+hash.o: hash.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/ircd_defs.h ../include/send.h ../libcharybdis/tools.h \
+ ../include/s_conf.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/patricia.h ../include/numeric.h ../include/channel.h \
+ ../include/client.h ../include/common.h ../include/hash.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/send.h ../libcharybdis/memory.h ../include/msg.h \
+ ../include/cache.h ../include/s_newconf.h
+hook.o: hook.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/tools.h ../include/hook.h \
+ ../include/irc_string.h
+hostmask.o: hostmask.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/s_conf.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../include/snomask.h ../include/patricia.h ../include/numeric.h \
+ ../include/hostmask.h ../include/numeric.h ../include/send.h \
+ ../include/irc_string.h
+irc_string.o: irc_string.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/sprintf_irc.h \
+ ../libcharybdis/tools.h ../include/irc_string.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/client.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/setup.h ../include/config.h ../include/ircd_defs.h \
+ ../include/reslib.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../libcharybdis/memory.h ../include/setup.h
+ircd.o: ircd.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../include/setup.h ../include/config.h \
+ ../libcharybdis/tools.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/ircd_defs.h ../include/send.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/channel.h ../include/class.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../libcharybdis/event.h \
+ ../include/hash.h ../include/irc_string.h ../include/ircd_signal.h \
+ ../include/sprintf_irc.h ../include/s_gline.h ../include/msg.h \
+ ../include/hostmask.h ../include/numeric.h ../include/parse.h \
+ ../include/res.h ../include/restart.h ../include/s_auth.h \
+ ../libcharybdis/commio.h ../include/s_conf.h ../include/class.h \
+ ../include/patricia.h ../include/numeric.h ../include/s_log.h \
+ ../include/s_serv.h ../include/s_user.h ../include/s_stats.h \
+ ../include/scache.h ../include/send.h ../include/whowas.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../libcharybdis/memory.h ../include/hook.h \
+ ../include/ircd_getopt.h ../libcharybdis/balloc.h ../include/newconf.h \
+ ../include/patricia.h ../include/reject.h ../include/s_newconf.h \
+ ../include/cache.h ../include/monitor.h ../libcharybdis/libcharybdis.h \
+ ../include/stdinc.h ../include/res.h ../include/numeric.h \
+ ../libcharybdis/linebuf.h ../include/sprintf_irc.h \
+ ../libcharybdis/commio.h ../libcharybdis/event.h \
+ ../include/patchlevel.h ../include/serno.h
+ircd_signal.o: ircd_signal.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_signal.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/restart.h \
+ ../include/s_log.h ../libcharybdis/memory.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/s_conf.h ../include/class.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/reslib.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/client.h ../include/send.h
+ircd_state.o: ircd_state.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/setup.h \
+ ../include/config.h ../include/client.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../libcharybdis/tools.h ../include/ircd.h \
+ ../include/channel.h ../include/class.h ../include/common.h \
+ ../libcharybdis/event.h ../include/hash.h ../include/irc_string.h \
+ ../include/ircd_signal.h ../include/sprintf_irc.h ../include/s_gline.h \
+ ../include/msg.h ../include/hostmask.h ../include/numeric.h \
+ ../include/parse.h ../include/res.h ../include/restart.h \
+ ../include/s_auth.h ../libcharybdis/commio.h ../include/s_conf.h \
+ ../include/class.h ../include/patricia.h ../include/numeric.h \
+ ../include/s_log.h ../include/s_serv.h ../include/s_user.h \
+ ../include/s_stats.h ../include/scache.h ../include/send.h \
+ ../include/whowas.h ../include/modules.h ../include/parse.h \
+ ../include/msg.h ../include/hook.h ../libcharybdis/memory.h \
+ ../include/hook.h ../include/ircd_getopt.h ../libcharybdis/balloc.h \
+ ../include/newconf.h ../include/patricia.h ../include/reject.h \
+ ../include/s_newconf.h ../include/cache.h ../include/monitor.h \
+ ../libcharybdis/libcharybdis.h ../include/stdinc.h ../include/res.h \
+ ../include/numeric.h ../libcharybdis/linebuf.h ../include/sprintf_irc.h \
+ ../libcharybdis/commio.h ../libcharybdis/event.h \
+ ../include/patchlevel.h ../include/serno.h
+kdparse.o: kdparse.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/hostmask.h \
+ ../include/client.h ../include/irc_string.h ../libcharybdis/memory.h \
+ ../include/hash.h
+listener.o: listener.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/setup.h \
+ ../include/listener.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/ircd_defs.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/s_conf.h ../include/class.h \
+ ../include/patricia.h ../include/numeric.h ../include/s_newconf.h \
+ ../include/s_stats.h ../include/send.h ../libcharybdis/memory.h \
+ ../include/s_auth.h ../include/reject.h
+match.o: match.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../include/ircd.h ../include/irc_string.h
+modules.o: modules.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/modules.h \
+ ../include/parse.h ../libcharybdis/tools.h ../include/msg.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/ircd_defs.h ../include/send.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/hook.h ../include/s_log.h \
+ ../include/ircd.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../include/snomask.h ../include/client.h ../include/send.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/numeric.h \
+ ../include/parse.h ../include/ircd_defs.h ../include/irc_string.h \
+ ../libcharybdis/memory.h ../libcharybdis/tools.h \
+ ../include/sprintf_irc.h
+monitor.o: monitor.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h ../include/monitor.h \
+ ../include/hash.h ../libcharybdis/event.h ../include/numeric.h
+newconf.o: newconf.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/newconf.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../libcharybdis/tools.h \
+ ../include/ircd_defs.h ../include/sprintf_irc.h ../include/common.h \
+ ../include/s_log.h ../include/s_conf.h ../include/class.h \
+ ../include/patricia.h ../include/numeric.h ../include/s_user.h \
+ ../include/s_newconf.h ../include/send.h ../include/setup.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/listener.h ../include/hostmask.h \
+ ../include/s_serv.h ../libcharybdis/event.h ../include/hash.h \
+ ../include/cache.h ../include/ircd.h ../include/snomask.h
+numeric.o: numeric.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/setup.h \
+ ../include/config.h ../include/s_conf.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/numeric.h ../include/irc_string.h \
+ ../include/common.h ../libcharybdis/memory.h messages.tab
+packet.o: packet.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_serv.h ../include/client.h \
+ ../include/common.h ../include/ircd.h ../include/parse.h \
+ ../include/packet.h ../include/irc_string.h ../libcharybdis/memory.h \
+ ../include/hook.h ../include/send.h
+parse.o: parse.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/parse.h \
+ ../libcharybdis/tools.h ../include/client.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../include/channel.h ../include/common.h ../include/hash.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../include/numeric.h ../include/s_log.h ../include/s_stats.h \
+ ../include/send.h ../include/msg.h ../include/s_conf.h \
+ ../include/class.h ../include/patricia.h ../include/numeric.h \
+ ../libcharybdis/memory.h ../include/s_serv.h
+patricia.o: patricia.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/ircd_defs.h \
+ ../include/send.h ../include/patricia.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/numeric.h \
+ ../libcharybdis/balloc.h
+res.o: res.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/ircd_defs.h ../include/send.h ../include/common.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../include/ircd_defs.h ../include/setup.h ../libcharybdis/balloc.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/commio.h ../include/config.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../include/reslib.h ../libcharybdis/tools.h ../libcharybdis/event.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/numeric.h
+reslib.o: reslib.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/common.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/ircd_defs.h ../include/setup.h \
+ ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/commio.h ../include/config.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/reslib.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/reslib.h ../libcharybdis/tools.h \
+ ../libcharybdis/event.h ../include/irc_string.h \
+ ../include/sprintf_irc.h
+reject.o: reject.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../include/patricia.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/numeric.h ../include/client.h ../include/s_conf.h \
+ ../include/patricia.h ../libcharybdis/event.h ../libcharybdis/tools.h \
+ ../include/reject.h ../include/s_stats.h ../include/msg.h
+restart.o: restart.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/restart.h ../include/common.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/setup.h ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/send.h ../include/s_log.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/config.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../include/snomask.h \
+ ../include/client.h ../libcharybdis/memory.h
+s_auth.o: s_auth.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/config.h \
+ ../libcharybdis/tools.h ../include/s_auth.h ../include/res.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../include/s_conf.h ../include/class.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../include/channel.h \
+ ../include/snomask.h ../include/patricia.h ../include/numeric.h \
+ ../include/client.h ../include/common.h ../libcharybdis/event.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../include/numeric.h ../include/packet.h ../include/res.h \
+ ../libcharybdis/commio.h ../include/s_log.h ../include/s_stats.h \
+ ../include/send.h ../libcharybdis/memory.h ../include/hook.h
+s_conf.o: s_conf.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../libcharybdis/tools.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/s_serv.h \
+ ../include/s_stats.h ../include/channel.h ../include/class.h \
+ ../include/client.h ../include/common.h ../libcharybdis/event.h \
+ ../include/hash.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/listener.h ../include/hostmask.h \
+ ../include/modules.h ../include/parse.h ../include/msg.h \
+ ../include/hook.h ../include/numeric.h ../libcharybdis/commio.h \
+ ../include/s_log.h ../include/send.h ../include/s_gline.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h ../include/patricia.h \
+ ../include/reject.h ../include/cache.h
+s_newconf.o: s_newconf.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/common.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/memory.h ../include/s_serv.h \
+ ../include/send.h ../include/hostmask.h ../include/newconf.h \
+ ../include/hash.h ../libcharybdis/balloc.h ../libcharybdis/event.h \
+ ../include/sprintf_irc.h
+s_gline.o: s_gline.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/config.h \
+ ../include/irc_string.h ../include/ircd.h ../include/hostmask.h \
+ ../include/numeric.h ../libcharybdis/commio.h ../include/s_conf.h \
+ ../include/class.h ../include/patricia.h ../include/numeric.h \
+ ../include/scache.h ../include/send.h ../include/msg.h \
+ ../include/s_serv.h ../include/s_gline.h ../include/hash.h \
+ ../libcharybdis/event.h ../libcharybdis/memory.h
+s_log.o: s_log.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/ircd_defs.h ../include/send.h \
+ ../include/s_log.h ../include/s_conf.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/patricia.h \
+ ../include/numeric.h ../include/sprintf_irc.h ../include/send.h \
+ ../include/client.h ../include/s_serv.h
+s_serv.o: s_serv.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/s_serv.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../libcharybdis/event.h \
+ ../include/hash.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../include/ircd_defs.h ../include/numeric.h \
+ ../include/packet.h ../include/res.h ../libcharybdis/commio.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/s_log.h \
+ ../include/s_stats.h ../include/s_user.h ../include/scache.h \
+ ../include/send.h ../libcharybdis/memory.h ../include/channel.h \
+ ../include/hook.h ../include/msg.h
+s_stats.o: s_stats.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/s_stats.h \
+ ../include/client.h ../include/ircd_defs.h ../include/s_log.h \
+ ../include/send.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../libcharybdis/commio.h ../include/send.h ../libcharybdis/memory.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/whowas.h \
+ ../include/hash.h ../include/scache.h ../include/reject.h
+s_user.o: s_user.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../libcharybdis/tools.h \
+ ../include/s_user.h ../include/channel.h ../include/ircd_defs.h \
+ ../include/s_log.h ../include/send.h ../include/class.h \
+ ../libcharybdis/tools.h ../include/client.h ../libcharybdis/linebuf.h \
+ ../libcharybdis/tools.h ../include/channel.h ../include/res.h \
+ ../include/common.h ../libcharybdis/commio.h ../include/setup.h \
+ ../include/config.h ../include/ircd_defs.h ../include/reslib.h \
+ ../include/irc_string.h ../include/sprintf_irc.h ../include/ircd.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/hash.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../include/listener.h \
+ ../include/msg.h ../include/numeric.h ../libcharybdis/commio.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../include/s_newconf.h ../include/s_log.h \
+ ../include/s_serv.h ../include/s_stats.h ../include/scache.h \
+ ../include/send.h ../include/supported.h ../include/whowas.h \
+ ../libcharybdis/memory.h ../include/packet.h ../include/reject.h \
+ ../include/cache.h ../include/hook.h ../include/monitor.h \
+ ../include/snomask.h
+scache.o: scache.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/setup.h ../include/config.h ../include/ircd_defs.h \
+ ../include/reslib.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../include/send.h \
+ ../include/scache.h ../libcharybdis/memory.h
+send.o: send.c ../include/stdinc.h ../include/config.h ../include/setup.h \
+ ../include/defaults.h ../libcharybdis/tools.h ../include/send.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../include/channel.h ../include/class.h ../libcharybdis/tools.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/common.h ../include/irc_string.h \
+ ../include/ircd.h ../include/numeric.h ../libcharybdis/commio.h \
+ ../include/s_serv.h ../include/sprintf_irc.h ../include/s_conf.h \
+ ../include/class.h ../include/patricia.h ../include/numeric.h \
+ ../include/s_newconf.h ../libcharybdis/linebuf.h ../include/s_log.h \
+ ../libcharybdis/memory.h ../include/hook.h
+snomask.o: snomask.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/client.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../libcharybdis/linebuf.h ../libcharybdis/tools.h ../include/channel.h \
+ ../include/res.h ../include/common.h ../libcharybdis/commio.h \
+ ../include/setup.h ../include/config.h ../include/ircd_defs.h \
+ ../include/reslib.h ../include/irc_string.h ../include/sprintf_irc.h \
+ ../include/ircd.h ../libcharybdis/tools.h ../libcharybdis/memory.h \
+ ../libcharybdis/balloc.h ../libcharybdis/memory.h ../include/snomask.h \
+ ../include/client.h ../include/snomask.h
+whowas.o: whowas.c ../include/stdinc.h ../include/config.h \
+ ../include/setup.h ../include/defaults.h ../include/whowas.h \
+ ../include/ircd_defs.h ../include/s_log.h ../include/send.h \
+ ../include/client.h ../libcharybdis/linebuf.h ../libcharybdis/tools.h \
+ ../include/channel.h ../include/res.h ../include/common.h \
+ ../libcharybdis/commio.h ../include/setup.h ../include/config.h \
+ ../include/ircd_defs.h ../include/reslib.h ../include/irc_string.h \
+ ../include/sprintf_irc.h ../include/ircd.h ../libcharybdis/tools.h \
+ ../libcharybdis/memory.h ../libcharybdis/balloc.h \
+ ../libcharybdis/memory.h ../include/snomask.h ../include/client.h \
+ ../include/common.h ../include/hash.h ../include/irc_string.h \
+ ../include/ircd.h ../include/ircd_defs.h ../include/numeric.h \
+ ../include/s_serv.h ../include/s_user.h ../include/send.h \
+ ../include/s_conf.h ../include/class.h ../include/patricia.h \
+ ../include/numeric.h ../libcharybdis/memory.h
--- /dev/null
+/* $Id: .indent.pro 813 2006-02-14 20:52:15Z nenolod $ */
+
+/* copy this file to the source dir then run indent file.c */
+
+--gnu-style
+
+/* This is the indent before the brace not inside the block. */
+--brace-indent0
+
+/* Indent case: by 2 and braces inside case by 0(then by 0)... */
+--case-brace-indentation0
+--case-indentation2
+
+--indent-level8
+
+/* Put while() on the brace from do... */
+--cuddle-do-while
+
+/* Disable an annoying format... */
+--no-space-after-function-call-names
+
+/* Disable an annoying format... */
+--dont-break-procedure-type
+
+/* Disable an annoying format... */
+--no-space-after-casts
+
+--line-length100
+
+/* typedefs */
+-T boolean_t
+-T node_t
+-T list_t
+-T tld_t
+-T kline_t
+-T EVH
+-T sra_t
+-T server_t
+-T user_t
+-T channel_t
+-T chanuser_t
+-T myuser_t
+-T mychan_t
+-T chanacs_t
+-T CONFIGENTRY
+-T CONFIGFILE
+-T Block
+-T MemBlock
+-T BlockHeap
--- /dev/null
+#
+# Makefile.in for ircd/src
+#
+# $Id: Makefile.in 1887 2006-08-29 13:42:56Z jilles $
+#
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_BIN = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+RM = @RM@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+PICFLAGS = @PICFLAGS@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+LDFLAGS = @LDFLAGS@
+MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
+MV = @MV@
+RM = @RM@
+YACC = @YACC@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+
+FNVHASH_S = @FNVHASH_S@
+
+DOLLAR = $$
+
+IRCD_EXE = ircd
+
+PROGS = $(IRCD_EXE)
+
+SSL_LIBS = @SSL_LIBS@
+SSL_INCLUDES = @SSL_INCLUDES@
+
+IRCDLIBS = @MODULES_LIBS@ -L../libcharybdis -lcharybdis @LIBS@ $(SSL_LIBS)
+
+INCLUDES = -I../include -I../libcharybdis $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+default: all
+
+y.tab.o: y.tab.c ircd_parser.y
+ ${CC} ${CPPFLAGS} ${PICFLAGS} ${CFLAGS} -I. -c y.tab.c
+
+# Note GNU bison uses <file>.tab.c not y.tab.c
+y.tab.c: ircd_parser.y
+ ${YACC} -d ircd_parser.y
+
+lex.yy.o: lex.yy.c ircd_lexer.l
+ ${CC} ${CPPFLAGS} ${PICFLAGS} ${CFLAGS} -I. -c lex.yy.c
+
+lex.yy.c: ircd_lexer.l
+ ${LEX} ircd_lexer.l
+
+BASE_SRCS = \
+ blacklist.c \
+ cache.c \
+ channel.c \
+ chmode.c \
+ class.c \
+ client.c \
+ extban.c \
+ getopt.c \
+ hash.c \
+ hook.c \
+ hostmask.c \
+ irc_string.c \
+ ircd.c \
+ ircd_signal.c \
+ ircd_state.c \
+ kdparse.c \
+ listener.c \
+ match.c \
+ modules.c \
+ monitor.c \
+ newconf.c \
+ numeric.c \
+ packet.c \
+ parse.c \
+ patricia.c \
+ res.c \
+ reslib.c \
+ reject.c \
+ restart.c \
+ s_auth.c \
+ s_conf.c \
+ s_newconf.c \
+ s_gline.c \
+ s_log.c \
+ s_serv.c \
+ s_stats.c \
+ s_user.c \
+ scache.c \
+ send.c \
+ snomask.c \
+ supported.c \
+ whowas.c \
+ $(FNVHASH_S)
+
+SRCS = ${BASE_SRCS:.s=.o}
+
+OBJS = ${SRCS:.c=.o}
+
+all: ircd
+
+build: all
+
+ircd: $(OBJS) y.tab.o lex.yy.o version.o
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJS} lex.yy.o y.tab.o version.o ${IRCDLIBS} ${LEXLIB}
+ mv version.c version.c.last
+
+install-mkdirs:
+ -@if test ! -d $(DESTDIR)$(prefix); then \
+ echo "ircd: setting up ircd directory structure"; \
+ mkdir $(DESTDIR)$(prefix); \
+ fi
+ -@if test ! -d $(DESTDIR)$(exec_prefix); then \
+ mkdir $(DESTDIR)$(exec_prefix); \
+ fi
+ -@if test ! -d $(DESTDIR)$(bindir); then \
+ mkdir $(DESTDIR)$(bindir); \
+ fi
+ -@if test ! -d $(DESTDIR)$(libdir); then \
+ mkdir $(DESTDIR)$(libdir); \
+ fi
+
+install: install-mkdirs build
+ -@if test -f $(DESTDIR)$(bindir)/ircd; then \
+ echo "ircd: backing up ircd"; \
+ fi
+ @echo "ircd: installing ircd ($(PROGS))"
+ @for i in $(PROGS); do \
+ if test -f $(DESTDIR)$(bindir)/$$i; then \
+ $(MV) $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.old; \
+ fi; \
+ $(INSTALL_BIN) $$i $(DESTDIR)$(bindir); \
+ done
+
+version.c: version.c.SH
+ /bin/sh ./version.c.SH
+
+
+# this is really the default rule for c files
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $<
+.s.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $<
+
+.PHONY: depend clean distclean
+depend:
+ ${MKDEP} ${CPPFLAGS} ${BASE_SRCS} > .depend
+
+clean:
+ ${RM} -f *.o *.exe *~ y.tab.* lex.yy.c ircd.core core ircd
+
+lint:
+ lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(SRCS) >>../lint.out
+
+distclean: clean
+ ${RM} -f Makefile version.c.last
+
+include .depend
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * blacklist.c: Manages DNS blacklist entries and lookups
+ *
+ * Copyright (C) 2006 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: blacklist.c 2743 2006-11-10 15:15:00Z jilles $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "res.h"
+#include "tools.h"
+#include "memory.h"
+#include "numeric.h"
+#include "reject.h"
+#include "s_conf.h"
+#include "s_user.h"
+#include "blacklist.h"
+
+dlink_list blacklist_list = { NULL, NULL, 0 };
+
+/* private interfaces */
+static struct Blacklist *find_blacklist(char *name)
+{
+ dlink_node *nptr;
+
+ DLINK_FOREACH(nptr, blacklist_list.head)
+ {
+ struct Blacklist *blptr = (struct Blacklist *) nptr->data;
+
+ if (!irccmp(blptr->host, name))
+ return blptr;
+ }
+
+ return NULL;
+}
+
+static void blacklist_dns_callback(void *vptr, struct DNSReply *reply)
+{
+ struct BlacklistClient *blcptr = (struct BlacklistClient *) vptr;
+
+ if (blcptr == NULL || blcptr->client_p == NULL)
+ return;
+
+ if (blcptr->client_p->preClient == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "blacklist_dns_callback(): blcptr->client_p->preClient (%s) is NULL", get_client_name(blcptr->client_p, HIDE_IP));
+ MyFree(blcptr);
+ return;
+ }
+
+ /* they have a blacklist entry for this client */
+ if (reply != NULL && blcptr->client_p->preClient->dnsbl_listed == NULL)
+ {
+ blcptr->client_p->preClient->dnsbl_listed = blcptr->blacklist;
+ /* reference to blacklist moves from blcptr to client_p->preClient... */
+ }
+ else
+ unref_blacklist(blcptr->blacklist);
+
+ dlinkDelete(&blcptr->node, &blcptr->client_p->preClient->dnsbl_queries);
+
+ /* yes, it can probably happen... */
+ if (dlink_list_length(&blcptr->client_p->preClient->dnsbl_queries) == 0 && blcptr->client_p->flags & FLAGS_SENTUSER && !EmptyString(blcptr->client_p->name))
+ {
+ char buf[USERLEN + 1];
+ strlcpy(buf, blcptr->client_p->username, sizeof buf);
+ register_local_user(blcptr->client_p, blcptr->client_p, buf);
+ }
+
+ MyFree(blcptr);
+}
+
+/* XXX: no IPv6 implementation, not to concerned right now though. */
+static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *client_p)
+{
+ struct BlacklistClient *blcptr = MyMalloc(sizeof(struct BlacklistClient));
+ char buf[IRCD_BUFSIZE];
+ int ip[4];
+
+ blcptr->blacklist = blptr;
+ blcptr->client_p = client_p;
+
+ blcptr->dns_query.ptr = blcptr;
+ blcptr->dns_query.callback = blacklist_dns_callback;
+
+ /* XXX: yes I know this is bad, I don't really care right now */
+ sscanf(client_p->sockhost, "%d.%d.%d.%d", &ip[3], &ip[2], &ip[1], &ip[0]);
+
+ /* becomes 2.0.0.127.torbl.ahbl.org or whatever */
+ ircsnprintf(buf, IRCD_BUFSIZE, "%d.%d.%d.%d.%s", ip[0], ip[1], ip[2], ip[3], blptr->host);
+
+ gethost_byname_type(buf, &blcptr->dns_query, T_A);
+
+ dlinkAdd(blcptr, &blcptr->node, &client_p->preClient->dnsbl_queries);
+ blptr->refcount++;
+}
+
+/* public interfaces */
+struct Blacklist *new_blacklist(char *name, char *reject_reason)
+{
+ struct Blacklist *blptr;
+
+ if (name == NULL || reject_reason == NULL)
+ return NULL;
+
+ blptr = find_blacklist(name);
+ if (blptr == NULL)
+ {
+ blptr = MyMalloc(sizeof(struct Blacklist));
+ dlinkAddAlloc(blptr, &blacklist_list);
+ }
+ else
+ blptr->status &= ~CONF_ILLEGAL;
+ strlcpy(blptr->host, name, HOSTLEN);
+ strlcpy(blptr->reject_reason, reject_reason, IRCD_BUFSIZE);
+
+ return blptr;
+}
+
+void unref_blacklist(struct Blacklist *blptr)
+{
+ blptr->refcount--;
+ if (blptr->status & CONF_ILLEGAL && blptr->refcount <= 0)
+ {
+ dlinkFindDestroy(blptr, &blacklist_list);
+ MyFree(blptr);
+ }
+}
+
+void lookup_blacklists(struct Client *client_p)
+{
+ dlink_node *nptr;
+
+ /* We don't do IPv6 right now, sorry! */
+ if (client_p->localClient->ip.ss_family == AF_INET6)
+ return;
+
+ DLINK_FOREACH(nptr, blacklist_list.head)
+ {
+ struct Blacklist *blptr = (struct Blacklist *) nptr->data;
+
+ if (!(blptr->status & CONF_ILLEGAL))
+ initiate_blacklist_dnsquery(blptr, client_p);
+ }
+}
+
+void abort_blacklist_queries(struct Client *client_p)
+{
+ dlink_node *ptr, *next_ptr;
+ struct BlacklistClient *blcptr;
+
+ if (client_p->preClient == NULL)
+ return;
+ DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->preClient->dnsbl_queries.head)
+ {
+ blcptr = ptr->data;
+ dlinkDelete(&blcptr->node, &client_p->preClient->dnsbl_queries);
+ unref_blacklist(blcptr->blacklist);
+ delete_resolver_queries(&blcptr->dns_query);
+ MyFree(blcptr);
+ }
+}
+
+void destroy_blacklists(void)
+{
+ dlink_node *ptr, *next_ptr;
+ struct Blacklist *blptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, blacklist_list.head)
+ {
+ blptr = ptr->data;
+ blptr->hits = 0; /* keep it simple and consistent */
+ if (blptr->refcount > 0)
+ blptr->status |= CONF_ILLEGAL;
+ else
+ {
+ MyFree(ptr->data);
+ dlinkDestroy(ptr, &blacklist_list);
+ }
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * cache.c - code for caching files
+ *
+ * Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2003-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: cache.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "common.h"
+#include "s_conf.h"
+#include "tools.h"
+#include "client.h"
+#include "memory.h"
+#include "balloc.h"
+#include "event.h"
+#include "hash.h"
+#include "cache.h"
+#include "sprintf_irc.h"
+
+static BlockHeap *cachefile_heap = NULL;
+static BlockHeap *cacheline_heap = NULL;
+
+struct cachefile *user_motd = NULL;
+struct cachefile *oper_motd = NULL;
+struct cacheline *emptyline = NULL;
+dlink_list links_cache_list;
+char user_motd_changed[MAX_DATE_STRING];
+
+/* init_cache()
+ *
+ * inputs -
+ * outputs -
+ * side effects - inits the file/line cache blockheaps, loads motds
+ */
+void
+init_cache(void)
+{
+ cachefile_heap = BlockHeapCreate(sizeof(struct cachefile), CACHEFILE_HEAP_SIZE);
+ cacheline_heap = BlockHeapCreate(sizeof(struct cacheline), CACHELINE_HEAP_SIZE);
+
+ /* allocate the emptyline */
+ emptyline = BlockHeapAlloc(cacheline_heap);
+ emptyline->data[0] = ' ';
+ emptyline->data[1] = '\0';
+ user_motd_changed[0] = '\0';
+
+ user_motd = cache_file(MPATH, "ircd.motd", 0);
+ oper_motd = cache_file(OPATH, "opers.motd", 0);
+ memset(&links_cache_list, 0, sizeof(links_cache_list));
+}
+
+/* cache_file()
+ *
+ * inputs - file to cache, files "shortname", flags to set
+ * outputs - pointer to file cached, else NULL
+ * side effects -
+ */
+struct cachefile *
+cache_file(const char *filename, const char *shortname, int flags)
+{
+ FILE *in;
+ struct cachefile *cacheptr;
+ struct cacheline *lineptr;
+ char line[BUFSIZE];
+ char *p;
+
+ if((in = fopen(filename, "r")) == NULL)
+ return NULL;
+
+ if(strcmp(shortname, "ircd.motd") == 0)
+ {
+ struct stat sb;
+ struct tm *local_tm;
+
+ if(fstat(fileno(in), &sb) < 0)
+ return NULL;
+
+ local_tm = localtime(&sb.st_mtime);
+
+ if(local_tm != NULL)
+ ircsnprintf(user_motd_changed, sizeof(user_motd_changed),
+ "%d/%d/%d %d:%d",
+ local_tm->tm_mday, local_tm->tm_mon + 1,
+ 1900 + local_tm->tm_year, local_tm->tm_hour,
+ local_tm->tm_min);
+ }
+
+ cacheptr = BlockHeapAlloc(cachefile_heap);
+
+ strlcpy(cacheptr->name, shortname, sizeof(cacheptr->name));
+ cacheptr->flags = flags;
+
+ /* cache the file... */
+ while(fgets(line, sizeof(line), in) != NULL)
+ {
+ if((p = strchr(line, '\n')) != NULL)
+ *p = '\0';
+
+ if(!EmptyString(line))
+ {
+ lineptr = BlockHeapAlloc(cacheline_heap);
+ strlcpy(lineptr->data, line, sizeof(lineptr->data));
+ dlinkAddTail(lineptr, &lineptr->linenode, &cacheptr->contents);
+ }
+ else
+ dlinkAddTailAlloc(emptyline, &cacheptr->contents);
+ }
+
+ fclose(in);
+ return cacheptr;
+}
+
+void
+cache_links(void *unused)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ char *links_line;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, links_cache_list.head)
+ {
+ MyFree(ptr->data);
+ free_dlink_node(ptr);
+ }
+
+ links_cache_list.head = links_cache_list.tail = NULL;
+ links_cache_list.length = 0;
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ /* skip ourselves (done in /links) and hidden servers */
+ if(IsMe(target_p) ||
+ (IsHidden(target_p) && !ConfigServerHide.disable_hidden))
+ continue;
+
+ /* if the below is ever modified, change LINKSLINELEN */
+ links_line = MyMalloc(LINKSLINELEN);
+ ircsnprintf(links_line, LINKSLINELEN, "%s %s :1 %s",
+ target_p->name, me.name,
+ target_p->info[0] ? target_p->info :
+ "(Unknown Location)");
+
+ dlinkAddTailAlloc(links_line, &links_cache_list);
+ }
+}
+
+/* free_cachefile()
+ *
+ * inputs - cachefile to free
+ * outputs -
+ * side effects - cachefile and its data is free'd
+ */
+void
+free_cachefile(struct cachefile *cacheptr)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(cacheptr == NULL)
+ return;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, cacheptr->contents.head)
+ {
+ if(ptr->data != emptyline)
+ BlockHeapFree(cacheline_heap, ptr->data);
+ }
+
+ BlockHeapFree(cachefile_heap, cacheptr);
+}
+
+/* load_help()
+ *
+ * inputs -
+ * outputs -
+ * side effects - contents of help directories are loaded.
+ */
+void
+load_help(void)
+{
+ DIR *helpfile_dir = NULL;
+ struct dirent *ldirent= NULL;
+ char filename[MAXPATHLEN];
+ struct cachefile *cacheptr;
+
+#if defined(S_ISLNK) && defined(HAVE_LSTAT)
+ struct stat sb;
+#endif
+
+ /* opers must be done first */
+ helpfile_dir = opendir(HPATH);
+
+ if(helpfile_dir == NULL)
+ return;
+
+ while((ldirent = readdir(helpfile_dir)) != NULL)
+ {
+ ircsnprintf(filename, sizeof(filename), "%s/%s", HPATH, ldirent->d_name);
+ cacheptr = cache_file(filename, ldirent->d_name, HELP_OPER);
+ add_to_help_hash(cacheptr->name, cacheptr);
+ }
+
+ closedir(helpfile_dir);
+ helpfile_dir = opendir(UHPATH);
+
+ if(helpfile_dir == NULL)
+ return;
+
+ while((ldirent = readdir(helpfile_dir)) != NULL)
+ {
+ ircsnprintf(filename, sizeof(filename), "%s/%s", UHPATH, ldirent->d_name);
+
+#if defined(S_ISLNK) && defined(HAVE_LSTAT)
+ if(lstat(filename, &sb) < 0)
+ continue;
+
+ /* ok, if its a symlink, we work on the presumption if an
+ * oper help exists of that name, its a symlink to that --fl
+ */
+ if(S_ISLNK(sb.st_mode))
+ {
+ cacheptr = hash_find_help(ldirent->d_name, HELP_OPER);
+
+ if(cacheptr != NULL)
+ {
+ cacheptr->flags |= HELP_USER;
+ continue;
+ }
+ }
+#endif
+
+ cacheptr = cache_file(filename, ldirent->d_name, HELP_USER);
+ add_to_help_hash(cacheptr->name, cacheptr);
+ }
+
+ closedir(helpfile_dir);
+}
+
+/* send_user_motd()
+ *
+ * inputs - client to send motd to
+ * outputs - client is sent motd if exists, else ERR_NOMOTD
+ * side effects -
+ */
+void
+send_user_motd(struct Client *source_p)
+{
+ struct cacheline *lineptr;
+ dlink_node *ptr;
+ const char *myname = get_id(&me, source_p);
+ const char *nick = get_id(source_p, source_p);
+
+ if(user_motd == NULL || dlink_list_length(&user_motd->contents) == 0)
+ {
+ sendto_one(source_p, form_str(ERR_NOMOTD), myname, nick);
+ return;
+ }
+
+ sendto_one(source_p, form_str(RPL_MOTDSTART), myname, nick, me.name);
+
+ DLINK_FOREACH(ptr, user_motd->contents.head)
+ {
+ lineptr = ptr->data;
+ sendto_one(source_p, form_str(RPL_MOTD), myname, nick, lineptr->data);
+ }
+
+ sendto_one(source_p, form_str(RPL_ENDOFMOTD), myname, nick);
+}
+
+/* send_oper_motd()
+ *
+ * inputs - client to send motd to
+ * outputs - client is sent oper motd if exists
+ * side effects -
+ */
+void
+send_oper_motd(struct Client *source_p)
+{
+ struct cacheline *lineptr;
+ dlink_node *ptr;
+
+ if(oper_motd == NULL || dlink_list_length(&oper_motd->contents) == 0)
+ return;
+
+ sendto_one(source_p, form_str(RPL_OMOTDSTART),
+ me.name, source_p->name);
+
+ DLINK_FOREACH(ptr, oper_motd->contents.head)
+ {
+ lineptr = ptr->data;
+ sendto_one(source_p, form_str(RPL_OMOTD),
+ me.name, source_p->name, lineptr->data);
+ }
+
+ sendto_one(source_p, form_str(RPL_ENDOFOMOTD),
+ me.name, source_p->name);
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * channel.c: Controls channels.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: channel.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "hook.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h" /* captab */
+#include "s_user.h"
+#include "send.h"
+#include "whowas.h"
+#include "s_conf.h" /* ConfigFileEntry, ConfigChannel */
+#include "s_newconf.h"
+#include "event.h"
+#include "memory.h"
+#include "balloc.h"
+#include "s_log.h"
+
+extern dlink_list global_channel_list;
+
+extern struct config_channel_entry ConfigChannel;
+extern BlockHeap *channel_heap;
+extern BlockHeap *ban_heap;
+extern BlockHeap *topic_heap;
+extern BlockHeap *member_heap;
+
+static int channel_capabs[] = { CAP_EX, CAP_IE,
+ CAP_SERVICE,
+ CAP_TS6
+};
+
+#define NCHCAPS (sizeof(channel_capabs)/sizeof(int))
+#define NCHCAP_COMBOS (1 << NCHCAPS)
+
+static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
+
+static void free_topic(struct Channel *chptr);
+
+static int h_can_join;
+
+/* init_channels()
+ *
+ * input -
+ * output -
+ * side effects - initialises the various blockheaps
+ */
+void
+init_channels(void)
+{
+ channel_heap = BlockHeapCreate(sizeof(struct Channel), CHANNEL_HEAP_SIZE);
+ ban_heap = BlockHeapCreate(sizeof(struct Ban), BAN_HEAP_SIZE);
+ topic_heap = BlockHeapCreate(TOPICLEN + 1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE);
+ member_heap = BlockHeapCreate(sizeof(struct membership), MEMBER_HEAP_SIZE);
+
+ h_can_join = register_hook("can_join");
+}
+
+/*
+ * allocate_channel - Allocates a channel
+ */
+struct Channel *
+allocate_channel(const char *chname)
+{
+ struct Channel *chptr;
+ chptr = BlockHeapAlloc(channel_heap);
+ DupNString(chptr->chname, chname, CHANNELLEN);
+ return (chptr);
+}
+
+void
+free_channel(struct Channel *chptr)
+{
+ MyFree(chptr->chname);
+ BlockHeapFree(channel_heap, chptr);
+}
+
+struct Ban *
+allocate_ban(const char *banstr, const char *who)
+{
+ struct Ban *bptr;
+ bptr = BlockHeapAlloc(ban_heap);
+ DupNString(bptr->banstr, banstr, BANLEN);
+ DupNString(bptr->who, who, BANLEN);
+
+ return (bptr);
+}
+
+void
+free_ban(struct Ban *bptr)
+{
+ MyFree(bptr->banstr);
+ MyFree(bptr->who);
+ BlockHeapFree(ban_heap, bptr);
+}
+
+
+/* find_channel_membership()
+ *
+ * input - channel to find them in, client to find
+ * output - membership of client in channel, else NULL
+ * side effects -
+ */
+struct membership *
+find_channel_membership(struct Channel *chptr, struct Client *client_p)
+{
+ struct membership *msptr;
+ dlink_node *ptr;
+
+ if(!IsClient(client_p))
+ return NULL;
+
+ /* Pick the most efficient list to use to be nice to things like
+ * CHANSERV which could be in a large number of channels
+ */
+ if(dlink_list_length(&chptr->members) < dlink_list_length(&client_p->user->channel))
+ {
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+
+ if(msptr->client_p == client_p)
+ return msptr;
+ }
+ }
+ else
+ {
+ DLINK_FOREACH(ptr, client_p->user->channel.head)
+ {
+ msptr = ptr->data;
+
+ if(msptr->chptr == chptr)
+ return msptr;
+ }
+ }
+
+ return NULL;
+}
+
+/* find_channel_status()
+ *
+ * input - membership to get status for, whether we can combine flags
+ * output - flags of user on channel
+ * side effects -
+ */
+const char *
+find_channel_status(struct membership *msptr, int combine)
+{
+ static char buffer[3];
+ char *p;
+
+ p = buffer;
+
+ if(is_chanop(msptr))
+ {
+ if(!combine)
+ return "@";
+ *p++ = '@';
+ }
+
+ if(is_voiced(msptr))
+ *p++ = '+';
+
+ *p = '\0';
+ return buffer;
+}
+
+/* add_user_to_channel()
+ *
+ * input - channel to add client to, client to add, channel flags
+ * output -
+ * side effects - user is added to channel
+ */
+void
+add_user_to_channel(struct Channel *chptr, struct Client *client_p, int flags)
+{
+ struct membership *msptr;
+
+ s_assert(client_p->user != NULL);
+ if(client_p->user == NULL)
+ return;
+
+ msptr = BlockHeapAlloc(member_heap);
+
+ msptr->chptr = chptr;
+ msptr->client_p = client_p;
+ msptr->flags = flags;
+
+ dlinkAdd(msptr, &msptr->usernode, &client_p->user->channel);
+ dlinkAdd(msptr, &msptr->channode, &chptr->members);
+
+ if(MyClient(client_p))
+ dlinkAdd(msptr, &msptr->locchannode, &chptr->locmembers);
+}
+
+/* remove_user_from_channel()
+ *
+ * input - membership pointer to remove from channel
+ * output -
+ * side effects - membership (thus user) is removed from channel
+ */
+void
+remove_user_from_channel(struct membership *msptr)
+{
+ struct Client *client_p;
+ struct Channel *chptr;
+ s_assert(msptr != NULL);
+ if(msptr == NULL)
+ return;
+
+ client_p = msptr->client_p;
+ chptr = msptr->chptr;
+
+ dlinkDelete(&msptr->usernode, &client_p->user->channel);
+ dlinkDelete(&msptr->channode, &chptr->members);
+
+ if(client_p->servptr == &me)
+ dlinkDelete(&msptr->locchannode, &chptr->locmembers);
+
+ chptr->users_last = CurrentTime;
+
+ if(!(chptr->mode.mode & MODE_PERMANENT) && dlink_list_length(&chptr->members) <= 0)
+ destroy_channel(chptr);
+
+ BlockHeapFree(member_heap, msptr);
+
+ return;
+}
+
+/* remove_user_from_channels()
+ *
+ * input - user to remove from all channels
+ * output -
+ * side effects - user is removed from all channels
+ */
+void
+remove_user_from_channels(struct Client *client_p)
+{
+ struct Channel *chptr;
+ struct membership *msptr;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(client_p == NULL)
+ return;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->user->channel.head)
+ {
+ msptr = ptr->data;
+ chptr = msptr->chptr;
+
+ dlinkDelete(&msptr->channode, &chptr->members);
+
+ if(client_p->servptr == &me)
+ dlinkDelete(&msptr->locchannode, &chptr->locmembers);
+
+ chptr->users_last = CurrentTime;
+
+ if(!(chptr->mode.mode & MODE_PERMANENT) && dlink_list_length(&chptr->members) <= 0)
+ destroy_channel(chptr);
+
+ BlockHeapFree(member_heap, msptr);
+ }
+
+ client_p->user->channel.head = client_p->user->channel.tail = NULL;
+ client_p->user->channel.length = 0;
+}
+
+/* invalidate_bancache_user()
+ *
+ * input - user to invalidate ban cache for
+ * output -
+ * side effects - ban cache is invalidated for all memberships of that user
+ * to be used after a nick change
+ */
+void
+invalidate_bancache_user(struct Client *client_p)
+{
+ struct membership *msptr;
+ dlink_node *ptr;
+
+ if(client_p == NULL)
+ return;
+
+ DLINK_FOREACH(ptr, client_p->user->channel.head)
+ {
+ msptr = ptr->data;
+ msptr->bants = 0;
+ msptr->flags &= ~CHFL_BANNED;
+ }
+}
+
+/* check_channel_name()
+ *
+ * input - channel name
+ * output - 1 if valid channel name, else 0
+ * side effects -
+ */
+int
+check_channel_name(const char *name)
+{
+ s_assert(name != NULL);
+ if(name == NULL)
+ return 0;
+
+ for (; *name; ++name)
+ {
+ if(!IsChanChar(*name))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* free_channel_list()
+ *
+ * input - dlink list to free
+ * output -
+ * side effects - list of b/e/I modes is cleared
+ */
+void
+free_channel_list(dlink_list * list)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct Ban *actualBan;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
+ {
+ actualBan = ptr->data;
+ free_ban(actualBan);
+ }
+
+ list->head = list->tail = NULL;
+ list->length = 0;
+}
+
+/* destroy_channel()
+ *
+ * input - channel to destroy
+ * output -
+ * side effects - channel is obliterated
+ */
+void
+destroy_channel(struct Channel *chptr)
+{
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
+ {
+ del_invite(chptr, ptr->data);
+ }
+
+ /* free all bans/exceptions/denies */
+ free_channel_list(&chptr->banlist);
+ free_channel_list(&chptr->exceptlist);
+ free_channel_list(&chptr->invexlist);
+
+ /* Free the topic */
+ free_topic(chptr);
+
+ dlinkDelete(&chptr->node, &global_channel_list);
+ del_from_channel_hash(chptr->chname, chptr);
+ free_channel(chptr);
+}
+
+/* channel_pub_or_secret()
+ *
+ * input - channel
+ * output - "=" if public, "@" if secret, else "*"
+ * side effects -
+ */
+static const char *
+channel_pub_or_secret(struct Channel *chptr)
+{
+ if(PubChannel(chptr))
+ return ("=");
+ else if(SecretChannel(chptr))
+ return ("@");
+ return ("*");
+}
+
+/* channel_member_names()
+ *
+ * input - channel to list, client to list to, show endofnames
+ * output -
+ * side effects - client is given list of users on channel
+ */
+void
+channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eon)
+{
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *ptr;
+ char lbuf[BUFSIZE];
+ char *t;
+ int mlen;
+ int tlen;
+ int cur_len;
+ int is_member;
+ int stack = IsCapable(client_p, CLICAP_MULTI_PREFIX);
+
+ if(ShowChannel(client_p, chptr))
+ {
+ is_member = IsMember(client_p, chptr);
+
+ cur_len = mlen = ircsprintf(lbuf, form_str(RPL_NAMREPLY),
+ me.name, client_p->name,
+ channel_pub_or_secret(chptr), chptr->chname);
+
+ t = lbuf + cur_len;
+
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(IsInvisible(target_p) && !is_member)
+ continue;
+
+ /* space, possible "@+" prefix */
+ if(cur_len + strlen(target_p->name) + 3 >= BUFSIZE - 3)
+ {
+ *(t - 1) = '\0';
+ sendto_one(client_p, "%s", lbuf);
+ cur_len = mlen;
+ t = lbuf + mlen;
+ }
+
+ tlen = ircsprintf(t, "%s%s ", find_channel_status(msptr, stack),
+ target_p->name);
+
+ cur_len += tlen;
+ t += tlen;
+ }
+
+ /* The old behaviour here was to always output our buffer,
+ * even if there are no clients we can show. This happens
+ * when a client does "NAMES" with no parameters, and all
+ * the clients on a -sp channel are +i. I dont see a good
+ * reason for keeping that behaviour, as it just wastes
+ * bandwidth. --anfl
+ */
+ if(cur_len != mlen)
+ {
+ *(t - 1) = '\0';
+ sendto_one(client_p, "%s", lbuf);
+ }
+ }
+
+ if(show_eon)
+ sendto_one(client_p, form_str(RPL_ENDOFNAMES),
+ me.name, client_p->name, chptr->chname);
+}
+
+/* del_invite()
+ *
+ * input - channel to remove invite from, client to remove
+ * output -
+ * side effects - user is removed from invite list, if exists
+ */
+void
+del_invite(struct Channel *chptr, struct Client *who)
+{
+ dlinkFindDestroy(who, &chptr->invites);
+ dlinkFindDestroy(chptr, &who->user->invited);
+}
+
+/* is_banned()
+ *
+ * input - channel to check bans for, user to check bans against
+ * optional prebuilt buffers
+ * output - 1 if banned, else 0
+ * side effects -
+ */
+int
+is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr,
+ const char *s, const char *s2)
+{
+ char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
+ char *s3 = NULL;
+ dlink_node *ptr;
+ struct Ban *actualBan = NULL;
+ struct Ban *actualExcept = NULL;
+
+ if(!MyClient(who))
+ return 0;
+
+ /* if the buffers havent been built, do it here */
+ if(s == NULL)
+ {
+ ircsprintf(src_host, "%s!%s@%s", who->name, who->username, who->host);
+ ircsprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost);
+
+ s = src_host;
+ s2 = src_iphost;
+ }
+ if(who->localClient->mangledhost != NULL)
+ {
+ /* if host mangling mode enabled, also check their real host */
+ if(!strcmp(who->host, who->localClient->mangledhost))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost);
+ s3 = src_althost;
+ }
+ /* if host mangling mode not enabled and no other spoof,
+ * also check the mangled form of their host */
+ else if (!IsDynSpoof(who))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
+ s3 = src_althost;
+ }
+ }
+
+ DLINK_FOREACH(ptr, chptr->banlist.head)
+ {
+ actualBan = ptr->data;
+ if(match(actualBan->banstr, s) ||
+ match(actualBan->banstr, s2) ||
+ match_cidr(actualBan->banstr, s2) ||
+ match_extban(actualBan->banstr, who, chptr, CHFL_BAN) ||
+ (s3 != NULL && match(actualBan->banstr, s3)))
+ break;
+ else
+ actualBan = NULL;
+ }
+
+ if((actualBan != NULL) && ConfigChannel.use_except)
+ {
+ DLINK_FOREACH(ptr, chptr->exceptlist.head)
+ {
+ actualExcept = ptr->data;
+
+ /* theyre exempted.. */
+ if(match(actualExcept->banstr, s) ||
+ match(actualExcept->banstr, s2) ||
+ match_cidr(actualExcept->banstr, s2) ||
+ match_extban(actualExcept->banstr, who, chptr, CHFL_EXCEPTION) ||
+ (s3 != NULL && match(actualExcept->banstr, s3)))
+ {
+ /* cache the fact theyre not banned */
+ if(msptr != NULL)
+ {
+ msptr->bants = chptr->bants;
+ msptr->flags &= ~CHFL_BANNED;
+ }
+
+ return CHFL_EXCEPTION;
+ }
+ }
+ }
+
+ /* cache the banned/not banned status */
+ if(msptr != NULL)
+ {
+ msptr->bants = chptr->bants;
+
+ if(actualBan != NULL)
+ {
+ msptr->flags |= CHFL_BANNED;
+ return CHFL_BAN;
+ }
+ else
+ {
+ msptr->flags &= ~CHFL_BANNED;
+ return 0;
+ }
+ }
+
+ return ((actualBan ? CHFL_BAN : 0));
+}
+
+/* is_quieted()
+ *
+ * input - channel to check bans for, user to check bans against
+ * optional prebuilt buffers
+ * output - 1 if banned, else 0
+ * side effects -
+ */
+int
+is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr,
+ const char *s, const char *s2)
+{
+ char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
+ char *s3 = NULL;
+ dlink_node *ptr;
+ struct Ban *actualBan = NULL;
+ struct Ban *actualExcept = NULL;
+
+ if(!MyClient(who))
+ return 0;
+
+ /* if the buffers havent been built, do it here */
+ if(s == NULL)
+ {
+ ircsprintf(src_host, "%s!%s@%s", who->name, who->username, who->host);
+ ircsprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost);
+
+ s = src_host;
+ s2 = src_iphost;
+ }
+ if(who->localClient->mangledhost != NULL)
+ {
+ /* if host mangling mode enabled, also check their real host */
+ if(!strcmp(who->host, who->localClient->mangledhost))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost);
+ s3 = src_althost;
+ }
+ /* if host mangling mode not enabled and no other spoof,
+ * also check the mangled form of their host */
+ else if (!IsDynSpoof(who))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
+ s3 = src_althost;
+ }
+ }
+
+ DLINK_FOREACH(ptr, chptr->quietlist.head)
+ {
+ actualBan = ptr->data;
+ if(match(actualBan->banstr, s) ||
+ match(actualBan->banstr, s2) ||
+ match_cidr(actualBan->banstr, s2) ||
+ match_extban(actualBan->banstr, who, chptr, CHFL_QUIET) ||
+ (s3 != NULL && match(actualBan->banstr, s3)))
+ break;
+ else
+ actualBan = NULL;
+ }
+
+ if((actualBan != NULL) && ConfigChannel.use_except)
+ {
+ DLINK_FOREACH(ptr, chptr->exceptlist.head)
+ {
+ actualExcept = ptr->data;
+
+ /* theyre exempted.. */
+ if(match(actualExcept->banstr, s) ||
+ match(actualExcept->banstr, s2) ||
+ match_cidr(actualExcept->banstr, s2) ||
+ match_extban(actualExcept->banstr, who, chptr, CHFL_EXCEPTION) ||
+ (s3 != NULL && match(actualExcept->banstr, s3)))
+ {
+ /* cache the fact theyre not banned */
+ if(msptr != NULL)
+ {
+ msptr->bants = chptr->bants;
+ msptr->flags &= ~CHFL_BANNED;
+ }
+
+ return CHFL_EXCEPTION;
+ }
+ }
+ }
+
+ /* cache the banned/not banned status */
+ if(msptr != NULL)
+ {
+ msptr->bants = chptr->bants;
+
+ if(actualBan != NULL)
+ {
+ msptr->flags |= CHFL_BANNED;
+ return CHFL_BAN;
+ }
+ else
+ {
+ msptr->flags &= ~CHFL_BANNED;
+ return 0;
+ }
+ }
+
+ return ((actualBan ? CHFL_BAN : 0));
+}
+
+/* can_join()
+ *
+ * input - client to check, channel to check for, key
+ * output - reason for not being able to join, else 0
+ * side effects -
+ */
+int
+can_join(struct Client *source_p, struct Channel *chptr, char *key)
+{
+ dlink_node *lp;
+ dlink_node *ptr;
+ struct Ban *invex = NULL;
+ char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
+ int use_althost = 0;
+ hook_data_channel moduledata;
+
+ s_assert(source_p->localClient != NULL);
+
+ ircsprintf(src_host, "%s!%s@%s", source_p->name, source_p->username, source_p->host);
+ ircsprintf(src_iphost, "%s!%s@%s", source_p->name, source_p->username, source_p->sockhost);
+ if(source_p->localClient->mangledhost != NULL)
+ {
+ /* if host mangling mode enabled, also check their real host */
+ if(!strcmp(source_p->host, source_p->localClient->mangledhost))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->orighost);
+ use_althost = 1;
+ }
+ /* if host mangling mode not enabled and no other spoof,
+ * also check the mangled form of their host */
+ else if (!IsDynSpoof(source_p))
+ {
+ ircsprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->localClient->mangledhost);
+ use_althost = 1;
+ }
+ }
+
+ if((is_banned(chptr, source_p, NULL, src_host, src_iphost)) == CHFL_BAN)
+ return (ERR_BANNEDFROMCHAN);
+
+ if(chptr->mode.mode & MODE_INVITEONLY)
+ {
+ DLINK_FOREACH(lp, source_p->user->invited.head)
+ {
+ if(lp->data == chptr)
+ break;
+ }
+ if(lp == NULL)
+ {
+ if(!ConfigChannel.use_invex)
+ return (ERR_INVITEONLYCHAN);
+ DLINK_FOREACH(ptr, chptr->invexlist.head)
+ {
+ invex = ptr->data;
+ if(match(invex->banstr, src_host)
+ || match(invex->banstr, src_iphost)
+ || match_cidr(invex->banstr, src_iphost)
+ || match_extban(invex->banstr, source_p, chptr, CHFL_INVEX)
+ || (use_althost && match(invex->banstr, src_althost)))
+ break;
+ }
+ if(ptr == NULL)
+ return (ERR_INVITEONLYCHAN);
+ }
+ }
+
+ if(*chptr->mode.key && (EmptyString(key) || irccmp(chptr->mode.key, key)))
+ return (ERR_BADCHANNELKEY);
+
+ if(chptr->mode.limit &&
+ dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
+ return (ERR_CHANNELISFULL);
+
+ if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser))
+ return ERR_NEEDREGGEDNICK;
+
+ /* join throttling stuff --nenolod */
+ if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
+ {
+ if ((CurrentTime - chptr->join_delta <=
+ chptr->mode.join_time) && (chptr->join_count >=
+ chptr->mode.join_num))
+ return ERR_THROTTLE;
+ }
+
+ moduledata.client = source_p;
+ moduledata.chptr = chptr;
+ moduledata.approved = 0;
+
+ call_hook(h_can_join, &moduledata);
+
+ return moduledata.approved;
+}
+
+/* can_send()
+ *
+ * input - user to check in channel, membership pointer
+ * output - whether can explicitly send or not, else CAN_SEND_NONOP
+ * side effects -
+ */
+int
+can_send(struct Channel *chptr, struct Client *source_p, struct membership *msptr)
+{
+ if(IsServer(source_p) || IsService(source_p))
+ return CAN_SEND_OPV;
+
+ if(MyClient(source_p) && hash_find_resv(chptr->chname) &&
+ !IsOper(source_p) && !IsExemptResv(source_p))
+ return CAN_SEND_NO;
+
+ if(msptr == NULL)
+ {
+ msptr = find_channel_membership(chptr, source_p);
+
+ if(msptr == NULL)
+ {
+ /* if its +m or +n and theyre not in the channel,
+ * they cant send. we dont check bans here because
+ * theres no possibility of caching them --fl
+ */
+ if(chptr->mode.mode & MODE_NOPRIVMSGS || chptr->mode.mode & MODE_MODERATED)
+ return CAN_SEND_NO;
+ else
+ return CAN_SEND_NONOP;
+ }
+ }
+
+ if(is_chanop_voiced(msptr))
+ return CAN_SEND_OPV;
+
+ if(chptr->mode.mode & MODE_MODERATED)
+ return CAN_SEND_NO;
+
+ if(MyClient(source_p))
+ {
+ /* cached can_send */
+ if(msptr->bants == chptr->bants)
+ {
+ if(can_send_banned(msptr))
+ return CAN_SEND_NO;
+ }
+ else if(is_banned(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN
+ || is_quieted(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN)
+ return CAN_SEND_NO;
+ }
+
+ return CAN_SEND_NONOP;
+}
+
+/* find_bannickchange_channel()
+ * Input: client to check
+ * Output: channel preventing nick change
+ */
+struct Channel *
+find_bannickchange_channel(struct Client *client_p)
+{
+ struct Channel *chptr;
+ struct membership *msptr;
+ dlink_node *ptr;
+ char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
+ char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
+
+ if (!MyClient(client_p))
+ return NULL;
+
+ ircsprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host);
+ ircsprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost);
+
+ DLINK_FOREACH(ptr, client_p->user->channel.head)
+ {
+ msptr = ptr->data;
+ chptr = msptr->chptr;
+ if (is_chanop_voiced(msptr))
+ continue;
+ /* cached can_send */
+ if (msptr->bants == chptr->bants)
+ {
+ if (can_send_banned(msptr))
+ return chptr;
+ }
+ else if (is_banned(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN
+ || is_quieted(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN)
+ return chptr;
+ }
+ return NULL;
+}
+
+/* void check_spambot_warning(struct Client *source_p)
+ * Input: Client to check, channel name or NULL if this is a part.
+ * Output: none
+ * Side-effects: Updates the client's oper_warn_count_down, warns the
+ * IRC operators if necessary, and updates join_leave_countdown as
+ * needed.
+ */
+void
+check_spambot_warning(struct Client *source_p, const char *name)
+{
+ int t_delta;
+ int decrement_count;
+ if((GlobalSetOptions.spam_num &&
+ (source_p->localClient->join_leave_count >= GlobalSetOptions.spam_num)))
+ {
+ if(source_p->localClient->oper_warn_count_down > 0)
+ source_p->localClient->oper_warn_count_down--;
+ else
+ source_p->localClient->oper_warn_count_down = 0;
+ if(source_p->localClient->oper_warn_count_down == 0)
+ {
+ /* Its already known as a possible spambot */
+ if(name != NULL)
+ sendto_realops_snomask(SNO_BOTS, L_ALL,
+ "User %s (%s@%s) trying to join %s is a possible spambot",
+ source_p->name,
+ source_p->username, source_p->host, name);
+ else
+ sendto_realops_snomask(SNO_BOTS, L_ALL,
+ "User %s (%s@%s) is a possible spambot",
+ source_p->name,
+ source_p->username, source_p->host);
+ source_p->localClient->oper_warn_count_down = OPER_SPAM_COUNTDOWN;
+ }
+ }
+ else
+ {
+ if((t_delta =
+ (CurrentTime - source_p->localClient->last_leave_time)) >
+ JOIN_LEAVE_COUNT_EXPIRE_TIME)
+ {
+ decrement_count = (t_delta / JOIN_LEAVE_COUNT_EXPIRE_TIME);
+ if(decrement_count > source_p->localClient->join_leave_count)
+ source_p->localClient->join_leave_count = 0;
+ else
+ source_p->localClient->join_leave_count -= decrement_count;
+ }
+ else
+ {
+ if((CurrentTime -
+ (source_p->localClient->last_join_time)) < GlobalSetOptions.spam_time)
+ {
+ /* oh, its a possible spambot */
+ source_p->localClient->join_leave_count++;
+ }
+ }
+ if(name != NULL)
+ source_p->localClient->last_join_time = CurrentTime;
+ else
+ source_p->localClient->last_leave_time = CurrentTime;
+ }
+}
+
+/* check_splitmode()
+ *
+ * input -
+ * output -
+ * side effects - compares usercount and servercount against their split
+ * values and adjusts splitmode accordingly
+ */
+void
+check_splitmode(void *unused)
+{
+ if(splitchecking && (ConfigChannel.no_join_on_split || ConfigChannel.no_create_on_split))
+ {
+ /* not split, we're being asked to check now because someone
+ * has left
+ */
+ if(!splitmode)
+ {
+ if(eob_count < split_servers || Count.total < split_users)
+ {
+ splitmode = 1;
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Network split, activating splitmode");
+ eventAddIsh("check_splitmode", check_splitmode, NULL, 2);
+ }
+ }
+ /* in splitmode, check whether its finished */
+ else if(eob_count >= split_servers && Count.total >= split_users)
+ {
+ splitmode = 0;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Network rejoined, deactivating splitmode");
+
+ eventDelete(check_splitmode, NULL);
+ }
+ }
+}
+
+
+/* allocate_topic()
+ *
+ * input - channel to allocate topic for
+ * output - 1 on success, else 0
+ * side effects - channel gets a topic allocated
+ */
+static void
+allocate_topic(struct Channel *chptr)
+{
+ void *ptr;
+
+ if(chptr == NULL)
+ return;
+
+ ptr = BlockHeapAlloc(topic_heap);
+
+ /* Basically we allocate one large block for the topic and
+ * the topic info. We then split it up into two and shove it
+ * in the chptr
+ */
+ chptr->topic = ptr;
+ chptr->topic_info = (char *) ptr + TOPICLEN + 1;
+ *chptr->topic = '\0';
+ *chptr->topic_info = '\0';
+}
+
+/* free_topic()
+ *
+ * input - channel which has topic to free
+ * output -
+ * side effects - channels topic is free'd
+ */
+static void
+free_topic(struct Channel *chptr)
+{
+ void *ptr;
+
+ if(chptr == NULL || chptr->topic == NULL)
+ return;
+
+ /* This is safe for now - If you change allocate_topic you
+ * MUST change this as well
+ */
+ ptr = chptr->topic;
+ BlockHeapFree(topic_heap, ptr);
+ chptr->topic = NULL;
+ chptr->topic_info = NULL;
+}
+
+/* set_channel_topic()
+ *
+ * input - channel, topic to set, topic info and topic ts
+ * output -
+ * side effects - channels topic, topic info and TS are set.
+ */
+void
+set_channel_topic(struct Channel *chptr, const char *topic, const char *topic_info, time_t topicts)
+{
+ if(strlen(topic) > 0)
+ {
+ if(chptr->topic == NULL)
+ allocate_topic(chptr);
+ strlcpy(chptr->topic, topic, TOPICLEN + 1);
+ strlcpy(chptr->topic_info, topic_info, USERHOST_REPLYLEN);
+ chptr->topic_time = topicts;
+ }
+ else
+ {
+ if(chptr->topic != NULL)
+ free_topic(chptr);
+ chptr->topic_time = 0;
+ }
+}
+
+static const struct mode_letter
+{
+ const unsigned int mode;
+ const unsigned char letter;
+} flags[] =
+{
+ {MODE_INVITEONLY, 'i'},
+ {MODE_MODERATED, 'm'},
+ {MODE_NOPRIVMSGS, 'n'},
+ {MODE_PRIVATE, 'p'},
+ {MODE_SECRET, 's'},
+ {MODE_TOPICLIMIT, 't'},
+ {MODE_NOCOLOR, 'c'},
+ {MODE_FREEINVITE, 'g'},
+ {MODE_OPMODERATE, 'z'},
+ {MODE_EXLIMIT, 'L'},
+ {MODE_PERMANENT, 'P'},
+ {MODE_FREETARGET, 'F'},
+ {MODE_DISFORWARD, 'Q'},
+ {MODE_REGONLY, 'r'},
+ {0, '\0'}
+};
+
+/* channel_modes()
+ *
+ * inputs - pointer to channel
+ * - pointer to client
+ * output - NONE
+ * side effects - write the "simple" list of channel modes for channel
+ * chptr onto buffer mbuf with the parameters in pbuf.
+ *
+ * Stolen from ShadowIRCd 4 --nenolod
+ */
+const char *
+channel_modes(struct Channel *chptr, struct Client *client_p)
+{
+ int i;
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+ static char final[BUFSIZE];
+ char *mbuf = buf1;
+ char *pbuf = buf2;
+
+ *mbuf++ = '+';
+ *pbuf = '\0';
+
+ for (i = 0; flags[i].mode; ++i)
+ if(chptr->mode.mode & flags[i].mode)
+ *mbuf++ = flags[i].letter;
+
+ if(chptr->mode.limit)
+ {
+ *mbuf++ = 'l';
+
+ if(IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
+ pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit);
+ }
+
+ if(*chptr->mode.key)
+ {
+ *mbuf++ = 'k';
+
+ if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
+ pbuf += ircsprintf(pbuf, "%s ", chptr->mode.key);
+ }
+
+ if(chptr->mode.join_num)
+ {
+ *mbuf++ = 'j';
+
+ if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
+ pbuf += ircsprintf(pbuf, "%d:%d ", chptr->mode.join_num,
+ chptr->mode.join_time);
+ }
+
+ if(*chptr->mode.forward && (ConfigChannel.use_forward || IsServer(client_p) || IsMe(client_p)))
+ {
+ *mbuf++ = 'f';
+
+ if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
+ pbuf += ircsprintf(pbuf, "%s ", chptr->mode.forward);
+ }
+
+ *mbuf = '\0';
+
+ ircsprintf(final, "%s %s", buf1, buf2);
+ return final;
+}
+
+/* Now lets do some stuff to keep track of what combinations of
+ * servers exist...
+ * Note that the number of combinations doubles each time you add
+ * something to this list. Each one is only quick if no servers use that
+ * combination, but if the numbers get too high here MODE will get too
+ * slow. I suggest if you get more than 7 here, you consider getting rid
+ * of some and merging or something. If it wasn't for irc+cs we would
+ * probably not even need to bother about most of these, but unfortunately
+ * we do. -A1kmm
+ */
+
+/* void init_chcap_usage_counts(void)
+ *
+ * Inputs - none
+ * Output - none
+ * Side-effects - Initialises the usage counts to zero. Fills in the
+ * chcap_yes and chcap_no combination tables.
+ */
+void
+init_chcap_usage_counts(void)
+{
+ unsigned long m, c, y, n;
+
+ memset(chcap_combos, 0, sizeof(chcap_combos));
+
+ /* For every possible combination */
+ for (m = 0; m < NCHCAP_COMBOS; m++)
+ {
+ /* Check each capab */
+ for (c = y = n = 0; c < NCHCAPS; c++)
+ {
+ if((m & (1 << c)) == 0)
+ n |= channel_capabs[c];
+ else
+ y |= channel_capabs[c];
+ }
+ chcap_combos[m].cap_yes = y;
+ chcap_combos[m].cap_no = n;
+ }
+}
+
+/* void set_chcap_usage_counts(struct Client *serv_p)
+ * Input: serv_p; The client whose capabs to register.
+ * Output: none
+ * Side-effects: Increments the usage counts for the correct capab
+ * combination.
+ */
+void
+set_chcap_usage_counts(struct Client *serv_p)
+{
+ int n;
+
+ for (n = 0; n < NCHCAP_COMBOS; n++)
+ {
+ if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
+ NotCapable(serv_p, chcap_combos[n].cap_no))
+ {
+ chcap_combos[n].count++;
+ return;
+ }
+ }
+
+ /* This should be impossible -A1kmm. */
+ s_assert(0);
+}
+
+/* void set_chcap_usage_counts(struct Client *serv_p)
+ *
+ * Inputs - serv_p; The client whose capabs to register.
+ * Output - none
+ * Side-effects - Decrements the usage counts for the correct capab
+ * combination.
+ */
+void
+unset_chcap_usage_counts(struct Client *serv_p)
+{
+ int n;
+
+ for (n = 0; n < NCHCAP_COMBOS; n++)
+ {
+ if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
+ NotCapable(serv_p, chcap_combos[n].cap_no))
+ {
+ /* Hopefully capabs can't change dynamically or anything... */
+ s_assert(chcap_combos[n].count > 0);
+
+ if(chcap_combos[n].count > 0)
+ chcap_combos[n].count--;
+ return;
+ }
+ }
+
+ /* This should be impossible -A1kmm. */
+ s_assert(0);
+}
+
+/* void send_cap_mode_changes(struct Client *client_p,
+ * struct Client *source_p,
+ * struct Channel *chptr, int cap, int nocap)
+ * Input: The client sending(client_p), the source client(source_p),
+ * the channel to send mode changes for(chptr)
+ * Output: None.
+ * Side-effects: Sends the appropriate mode changes to capable servers.
+ *
+ * Reverted back to my original design, except that we now keep a count
+ * of the number of servers which each combination as an optimisation, so
+ * the capabs combinations which are not needed are not worked out. -A1kmm
+ */
+void
+send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, struct ChModeChange mode_changes[], int mode_count)
+{
+ static char modebuf[BUFSIZE];
+ static char parabuf[BUFSIZE];
+ int i, mbl, pbl, nc, mc, preflen, len;
+ char *pbuf;
+ const char *arg;
+ int dir;
+ int j;
+ int cap;
+ int nocap;
+ int arglen;
+
+ /* Now send to servers... */
+ for (j = 0; j < NCHCAP_COMBOS; j++)
+ {
+ if(chcap_combos[j].count == 0)
+ continue;
+
+ mc = 0;
+ nc = 0;
+ pbl = 0;
+ parabuf[0] = 0;
+ pbuf = parabuf;
+ dir = MODE_QUERY;
+
+ cap = chcap_combos[j].cap_yes;
+ nocap = chcap_combos[j].cap_no;
+
+ if(cap & CAP_TS6)
+ mbl = preflen = ircsprintf(modebuf, ":%s TMODE %ld %s ",
+ use_id(source_p), (long) chptr->channelts,
+ chptr->chname);
+ else
+ mbl = preflen = ircsprintf(modebuf, ":%s MODE %s ",
+ source_p->name, chptr->chname);
+
+ /* loop the list of - modes we have */
+ for (i = 0; i < mode_count; i++)
+ {
+ /* if they dont support the cap we need, or they do support a cap they
+ * cant have, then dont add it to the modebuf.. that way they wont see
+ * the mode
+ */
+ if((mode_changes[i].letter == 0) ||
+ ((cap & mode_changes[i].caps) != mode_changes[i].caps)
+ || ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps))
+ continue;
+
+ if((cap & CAP_TS6) && !EmptyString(mode_changes[i].id))
+ arg = mode_changes[i].id;
+ else
+ arg = mode_changes[i].arg;
+
+ if(arg)
+ {
+ arglen = strlen(arg);
+
+ /* dont even think about it! --fl */
+ if(arglen > MODEBUFLEN - 5)
+ continue;
+ }
+
+ /* if we're creeping past the buf size, we need to send it and make
+ * another line for the other modes
+ * XXX - this could give away server topology with uids being
+ * different lengths, but not much we can do, except possibly break
+ * them as if they were the longest of the nick or uid at all times,
+ * which even then won't work as we don't always know the uid -A1kmm.
+ */
+ if(arg && ((mc == MAXMODEPARAMSSERV) ||
+ ((mbl + pbl + arglen + 4) > (BUFSIZE - 3))))
+ {
+ if(nc != 0)
+ sendto_server(client_p, chptr, cap, nocap,
+ "%s %s", modebuf, parabuf);
+ nc = 0;
+ mc = 0;
+
+ mbl = preflen;
+ pbl = 0;
+ pbuf = parabuf;
+ parabuf[0] = 0;
+ dir = MODE_QUERY;
+ }
+
+ if(dir != mode_changes[i].dir)
+ {
+ modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
+ dir = mode_changes[i].dir;
+ }
+
+ modebuf[mbl++] = mode_changes[i].letter;
+ modebuf[mbl] = 0;
+ nc++;
+
+ if(arg != NULL)
+ {
+ len = ircsprintf(pbuf, "%s ", arg);
+ pbuf += len;
+ pbl += len;
+ mc++;
+ }
+ }
+
+ if(pbl && parabuf[pbl - 1] == ' ')
+ parabuf[pbl - 1] = 0;
+
+ if(nc != 0)
+ sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf);
+ }
+}
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * chmode.c: channel mode management
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis 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
+ *
+ * $Id: chmode.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "hook.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h" /* captab */
+#include "s_user.h"
+#include "send.h"
+#include "whowas.h"
+#include "s_conf.h" /* ConfigFileEntry, ConfigChannel */
+#include "s_newconf.h"
+#include "event.h"
+#include "memory.h"
+#include "balloc.h"
+#include "s_log.h"
+
+/* bitmasks for error returns, so we send once per call */
+#define SM_ERR_NOTS 0x00000001 /* No TS on channel */
+#define SM_ERR_NOOPS 0x00000002 /* No chan ops */
+#define SM_ERR_UNKNOWN 0x00000004
+#define SM_ERR_RPL_C 0x00000008
+#define SM_ERR_RPL_B 0x00000010
+#define SM_ERR_RPL_E 0x00000020
+#define SM_ERR_NOTONCHANNEL 0x00000040 /* Not on channel */
+#define SM_ERR_RPL_I 0x00000100
+#define SM_ERR_RPL_D 0x00000200
+#define SM_ERR_NOPRIVS 0x00000400
+#define SM_ERR_RPL_Q 0x00000800
+#define SM_ERR_RPL_F 0x00001000
+
+void set_channel_mode(struct Client *, struct Client *,
+ struct Channel *, struct membership *, int, const char **);
+
+int add_id(struct Client *source_p, struct Channel *chptr,
+ const char *banid, dlink_list * list, long mode_type);
+
+static struct ChModeChange mode_changes[BUFSIZE];
+static int mode_count;
+static int mode_limit;
+static int mask_pos;
+
+int
+get_channel_access(struct Client *source_p, struct membership *msptr)
+{
+ if(!MyClient(source_p) || is_chanop(msptr))
+ return CHFL_CHANOP;
+
+ return CHFL_PEON;
+}
+
+/* add_id()
+ *
+ * inputs - client, channel, id to add, type
+ * outputs - 0 on failure, 1 on success
+ * side effects - given id is added to the appropriate list
+ */
+int
+add_id(struct Client *source_p, struct Channel *chptr, const char *banid,
+ dlink_list * list, long mode_type)
+{
+ struct Ban *actualBan;
+ static char who[BANLEN];
+ char *realban = LOCAL_COPY(banid);
+ dlink_node *ptr;
+
+ /* dont let local clients overflow the banlist, or set redundant
+ * bans
+ */
+ if(MyClient(source_p))
+ {
+ if((dlink_list_length(&chptr->banlist) + dlink_list_length(&chptr->exceptlist) + dlink_list_length(&chptr->invexlist) + dlink_list_length(&chptr->quietlist)) >= (chptr->mode.mode & MODE_EXLIMIT ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
+ {
+ sendto_one(source_p, form_str(ERR_BANLISTFULL),
+ me.name, source_p->name, chptr->chname, realban);
+ return 0;
+ }
+
+ collapse(realban);
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ actualBan = ptr->data;
+ if(match(actualBan->banstr, realban))
+ return 0;
+ }
+ }
+ /* dont let remotes set duplicates */
+ else
+ {
+ DLINK_FOREACH(ptr, list->head)
+ {
+ actualBan = ptr->data;
+ if(!irccmp(actualBan->banstr, realban))
+ return 0;
+ }
+ }
+
+
+ if(IsPerson(source_p))
+ ircsprintf(who, "%s!%s@%s", source_p->name, source_p->username, source_p->host);
+ else
+ strlcpy(who, source_p->name, sizeof(who));
+
+ actualBan = allocate_ban(realban, who);
+ actualBan->when = CurrentTime;
+
+ dlinkAdd(actualBan, &actualBan->node, list);
+
+ /* invalidate the can_send() cache */
+ if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+ chptr->bants++;
+
+ return 1;
+}
+
+/* del_id()
+ *
+ * inputs - channel, id to remove, type
+ * outputs - 0 on failure, 1 on success
+ * side effects - given id is removed from the appropriate list
+ */
+int
+del_id(struct Channel *chptr, const char *banid, dlink_list * list, long mode_type)
+{
+ dlink_node *ptr;
+ struct Ban *banptr;
+
+ if(EmptyString(banid))
+ return 0;
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ banptr = ptr->data;
+
+ if(irccmp(banid, banptr->banstr) == 0)
+ {
+ dlinkDelete(&banptr->node, list);
+ free_ban(banptr);
+
+ /* invalidate the can_send() cache */
+ if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+ chptr->bants++;
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* check_string()
+ *
+ * input - string to check
+ * output - pointer to 'fixed' string, or "*" if empty
+ * side effects - any white space found becomes \0
+ */
+static char *
+check_string(char *s)
+{
+ char *str = s;
+ static char splat[] = "*";
+ if(!(s && *s))
+ return splat;
+
+ for(; *s; ++s)
+ {
+ if(IsSpace(*s))
+ {
+ *s = '\0';
+ break;
+ }
+ }
+ return str;
+}
+
+/* pretty_mask()
+ *
+ * inputs - mask to pretty
+ * outputs - better version of the mask
+ * side effects - mask is chopped to limits, and transformed:
+ * x!y@z => x!y@z
+ * y@z => *!y@z
+ * x!y => x!y@*
+ * x => x!*@*
+ * z.d => *!*@z.d
+ */
+static char *
+pretty_mask(const char *idmask)
+{
+ static char mask_buf[BUFSIZE];
+ int old_mask_pos;
+ char *nick, *user, *host;
+ char splat[] = "*";
+ char *t, *at, *ex;
+ char ne = 0, ue = 0, he = 0; /* save values at nick[NICKLEN], et all */
+ char *mask;
+
+ mask = LOCAL_COPY(idmask);
+ mask = check_string(mask);
+ collapse(mask);
+
+ nick = user = host = splat;
+
+ if((size_t) BUFSIZE - mask_pos < strlen(mask) + 5)
+ return NULL;
+
+ old_mask_pos = mask_pos;
+
+ if (*mask == '$')
+ {
+ mask_pos += ircsprintf(mask_buf + mask_pos, "%s", mask) + 1;
+ t = mask_buf + old_mask_pos + 1;
+ if (*t == '!')
+ *t = '~';
+ if (*t == '~')
+ t++;
+ *t = ToLower(*t);
+ return mask_buf + old_mask_pos;
+ }
+
+ at = ex = NULL;
+ if((t = strchr(mask, '@')) != NULL)
+ {
+ at = t;
+ *t++ = '\0';
+ if(*t != '\0')
+ host = t;
+
+ if((t = strchr(mask, '!')) != NULL)
+ {
+ ex = t;
+ *t++ = '\0';
+ if(*t != '\0')
+ user = t;
+ if(*mask != '\0')
+ nick = mask;
+ }
+ else
+ {
+ if(*mask != '\0')
+ user = mask;
+ }
+ }
+ else if((t = strchr(mask, '!')) != NULL)
+ {
+ ex = t;
+ *t++ = '\0';
+ if(*mask != '\0')
+ nick = mask;
+ if(*t != '\0')
+ user = t;
+ }
+ else if(strchr(mask, '.') != NULL || strchr(mask, ':') != NULL)
+ {
+ if(*mask != '\0')
+ host = mask;
+ }
+ else
+ {
+ if(*mask != '\0')
+ nick = mask;
+ }
+
+ /* truncate values to max lengths */
+ if(strlen(nick) > NICKLEN - 1)
+ {
+ ne = nick[NICKLEN - 1];
+ nick[NICKLEN - 1] = '\0';
+ }
+ if(strlen(user) > USERLEN)
+ {
+ ue = user[USERLEN];
+ user[USERLEN] = '\0';
+ }
+ if(strlen(host) > HOSTLEN)
+ {
+ he = host[HOSTLEN];
+ host[HOSTLEN] = '\0';
+ }
+
+ mask_pos += ircsprintf(mask_buf + mask_pos, "%s!%s@%s", nick, user, host) + 1;
+
+ /* restore mask, since we may need to use it again later */
+ if(at)
+ *at = '@';
+ if(ex)
+ *ex = '!';
+ if(ne)
+ nick[NICKLEN - 1] = ne;
+ if(ue)
+ user[USERLEN] = ue;
+ if(he)
+ host[HOSTLEN] = he;
+
+ return mask_buf + old_mask_pos;
+}
+
+/* fix_key()
+ *
+ * input - key to fix
+ * output - the same key, fixed
+ * side effects - anything below ascii 13 is discarded, ':' discarded,
+ * high ascii is dropped to lower half of ascii table
+ */
+static char *
+fix_key(char *arg)
+{
+ u_char *s, *t, c;
+
+ for(s = t = (u_char *) arg; (c = *s); s++)
+ {
+ c &= 0x7f;
+ if(c != ':' && c != ',' && c > ' ')
+ *t++ = c;
+ }
+
+ *t = '\0';
+ return arg;
+}
+
+/* fix_key_remote()
+ *
+ * input - key to fix
+ * ouput - the same key, fixed
+ * side effects - high ascii dropped to lower half of table,
+ * CR/LF/':' are dropped
+ */
+static char *
+fix_key_remote(char *arg)
+{
+ u_char *s, *t, c;
+
+ for(s = t = (u_char *) arg; (c = *s); s++)
+ {
+ c &= 0x7f;
+ if((c != 0x0a) && (c != ':') && (c != ',') && (c != 0x0d) && (c != ' '))
+ *t++ = c;
+ }
+
+ *t = '\0';
+ return arg;
+}
+
+/* chm_*()
+ *
+ * The handlers for each specific mode.
+ */
+void
+chm_nosuch(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ if(*errors & SM_ERR_UNKNOWN)
+ return;
+ *errors |= SM_ERR_UNKNOWN;
+ sendto_one(source_p, form_str(ERR_UNKNOWNMODE), me.name, source_p->name, c);
+}
+
+void
+chm_simple(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ /* +ntspmaikl == 9 + MAXMODEPARAMS (4 * +o) */
+ if(MyClient(source_p) && (++mode_limit > (9 + MAXMODEPARAMS)))
+ return;
+
+ /* setting + */
+ if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
+ {
+ /* if +f is disabled, ignore an attempt to set +QF locally */
+ if(!ConfigChannel.use_forward && MyClient(source_p) &&
+ (c == 'Q' || c == 'F'))
+ return;
+
+ chptr->mode.mode |= mode_type;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count++].arg = NULL;
+ }
+ else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
+ {
+ chptr->mode.mode &= ~mode_type;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+ }
+}
+
+void
+chm_staff(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ if(!IsOper(source_p) && !IsServer(source_p))
+ {
+ if(!(*errors & SM_ERR_NOPRIVS))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
+ *errors |= SM_ERR_NOPRIVS;
+ return;
+ }
+
+ /* setting + */
+ if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
+ {
+ chptr->mode.mode |= mode_type;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count++].arg = NULL;
+ }
+ else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
+ {
+ chptr->mode.mode &= ~mode_type;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+ }
+}
+
+void
+chm_ban(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ const char *mask;
+ const char *raw_mask;
+ dlink_list *list;
+ dlink_node *ptr;
+ struct Ban *banptr;
+ int errorval;
+ int rpl_list;
+ int rpl_endlist;
+ int caps;
+ int mems;
+
+ switch (mode_type)
+ {
+ case CHFL_BAN:
+ list = &chptr->banlist;
+ errorval = SM_ERR_RPL_B;
+ rpl_list = RPL_BANLIST;
+ rpl_endlist = RPL_ENDOFBANLIST;
+ mems = ALL_MEMBERS;
+ caps = 0;
+ break;
+
+ case CHFL_EXCEPTION:
+ /* if +e is disabled, allow all but +e locally */
+ if(!ConfigChannel.use_except && MyClient(source_p) &&
+ ((dir == MODE_ADD) && (parc > *parn)))
+ return;
+
+ list = &chptr->exceptlist;
+ errorval = SM_ERR_RPL_E;
+ rpl_list = RPL_EXCEPTLIST;
+ rpl_endlist = RPL_ENDOFEXCEPTLIST;
+ caps = CAP_EX;
+
+ if(ConfigChannel.use_except || (dir == MODE_DEL))
+ mems = ONLY_CHANOPS;
+ else
+ mems = ONLY_SERVERS;
+ break;
+
+ case CHFL_INVEX:
+ /* if +I is disabled, allow all but +I locally */
+ if(!ConfigChannel.use_invex && MyClient(source_p) &&
+ (dir == MODE_ADD) && (parc > *parn))
+ return;
+
+ list = &chptr->invexlist;
+ errorval = SM_ERR_RPL_I;
+ rpl_list = RPL_INVITELIST;
+ rpl_endlist = RPL_ENDOFINVITELIST;
+ caps = CAP_IE;
+
+ if(ConfigChannel.use_invex || (dir == MODE_DEL))
+ mems = ONLY_CHANOPS;
+ else
+ mems = ONLY_SERVERS;
+ break;
+
+ case CHFL_QUIET:
+ list = &chptr->quietlist;
+ errorval = SM_ERR_RPL_Q;
+ rpl_list = RPL_BANLIST;
+ rpl_endlist = RPL_ENDOFBANLIST;
+ mems = ALL_MEMBERS;
+ caps = 0;
+ break;
+
+ default:
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "chm_ban() called with unknown type!");
+ return;
+ break;
+ }
+
+ if(dir == 0 || parc <= *parn)
+ {
+ if((*errors & errorval) != 0)
+ return;
+ *errors |= errorval;
+
+ /* non-ops cant see +eI lists.. */
+ if(alevel != CHFL_CHANOP && mode_type != CHFL_BAN &&
+ mode_type != CHFL_QUIET)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ banptr = ptr->data;
+ sendto_one(source_p, form_str(rpl_list),
+ me.name, source_p->name, chptr->chname,
+ banptr->banstr, banptr->who, banptr->when);
+ }
+ sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname);
+ return;
+ }
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
+ return;
+
+ raw_mask = parv[(*parn)];
+ (*parn)++;
+
+ /* empty ban, or starts with ':' which messes up s2s, ignore it */
+ if(EmptyString(raw_mask) || *raw_mask == ':')
+ return;
+
+ if(!MyClient(source_p))
+ {
+ if(strchr(raw_mask, ' '))
+ return;
+
+ mask = raw_mask;
+ }
+ else
+ mask = pretty_mask(raw_mask);
+
+ /* we'd have problems parsing this, hyb6 does it too */
+ if(strlen(mask) > (MODEBUFLEN - 2))
+ return;
+
+ /* if we're adding a NEW id */
+ if(dir == MODE_ADD)
+ {
+ if (*mask == '$' && MyClient(source_p))
+ {
+ if (!valid_extban(mask, source_p, chptr, mode_type))
+ /* XXX perhaps return an error message here */
+ return;
+ }
+
+ /* dont allow local clients to overflow the banlist, dont
+ * let remote servers set duplicate bans
+ */
+ if(!add_id(source_p, chptr, mask, list, mode_type))
+ return;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = caps;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = mems;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = mask;
+ }
+ else if(dir == MODE_DEL)
+ {
+ if(del_id(chptr, mask, list, mode_type) == 0)
+ {
+ /* mask isn't a valid ban, check raw_mask */
+ if(del_id(chptr, raw_mask, list, mode_type))
+ mask = raw_mask;
+ }
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = caps;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = mems;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = mask;
+ }
+}
+
+void
+chm_op(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ struct membership *mstptr;
+ const char *opnick;
+ struct Client *targ_p;
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if((dir == MODE_QUERY) || (parc <= *parn))
+ return;
+
+ opnick = parv[(*parn)];
+ (*parn)++;
+
+ /* empty nick */
+ if(EmptyString(opnick))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), "*");
+ return;
+ }
+
+ if((targ_p = find_chasing(source_p, opnick, NULL)) == NULL)
+ {
+ return;
+ }
+
+ mstptr = find_channel_membership(chptr, targ_p);
+
+ if(mstptr == NULL)
+ {
+ if(!(*errors & SM_ERR_NOTONCHANNEL) && MyClient(source_p))
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL), opnick, chptr->chname);
+ *errors |= SM_ERR_NOTONCHANNEL;
+ return;
+ }
+
+ if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
+ return;
+
+ if(dir == MODE_ADD)
+ {
+ if(targ_p == source_p)
+ return;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = targ_p->id;
+ mode_changes[mode_count].arg = targ_p->name;
+ mode_changes[mode_count++].client = targ_p;
+
+ mstptr->flags |= CHFL_CHANOP;
+ mstptr->flags &= ~CHFL_DEOPPED;
+ }
+ else
+ {
+ if(MyClient(source_p) && IsService(targ_p))
+ {
+ sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
+ me.name, source_p->name, targ_p->name, chptr->chname);
+ return;
+ }
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = targ_p->id;
+ mode_changes[mode_count].arg = targ_p->name;
+ mode_changes[mode_count++].client = targ_p;
+
+ mstptr->flags &= ~CHFL_CHANOP;
+ }
+}
+
+void
+chm_voice(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ struct membership *mstptr;
+ const char *opnick;
+ struct Client *targ_p;
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if((dir == MODE_QUERY) || parc <= *parn)
+ return;
+
+ opnick = parv[(*parn)];
+ (*parn)++;
+
+ /* empty nick */
+ if(EmptyString(opnick))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), "*");
+ return;
+ }
+
+ if((targ_p = find_chasing(source_p, opnick, NULL)) == NULL)
+ {
+ return;
+ }
+
+ mstptr = find_channel_membership(chptr, targ_p);
+
+ if(mstptr == NULL)
+ {
+ if(!(*errors & SM_ERR_NOTONCHANNEL) && MyClient(source_p))
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL), opnick, chptr->chname);
+ *errors |= SM_ERR_NOTONCHANNEL;
+ return;
+ }
+
+ if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
+ return;
+
+ if(dir == MODE_ADD)
+ {
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = targ_p->id;
+ mode_changes[mode_count].arg = targ_p->name;
+ mode_changes[mode_count++].client = targ_p;
+
+ mstptr->flags |= CHFL_VOICE;
+ }
+ else
+ {
+ mode_changes[mode_count].letter = 'v';
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = targ_p->id;
+ mode_changes[mode_count].arg = targ_p->name;
+ mode_changes[mode_count++].client = targ_p;
+
+ mstptr->flags &= ~CHFL_VOICE;
+ }
+}
+
+void
+chm_limit(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ const char *lstr;
+ static char limitstr[30];
+ int limit;
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if(dir == MODE_QUERY)
+ return;
+
+ if((dir == MODE_ADD) && parc > *parn)
+ {
+ lstr = parv[(*parn)];
+ (*parn)++;
+
+ if(EmptyString(lstr) || (limit = atoi(lstr)) <= 0)
+ return;
+
+ ircsprintf(limitstr, "%d", limit);
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = limitstr;
+
+ chptr->mode.limit = limit;
+ }
+ else if(dir == MODE_DEL)
+ {
+ if(!chptr->mode.limit)
+ return;
+
+ chptr->mode.limit = 0;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+ }
+}
+
+void
+chm_throttle(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ int joins = 0, timeslice = 0;
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if(dir == MODE_QUERY)
+ return;
+
+ if((dir == MODE_ADD) && parc > *parn)
+ {
+ sscanf(parv[(*parn)], "%d:%d", &joins, ×lice);
+
+ if(!joins || !timeslice)
+ return;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = parv[(*parn)];
+
+ (*parn)++;
+
+ chptr->mode.join_num = joins;
+ chptr->mode.join_time = timeslice;
+ }
+ else if(dir == MODE_DEL)
+ {
+ if(!chptr->mode.join_num)
+ return;
+
+ chptr->mode.join_num = 0;
+ chptr->mode.join_time = 0;
+ chptr->join_count = 0;
+ chptr->join_delta = 0;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+ }
+}
+
+void
+chm_forward(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ struct Channel *targptr = NULL;
+ struct membership *msptr;
+ const char *forward;
+
+ /* if +f is disabled, ignore local attempts to set it */
+ if(!ConfigChannel.use_forward && MyClient(source_p) &&
+ (dir == MODE_ADD) && (parc > *parn))
+ return;
+
+ if(dir == MODE_QUERY || (dir == MODE_ADD && parc <= *parn))
+ {
+ if (!(*errors & SM_ERR_RPL_F))
+ {
+ if (*chptr->mode.forward == '\0')
+ sendto_one(source_p, ":%s NOTICE %s :%s has no forward channel", me.name, source_p->name, chptr->chname);
+ else
+ sendto_one(source_p, ":%s NOTICE %s :%s forward channel is %s", me.name, source_p->name, chptr->chname, chptr->mode.forward);
+ *errors |= SM_ERR_RPL_F;
+ }
+ return;
+ }
+
+#ifndef FORWARD_OPERONLY
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+#else
+ if(!IsOper(source_p) && !IsServer(source_p))
+ {
+ if(!(*errors & SM_ERR_NOPRIVS))
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
+ *errors |= SM_ERR_NOPRIVS;
+ return;
+ }
+#endif
+
+ if(dir == MODE_ADD && parc > *parn)
+ {
+ forward = parv[(*parn)];
+ (*parn)++;
+
+ if(EmptyString(forward))
+ return;
+ if(!check_channel_name(forward) ||
+ (MyClient(source_p) && (strlen(forward) > LOC_CHANNELLEN || hash_find_resv(forward))))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), forward);
+ return;
+ }
+ /* don't forward to inconsistent target -- jilles */
+ if(chptr->chname[0] == '#' && forward[0] == '&')
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME,
+ form_str(ERR_BADCHANNAME), forward);
+ return;
+ }
+ if(MyClient(source_p) && (targptr = find_channel(forward)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), forward);
+ return;
+ }
+ if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET))
+ {
+ if((msptr = find_channel_membership(targptr, source_p)) == NULL ||
+ get_channel_access(source_p, msptr) != CHFL_CHANOP)
+ {
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, targptr->chname);
+ return;
+ }
+ }
+
+ strlcpy(chptr->mode.forward, forward, sizeof(chptr->mode.forward));
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ConfigChannel.use_forward ? ALL_MEMBERS : ONLY_SERVERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = forward;
+ }
+ else if(dir == MODE_DEL)
+ {
+ if(!(*chptr->mode.forward))
+ return;
+
+ *chptr->mode.forward = '\0';
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+ }
+}
+
+void
+chm_key(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ char *key;
+
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if(dir == MODE_QUERY)
+ return;
+
+ if((dir == MODE_ADD) && parc > *parn)
+ {
+ key = LOCAL_COPY(parv[(*parn)]);
+ (*parn)++;
+
+ if(MyClient(source_p))
+ fix_key(key);
+ else
+ fix_key_remote(key);
+
+ if(EmptyString(key))
+ return;
+
+ s_assert(key[0] != ' ');
+ strlcpy(chptr->mode.key, key, sizeof(chptr->mode.key));
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_ADD;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = chptr->mode.key;
+ }
+ else if(dir == MODE_DEL)
+ {
+ static char splat[] = "*";
+ int i;
+
+ if(parc > *parn)
+ (*parn)++;
+
+ if(!(*chptr->mode.key))
+ return;
+
+ /* hack time. when we get a +k-k mode, the +k arg is
+ * chptr->mode.key, which the -k sets to \0, so hunt for a
+ * +k when we get a -k, and set the arg to splat. --anfl
+ */
+ for(i = 0; i < mode_count; i++)
+ {
+ if(mode_changes[i].letter == 'k' && mode_changes[i].dir == MODE_ADD)
+ mode_changes[i].arg = splat;
+ }
+
+ *chptr->mode.key = 0;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = MODE_DEL;
+ mode_changes[mode_count].caps = 0;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = "*";
+ }
+}
+
+void
+chm_regonly(struct Client *source_p, struct Channel *chptr,
+ int alevel, int parc, int *parn,
+ const char **parv, int *errors, int dir, char c, long mode_type)
+{
+ if(alevel != CHFL_CHANOP)
+ {
+ if(!(*errors & SM_ERR_NOOPS))
+ sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+ me.name, source_p->name, chptr->chname);
+ *errors |= SM_ERR_NOOPS;
+ return;
+ }
+
+ if(dir == MODE_QUERY)
+ return;
+
+ if(((dir == MODE_ADD) && (chptr->mode.mode & MODE_REGONLY)) ||
+ ((dir == MODE_DEL) && !(chptr->mode.mode & MODE_REGONLY)))
+ return;
+
+ if(dir == MODE_ADD)
+ chptr->mode.mode |= MODE_REGONLY;
+ else
+ chptr->mode.mode &= ~MODE_REGONLY;
+
+ mode_changes[mode_count].letter = c;
+ mode_changes[mode_count].dir = dir;
+ mode_changes[mode_count].caps = CAP_SERVICE;
+ mode_changes[mode_count].nocaps = 0;
+ mode_changes[mode_count].mems = ALL_MEMBERS;
+ mode_changes[mode_count].id = NULL;
+ mode_changes[mode_count++].arg = NULL;
+}
+
+/* *INDENT-OFF* */
+struct ChannelMode chmode_table[256] =
+{
+ {chm_nosuch, 0 }, /* 0x00 */
+ {chm_nosuch, 0 }, /* 0x01 */
+ {chm_nosuch, 0 }, /* 0x02 */
+ {chm_nosuch, 0 }, /* 0x03 */
+ {chm_nosuch, 0 }, /* 0x04 */
+ {chm_nosuch, 0 }, /* 0x05 */
+ {chm_nosuch, 0 }, /* 0x06 */
+ {chm_nosuch, 0 }, /* 0x07 */
+ {chm_nosuch, 0 }, /* 0x08 */
+ {chm_nosuch, 0 }, /* 0x09 */
+ {chm_nosuch, 0 }, /* 0x0a */
+ {chm_nosuch, 0 }, /* 0x0b */
+ {chm_nosuch, 0 }, /* 0x0c */
+ {chm_nosuch, 0 }, /* 0x0d */
+ {chm_nosuch, 0 }, /* 0x0e */
+ {chm_nosuch, 0 }, /* 0x0f */
+ {chm_nosuch, 0 }, /* 0x10 */
+ {chm_nosuch, 0 }, /* 0x11 */
+ {chm_nosuch, 0 }, /* 0x12 */
+ {chm_nosuch, 0 }, /* 0x13 */
+ {chm_nosuch, 0 }, /* 0x14 */
+ {chm_nosuch, 0 }, /* 0x15 */
+ {chm_nosuch, 0 }, /* 0x16 */
+ {chm_nosuch, 0 }, /* 0x17 */
+ {chm_nosuch, 0 }, /* 0x18 */
+ {chm_nosuch, 0 }, /* 0x19 */
+ {chm_nosuch, 0 }, /* 0x1a */
+ {chm_nosuch, 0 }, /* 0x1b */
+ {chm_nosuch, 0 }, /* 0x1c */
+ {chm_nosuch, 0 }, /* 0x1d */
+ {chm_nosuch, 0 }, /* 0x1e */
+ {chm_nosuch, 0 }, /* 0x1f */
+ {chm_nosuch, 0 }, /* 0x20 */
+ {chm_nosuch, 0 }, /* 0x21 */
+ {chm_nosuch, 0 }, /* 0x22 */
+ {chm_nosuch, 0 }, /* 0x23 */
+ {chm_nosuch, 0 }, /* 0x24 */
+ {chm_nosuch, 0 }, /* 0x25 */
+ {chm_nosuch, 0 }, /* 0x26 */
+ {chm_nosuch, 0 }, /* 0x27 */
+ {chm_nosuch, 0 }, /* 0x28 */
+ {chm_nosuch, 0 }, /* 0x29 */
+ {chm_nosuch, 0 }, /* 0x2a */
+ {chm_nosuch, 0 }, /* 0x2b */
+ {chm_nosuch, 0 }, /* 0x2c */
+ {chm_nosuch, 0 }, /* 0x2d */
+ {chm_nosuch, 0 }, /* 0x2e */
+ {chm_nosuch, 0 }, /* 0x2f */
+ {chm_nosuch, 0 }, /* 0x30 */
+ {chm_nosuch, 0 }, /* 0x31 */
+ {chm_nosuch, 0 }, /* 0x32 */
+ {chm_nosuch, 0 }, /* 0x33 */
+ {chm_nosuch, 0 }, /* 0x34 */
+ {chm_nosuch, 0 }, /* 0x35 */
+ {chm_nosuch, 0 }, /* 0x36 */
+ {chm_nosuch, 0 }, /* 0x37 */
+ {chm_nosuch, 0 }, /* 0x38 */
+ {chm_nosuch, 0 }, /* 0x39 */
+ {chm_nosuch, 0 }, /* 0x3a */
+ {chm_nosuch, 0 }, /* 0x3b */
+ {chm_nosuch, 0 }, /* 0x3c */
+ {chm_nosuch, 0 }, /* 0x3d */
+ {chm_nosuch, 0 }, /* 0x3e */
+ {chm_nosuch, 0 }, /* 0x3f */
+
+ {chm_nosuch, 0 }, /* @ */
+ {chm_nosuch, 0 }, /* A */
+ {chm_nosuch, 0 }, /* B */
+ {chm_nosuch, 0 }, /* C */
+ {chm_nosuch, 0 }, /* D */
+ {chm_nosuch, 0 }, /* E */
+ {chm_simple, MODE_FREETARGET }, /* F */
+ {chm_nosuch, 0 }, /* G */
+ {chm_nosuch, 0 }, /* H */
+ {chm_ban, CHFL_INVEX }, /* I */
+ {chm_nosuch, 0 }, /* J */
+ {chm_nosuch, 0 }, /* K */
+ {chm_staff, MODE_EXLIMIT }, /* L */
+ {chm_nosuch, 0 }, /* M */
+ {chm_nosuch, 0 }, /* N */
+ {chm_nosuch, 0 }, /* O */
+ {chm_staff, MODE_PERMANENT }, /* P */
+ {chm_simple, MODE_DISFORWARD }, /* Q */
+ {chm_nosuch, 0 }, /* R */
+ {chm_nosuch, 0 }, /* S */
+ {chm_nosuch, 0 }, /* T */
+ {chm_nosuch, 0 }, /* U */
+ {chm_nosuch, 0 }, /* V */
+ {chm_nosuch, 0 }, /* W */
+ {chm_nosuch, 0 }, /* X */
+ {chm_nosuch, 0 }, /* Y */
+ {chm_nosuch, 0 }, /* Z */
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 },
+ {chm_nosuch, 0 }, /* a */
+ {chm_ban, CHFL_BAN }, /* b */
+ {chm_simple, MODE_NOCOLOR }, /* c */
+ {chm_nosuch, 0 }, /* d */
+ {chm_ban, CHFL_EXCEPTION }, /* e */
+ {chm_forward, 0 }, /* f */
+ {chm_simple, MODE_FREEINVITE }, /* g */
+ {chm_nosuch, 0 }, /* h */
+ {chm_simple, MODE_INVITEONLY }, /* i */
+ {chm_throttle, 0 }, /* j */
+ {chm_key, 0 }, /* k */
+ {chm_limit, 0 }, /* l */
+ {chm_simple, MODE_MODERATED }, /* m */
+ {chm_simple, MODE_NOPRIVMSGS }, /* n */
+ {chm_op, 0 }, /* o */
+ {chm_simple, MODE_PRIVATE }, /* p */
+ {chm_ban, CHFL_QUIET }, /* q */
+ {chm_regonly, 0 }, /* r */
+ {chm_simple, MODE_SECRET }, /* s */
+ {chm_simple, MODE_TOPICLIMIT }, /* t */
+ {chm_nosuch, 0 }, /* u */
+ {chm_voice, 0 }, /* v */
+ {chm_nosuch, 0 }, /* w */
+ {chm_nosuch, 0 }, /* x */
+ {chm_nosuch, 0 }, /* y */
+ {chm_simple, MODE_OPMODERATE }, /* z */
+
+ {chm_nosuch, 0 }, /* 0x7b */
+ {chm_nosuch, 0 }, /* 0x7c */
+ {chm_nosuch, 0 }, /* 0x7d */
+ {chm_nosuch, 0 }, /* 0x7e */
+ {chm_nosuch, 0 }, /* 0x7f */
+
+ {chm_nosuch, 0 }, /* 0x80 */
+ {chm_nosuch, 0 }, /* 0x81 */
+ {chm_nosuch, 0 }, /* 0x82 */
+ {chm_nosuch, 0 }, /* 0x83 */
+ {chm_nosuch, 0 }, /* 0x84 */
+ {chm_nosuch, 0 }, /* 0x85 */
+ {chm_nosuch, 0 }, /* 0x86 */
+ {chm_nosuch, 0 }, /* 0x87 */
+ {chm_nosuch, 0 }, /* 0x88 */
+ {chm_nosuch, 0 }, /* 0x89 */
+ {chm_nosuch, 0 }, /* 0x8a */
+ {chm_nosuch, 0 }, /* 0x8b */
+ {chm_nosuch, 0 }, /* 0x8c */
+ {chm_nosuch, 0 }, /* 0x8d */
+ {chm_nosuch, 0 }, /* 0x8e */
+ {chm_nosuch, 0 }, /* 0x8f */
+
+ {chm_nosuch, 0 }, /* 0x90 */
+ {chm_nosuch, 0 }, /* 0x91 */
+ {chm_nosuch, 0 }, /* 0x92 */
+ {chm_nosuch, 0 }, /* 0x93 */
+ {chm_nosuch, 0 }, /* 0x94 */
+ {chm_nosuch, 0 }, /* 0x95 */
+ {chm_nosuch, 0 }, /* 0x96 */
+ {chm_nosuch, 0 }, /* 0x97 */
+ {chm_nosuch, 0 }, /* 0x98 */
+ {chm_nosuch, 0 }, /* 0x99 */
+ {chm_nosuch, 0 }, /* 0x9a */
+ {chm_nosuch, 0 }, /* 0x9b */
+ {chm_nosuch, 0 }, /* 0x9c */
+ {chm_nosuch, 0 }, /* 0x9d */
+ {chm_nosuch, 0 }, /* 0x9e */
+ {chm_nosuch, 0 }, /* 0x9f */
+
+ {chm_nosuch, 0 }, /* 0xa0 */
+ {chm_nosuch, 0 }, /* 0xa1 */
+ {chm_nosuch, 0 }, /* 0xa2 */
+ {chm_nosuch, 0 }, /* 0xa3 */
+ {chm_nosuch, 0 }, /* 0xa4 */
+ {chm_nosuch, 0 }, /* 0xa5 */
+ {chm_nosuch, 0 }, /* 0xa6 */
+ {chm_nosuch, 0 }, /* 0xa7 */
+ {chm_nosuch, 0 }, /* 0xa8 */
+ {chm_nosuch, 0 }, /* 0xa9 */
+ {chm_nosuch, 0 }, /* 0xaa */
+ {chm_nosuch, 0 }, /* 0xab */
+ {chm_nosuch, 0 }, /* 0xac */
+ {chm_nosuch, 0 }, /* 0xad */
+ {chm_nosuch, 0 }, /* 0xae */
+ {chm_nosuch, 0 }, /* 0xaf */
+
+ {chm_nosuch, 0 }, /* 0xb0 */
+ {chm_nosuch, 0 }, /* 0xb1 */
+ {chm_nosuch, 0 }, /* 0xb2 */
+ {chm_nosuch, 0 }, /* 0xb3 */
+ {chm_nosuch, 0 }, /* 0xb4 */
+ {chm_nosuch, 0 }, /* 0xb5 */
+ {chm_nosuch, 0 }, /* 0xb6 */
+ {chm_nosuch, 0 }, /* 0xb7 */
+ {chm_nosuch, 0 }, /* 0xb8 */
+ {chm_nosuch, 0 }, /* 0xb9 */
+ {chm_nosuch, 0 }, /* 0xba */
+ {chm_nosuch, 0 }, /* 0xbb */
+ {chm_nosuch, 0 }, /* 0xbc */
+ {chm_nosuch, 0 }, /* 0xbd */
+ {chm_nosuch, 0 }, /* 0xbe */
+ {chm_nosuch, 0 }, /* 0xbf */
+
+ {chm_nosuch, 0 }, /* 0xc0 */
+ {chm_nosuch, 0 }, /* 0xc1 */
+ {chm_nosuch, 0 }, /* 0xc2 */
+ {chm_nosuch, 0 }, /* 0xc3 */
+ {chm_nosuch, 0 }, /* 0xc4 */
+ {chm_nosuch, 0 }, /* 0xc5 */
+ {chm_nosuch, 0 }, /* 0xc6 */
+ {chm_nosuch, 0 }, /* 0xc7 */
+ {chm_nosuch, 0 }, /* 0xc8 */
+ {chm_nosuch, 0 }, /* 0xc9 */
+ {chm_nosuch, 0 }, /* 0xca */
+ {chm_nosuch, 0 }, /* 0xcb */
+ {chm_nosuch, 0 }, /* 0xcc */
+ {chm_nosuch, 0 }, /* 0xcd */
+ {chm_nosuch, 0 }, /* 0xce */
+ {chm_nosuch, 0 }, /* 0xcf */
+
+ {chm_nosuch, 0 }, /* 0xd0 */
+ {chm_nosuch, 0 }, /* 0xd1 */
+ {chm_nosuch, 0 }, /* 0xd2 */
+ {chm_nosuch, 0 }, /* 0xd3 */
+ {chm_nosuch, 0 }, /* 0xd4 */
+ {chm_nosuch, 0 }, /* 0xd5 */
+ {chm_nosuch, 0 }, /* 0xd6 */
+ {chm_nosuch, 0 }, /* 0xd7 */
+ {chm_nosuch, 0 }, /* 0xd8 */
+ {chm_nosuch, 0 }, /* 0xd9 */
+ {chm_nosuch, 0 }, /* 0xda */
+ {chm_nosuch, 0 }, /* 0xdb */
+ {chm_nosuch, 0 }, /* 0xdc */
+ {chm_nosuch, 0 }, /* 0xdd */
+ {chm_nosuch, 0 }, /* 0xde */
+ {chm_nosuch, 0 }, /* 0xdf */
+
+ {chm_nosuch, 0 }, /* 0xe0 */
+ {chm_nosuch, 0 }, /* 0xe1 */
+ {chm_nosuch, 0 }, /* 0xe2 */
+ {chm_nosuch, 0 }, /* 0xe3 */
+ {chm_nosuch, 0 }, /* 0xe4 */
+ {chm_nosuch, 0 }, /* 0xe5 */
+ {chm_nosuch, 0 }, /* 0xe6 */
+ {chm_nosuch, 0 }, /* 0xe7 */
+ {chm_nosuch, 0 }, /* 0xe8 */
+ {chm_nosuch, 0 }, /* 0xe9 */
+ {chm_nosuch, 0 }, /* 0xea */
+ {chm_nosuch, 0 }, /* 0xeb */
+ {chm_nosuch, 0 }, /* 0xec */
+ {chm_nosuch, 0 }, /* 0xed */
+ {chm_nosuch, 0 }, /* 0xee */
+ {chm_nosuch, 0 }, /* 0xef */
+
+ {chm_nosuch, 0 }, /* 0xf0 */
+ {chm_nosuch, 0 }, /* 0xf1 */
+ {chm_nosuch, 0 }, /* 0xf2 */
+ {chm_nosuch, 0 }, /* 0xf3 */
+ {chm_nosuch, 0 }, /* 0xf4 */
+ {chm_nosuch, 0 }, /* 0xf5 */
+ {chm_nosuch, 0 }, /* 0xf6 */
+ {chm_nosuch, 0 }, /* 0xf7 */
+ {chm_nosuch, 0 }, /* 0xf8 */
+ {chm_nosuch, 0 }, /* 0xf9 */
+ {chm_nosuch, 0 }, /* 0xfa */
+ {chm_nosuch, 0 }, /* 0xfb */
+ {chm_nosuch, 0 }, /* 0xfc */
+ {chm_nosuch, 0 }, /* 0xfd */
+ {chm_nosuch, 0 }, /* 0xfe */
+ {chm_nosuch, 0 }, /* 0xff */
+};
+
+/* *INDENT-ON* */
+
+/* set_channel_mode()
+ *
+ * inputs - client, source, channel, membership pointer, params
+ * output -
+ * side effects - channel modes/memberships are changed, MODE is issued
+ *
+ * Extensively modified to be hotpluggable, 03/09/06 -- nenolod
+ */
+void
+set_channel_mode(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, struct membership *msptr, int parc, const char *parv[])
+{
+ static char modebuf[BUFSIZE];
+ static char parabuf[BUFSIZE];
+ char *mbuf;
+ char *pbuf;
+ int cur_len, mlen, paralen, paracount, arglen, len;
+ int i, j, flags;
+ int dir = MODE_ADD;
+ int parn = 1;
+ int errors = 0;
+ int alevel;
+ const char *ml = parv[0];
+ char c;
+ struct Client *fakesource_p;
+
+ mask_pos = 0;
+ mode_count = 0;
+ mode_limit = 0;
+
+ alevel = get_channel_access(source_p, msptr);
+
+ /* Hide connecting server on netburst -- jilles */
+ if (ConfigServerHide.flatten_links && IsServer(source_p) && !has_id(source_p) && !HasSentEob(source_p))
+ fakesource_p = &me;
+ else
+ fakesource_p = source_p;
+
+ for(; (c = *ml) != 0; ml++)
+ {
+ switch (c)
+ {
+ case '+':
+ dir = MODE_ADD;
+ break;
+ case '-':
+ dir = MODE_DEL;
+ break;
+ case '=':
+ dir = MODE_QUERY;
+ break;
+ default:
+ chmode_table[(unsigned char) c].set_func(fakesource_p, chptr, alevel,
+ parc, &parn, parv,
+ &errors, dir, c,
+ chmode_table[(unsigned char) c].mode_type);
+ break;
+ }
+ }
+
+ /* bail out if we have nothing to do... */
+ if(!mode_count)
+ return;
+
+ if(IsServer(source_p))
+ mlen = ircsprintf(modebuf, ":%s MODE %s ", fakesource_p->name, chptr->chname);
+ else
+ mlen = ircsprintf(modebuf, ":%s!%s@%s MODE %s ",
+ source_p->name, source_p->username,
+ source_p->host, chptr->chname);
+
+ for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS)
+ {
+ cur_len = mlen;
+ mbuf = modebuf + mlen;
+ pbuf = parabuf;
+ parabuf[0] = '\0';
+ paracount = paralen = 0;
+ dir = MODE_QUERY;
+
+ for(i = 0; i < mode_count; i++)
+ {
+ if(mode_changes[i].letter == 0 || mode_changes[i].mems != flags)
+ continue;
+
+ if(mode_changes[i].arg != NULL)
+ {
+ arglen = strlen(mode_changes[i].arg);
+
+ if(arglen > MODEBUFLEN - 5)
+ continue;
+ }
+ else
+ arglen = 0;
+
+ /* if we're creeping over MAXMODEPARAMSSERV, or over
+ * bufsize (4 == +/-,modechar,two spaces) send now.
+ */
+ if(mode_changes[i].arg != NULL &&
+ ((paracount == MAXMODEPARAMSSERV) ||
+ ((cur_len + paralen + arglen + 4) > (BUFSIZE - 3))))
+ {
+ *mbuf = '\0';
+
+ if(cur_len > mlen)
+ sendto_channel_local(flags, chptr, "%s %s", modebuf,
+ parabuf);
+ else
+ continue;
+
+ paracount = paralen = 0;
+ cur_len = mlen;
+ mbuf = modebuf + mlen;
+ pbuf = parabuf;
+ parabuf[0] = '\0';
+ dir = MODE_QUERY;
+ }
+
+ if(dir != mode_changes[i].dir)
+ {
+ *mbuf++ = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
+ cur_len++;
+ dir = mode_changes[i].dir;
+ }
+
+ *mbuf++ = mode_changes[i].letter;
+ cur_len++;
+
+ if(mode_changes[i].arg != NULL)
+ {
+ paracount++;
+ len = ircsprintf(pbuf, "%s ", mode_changes[i].arg);
+ pbuf += len;
+ paralen += len;
+ }
+ }
+
+ if(paralen && parabuf[paralen - 1] == ' ')
+ parabuf[paralen - 1] = '\0';
+
+ *mbuf = '\0';
+ if(cur_len > mlen)
+ sendto_channel_local(flags, chptr, "%s %s", modebuf, parabuf);
+ }
+
+ /* only propagate modes originating locally, or if we're hubbing */
+ if(MyClient(source_p) || dlink_list_length(&serv_list) > 1)
+ send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * class.c: Controls connection classes.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: class.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "config.h"
+
+#include "tools.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "irc_string.h"
+#include "memory.h"
+#include "patricia.h"
+
+#define BAD_CONF_CLASS -1
+#define BAD_PING -2
+#define BAD_CLIENT_CLASS -3
+
+dlink_list class_list;
+struct Class *default_class;
+
+struct Class *
+make_class(void)
+{
+ struct Class *tmp;
+
+ tmp = (struct Class *) MyMalloc(sizeof(struct Class));
+
+ ConFreq(tmp) = DEFAULT_CONNECTFREQUENCY;
+ PingFreq(tmp) = DEFAULT_PINGFREQUENCY;
+ MaxUsers(tmp) = 1;
+ MaxSendq(tmp) = DEFAULT_SENDQ;
+
+ tmp->ip_limits = New_Patricia(PATRICIA_BITS);
+ return tmp;
+}
+
+void
+free_class(struct Class *tmp)
+{
+ if(tmp->ip_limits)
+ Destroy_Patricia(tmp->ip_limits, NULL);
+
+ MyFree(tmp->class_name);
+ MyFree(tmp);
+
+}
+
+/*
+ * get_conf_ping
+ *
+ * inputs - pointer to struct ConfItem
+ * output - ping frequency
+ * side effects - NONE
+ */
+static int
+get_conf_ping(struct ConfItem *aconf)
+{
+ if((aconf) && ClassPtr(aconf))
+ return (ConfPingFreq(aconf));
+
+ return (BAD_PING);
+}
+
+/*
+ * get_client_class
+ *
+ * inputs - pointer to client struct
+ * output - pointer to name of class
+ * side effects - NONE
+ */
+const char *
+get_client_class(struct Client *target_p)
+{
+ const char *retc = "unknown";
+
+ if(target_p == NULL || IsMe(target_p))
+ return retc;
+
+ if(IsServer(target_p))
+ {
+ struct server_conf *server_p = target_p->localClient->att_sconf;
+ return server_p->class_name;
+ }
+ else
+ {
+ struct ConfItem *aconf;
+ aconf = target_p->localClient->att_conf;
+
+ if((aconf == NULL) || (aconf->className == NULL))
+ retc = "default";
+ else
+ retc = aconf->className;
+ }
+
+ return (retc);
+}
+
+/*
+ * get_client_ping
+ *
+ * inputs - pointer to client struct
+ * output - ping frequency
+ * side effects - NONE
+ */
+int
+get_client_ping(struct Client *target_p)
+{
+ int ping = 0;
+
+ if(IsServer(target_p))
+ {
+ struct server_conf *server_p = target_p->localClient->att_sconf;
+ ping = PingFreq(server_p->class);
+ }
+ else
+ {
+ struct ConfItem *aconf;
+
+ aconf = target_p->localClient->att_conf;
+
+ if(aconf != NULL)
+ ping = get_conf_ping(aconf);
+ else
+ ping = DEFAULT_PINGFREQUENCY;
+ }
+
+ if(ping <= 0)
+ ping = DEFAULT_PINGFREQUENCY;
+
+ return ping;
+}
+
+/*
+ * get_con_freq
+ *
+ * inputs - pointer to class struct
+ * output - connection frequency
+ * side effects - NONE
+ */
+int
+get_con_freq(struct Class *clptr)
+{
+ if(clptr)
+ return (ConFreq(clptr));
+ return (DEFAULT_CONNECTFREQUENCY);
+}
+
+/* add_class()
+ *
+ * input - class to add
+ * output -
+ * side effects - class is added to class_list if new, else old class
+ * is updated with new values.
+ */
+void
+add_class(struct Class *classptr)
+{
+ struct Class *tmpptr;
+
+ tmpptr = find_class(classptr->class_name);
+
+ if(tmpptr == default_class)
+ {
+ dlinkAddAlloc(classptr, &class_list);
+ CurrUsers(classptr) = 0;
+ }
+ else
+ {
+ MaxUsers(tmpptr) = MaxUsers(classptr);
+ MaxLocal(tmpptr) = MaxLocal(classptr);
+ MaxGlobal(tmpptr) = MaxGlobal(classptr);
+ MaxIdent(tmpptr) = MaxIdent(classptr);
+ PingFreq(tmpptr) = PingFreq(classptr);
+ MaxSendq(tmpptr) = MaxSendq(classptr);
+ ConFreq(tmpptr) = ConFreq(classptr);
+ CidrBitlen(tmpptr) = CidrBitlen(classptr);
+ CidrAmount(tmpptr) = CidrAmount(classptr);
+
+ free_class(classptr);
+ }
+}
+
+
+/*
+ * find_class
+ *
+ * inputs - string name of class
+ * output - corresponding class pointer
+ * side effects - NONE
+ */
+struct Class *
+find_class(const char *classname)
+{
+ struct Class *cltmp;
+ dlink_node *ptr;
+
+ if(classname == NULL)
+ return default_class;
+
+ DLINK_FOREACH(ptr, class_list.head)
+ {
+ cltmp = ptr->data;
+
+ if(!strcmp(ClassName(cltmp), classname))
+ return cltmp;
+ }
+
+ return default_class;
+}
+
+/*
+ * check_class
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects -
+ */
+void
+check_class()
+{
+ struct Class *cltmp;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, class_list.head)
+ {
+ cltmp = ptr->data;
+
+ if(MaxUsers(cltmp) < 0)
+ {
+ dlinkDestroy(ptr, &class_list);
+ if(CurrUsers(cltmp) <= 0)
+ free_class(cltmp);
+ }
+ }
+}
+
+/*
+ * initclass
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects -
+ */
+void
+initclass()
+{
+ default_class = make_class();
+ DupString(ClassName(default_class), "default");
+}
+
+/*
+ * report_classes
+ *
+ * inputs - pointer to client to report to
+ * output - NONE
+ * side effects - class report is done to this client
+ */
+void
+report_classes(struct Client *source_p)
+{
+ struct Class *cltmp;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, class_list.head)
+ {
+ cltmp = ptr->data;
+
+ sendto_one_numeric(source_p, RPL_STATSYLINE,
+ form_str(RPL_STATSYLINE),
+ ClassName(cltmp), PingFreq(cltmp),
+ ConFreq(cltmp), MaxUsers(cltmp),
+ MaxSendq(cltmp),
+ MaxLocal(cltmp), MaxIdent(cltmp),
+ MaxGlobal(cltmp), MaxIdent(cltmp),
+ CurrUsers(cltmp));
+ }
+
+ /* also output the default class */
+ sendto_one_numeric(source_p, RPL_STATSYLINE, form_str(RPL_STATSYLINE),
+ ClassName(default_class), PingFreq(default_class),
+ ConFreq(default_class), MaxUsers(default_class),
+ MaxSendq(default_class),
+ MaxLocal(default_class), MaxIdent(default_class),
+ MaxGlobal(default_class), MaxIdent(default_class),
+ CurrUsers(default_class));
+}
+
+/*
+ * get_sendq
+ *
+ * inputs - pointer to client
+ * output - sendq for this client as found from its class
+ * side effects - NONE
+ */
+long
+get_sendq(struct Client *client_p)
+{
+ if(client_p == NULL || IsMe(client_p))
+ return DEFAULT_SENDQ;
+
+ if(IsServer(client_p))
+ {
+ struct server_conf *server_p;
+ server_p = client_p->localClient->att_sconf;
+ return MaxSendq(server_p->class);
+ }
+ else
+ {
+ struct ConfItem *aconf = client_p->localClient->att_conf;
+
+ if(aconf != NULL && aconf->status & CONF_CLIENT)
+ return ConfMaxSendq(aconf);
+ }
+
+ return DEFAULT_SENDQ;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * client.c: Controls clients.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: client.c 1861 2006-08-26 23:21:42Z jilles $
+ */
+#include "stdinc.h"
+#include "config.h"
+
+#include "tools.h"
+#include "client.h"
+#include "class.h"
+#include "common.h"
+#include "event.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "s_gline.h"
+#include "numeric.h"
+#include "packet.h"
+#include "s_auth.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_stats.h"
+#include "send.h"
+#include "whowas.h"
+#include "s_user.h"
+#include "linebuf.h"
+#include "hash.h"
+#include "memory.h"
+#include "hostmask.h"
+#include "balloc.h"
+#include "listener.h"
+#include "hook.h"
+#include "msg.h"
+#include "monitor.h"
+#include "blacklist.h"
+
+#define DEBUG_EXITED_CLIENTS
+
+static void check_pings_list(dlink_list * list);
+static void check_unknowns_list(dlink_list * list);
+static void free_exited_clients(void *unused);
+static void exit_aborted_clients(void *unused);
+
+static int exit_remote_client(struct Client *, struct Client *, struct Client *,const char *);
+static int exit_remote_server(struct Client *, struct Client *, struct Client *,const char *);
+static int exit_local_client(struct Client *, struct Client *, struct Client *,const char *);
+static int exit_unknown_client(struct Client *, struct Client *, struct Client *,const char *);
+static int exit_local_server(struct Client *, struct Client *, struct Client *,const char *);
+static int qs_server(struct Client *, struct Client *, struct Client *, const char *comment);
+
+static EVH check_pings;
+
+extern BlockHeap *client_heap;
+extern BlockHeap *lclient_heap;
+extern BlockHeap *pclient_heap;
+
+extern char current_uid[IDLEN];
+
+enum
+{
+ D_LINED,
+ K_LINED,
+ G_LINED
+};
+
+dlink_list dead_list;
+#ifdef DEBUG_EXITED_CLIENTS
+static dlink_list dead_remote_list;
+#endif
+
+struct abort_client
+{
+ dlink_node node;
+ struct Client *client;
+ char notice[REASONLEN];
+};
+
+static dlink_list abort_list;
+
+
+/*
+ * init_client
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects - initialize client free memory
+ */
+void
+init_client(void)
+{
+ /*
+ * start off the check ping event .. -- adrian
+ * Every 30 seconds is plenty -- db
+ */
+ client_heap = BlockHeapCreate(sizeof(struct Client), CLIENT_HEAP_SIZE);
+ lclient_heap = BlockHeapCreate(sizeof(struct LocalUser), LCLIENT_HEAP_SIZE);
+ pclient_heap = BlockHeapCreate(sizeof(struct PreClient), PCLIENT_HEAP_SIZE);
+ eventAddIsh("check_pings", check_pings, NULL, 30);
+ eventAddIsh("free_exited_clients", &free_exited_clients, NULL, 4);
+ eventAddIsh("exit_aborted_clients", exit_aborted_clients, NULL, 1);
+}
+
+
+/*
+ * make_client - create a new Client struct and set it to initial state.
+ *
+ * from == NULL, create local client (a client connected
+ * to a socket).
+ *
+ * from, create remote client (behind a socket
+ * associated with the client defined by
+ * 'from'). ('from' is a local client!!).
+ */
+struct Client *
+make_client(struct Client *from)
+{
+ struct Client *client_p = NULL;
+ struct LocalUser *localClient;
+
+ client_p = BlockHeapAlloc(client_heap);
+
+ if(from == NULL)
+ {
+ client_p->from = client_p; /* 'from' of local client is self! */
+
+ localClient = (struct LocalUser *) BlockHeapAlloc(lclient_heap);
+ SetMyConnect(client_p);
+ client_p->localClient = localClient;
+
+ client_p->localClient->lasttime = client_p->localClient->firsttime = CurrentTime;
+
+ client_p->localClient->fd = -1;
+ client_p->localClient->ctrlfd = -1;
+
+ client_p->preClient = (struct PreClient *) BlockHeapAlloc(pclient_heap);
+
+ /* as good a place as any... */
+ dlinkAdd(client_p, &client_p->localClient->tnode, &unknown_list);
+ }
+ else
+ { /* from is not NULL */
+ client_p->localClient = NULL;
+ client_p->preClient = NULL;
+ client_p->from = from; /* 'from' of local client is self! */
+ }
+
+ SetUnknown(client_p);
+ strcpy(client_p->username, "unknown");
+
+ return client_p;
+}
+
+void
+free_pre_client(struct Client *client_p)
+{
+ struct Blacklist *blptr;
+
+ s_assert(NULL != client_p);
+
+ if(client_p->preClient == NULL)
+ return;
+
+ blptr = client_p->preClient->dnsbl_listed;
+ if (blptr != NULL)
+ unref_blacklist(blptr);
+ abort_blacklist_queries(client_p);
+ BlockHeapFree(pclient_heap, client_p->preClient);
+ client_p->preClient = NULL;
+}
+
+static void
+free_local_client(struct Client *client_p)
+{
+ s_assert(NULL != client_p);
+ s_assert(&me != client_p);
+
+ if(client_p->localClient == NULL)
+ return;
+
+ /*
+ * clean up extra sockets from P-lines which have been discarded.
+ */
+ if(client_p->localClient->listener)
+ {
+ s_assert(0 < client_p->localClient->listener->ref_count);
+ if(0 == --client_p->localClient->listener->ref_count
+ && !client_p->localClient->listener->active)
+ free_listener(client_p->localClient->listener);
+ client_p->localClient->listener = 0;
+ }
+
+ if(client_p->localClient->fd >= 0)
+ comm_close(client_p->localClient->fd);
+
+ if(client_p->localClient->passwd)
+ {
+ memset(client_p->localClient->passwd, 0,
+ strlen(client_p->localClient->passwd));
+ MyFree(client_p->localClient->passwd);
+ }
+
+ MyFree(client_p->localClient->challenge);
+ MyFree(client_p->localClient->fullcaps);
+ MyFree(client_p->localClient->opername);
+ MyFree(client_p->localClient->mangledhost);
+
+ BlockHeapFree(lclient_heap, client_p->localClient);
+ client_p->localClient = NULL;
+}
+
+void
+free_client(struct Client *client_p)
+{
+ s_assert(NULL != client_p);
+ s_assert(&me != client_p);
+ free_local_client(client_p);
+ free_pre_client(client_p);
+ BlockHeapFree(client_heap, client_p);
+}
+
+/*
+ * check_pings - go through the local client list and check activity
+ * kill off stuff that should die
+ *
+ * inputs - NOT USED (from event)
+ * output - next time_t when check_pings() should be called again
+ * side effects -
+ *
+ *
+ * A PING can be sent to clients as necessary.
+ *
+ * Client/Server ping outs are handled.
+ */
+
+/*
+ * Addon from adrian. We used to call this after nextping seconds,
+ * however I've changed it to run once a second. This is only for
+ * PING timeouts, not K/etc-line checks (thanks dianora!). Having it
+ * run once a second makes life a lot easier - when a new client connects
+ * and they need a ping in 4 seconds, if nextping was set to 20 seconds
+ * we end up waiting 20 seconds. This is stupid. :-)
+ * I will optimise (hah!) check_pings() once I've finished working on
+ * tidying up other network IO evilnesses.
+ * -- adrian
+ */
+
+static void
+check_pings(void *notused)
+{
+ check_pings_list(&lclient_list);
+ check_pings_list(&serv_list);
+ check_unknowns_list(&unknown_list);
+}
+
+/*
+ * Check_pings_list()
+ *
+ * inputs - pointer to list to check
+ * output - NONE
+ * side effects -
+ */
+static void
+check_pings_list(dlink_list * list)
+{
+ char scratch[32]; /* way too generous but... */
+ struct Client *client_p; /* current local client_p being examined */
+ int ping = 0; /* ping time value from client */
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
+ {
+ client_p = ptr->data;
+
+ /*
+ ** Note: No need to notify opers here. It's
+ ** already done when "FLAGS_DEADSOCKET" is set.
+ */
+ if(!MyConnect(client_p) || IsDead(client_p))
+ continue;
+
+ if(IsPerson(client_p))
+ {
+ if(!IsExemptKline(client_p) &&
+ GlobalSetOptions.idletime &&
+ !IsOper(client_p) &&
+ !IsIdlelined(client_p) &&
+ ((CurrentTime - client_p->localClient->last) > GlobalSetOptions.idletime))
+ {
+ struct ConfItem *aconf;
+
+ aconf = make_conf();
+ aconf->status = CONF_KILL;
+
+ DupString(aconf->host, client_p->host);
+ DupString(aconf->passwd, "idle exceeder");
+ DupString(aconf->user, client_p->username);
+ aconf->port = 0;
+ aconf->hold = CurrentTime + 60;
+ add_temp_kline(aconf);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Idle time limit exceeded for %s - temp k-lining",
+ get_client_name(client_p, HIDE_IP));
+
+ exit_client(client_p, client_p, &me, aconf->passwd);
+ continue;
+ }
+ }
+
+ if(!IsRegistered(client_p))
+ ping = ConfigFileEntry.connect_timeout;
+ else
+ ping = get_client_ping(client_p);
+
+ if(ping < (CurrentTime - client_p->localClient->lasttime))
+ {
+ /*
+ * If the client/server hasnt talked to us in 2*ping seconds
+ * and it has a ping time, then close its connection.
+ */
+ if(((CurrentTime - client_p->localClient->lasttime) >= (2 * ping)
+ && (client_p->flags & FLAGS_PINGSENT)))
+ {
+ if(IsAnyServer(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL,
+ "No response from %s, closing link",
+ get_server_name(client_p, HIDE_IP));
+ ilog(L_SERVER,
+ "No response from %s, closing link",
+ log_client_name(client_p, HIDE_IP));
+ }
+ (void) ircsnprintf(scratch, sizeof(scratch),
+ "Ping timeout: %d seconds",
+ (int) (CurrentTime - client_p->localClient->lasttime));
+
+ exit_client(client_p, client_p, &me, scratch);
+ continue;
+ }
+ else if((client_p->flags & FLAGS_PINGSENT) == 0)
+ {
+ /*
+ * if we havent PINGed the connection and we havent
+ * heard from it in a while, PING it to make sure
+ * it is still alive.
+ */
+ client_p->flags |= FLAGS_PINGSENT;
+ /* not nice but does the job */
+ client_p->localClient->lasttime = CurrentTime - ping;
+ sendto_one(client_p, "PING :%s", me.name);
+ }
+ }
+ /* ping_timeout: */
+
+ }
+}
+
+/*
+ * check_unknowns_list
+ *
+ * inputs - pointer to list of unknown clients
+ * output - NONE
+ * side effects - unknown clients get marked for termination after n seconds
+ */
+static void
+check_unknowns_list(dlink_list * list)
+{
+ dlink_node *ptr, *next_ptr;
+ struct Client *client_p;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
+ {
+ client_p = ptr->data;
+
+ if(IsDead(client_p) || IsClosing(client_p))
+ continue;
+
+ /*
+ * Check UNKNOWN connections - if they have been in this state
+ * for > 30s, close them.
+ */
+
+ if((CurrentTime - client_p->localClient->firsttime) > 30)
+ exit_client(client_p, client_p, &me, "Connection timed out");
+ }
+}
+
+static void
+notify_banned_client(struct Client *client_p, struct ConfItem *aconf, int ban)
+{
+ static const char conn_closed[] = "Connection closed";
+ static const char d_lined[] = "D-lined";
+ static const char k_lined[] = "K-lined";
+ static const char g_lined[] = "G-lined";
+ const char *reason = NULL;
+ const char *exit_reason = conn_closed;
+
+ if(ConfigFileEntry.kline_with_reason && !EmptyString(aconf->passwd))
+ {
+ reason = aconf->passwd;
+ exit_reason = aconf->passwd;
+ }
+ else
+ {
+ switch (aconf->status)
+ {
+ case D_LINED:
+ reason = d_lined;
+ break;
+ case G_LINED:
+ reason = g_lined;
+ break;
+ default:
+ reason = k_lined;
+ break;
+ }
+ }
+
+ if(ban == D_LINED && !IsPerson(client_p))
+ sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined");
+ else
+ sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
+ me.name, client_p->name, reason);
+
+ exit_client(client_p, client_p, &me,
+ EmptyString(ConfigFileEntry.kline_reason) ? exit_reason :
+ ConfigFileEntry.kline_reason);
+}
+
+/*
+ * check_banned_lines
+ * inputs - NONE
+ * output - NONE
+ * side effects - Check all connections for a pending k/d/gline against the
+ * client, exit the client if found.
+ */
+void
+check_banned_lines(void)
+{
+ struct Client *client_p; /* current local client_p being examined */
+ struct ConfItem *aconf = NULL;
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ client_p = ptr->data;
+
+ if(IsMe(client_p))
+ continue;
+
+ /* if there is a returned struct ConfItem then kill it */
+ if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip, client_p->localClient->ip.ss_family)))
+ {
+ if(aconf->status & CONF_EXEMPTDLINE)
+ continue;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "DLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, aconf, D_LINED);
+ continue; /* and go examine next fd/client_p */
+ }
+
+ if(!IsPerson(client_p))
+ continue;
+
+ if((aconf = find_kline(client_p)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "KLINE over-ruled for %s, client is kline_exempt [%s@%s]",
+ get_client_name(client_p, HIDE_IP),
+ aconf->user, aconf->host);
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "KLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+ notify_banned_client(client_p, aconf, K_LINED);
+ continue;
+ }
+ else if((aconf = find_gline(client_p)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE over-ruled for %s, client is kline_exempt [%s@%s]",
+ get_client_name(client_p, HIDE_IP),
+ aconf->user, aconf->host);
+ continue;
+ }
+
+ if(IsExemptGline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE over-ruled for %s, client is gline_exempt [%s@%s]",
+ get_client_name(client_p, HIDE_IP),
+ aconf->user, aconf->host);
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, aconf, G_LINED);
+ continue;
+ }
+ else if((aconf = find_xline(client_p->info, 1)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "XLINE over-ruled for %s, client is kline_exempt [%s]",
+ get_client_name(client_p, HIDE_IP),
+ aconf->name);
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "XLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ (void) exit_client(client_p, client_p, &me, "Bad user info");
+ continue;
+ }
+ }
+
+ /* also check the unknowns list for new dlines */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head)
+ {
+ client_p = ptr->data;
+
+ if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)))
+ {
+ if(aconf->status & CONF_EXEMPTDLINE)
+ continue;
+
+ notify_banned_client(client_p, aconf, D_LINED);
+ }
+ }
+
+}
+
+/* check_klines_event()
+ *
+ * inputs -
+ * outputs -
+ * side effects - check_klines() is called, kline_queued unset
+ */
+void
+check_klines_event(void *unused)
+{
+ kline_queued = 0;
+ check_klines();
+}
+
+/* check_klines
+ *
+ * inputs -
+ * outputs -
+ * side effects - all clients will be checked for klines
+ */
+void
+check_klines(void)
+{
+ struct Client *client_p;
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ client_p = ptr->data;
+
+ if(IsMe(client_p) || !IsPerson(client_p))
+ continue;
+
+ if((aconf = find_kline(client_p)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "KLINE over-ruled for %s, client is kline_exempt",
+ get_client_name(client_p, HIDE_IP));
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "KLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, aconf, K_LINED);
+ continue;
+ }
+ }
+}
+
+/* check_glines()
+ *
+ * inputs -
+ * outputs -
+ * side effects - all clients will be checked for glines
+ */
+void
+check_glines(void)
+{
+ struct Client *client_p;
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ client_p = ptr->data;
+
+ if(IsMe(client_p) || !IsPerson(client_p))
+ continue;
+
+ if((aconf = find_gline(client_p)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE over-ruled for %s, client is kline_exempt",
+ get_client_name(client_p, HIDE_IP));
+ continue;
+ }
+
+ if(IsExemptGline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE over-ruled for %s, client is gline_exempt",
+ get_client_name(client_p, HIDE_IP));
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "GLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, aconf, K_LINED);
+ continue;
+ }
+ }
+}
+
+/* check_dlines()
+ *
+ * inputs -
+ * outputs -
+ * side effects - all clients will be checked for dlines
+ */
+void
+check_dlines(void)
+{
+ struct Client *client_p;
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ client_p = ptr->data;
+
+ if(IsMe(client_p))
+ continue;
+
+ if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL)
+ {
+ if(aconf->status & CONF_EXEMPTDLINE)
+ continue;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "DLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, aconf, D_LINED);
+ continue;
+ }
+ }
+
+ /* dlines need to be checked against unknowns too */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head)
+ {
+ client_p = ptr->data;
+
+ if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL)
+ {
+ if(aconf->status & CONF_EXEMPTDLINE)
+ continue;
+
+ notify_banned_client(client_p, aconf, D_LINED);
+ }
+ }
+}
+
+/* check_xlines
+ *
+ * inputs -
+ * outputs -
+ * side effects - all clients will be checked for xlines
+ */
+void
+check_xlines(void)
+{
+ struct Client *client_p;
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ client_p = ptr->data;
+
+ if(IsMe(client_p) || !IsPerson(client_p))
+ continue;
+
+ if((aconf = find_xline(client_p->info, 1)) != NULL)
+ {
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "XLINE over-ruled for %s, client is kline_exempt",
+ get_client_name(client_p, HIDE_IP));
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "XLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ (void) exit_client(client_p, client_p, &me, "Bad user info");
+ continue;
+ }
+ }
+}
+
+/*
+ * update_client_exit_stats
+ *
+ * input - pointer to client
+ * output - NONE
+ * side effects -
+ */
+static void
+update_client_exit_stats(struct Client *client_p)
+{
+ if(IsServer(client_p))
+ {
+ sendto_realops_snomask(SNO_EXTERNAL, L_ALL,
+ "Server %s split from %s",
+ client_p->name, client_p->servptr->name);
+ if(HasSentEob(client_p))
+ eob_count--;
+ }
+ else if(IsClient(client_p))
+ {
+ --Count.total;
+ if(IsOper(client_p))
+ --Count.oper;
+ if(IsInvisible(client_p))
+ --Count.invisi;
+ }
+
+ if(splitchecking && !splitmode)
+ check_splitmode(NULL);
+}
+
+/*
+ * release_client_state
+ *
+ * input - pointer to client to release
+ * output - NONE
+ * side effects -
+ */
+static void
+release_client_state(struct Client *client_p)
+{
+ if(client_p->user != NULL)
+ {
+ free_user(client_p->user, client_p); /* try this here */
+ }
+ if(client_p->serv)
+ {
+ if(client_p->serv->user != NULL)
+ free_user(client_p->serv->user, client_p);
+ if(client_p->serv->fullcaps)
+ MyFree(client_p->serv->fullcaps);
+ MyFree(client_p->serv);
+ }
+}
+
+/*
+ * remove_client_from_list
+ * inputs - point to client to remove
+ * output - NONE
+ * side effects - taken the code from ExitOneClient() for this
+ * and placed it here. - avalon
+ */
+static void
+remove_client_from_list(struct Client *client_p)
+{
+ s_assert(NULL != client_p);
+
+ if(client_p == NULL)
+ return;
+
+ /* A client made with make_client()
+ * is on the unknown_list until removed.
+ * If it =does= happen to exit before its removed from that list
+ * and its =not= on the global_client_list, it will core here.
+ * short circuit that case now -db
+ */
+ if(client_p->node.prev == NULL && client_p->node.next == NULL)
+ return;
+
+ dlinkDelete(&client_p->node, &global_client_list);
+
+ update_client_exit_stats(client_p);
+}
+
+
+/*
+ * find_person - find person by (nick)name.
+ * inputs - pointer to name
+ * output - return client pointer
+ * side effects -
+ */
+struct Client *
+find_person(const char *name)
+{
+ struct Client *c2ptr;
+
+ c2ptr = find_client(name);
+
+ if(c2ptr && IsPerson(c2ptr))
+ return (c2ptr);
+ return (NULL);
+}
+
+struct Client *
+find_named_person(const char *name)
+{
+ struct Client *c2ptr;
+
+ c2ptr = find_named_client(name);
+
+ if(c2ptr && IsPerson(c2ptr))
+ return (c2ptr);
+ return (NULL);
+}
+
+
+/*
+ * find_chasing - find the client structure for a nick name (user)
+ * using history mechanism if necessary. If the client is not found,
+ * an error message (NO SUCH NICK) is generated. If the client was found
+ * through the history, chasing will be 1 and otherwise 0.
+ */
+struct Client *
+find_chasing(struct Client *source_p, const char *user, int *chasing)
+{
+ struct Client *who;
+
+ if(MyClient(source_p))
+ who = find_named_person(user);
+ else
+ who = find_person(user);
+
+ if(chasing)
+ *chasing = 0;
+
+ if(who || IsDigit(*user))
+ return who;
+
+ if(!(who = get_history(user, (long) KILLCHASETIMELIMIT)))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+ form_str(ERR_NOSUCHNICK), user);
+ return (NULL);
+ }
+ if(chasing)
+ *chasing = 1;
+ return who;
+}
+
+/*
+ * get_client_name - Return the name of the client
+ * for various tracking and
+ * admin purposes. The main purpose of this function is to
+ * return the "socket host" name of the client, if that
+ * differs from the advertised name (other than case).
+ * But, this can be used to any client structure.
+ *
+ * NOTE 1:
+ * Watch out the allocation of "nbuf", if either source_p->name
+ * or source_p->sockhost gets changed into pointers instead of
+ * directly allocated within the structure...
+ *
+ * NOTE 2:
+ * Function return either a pointer to the structure (source_p) or
+ * to internal buffer (nbuf). *NEVER* use the returned pointer
+ * to modify what it points!!!
+ */
+
+const char *
+get_client_name(struct Client *client, int showip)
+{
+ static char nbuf[HOSTLEN * 2 + USERLEN + 5];
+
+ s_assert(NULL != client);
+ if(client == NULL)
+ return NULL;
+
+ if(MyConnect(client))
+ {
+ if(!irccmp(client->name, client->host))
+ return client->name;
+
+ if(ConfigFileEntry.hide_spoof_ips &&
+ showip == SHOW_IP && IsIPSpoof(client))
+ showip = MASK_IP;
+#ifdef HIDE_SERVERS_IPS
+ if(IsAnyServer(client))
+ showip = MASK_IP;
+#endif
+
+ /* And finally, let's get the host information, ip or name */
+ switch (showip)
+ {
+ case SHOW_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
+ client->name, client->username,
+ client->sockhost);
+ break;
+ case MASK_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@255.255.255.255]",
+ client->name, client->username);
+ break;
+ default:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
+ client->name, client->username, client->host);
+ }
+ return nbuf;
+ }
+
+ /* As pointed out by Adel Mezibra
+ * Neph|l|m@EFnet. Was missing a return here.
+ */
+ return client->name;
+}
+
+const char *
+get_server_name(struct Client *target_p, int showip)
+{
+ static char nbuf[HOSTLEN * 2 + USERLEN + 5];
+
+ if(target_p == NULL)
+ return NULL;
+
+ if(!MyConnect(target_p) || !irccmp(target_p->name, target_p->host))
+ return target_p->name;
+
+#ifdef HIDE_SERVERS_IPS
+ if(EmptyString(target_p->name))
+ {
+ ircsnprintf(nbuf, sizeof(nbuf), "[%s@255.255.255.255]",
+ target_p->username);
+ return nbuf;
+ }
+ else
+ return target_p->name;
+#endif
+
+ switch (showip)
+ {
+ case SHOW_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
+ target_p->name, target_p->username,
+ target_p->sockhost);
+ break;
+
+ case MASK_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@255.255.255.255]",
+ target_p->name, target_p->username);
+
+ default:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]",
+ target_p->name, target_p->username,
+ target_p->host);
+ }
+
+ return nbuf;
+}
+
+/* log_client_name()
+ *
+ * This version is the same as get_client_name, but doesnt contain the
+ * code that will hide IPs always. This should be used for logfiles.
+ */
+const char *
+log_client_name(struct Client *target_p, int showip)
+{
+ static char nbuf[HOSTLEN * 2 + USERLEN + 5];
+
+ if(target_p == NULL)
+ return NULL;
+
+ if(MyConnect(target_p))
+ {
+ if(irccmp(target_p->name, target_p->host) == 0)
+ return target_p->name;
+
+ switch (showip)
+ {
+ case SHOW_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]", target_p->name,
+ target_p->username, target_p->sockhost);
+ break;
+
+ case MASK_IP:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@255.255.255.255]",
+ target_p->name, target_p->username);
+
+ default:
+ ircsnprintf(nbuf, sizeof(nbuf), "%s[%s@%s]", target_p->name,
+ target_p->username, target_p->host);
+ }
+
+ return nbuf;
+ }
+
+ return target_p->name;
+}
+
+/* is_remote_connect - Returns whether a server was /connect'ed by a remote
+ * oper (send notices netwide) */
+int
+is_remote_connect(struct Client *client_p)
+{
+ struct Client *oper;
+
+ if (client_p->serv == NULL)
+ return FALSE;
+ oper = find_named_person(client_p->serv->by);
+ return oper != NULL && IsOper(oper) && !MyConnect(oper);
+}
+
+static void
+free_exited_clients(void *unused)
+{
+ dlink_node *ptr, *next;
+ struct Client *target_p;
+
+ DLINK_FOREACH_SAFE(ptr, next, dead_list.head)
+ {
+ target_p = ptr->data;
+
+#ifdef DEBUG_EXITED_CLIENTS
+ {
+ struct abort_client *abt;
+ dlink_node *aptr;
+ int found = 0;
+
+ DLINK_FOREACH(aptr, abort_list.head)
+ {
+ abt = aptr->data;
+ if(abt->client == target_p)
+ {
+ s_assert(0);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "On abort_list: %s stat: %u flags: %u/%u handler: %c",
+ target_p->name, (unsigned int) target_p->status,
+ target_p->flags, target_p->flags2, target_p->handler);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Please report this to the ratbox developers!");
+ found++;
+ }
+ }
+
+ if(found)
+ {
+ dlinkDestroy(ptr, &dead_list);
+ continue;
+ }
+ }
+#endif
+
+ if(ptr->data == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Warning: null client on dead_list!");
+ dlinkDestroy(ptr, &dead_list);
+ continue;
+ }
+ release_client_state(target_p);
+ free_client(target_p);
+ dlinkDestroy(ptr, &dead_list);
+ }
+
+#ifdef DEBUG_EXITED_CLIENTS
+ DLINK_FOREACH_SAFE(ptr, next, dead_remote_list.head)
+ {
+ target_p = ptr->data;
+
+ if(ptr->data == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Warning: null client on dead_list!");
+ dlinkDestroy(ptr, &dead_list);
+ continue;
+ }
+ release_client_state(target_p);
+ free_client(target_p);
+ dlinkDestroy(ptr, &dead_remote_list);
+ }
+#endif
+
+}
+
+/*
+** Recursively send QUITs and SQUITs for source_p and all its dependent clients
+** and servers to those servers that need them. A server needs the client
+** QUITs if it can't figure them out from the SQUIT (ie pre-TS4) or if it
+** isn't getting the SQUIT because of @#(*&@)# hostmasking. With TS4, once
+** a link gets a SQUIT, it doesn't need any QUIT/SQUITs for clients depending
+** on that one -orabidoo
+*/
+static void
+recurse_send_quits(struct Client *client_p, struct Client *source_p,
+ struct Client *to, const char *comment1,
+ const char *comment)
+{
+ struct Client *target_p;
+ dlink_node *ptr, *ptr_next;
+ /* If this server can handle quit storm (QS) removal
+ * of dependents, just send the SQUIT
+ */
+
+ if(IsCapable(to, CAP_QS))
+ {
+ sendto_one(to, "SQUIT %s :%s",
+ get_id(source_p, to), comment);
+ }
+ else
+ {
+ DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->serv->users.head)
+ {
+ target_p = ptr->data;
+ sendto_one(to, ":%s QUIT :%s", target_p->name, comment1);
+ }
+ DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->serv->servers.head)
+ {
+ target_p = ptr->data;
+ recurse_send_quits(client_p, target_p, to, comment1, comment);
+ }
+ sendto_one(to, "SQUIT %s :%s", source_p->name, comment);
+ }
+}
+
+/*
+** Remove all clients that depend on source_p; assumes all (S)QUITs have
+** already been sent. we make sure to exit a server's dependent clients
+** and servers before the server itself; exit_one_client takes care of
+** actually removing things off llists. tweaked from +CSr31 -orabidoo
+*/
+/*
+ * added sanity test code.... source_p->serv might be NULL...
+ */
+static void
+recurse_remove_clients(struct Client *source_p, const char *comment)
+{
+ struct Client *target_p;
+ dlink_node *ptr, *ptr_next;
+
+ if(IsMe(source_p))
+ return;
+
+ if(source_p->serv == NULL) /* oooops. uh this is actually a major bug */
+ return;
+
+ /* this is very ugly, but it saves cpu :P */
+ if(ConfigFileEntry.nick_delay > 0)
+ {
+ DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->serv->users.head)
+ {
+ target_p = ptr->data;
+ target_p->flags |= FLAGS_KILLED;
+ add_nd_entry(target_p->name);
+
+ if(!IsDead(target_p) && !IsClosing(target_p))
+ exit_remote_client(NULL, target_p, &me, comment);
+ }
+ }
+ else
+ {
+ DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->serv->users.head)
+ {
+ target_p = ptr->data;
+ target_p->flags |= FLAGS_KILLED;
+
+ if(!IsDead(target_p) && !IsClosing(target_p))
+ exit_remote_client(NULL, target_p, &me, comment);
+ }
+ }
+
+ DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->serv->servers.head)
+ {
+ target_p = ptr->data;
+ recurse_remove_clients(target_p, comment);
+ qs_server(NULL, target_p, &me, comment);
+ }
+}
+
+/*
+** Remove *everything* that depends on source_p, from all lists, and sending
+** all necessary QUITs and SQUITs. source_p itself is still on the lists,
+** and its SQUITs have been sent except for the upstream one -orabidoo
+*/
+static void
+remove_dependents(struct Client *client_p,
+ struct Client *source_p,
+ struct Client *from, const char *comment, const char *comment1)
+{
+ struct Client *to;
+ dlink_node *ptr, *next;
+
+ DLINK_FOREACH_SAFE(ptr, next, serv_list.head)
+ {
+ to = ptr->data;
+
+ if(IsMe(to) || to == source_p->from ||
+ (to == client_p && IsCapable(to, CAP_QS)))
+ continue;
+
+ recurse_send_quits(client_p, source_p, to, comment1, comment);
+ }
+
+ recurse_remove_clients(source_p, comment1);
+}
+
+void
+exit_aborted_clients(void *unused)
+{
+ struct abort_client *abt;
+ dlink_node *ptr, *next;
+ DLINK_FOREACH_SAFE(ptr, next, abort_list.head)
+ {
+ abt = ptr->data;
+
+#ifdef DEBUG_EXITED_CLIENTS
+ {
+ if(dlinkFind(abt->client, &dead_list))
+ {
+ s_assert(0);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "On dead_list: %s stat: %u flags: %u/%u handler: %c",
+ abt->client->name, (unsigned int) abt->client->status,
+ abt->client->flags, abt->client->flags2, abt->client->handler);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Please report this to the ratbox developers!");
+ continue;
+ }
+ }
+#endif
+
+ s_assert(*((unsigned long*)abt->client) != 0xdeadbeef); /* This is lame but its a debug thing */
+ dlinkDelete(ptr, &abort_list);
+
+ if(IsAnyServer(abt->client))
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Closing link to %s: %s",
+ get_server_name(abt->client, HIDE_IP), abt->notice);
+
+ /* its no longer on abort list - we *must* remove
+ * FLAGS_CLOSING otherwise exit_client() will not run --fl
+ */
+ abt->client->flags &= ~FLAGS_CLOSING;
+ exit_client(abt->client, abt->client, &me, abt->notice);
+ MyFree(abt);
+ }
+}
+
+
+/*
+ * dead_link - Adds client to a list of clients that need an exit_client()
+ *
+ */
+void
+dead_link(struct Client *client_p)
+{
+ struct abort_client *abt;
+
+ s_assert(!IsMe(client_p));
+ if(IsDead(client_p) || IsClosing(client_p) || IsMe(client_p))
+ return;
+
+ abt = (struct abort_client *) MyMalloc(sizeof(struct abort_client));
+
+ if(client_p->flags & FLAGS_SENDQEX)
+ strlcpy(abt->notice, "Max SendQ exceeded", sizeof(abt->notice));
+ else
+ ircsnprintf(abt->notice, sizeof(abt->notice), "Write error: %s", strerror(errno));
+
+ abt->client = client_p;
+ SetIOError(client_p);
+ SetDead(client_p);
+ SetClosing(client_p);
+ dlinkAdd(abt, &abt->node, &abort_list);
+}
+
+
+/* This does the remove of the user from channels..local or remote */
+static inline void
+exit_generic_client(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ dlink_node *ptr, *next_ptr;
+
+ if(IsOper(source_p))
+ dlinkFindDestroy(source_p, &oper_list);
+
+ sendto_common_channels_local(source_p, ":%s!%s@%s QUIT :%s",
+ source_p->name,
+ source_p->username, source_p->host, comment);
+
+ remove_user_from_channels(source_p);
+
+ /* Should not be in any channels now */
+ s_assert(source_p->user->channel.head == NULL);
+
+ /* Clean up invitefield */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->user->invited.head)
+ {
+ del_invite(ptr->data, source_p);
+ }
+
+ /* Clean up allow lists */
+ del_all_accepts(source_p);
+
+ add_history(source_p, 0);
+ off_history(source_p);
+
+ monitor_signoff(source_p);
+
+ if(has_id(source_p))
+ del_from_id_hash(source_p->id, source_p);
+
+ del_from_hostname_hash(source_p->orighost, source_p);
+ del_from_client_hash(source_p->name, source_p);
+ remove_client_from_list(source_p);
+}
+
+/*
+ * Assumes IsPerson(source_p) && !MyConnect(source_p)
+ */
+
+static int
+exit_remote_client(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ exit_generic_client(client_p, source_p, from, comment);
+
+ if(source_p->servptr && source_p->servptr->serv)
+ {
+ dlinkDelete(&source_p->lnode, &source_p->servptr->serv->users);
+ }
+
+ if((source_p->flags & FLAGS_KILLED) == 0)
+ {
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+ ":%s QUIT :%s", use_id(source_p), comment);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ ":%s QUIT :%s", source_p->name, comment);
+ }
+
+ SetDead(source_p);
+#ifdef DEBUG_EXITED_CLIENTS
+ dlinkAddAlloc(source_p, &dead_remote_list);
+#else
+ dlinkAddAlloc(source_p, &dead_list);
+#endif
+ return(CLIENT_EXITED);
+}
+
+/*
+ * This assumes IsUnknown(source_p) == TRUE and MyConnect(source_p) == TRUE
+ */
+
+static int
+exit_unknown_client(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ delete_auth_queries(source_p);
+ client_flush_input(source_p);
+ dlinkDelete(&source_p->localClient->tnode, &unknown_list);
+
+ if(!IsIOError(source_p))
+ sendto_one(source_p, "ERROR :Closing Link: 127.0.0.1 (%s)", comment);
+
+ close_connection(source_p);
+
+ if(has_id(source_p))
+ del_from_id_hash(source_p->id, source_p);
+
+ del_from_hostname_hash(source_p->host, source_p);
+ del_from_client_hash(source_p->name, source_p);
+ remove_client_from_list(source_p);
+ free_pre_client(source_p);
+ SetDead(source_p);
+ dlinkAddAlloc(source_p, &dead_list);
+
+ /* Note that we don't need to add unknowns to the dead_list */
+ return(CLIENT_EXITED);
+}
+
+static int
+exit_remote_server(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ static char comment1[(HOSTLEN*2)+2];
+ static char newcomment[BUFSIZE];
+ struct Client *target_p;
+
+ if(ConfigServerHide.flatten_links)
+ strcpy(comment1, "*.net *.split");
+ else
+ {
+ if((source_p->serv) && (source_p->serv->up))
+ strcpy(comment1, source_p->serv->up);
+ else
+ strcpy(comment1, "<Unknown>");
+
+ strcat(comment1, " ");
+ strcat(comment1, source_p->name);
+ }
+ if (IsPerson(from))
+ ircsnprintf(newcomment, sizeof(newcomment), "by %s: %s",
+ from->name, comment);
+
+ if(source_p->serv != NULL)
+ remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
+
+ if(source_p->servptr && source_p->servptr->serv)
+ dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
+ else
+ s_assert(0);
+
+ dlinkFindDestroy(source_p, &global_serv_list);
+ target_p = source_p->from;
+
+ if(target_p != NULL && IsServer(target_p) && target_p != client_p &&
+ !IsMe(target_p) && (source_p->flags & FLAGS_KILLED) == 0)
+ {
+ sendto_one(target_p, ":%s SQUIT %s :%s",
+ get_id(from, target_p), get_id(source_p, target_p),
+ comment);
+ }
+
+ if(has_id(source_p))
+ del_from_id_hash(source_p->id, source_p);
+
+ del_from_client_hash(source_p->name, source_p);
+ remove_client_from_list(source_p);
+
+ SetDead(source_p);
+#ifdef DEBUG_EXITED_CLIENTS
+ dlinkAddAlloc(source_p, &dead_remote_list);
+#else
+ dlinkAddAlloc(source_p, &dead_list);
+#endif
+ return 0;
+}
+
+static int
+qs_server(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ struct Client *target_p;
+
+ if(source_p->servptr && source_p->servptr->serv)
+ dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
+ else
+ s_assert(0);
+
+ dlinkFindDestroy(source_p, &global_serv_list);
+ target_p = source_p->from;
+
+ if(has_id(source_p))
+ del_from_id_hash(source_p->id, source_p);
+
+ del_from_client_hash(source_p->name, source_p);
+ remove_client_from_list(source_p);
+
+ SetDead(source_p);
+ dlinkAddAlloc(source_p, &dead_list);
+ return 0;
+}
+
+static int
+exit_local_server(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ static char comment1[(HOSTLEN*2)+2];
+ static char newcomment[BUFSIZE];
+ unsigned int sendk, recvk;
+
+ dlinkDelete(&source_p->localClient->tnode, &serv_list);
+ dlinkFindDestroy(source_p, &global_serv_list);
+
+ unset_chcap_usage_counts(source_p);
+ sendk = source_p->localClient->sendK;
+ recvk = source_p->localClient->receiveK;
+
+ /* Always show source here, so the server notices show
+ * which side initiated the split -- jilles
+ */
+ ircsnprintf(newcomment, sizeof(newcomment), "by %s: %s",
+ from == source_p ? me.name : from->name, comment);
+ if (!IsIOError(source_p))
+ sendto_one(source_p, "SQUIT %s :%s", use_id(source_p),
+ newcomment);
+ if(client_p != NULL && source_p != client_p && !IsIOError(source_p))
+ {
+ sendto_one(source_p, "ERROR :Closing Link: 127.0.0.1 %s (%s)",
+ source_p->name, comment);
+ }
+
+ if(source_p->localClient->ctrlfd >= 0)
+ {
+ comm_close(source_p->localClient->ctrlfd);
+ source_p->localClient->ctrlfd = -1;
+ }
+
+ if(source_p->servptr && source_p->servptr->serv)
+ dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
+ else
+ s_assert(0);
+
+
+ close_connection(source_p);
+
+ if(ConfigServerHide.flatten_links)
+ strcpy(comment1, "*.net *.split");
+ else
+ {
+ if((source_p->serv) && (source_p->serv->up))
+ strcpy(comment1, source_p->serv->up);
+ else
+ strcpy(comment1, "<Unknown>");
+
+ strcat(comment1, " ");
+ strcat(comment1, source_p->name);
+ }
+
+ if(source_p->serv != NULL)
+ remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s was connected"
+ " for %ld seconds. %d/%d sendK/recvK.",
+ source_p->name, CurrentTime - source_p->localClient->firsttime, sendk, recvk);
+
+ ilog(L_SERVER, "%s was connected for %ld seconds. %d/%d sendK/recvK.",
+ source_p->name, CurrentTime - source_p->localClient->firsttime, sendk, recvk);
+
+ if(has_id(source_p))
+ del_from_id_hash(source_p->id, source_p);
+
+ del_from_client_hash(source_p->name, source_p);
+ remove_client_from_list(source_p);
+
+ SetDead(source_p);
+ dlinkAddAlloc(source_p, &dead_list);
+ return 0;
+}
+
+
+/*
+ * This assumes IsPerson(source_p) == TRUE && MyConnect(source_p) == TRUE
+ */
+
+static int
+exit_local_client(struct Client *client_p, struct Client *source_p, struct Client *from,
+ const char *comment)
+{
+ unsigned long on_for;
+
+ exit_generic_client(client_p, source_p, from, comment);
+ clear_monitor(source_p);
+
+ s_assert(IsPerson(source_p));
+ client_flush_input(source_p);
+ dlinkDelete(&source_p->localClient->tnode, &lclient_list);
+ dlinkDelete(&source_p->lnode, &me.serv->users);
+
+ if(IsOper(source_p))
+ dlinkFindDestroy(source_p, &local_oper_list);
+
+ sendto_realops_snomask(SNO_CCONN, L_ALL,
+ "Client exiting: %s (%s@%s) [%s] [%s]",
+ source_p->name,
+ source_p->username, source_p->host, comment,
+ show_ip(NULL, source_p) ? source_p->sockhost : "255.255.255.255");
+
+ sendto_realops_snomask(SNO_CCONNEXT, L_ALL,
+ "CLIEXIT %s %s %s %s 0 %s",
+ source_p->name, source_p->username, source_p->host,
+ show_ip(NULL, source_p) ? source_p->sockhost : "255.255.255.255",
+ comment);
+
+ on_for = CurrentTime - source_p->localClient->firsttime;
+
+ ilog(L_USER, "%s (%3lu:%02lu:%02lu): %s!%s@%s %d/%d",
+ myctime(CurrentTime), on_for / 3600,
+ (on_for % 3600) / 60, on_for % 60,
+ source_p->name, source_p->username, source_p->host,
+ source_p->localClient->sendK, source_p->localClient->receiveK);
+
+ sendto_one(source_p, "ERROR :Closing Link: %s (%s)", source_p->host, comment);
+ close_connection(source_p);
+
+ if((source_p->flags & FLAGS_KILLED) == 0)
+ {
+ sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+ ":%s QUIT :%s", use_id(source_p), comment);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ ":%s QUIT :%s", source_p->name, comment);
+ }
+
+ SetDead(source_p);
+ dlinkAddAlloc(source_p, &dead_list);
+ return(CLIENT_EXITED);
+}
+
+
+/*
+** exit_client - This is old "m_bye". Name changed, because this is not a
+** protocol function, but a general server utility function.
+**
+** This function exits a client of *any* type (user, server, etc)
+** from this server. Also, this generates all necessary prototol
+** messages that this exit may cause.
+**
+** 1) If the client is a local client, then this implicitly
+** exits all other clients depending on this connection (e.g.
+** remote clients having 'from'-field that points to this.
+**
+** 2) If the client is a remote client, then only this is exited.
+**
+** For convenience, this function returns a suitable value for
+** m_function return value:
+**
+** CLIENT_EXITED if (client_p == source_p)
+** 0 if (client_p != source_p)
+*/
+int
+exit_client(struct Client *client_p, /* The local client originating the
+ * exit or NULL, if this exit is
+ * generated by this server for
+ * internal reasons.
+ * This will not get any of the
+ * generated messages. */
+ struct Client *source_p, /* Client exiting */
+ struct Client *from, /* Client firing off this Exit,
+ * never NULL! */
+ const char *comment /* Reason for the exit */
+ )
+{
+ hook_data_client_exit hdata;
+ if(IsClosing(source_p))
+ return -1;
+
+ /* note, this HAS to be here, when we exit a client we attempt to
+ * send them data, if this generates a write error we must *not* add
+ * them to the abort list --fl
+ */
+ SetClosing(source_p);
+
+ hdata.local_link = client_p;
+ hdata.target = source_p;
+ hdata.from = from;
+ hdata.comment = comment;
+ call_hook(h_client_exit, &hdata);
+
+ if(MyConnect(source_p))
+ {
+ /* Local clients of various types */
+ if(IsPerson(source_p))
+ return exit_local_client(client_p, source_p, from, comment);
+ else if(IsServer(source_p))
+ return exit_local_server(client_p, source_p, from, comment);
+ /* IsUnknown || IsConnecting || IsHandShake */
+ else if(!IsReject(source_p))
+ return exit_unknown_client(client_p, source_p, from, comment);
+ }
+ else
+ {
+ /* Remotes */
+ if(IsPerson(source_p))
+ return exit_remote_client(client_p, source_p, from, comment);
+ else if(IsServer(source_p))
+ return exit_remote_server(client_p, source_p, from, comment);
+ }
+
+ return -1;
+}
+
+/*
+ * Count up local client memory
+ */
+
+/* XXX one common Client list now */
+void
+count_local_client_memory(size_t * count, size_t * local_client_memory_used)
+{
+ size_t lusage;
+ BlockHeapUsage(lclient_heap, count, NULL, &lusage);
+ *local_client_memory_used = lusage + (*count * (sizeof(MemBlock) + sizeof(struct Client)));
+}
+
+/*
+ * Count up remote client memory
+ */
+void
+count_remote_client_memory(size_t * count, size_t * remote_client_memory_used)
+{
+ size_t lcount, rcount;
+ BlockHeapUsage(lclient_heap, &lcount, NULL, NULL);
+ BlockHeapUsage(client_heap, &rcount, NULL, NULL);
+ *count = rcount - lcount;
+ *remote_client_memory_used = *count * (sizeof(MemBlock) + sizeof(struct Client));
+}
+
+
+/*
+ * accept processing, this adds a form of "caller ID" to ircd
+ *
+ * If a client puts themselves into "caller ID only" mode,
+ * only clients that match a client pointer they have put on
+ * the accept list will be allowed to message them.
+ *
+ * [ source.on_allow_list ] -> [ target1 ] -> [ target2 ]
+ *
+ * [target.allow_list] -> [ source1 ] -> [source2 ]
+ *
+ * i.e. a target will have a link list of source pointers it will allow
+ * each source client then has a back pointer pointing back
+ * to the client that has it on its accept list.
+ * This allows for exit_one_client to remove these now bogus entries
+ * from any client having an accept on them.
+ */
+/*
+ * del_all_accepts
+ *
+ * inputs - pointer to exiting client
+ * output - NONE
+ * side effects - Walk through given clients allow_list and on_allow_list
+ * remove all references to this client
+ */
+void
+del_all_accepts(struct Client *client_p)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct Client *target_p;
+
+ if(MyClient(client_p) && client_p->localClient->allow_list.head)
+ {
+ /* clear this clients accept list, and remove them from
+ * everyones on_accept_list
+ */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->allow_list.head)
+ {
+ target_p = ptr->data;
+ dlinkFindDestroy(client_p, &target_p->on_allow_list);
+ dlinkDestroy(ptr, &client_p->localClient->allow_list);
+ }
+ }
+
+ /* remove this client from everyones accept list */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
+ {
+ target_p = ptr->data;
+ dlinkFindDestroy(client_p, &target_p->localClient->allow_list);
+ dlinkDestroy(ptr, &client_p->on_allow_list);
+ }
+}
+
+/*
+ * show_ip() - asks if the true IP shoudl be shown when source is
+ * askin for info about target
+ *
+ * Inputs - source_p who is asking
+ * - target_p who do we want the info on
+ * Output - returns 1 if clear IP can be showed, otherwise 0
+ * Side Effects - none
+ */
+
+int
+show_ip(struct Client *source_p, struct Client *target_p)
+{
+ if(IsAnyServer(target_p))
+ {
+#ifndef HIDE_SERVERS_IPS
+ if(source_p == NULL || IsOper(source_p))
+ return 1;
+#endif
+ return 0;
+ }
+ else if(IsIPSpoof(target_p))
+ {
+ /* source == NULL indicates message is being sent
+ * to local opers.
+ */
+ if(!ConfigFileEntry.hide_spoof_ips &&
+ (source_p == NULL || MyOper(source_p)))
+ return 1;
+ return 0;
+ }
+ else if(IsDynSpoof(target_p) && (source_p != NULL && !IsOper(source_p)))
+ return 0;
+ else
+ return 1;
+}
+
+int
+show_ip_conf(struct ConfItem *aconf, struct Client *source_p)
+{
+ if(IsConfDoSpoofIp(aconf))
+ {
+ if(!ConfigFileEntry.hide_spoof_ips && MyOper(source_p))
+ return 1;
+
+ return 0;
+ }
+ else
+ return 1;
+}
+
+/*
+ * initUser
+ *
+ * inputs - none
+ * outputs - none
+ *
+ * side effects - Creates a block heap for struct Users
+ *
+ */
+static BlockHeap *user_heap;
+void
+initUser(void)
+{
+ user_heap = BlockHeapCreate(sizeof(struct User), USER_HEAP_SIZE);
+ if(!user_heap)
+ outofmemory();
+}
+
+/*
+ * make_user
+ *
+ * inputs - pointer to client struct
+ * output - pointer to struct User
+ * side effects - add's an User information block to a client
+ * if it was not previously allocated.
+ */
+struct User *
+make_user(struct Client *client_p)
+{
+ struct User *user;
+
+ user = client_p->user;
+ if(!user)
+ {
+ user = (struct User *) BlockHeapAlloc(user_heap);
+ user->refcnt = 1;
+ client_p->user = user;
+ }
+ return user;
+}
+
+/*
+ * make_server
+ *
+ * inputs - pointer to client struct
+ * output - pointer to server_t
+ * side effects - add's an Server information block to a client
+ * if it was not previously allocated.
+ */
+server_t *
+make_server(struct Client *client_p)
+{
+ server_t *serv = client_p->serv;
+
+ if(!serv)
+ {
+ serv = (server_t *) MyMalloc(sizeof(server_t));
+ client_p->serv = serv;
+ }
+ return client_p->serv;
+}
+
+/*
+ * free_user
+ *
+ * inputs - pointer to user struct
+ * - pointer to client struct
+ * output - none
+ * side effects - Decrease user reference count by one and release block,
+ * if count reaches 0
+ */
+void
+free_user(struct User *user, struct Client *client_p)
+{
+ if(--user->refcnt <= 0)
+ {
+ if(user->away)
+ MyFree((char *) user->away);
+ /*
+ * sanity check
+ */
+ if(user->refcnt < 0 || user->invited.head || user->channel.head)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "* %#lx user (%s!%s@%s) %#lx %#lx %#lx %lu %d *",
+ (unsigned long) client_p,
+ client_p ? client_p->
+ name : "<noname>",
+ client_p->username,
+ client_p->host,
+ (unsigned long) user,
+ (unsigned long) user->invited.head,
+ (unsigned long) user->channel.head,
+ dlink_list_length(&user->channel),
+ user->refcnt);
+ s_assert(!user->refcnt);
+ s_assert(!user->invited.head);
+ s_assert(!user->channel.head);
+ }
+
+ BlockHeapFree(user_heap, user);
+ }
+}
+
+void
+init_uid(void)
+{
+ int i;
+
+ for(i = 0; i < 3; i++)
+ current_uid[i] = me.id[i];
+
+ for(i = 3; i < 9; i++)
+ current_uid[i] = 'A';
+
+ current_uid[9] = '\0';
+}
+
+
+char *
+generate_uid(void)
+{
+ int i;
+
+ for(i = 8; i > 3; i--)
+ {
+ if(current_uid[i] == 'Z')
+ {
+ current_uid[i] = '0';
+ return current_uid;
+ }
+ else if(current_uid[i] != '9')
+ {
+ current_uid[i]++;
+ return current_uid;
+ }
+ else
+ current_uid[i] = 'A';
+ }
+
+ /* if this next if() triggers, we're fucked. */
+ if(current_uid[3] == 'Z')
+ {
+ current_uid[i] = 'A';
+ s_assert(0);
+ }
+ else
+ current_uid[i]++;
+
+ return current_uid;
+}
+
+/*
+ * close_connection
+ * Close the physical connection. This function must make
+ * MyConnect(client_p) == FALSE, and set client_p->from == NULL.
+ */
+void
+close_connection(struct Client *client_p)
+{
+ s_assert(client_p != NULL);
+ if(client_p == NULL)
+ return;
+
+ s_assert(MyConnect(client_p));
+ if(!MyConnect(client_p))
+ return;
+
+ if(IsServer(client_p))
+ {
+ struct server_conf *server_p;
+
+ ServerStats->is_sv++;
+ ServerStats->is_sbs += client_p->localClient->sendB;
+ ServerStats->is_sbr += client_p->localClient->receiveB;
+ ServerStats->is_sks += client_p->localClient->sendK;
+ ServerStats->is_skr += client_p->localClient->receiveK;
+ ServerStats->is_sti += CurrentTime - client_p->localClient->firsttime;
+ if(ServerStats->is_sbs > 2047)
+ {
+ ServerStats->is_sks += (ServerStats->is_sbs >> 10);
+ ServerStats->is_sbs &= 0x3ff;
+ }
+ if(ServerStats->is_sbr > 2047)
+ {
+ ServerStats->is_skr += (ServerStats->is_sbr >> 10);
+ ServerStats->is_sbr &= 0x3ff;
+ }
+
+ /*
+ * If the connection has been up for a long amount of time, schedule
+ * a 'quick' reconnect, else reset the next-connect cycle.
+ */
+ if((server_p = find_server_conf(client_p->name)) != NULL)
+ {
+ /*
+ * Reschedule a faster reconnect, if this was a automatically
+ * connected configuration entry. (Note that if we have had
+ * a rehash in between, the status has been changed to
+ * CONF_ILLEGAL). But only do this if it was a "good" link.
+ */
+ server_p->hold = time(NULL);
+ server_p->hold +=
+ (server_p->hold - client_p->localClient->lasttime >
+ HANGONGOODLINK) ? HANGONRETRYDELAY : ConFreq(server_p->class);
+ }
+
+ }
+ else if(IsClient(client_p))
+ {
+ ServerStats->is_cl++;
+ ServerStats->is_cbs += client_p->localClient->sendB;
+ ServerStats->is_cbr += client_p->localClient->receiveB;
+ ServerStats->is_cks += client_p->localClient->sendK;
+ ServerStats->is_ckr += client_p->localClient->receiveK;
+ ServerStats->is_cti += CurrentTime - client_p->localClient->firsttime;
+ if(ServerStats->is_cbs > 2047)
+ {
+ ServerStats->is_cks += (ServerStats->is_cbs >> 10);
+ ServerStats->is_cbs &= 0x3ff;
+ }
+ if(ServerStats->is_cbr > 2047)
+ {
+ ServerStats->is_ckr += (ServerStats->is_cbr >> 10);
+ ServerStats->is_cbr &= 0x3ff;
+ }
+ }
+ else
+ ServerStats->is_ni++;
+
+ if(-1 < client_p->localClient->fd)
+ {
+ /* attempt to flush any pending dbufs. Evil, but .. -- adrian */
+ if(!IsIOError(client_p))
+ send_queued_write(client_p->localClient->fd, client_p);
+
+ comm_close(client_p->localClient->fd);
+ client_p->localClient->fd = -1;
+ }
+
+ if(HasServlink(client_p))
+ {
+ if(client_p->localClient->fd > -1)
+ {
+ comm_close(client_p->localClient->ctrlfd);
+ client_p->localClient->ctrlfd = -1;
+ }
+ }
+
+ linebuf_donebuf(&client_p->localClient->buf_sendq);
+ linebuf_donebuf(&client_p->localClient->buf_recvq);
+ detach_conf(client_p);
+
+ /* XXX shouldnt really be done here. */
+ detach_server_conf(client_p);
+
+ client_p->from = NULL; /* ...this should catch them! >:) --msa */
+ ClearMyConnect(client_p);
+ SetIOError(client_p);
+}
+
+
+
+void
+error_exit_client(struct Client *client_p, int error)
+{
+ /*
+ * ...hmm, with non-blocking sockets we might get
+ * here from quite valid reasons, although.. why
+ * would select report "data available" when there
+ * wasn't... so, this must be an error anyway... --msa
+ * actually, EOF occurs when read() returns 0 and
+ * in due course, select() returns that fd as ready
+ * for reading even though it ends up being an EOF. -avalon
+ */
+ char errmsg[255];
+ int current_error = comm_get_sockerr(client_p->localClient->fd);
+
+ SetIOError(client_p);
+
+ if(IsServer(client_p) || IsHandshake(client_p))
+ {
+ int connected = CurrentTime - client_p->localClient->firsttime;
+
+ if(error == 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL,
+ "Server %s closed the connection",
+ get_server_name(client_p, SHOW_IP));
+
+ ilog(L_SERVER, "Server %s closed the connection",
+ log_client_name(client_p, SHOW_IP));
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL,
+ "Lost connection to %s: %s",
+ client_p->name, strerror(current_error));
+ ilog(L_SERVER, "Lost connection to %s: %s",
+ log_client_name(client_p, SHOW_IP), strerror(current_error));
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s had been connected for %d day%s, %2d:%02d:%02d",
+ client_p->name, connected / 86400,
+ (connected / 86400 == 1) ? "" : "s",
+ (connected % 86400) / 3600,
+ (connected % 3600) / 60, connected % 60);
+ }
+
+ if(error == 0)
+ strlcpy(errmsg, "Remote host closed the connection", sizeof(errmsg));
+ else
+ ircsnprintf(errmsg, sizeof(errmsg), "Read error: %s", strerror(current_error));
+
+ exit_client(client_p, client_p, &me, errmsg);
+}
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * extban.c: extended ban types ($type:data)
+ *
+ * Copyright (C) 2006 charybdis 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
+ *
+ * $Id: extban.c 1389 2006-05-20 19:19:00Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+
+ExtbanFunc extban_table[256] = { NULL };
+
+int
+match_extban(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type)
+{
+ const char *p;
+ int invert = 0, result = EXTBAN_INVALID;
+ ExtbanFunc f;
+
+ if (*banstr != '$')
+ return 0;
+ p = banstr + 1;
+ if (*p == '~')
+ {
+ invert = 1;
+ p++;
+ }
+ f = extban_table[(unsigned char) ToLower(*p)];
+ if (*p != '\0')
+ {
+ p++;
+ if (*p == ':')
+ p++;
+ else
+ p = NULL;
+ }
+ if (f != NULL)
+ result = f(p, client_p, chptr, mode_type);
+ else
+ result = EXTBAN_INVALID;
+
+ if (invert)
+ return result == EXTBAN_NOMATCH;
+ else
+ return result == EXTBAN_MATCH;
+}
+
+int
+valid_extban(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type)
+{
+ const char *p;
+ int invert = 0, result = EXTBAN_INVALID;
+ ExtbanFunc f;
+
+ if (*banstr != '$')
+ return 0;
+ p = banstr + 1;
+ if (*p == '~')
+ {
+ invert = 1;
+ p++;
+ }
+ f = extban_table[(unsigned char) ToLower(*p)];
+ if (*p != '\0')
+ {
+ p++;
+ if (*p == ':')
+ p++;
+ else
+ p = NULL;
+ }
+ if (f != NULL)
+ result = f(p, client_p, chptr, mode_type);
+ else
+ result = EXTBAN_INVALID;
+
+ return result != EXTBAN_INVALID;
+}
+
+const char *
+get_extban_string(void)
+{
+ static char e[256];
+ int i, j;
+
+ j = 0;
+ for (i = 1; i < 256; i++)
+ if (i == ToLower(i) && extban_table[i])
+ e[j++] = i;
+ e[j] = 0;
+ return e;
+}
--- /dev/null
+/*
+ * charybdis: a slightly useful ircd.
+ * fnvhash.s: x86-optimised FNV hashing implementation
+ *
+ * Copyright (c) 2006 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: fnvhash.s 2725 2006-11-09 23:43:35Z jilles $
+ */
+
+/* Safely moves hashv from %edx to %eax and returns back to the calling parent. */
+fnv_out:
+ movzbl 12(%ebp), %ecx
+ movl -4(%ebp), %eax
+ movl %eax, %edx
+ shrl %cl, %edx
+ movl 12(%ebp), %eax
+ xorl $2, %eax
+ decl %eax
+ andl -4(%ebp), %eax
+ xorl %edx, %eax
+ movl %eax, -4(%ebp)
+ movl -4(%ebp), %eax
+ leave
+ ret
+
+/*
+ * Capitalizes the contents of %eax and adds it to the hashv in %edx.
+ * Returns hashv in register %eax.
+ * - nenolod
+ */
+.globl fnv_hash_upper
+ .type fnv_hash_upper, @function
+fnv_hash_upper:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $4, %esp
+ movl $-2128831035, -4(%ebp) /* u_int32_t h = FNV1_32_INIT */
+.eat_data_upper: /* while loop construct */
+ movl 8(%ebp), %eax /* move value of *s to %eax */
+ cmpb $0, (%eax) /* is eax == 0? */
+ jne .hash_capitalized /* if no, then capitalize and hash */
+ jmp fnv_out /* if yes, then exit out of the loop */
+.hash_capitalized:
+ movl 8(%ebp), %eax
+ movzbl (%eax), %eax /* increment s (%eax) */
+ movzbl ToUpperTab(%eax), %edx /* hashv ^= ToUpperTab(%eax) */
+ leal -4(%ebp), %eax
+ xorl %edx, (%eax) /* hashv = 0 */
+ incl 8(%ebp)
+ movl -4(%ebp), %eax
+ imull $16777619, %eax, %eax /* FNV1_32_PRIME */
+ movl %eax, -4(%ebp) /* add this byte to hashv, and */
+ jmp .eat_data_upper /* go back for more... */
+
+/*
+ * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
+ * Returns hashv in register %eax.
+ * - nenolod
+ */
+.globl fnv_hash
+ .type fnv_hash, @function
+fnv_hash:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $4, %esp
+ movl $-2128831035, -4(%ebp) /* u_int32_t h = FNV1_32_INIT */
+.eat_data: /* again, the while loop construct */
+ movl 8(%ebp), %eax /* move value of *s to eax */
+ cmpb $0, (%eax) /* is eax == 0? */
+ jne .hash_lowercase /* if not, jump to .hash_lowercase */
+ jmp fnv_out /* otherwise, jump to fnv_out */
+.hash_lowercase:
+ movl 8(%ebp), %eax
+ movzbl (%eax), %edx
+ leal -4(%ebp), %eax
+ xorl %edx, (%eax)
+ incl 8(%ebp) /* h << 1 */
+ movl -4(%ebp), %eax
+ imull $16777619, %eax, %eax /* FNV1_32_PRIME */
+ movl %eax, -4(%ebp) /* add this byte to hashv, then */
+ jmp .eat_data /* check for more... */
+
+/*
+ * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
+ * Returns hashv in register %eax.
+ *
+ * Bounds checking is performed.
+ * - nenolod
+ */
+.globl fnv_hash_len
+ .type fnv_hash_len, @function
+fnv_hash_len:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $8, %esp
+ movl $-2128831035, -4(%ebp)
+ movl 16(%ebp), %eax
+ addl 8(%ebp), %eax
+ movl %eax, -8(%ebp)
+.eat_data_len:
+ movl 8(%ebp), %eax
+ cmpb $0, (%eax)
+ je fnv_out
+ movl 8(%ebp), %eax
+ cmpl -8(%ebp), %eax
+ jb .hash_lowercase_len
+ jmp fnv_out
+.hash_lowercase_len:
+ movl 8(%ebp), %eax
+ movzbl (%eax), %edx
+ leal -4(%ebp), %eax
+ xorl %edx, (%eax)
+ incl 8(%ebp)
+ movl -4(%ebp), %eax
+ imull $16777619, %eax, %eax /* FNV1_32_PRIME */
+ movl %eax, -4(%ebp)
+ jmp .eat_data_len
+
+/*
+ * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
+ * Returns hashv in register %eax.
+ *
+ * Bounds checking is performed.
+ * - nenolod
+ */
+.globl fnv_hash_upper_len
+ .type fnv_hash_upper_len, @function
+fnv_hash_upper_len:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $8, %esp
+ movl $-2128831035, -4(%ebp)
+ movl 16(%ebp), %eax
+ addl 8(%ebp), %eax
+ movl %eax, -8(%ebp)
+.eat_upper_len:
+ movl 8(%ebp), %eax
+ cmpb $0, (%eax)
+ je fnv_out
+ movl 8(%ebp), %eax
+ cmpl -8(%ebp), %eax
+ jb .hash_uppercase_len
+ jmp fnv_out
+.hash_uppercase_len:
+ movl 8(%ebp), %eax
+ movzbl (%eax), %eax
+ movzbl ToUpperTab(%eax), %edx
+ leal -4(%ebp), %eax
+ xorl %edx, (%eax)
+ incl 8(%ebp)
+ movl -4(%ebp), %eax
+ imull $16777619, %eax, %eax /* FNV1_32_PRIME */
+ movl %eax, -4(%ebp)
+ jmp .eat_upper_len
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * getopt.c: Uses getopt to fetch the command line options.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: getopt.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+
+#include "ircd_getopt.h"
+
+# define OPTCHAR '-'
+
+void
+parseargs(int *argc, char ***argv, struct lgetopt *opts)
+{
+ int i;
+ char *progname = (*argv)[0];
+
+ /* loop through each argument */
+ for (;;)
+ {
+ int found = 0;
+
+ (*argc)--;
+ (*argv)++;
+
+ if(*argc < 1)
+ {
+ return;
+ }
+
+ /* check if it *is* an arg.. */
+ if((*argv)[0][0] != OPTCHAR)
+ {
+ return;
+ }
+
+ (*argv)[0]++;
+
+ /* search through our argument list, and see if it matches */
+ for (i = 0; opts[i].opt; i++)
+ {
+ if(!strcmp(opts[i].opt, (*argv)[0]))
+ {
+ /* found our argument */
+ found = 1;
+
+ switch (opts[i].argtype)
+ {
+ case YESNO:
+ *((int *) opts[i].argloc) = 1;
+ break;
+ case INTEGER:
+ if(*argc < 2)
+ {
+ fprintf(stderr,
+ "Error: option '%c%s' requires an argument\n",
+ OPTCHAR, opts[i].opt);
+ usage((*argv)[0]);
+ }
+
+ *((int *) opts[i].argloc) = atoi((*argv)[1]);
+
+ (*argc)--;
+ (*argv)++;
+ break;
+ case STRING:
+ if(*argc < 2)
+ {
+ fprintf(stderr,
+ "error: option '%c%s' requires an argument\n",
+ OPTCHAR, opts[i].opt);
+ usage(progname);
+ }
+
+ *((char **) opts[i].argloc) =
+ malloc(strlen((*argv)[1]) + 1);
+ strcpy(*((char **) opts[i].argloc), (*argv)[1]);
+
+ (*argc)--;
+ (*argv)++;
+ break;
+
+ case USAGE:
+ usage(progname);
+ /*NOTREACHED*/ default:
+ fprintf(stderr,
+ "Error: internal error in parseargs() at %s:%d\n",
+ __FILE__, __LINE__);
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ if(!found)
+ {
+ fprintf(stderr, "error: unknown argument '%c%s'\n", OPTCHAR, (*argv)[0]);
+ usage(progname);
+ }
+ }
+}
+
+void
+usage(char *name)
+{
+ int i = 0;
+
+ fprintf(stderr, "Usage: %s [options]\n", name);
+ fprintf(stderr, "Where valid options are:\n");
+
+ for (i = 0; myopts[i].opt; i++)
+ {
+ fprintf(stderr, "\t%c%-10s %-20s%s\n", OPTCHAR,
+ myopts[i].opt, (myopts[i].argtype == YESNO
+ || myopts[i].argtype ==
+ USAGE) ? "" : myopts[i].argtype ==
+ INTEGER ? "<number>" : "<string>", myopts[i].desc);
+ }
+
+ exit(EXIT_FAILURE);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * hash.c: Maintains hashtables.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: hash.c 1321 2006-05-13 23:49:14Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "tools.h"
+#include "s_conf.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "memory.h"
+#include "msg.h"
+#include "cache.h"
+#include "s_newconf.h"
+
+dlink_list *clientTable;
+dlink_list *channelTable;
+dlink_list *idTable;
+dlink_list *resvTable;
+dlink_list *hostTable;
+dlink_list *helpTable;
+dlink_list *ndTable;
+
+/*
+ * look in whowas.c for the missing ...[WW_MAX]; entry
+ */
+
+/*
+ * Hashing.
+ *
+ * The server uses a chained hash table to provide quick and efficient
+ * hash table maintenance (providing the hash function works evenly over
+ * the input range). The hash table is thus not susceptible to problems
+ * of filling all the buckets or the need to rehash.
+ * It is expected that the hash table would look something like this
+ * during use:
+ * +-----+ +-----+ +-----+ +-----+
+ * ---| 224 |----| 225 |----| 226 |---| 227 |---
+ * +-----+ +-----+ +-----+ +-----+
+ * | | |
+ * +-----+ +-----+ +-----+
+ * | A | | C | | D |
+ * +-----+ +-----+ +-----+
+ * |
+ * +-----+
+ * | B |
+ * +-----+
+ *
+ * A - GOPbot, B - chang, C - hanuaway, D - *.mu.OZ.AU
+ *
+ * The order shown above is just one instant of the server.
+ *
+ *
+ * The hash functions currently used are based Fowler/Noll/Vo hashes
+ * which work amazingly well and have a extremely low collision rate
+ * For more info see http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ *
+ */
+
+/* init_hash()
+ *
+ * clears the various hashtables
+ */
+void
+init_hash(void)
+{
+ clientTable = MyMalloc(sizeof(dlink_list) * U_MAX);
+ idTable = MyMalloc(sizeof(dlink_list) * U_MAX);
+ ndTable = MyMalloc(sizeof(dlink_list) * U_MAX);
+ channelTable = MyMalloc(sizeof(dlink_list) * CH_MAX);
+ hostTable = MyMalloc(sizeof(dlink_list) * HOST_MAX);
+ resvTable = MyMalloc(sizeof(dlink_list) * R_MAX);
+ helpTable = MyMalloc(sizeof(dlink_list) * HELP_MAX);
+}
+
+#ifndef RICER_HASHING
+u_int32_t
+fnv_hash_upper(const unsigned char *s, int bits)
+{
+ u_int32_t h = FNV1_32_INIT;
+
+ while (*s)
+ {
+ h ^= ToUpper(*s++);
+ h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
+ }
+ h = (h >> bits) ^ (h & ((2^bits)-1));
+ return h;
+}
+
+u_int32_t
+fnv_hash(const unsigned char *s, int bits)
+{
+ u_int32_t h = FNV1_32_INIT;
+
+ while (*s)
+ {
+ h ^= *s++;
+ h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
+ }
+ h = (h >> bits) ^ (h & ((2^bits)-1));
+ return h;
+}
+
+u_int32_t
+fnv_hash_len(const unsigned char *s, int bits, int len)
+{
+ u_int32_t h = FNV1_32_INIT;
+ const unsigned char *x = s + len;
+ while (*s && s < x)
+ {
+ h ^= *s++;
+ h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
+ }
+ h = (h >> bits) ^ (h & ((2^bits)-1));
+ return h;
+}
+
+u_int32_t
+fnv_hash_upper_len(const unsigned char *s, int bits, int len)
+{
+ u_int32_t h = FNV1_32_INIT;
+ const unsigned char *x = s + len;
+ while (*s && s < x)
+ {
+ h ^= ToUpper(*s++);
+ h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
+ }
+ h = (h >> bits) ^ (h & ((2^bits)-1));
+ return h;
+}
+#endif
+
+/* hash_nick()
+ *
+ * hashes a nickname, first converting to lowercase
+ */
+static u_int32_t
+hash_nick(const char *name)
+{
+ return fnv_hash_upper((const unsigned char *) name, U_MAX_BITS);
+}
+
+/* hash_id()
+ *
+ * hashes an id, case is kept
+ */
+static u_int32_t
+hash_id(const char *name)
+{
+ return fnv_hash((const unsigned char *) name, U_MAX_BITS);
+}
+
+/* hash_channel()
+ *
+ * hashes a channel name, based on first 30 chars only for efficiency
+ */
+static u_int32_t
+hash_channel(const char *name)
+{
+ return fnv_hash_upper_len((const unsigned char *) name, CH_MAX_BITS, 30);
+}
+
+/* hash_hostname()
+ *
+ * hashes a hostname, based on first 30 chars only, as thats likely to
+ * be more dynamic than rest.
+ */
+static u_int32_t
+hash_hostname(const char *name)
+{
+ return fnv_hash_upper_len((const unsigned char *) name, HOST_MAX_BITS, 30);
+}
+
+/* hash_resv()
+ *
+ * hashes a resv channel name, based on first 30 chars only
+ */
+static u_int32_t
+hash_resv(const char *name)
+{
+ return fnv_hash_upper_len((const unsigned char *) name, R_MAX_BITS, 30);
+}
+
+static unsigned int
+hash_help(const char *name)
+{
+ unsigned int h = 0;
+
+ while(*name)
+ {
+ h += (unsigned int) (ToLower(*name++) & 0xDF);
+ }
+
+ return (h % HELP_MAX);
+}
+
+/* add_to_id_hash()
+ *
+ * adds an entry to the id hash table
+ */
+void
+add_to_id_hash(const char *name, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ if(EmptyString(name) || (client_p == NULL))
+ return;
+
+ hashv = hash_id(name);
+ dlinkAddAlloc(client_p, &idTable[hashv]);
+}
+
+/* add_to_client_hash()
+ *
+ * adds an entry (client/server) to the client hash table
+ */
+void
+add_to_client_hash(const char *name, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ s_assert(client_p != NULL);
+ if(EmptyString(name) || (client_p == NULL))
+ return;
+
+ hashv = hash_nick(name);
+ dlinkAddAlloc(client_p, &clientTable[hashv]);
+}
+
+/* add_to_hostname_hash()
+ *
+ * adds a client entry to the hostname hash table
+ */
+void
+add_to_hostname_hash(const char *hostname, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ s_assert(hostname != NULL);
+ s_assert(client_p != NULL);
+ if(EmptyString(hostname) || (client_p == NULL))
+ return;
+
+ hashv = hash_hostname(hostname);
+ dlinkAddAlloc(client_p, &hostTable[hashv]);
+}
+
+/* add_to_resv_hash()
+ *
+ * adds a resv channel entry to the resv hash table
+ */
+void
+add_to_resv_hash(const char *name, struct ConfItem *aconf)
+{
+ unsigned int hashv;
+
+ s_assert(!EmptyString(name));
+ s_assert(aconf != NULL);
+ if(EmptyString(name) || aconf == NULL)
+ return;
+
+ hashv = hash_resv(name);
+ dlinkAddAlloc(aconf, &resvTable[hashv]);
+}
+
+void
+add_to_help_hash(const char *name, struct cachefile *hptr)
+{
+ unsigned int hashv;
+
+ if(EmptyString(name) || hptr == NULL)
+ return;
+
+ hashv = hash_help(name);
+ dlinkAddAlloc(hptr, &helpTable[hashv]);
+}
+
+void
+add_to_nd_hash(const char *name, struct nd_entry *nd)
+{
+ nd->hashv = hash_nick(name);
+ dlinkAdd(nd, &nd->hnode, &ndTable[nd->hashv]);
+}
+
+/* del_from_id_hash()
+ *
+ * removes an id from the id hash table
+ */
+void
+del_from_id_hash(const char *id, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ s_assert(id != NULL);
+ s_assert(client_p != NULL);
+ if(EmptyString(id) || client_p == NULL)
+ return;
+
+ hashv = hash_id(id);
+ dlinkFindDestroy(client_p, &idTable[hashv]);
+}
+
+/* del_from_client_hash()
+ *
+ * removes a client/server from the client hash table
+ */
+void
+del_from_client_hash(const char *name, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ /* no s_asserts, this can happen when removing a client that
+ * is unregistered.
+ */
+ if(EmptyString(name) || client_p == NULL)
+ return;
+
+ hashv = hash_nick(name);
+ dlinkFindDestroy(client_p, &clientTable[hashv]);
+}
+
+/* del_from_channel_hash()
+ *
+ * removes a channel from the channel hash table
+ */
+void
+del_from_channel_hash(const char *name, struct Channel *chptr)
+{
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ s_assert(chptr != NULL);
+
+ if(EmptyString(name) || chptr == NULL)
+ return;
+
+ hashv = hash_channel(name);
+ dlinkFindDestroy(chptr, &channelTable[hashv]);
+}
+
+/* del_from_hostname_hash()
+ *
+ * removes a client entry from the hostname hash table
+ */
+void
+del_from_hostname_hash(const char *hostname, struct Client *client_p)
+{
+ unsigned int hashv;
+
+ if(hostname == NULL || client_p == NULL)
+ return;
+
+ hashv = hash_hostname(hostname);
+
+ dlinkFindDestroy(client_p, &hostTable[hashv]);
+}
+
+/* del_from_resv_hash()
+ *
+ * removes a resv entry from the resv hash table
+ */
+void
+del_from_resv_hash(const char *name, struct ConfItem *aconf)
+{
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ s_assert(aconf != NULL);
+ if(EmptyString(name) || aconf == NULL)
+ return;
+
+ hashv = hash_resv(name);
+
+ dlinkFindDestroy(aconf, &resvTable[hashv]);
+}
+
+void
+clear_help_hash(void)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ int i;
+
+ HASH_WALK_SAFE(i, HELP_MAX, ptr, next_ptr, helpTable)
+ {
+ free_cachefile(ptr->data);
+ dlinkDestroy(ptr, &helpTable[i]);
+ }
+ HASH_WALK_END
+}
+
+/* find_id()
+ *
+ * finds a client entry from the id hash table
+ */
+struct Client *
+find_id(const char *name)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_id(name);
+
+ DLINK_FOREACH(ptr, idTable[hashv].head)
+ {
+ target_p = ptr->data;
+
+ if(strcmp(name, target_p->id) == 0)
+ return target_p;
+ }
+
+ return NULL;
+}
+
+/* hash_find_masked_server()
+ *
+ * Whats happening in this next loop ? Well, it takes a name like
+ * foo.bar.edu and proceeds to earch for *.edu and then *.bar.edu.
+ * This is for checking full server names against masks although
+ * it isnt often done this way in lieu of using matches().
+ *
+ * Rewrote to do *.bar.edu first, which is the most likely case,
+ * also made const correct
+ * --Bleep
+ */
+static struct Client *
+hash_find_masked_server(struct Client *source_p, const char *name)
+{
+ char buf[HOSTLEN + 1];
+ char *p = buf;
+ char *s;
+ struct Client *server;
+
+ if('*' == *name || '.' == *name)
+ return NULL;
+
+ /* copy it across to give us a buffer to work on */
+ strlcpy(buf, name, sizeof(buf));
+
+ while ((s = strchr(p, '.')) != 0)
+ {
+ *--s = '*';
+ /*
+ * Dont need to check IsServer() here since nicknames cant
+ * have *'s in them anyway.
+ */
+ if((server = find_server(source_p, s)))
+ return server;
+ p = s + 2;
+ }
+
+ return NULL;
+}
+
+/* find_any_client()
+ *
+ * finds a client/server/masked server entry from the hash
+ */
+struct Client *
+find_any_client(const char *name)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return NULL;
+
+ /* hunting for an id, not a nick */
+ if(IsDigit(*name))
+ return (find_id(name));
+
+ hashv = hash_nick(name);
+
+ DLINK_FOREACH(ptr, clientTable[hashv].head)
+ {
+ target_p = ptr->data;
+
+ if(irccmp(name, target_p->name) == 0)
+ return target_p;
+ }
+
+ /* wasnt found, look for a masked server */
+ return hash_find_masked_server(NULL, name);
+}
+
+/* find_client()
+ *
+ * finds a client/server entry from the client hash table
+ */
+struct Client *
+find_client(const char *name)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return NULL;
+
+ /* hunting for an id, not a nick */
+ if(IsDigit(*name))
+ return (find_id(name));
+
+ hashv = hash_nick(name);
+
+ DLINK_FOREACH(ptr, clientTable[hashv].head)
+ {
+ target_p = ptr->data;
+
+ if(irccmp(name, target_p->name) == 0)
+ return target_p;
+ }
+
+ return NULL;
+}
+
+/* find_named_client()
+ *
+ * finds a client/server entry from the client hash table
+ */
+struct Client *
+find_named_client(const char *name)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_nick(name);
+
+ DLINK_FOREACH(ptr, clientTable[hashv].head)
+ {
+ target_p = ptr->data;
+
+ if(irccmp(name, target_p->name) == 0)
+ return target_p;
+ }
+
+ return NULL;
+}
+
+/* find_server()
+ *
+ * finds a server from the client hash table
+ */
+struct Client *
+find_server(struct Client *source_p, const char *name)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ if(EmptyString(name))
+ return NULL;
+
+ if((source_p == NULL || !MyClient(source_p)) &&
+ IsDigit(*name) && strlen(name) == 3)
+ {
+ target_p = find_id(name);
+ return(target_p);
+ }
+
+ hashv = hash_nick(name);
+
+ DLINK_FOREACH(ptr, clientTable[hashv].head)
+ {
+ target_p = ptr->data;
+
+ if((IsServer(target_p) || IsMe(target_p)) &&
+ irccmp(name, target_p->name) == 0)
+ return target_p;
+ }
+
+ /* wasnt found, look for a masked server */
+ return hash_find_masked_server(source_p, name);
+}
+
+/* find_hostname()
+ *
+ * finds a hostname dlink list from the hostname hash table.
+ * we return the full dlink list, because you can have multiple
+ * entries with the same hostname
+ */
+dlink_node *
+find_hostname(const char *hostname)
+{
+ unsigned int hashv;
+
+ if(EmptyString(hostname))
+ return NULL;
+
+ hashv = hash_hostname(hostname);
+
+ return hostTable[hashv].head;
+}
+
+/* find_channel()
+ *
+ * finds a channel from the channel hash table
+ */
+struct Channel *
+find_channel(const char *name)
+{
+ struct Channel *chptr;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_channel(name);
+
+ DLINK_FOREACH(ptr, channelTable[hashv].head)
+ {
+ chptr = ptr->data;
+
+ if(irccmp(name, chptr->chname) == 0)
+ return chptr;
+ }
+
+ return NULL;
+}
+
+/*
+ * get_or_create_channel
+ * inputs - client pointer
+ * - channel name
+ * - pointer to int flag whether channel was newly created or not
+ * output - returns channel block or NULL if illegal name
+ * - also modifies *isnew
+ *
+ * Get Channel block for chname (and allocate a new channel
+ * block, if it didn't exist before).
+ */
+struct Channel *
+get_or_create_channel(struct Client *client_p, const char *chname, int *isnew)
+{
+ struct Channel *chptr;
+ dlink_node *ptr;
+ unsigned int hashv;
+ int len;
+ const char *s = chname;
+
+ if(EmptyString(s))
+ return NULL;
+
+ len = strlen(s);
+ if(len > CHANNELLEN)
+ {
+ char *t;
+ if(IsServer(client_p))
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "*** Long channel name from %s (%d > %d): %s",
+ client_p->name, len, CHANNELLEN, s);
+ }
+ len = CHANNELLEN;
+ t = LOCAL_COPY(s);
+ *(t + CHANNELLEN) = '\0';
+ s = t;
+ }
+
+ hashv = hash_channel(s);
+
+ DLINK_FOREACH(ptr, channelTable[hashv].head)
+ {
+ chptr = ptr->data;
+
+ if(irccmp(s, chptr->chname) == 0)
+ {
+ if(isnew != NULL)
+ *isnew = 0;
+ return chptr;
+ }
+ }
+
+ if(isnew != NULL)
+ *isnew = 1;
+
+ chptr = allocate_channel(s);
+
+ dlinkAdd(chptr, &chptr->node, &global_channel_list);
+
+ chptr->channelts = CurrentTime; /* doesn't hurt to set it here */
+
+ dlinkAddAlloc(chptr, &channelTable[hashv]);
+
+ return chptr;
+}
+
+/* hash_find_resv()
+ *
+ * hunts for a resv entry in the resv hash table
+ */
+struct ConfItem *
+hash_find_resv(const char *name)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ s_assert(name != NULL);
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_resv(name);
+
+ DLINK_FOREACH(ptr, resvTable[hashv].head)
+ {
+ aconf = ptr->data;
+
+ if(!irccmp(name, aconf->name))
+ {
+ aconf->port++;
+ return aconf;
+ }
+ }
+
+ return NULL;
+}
+
+struct cachefile *
+hash_find_help(const char *name, int flags)
+{
+ struct cachefile *hptr;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_help(name);
+
+ DLINK_FOREACH(ptr, helpTable[hashv].head)
+ {
+ hptr = ptr->data;
+
+ if((irccmp(name, hptr->name) == 0) &&
+ (hptr->flags & flags))
+ return hptr;
+ }
+
+ return NULL;
+}
+
+void
+clear_resv_hash(void)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ int i;
+
+ HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
+ {
+ aconf = ptr->data;
+
+ /* skip temp resvs */
+ if(aconf->hold)
+ continue;
+
+ free_conf(ptr->data);
+ dlinkDestroy(ptr, &resvTable[i]);
+ }
+ HASH_WALK_END
+}
+
+struct nd_entry *
+hash_find_nd(const char *name)
+{
+ struct nd_entry *nd;
+ dlink_node *ptr;
+ unsigned int hashv;
+
+ if(EmptyString(name))
+ return NULL;
+
+ hashv = hash_nick(name);
+
+ DLINK_FOREACH(ptr, ndTable[hashv].head)
+ {
+ nd = ptr->data;
+
+ if(!irccmp(name, nd->name))
+ return nd;
+ }
+
+ return NULL;
+}
+
+static void
+output_hash(struct Client *source_p, const char *name, int length, int *counts, int deepest)
+{
+ unsigned long total = 0;
+ int i;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :%s Hash Statistics", name);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :Size: %d Empty: %d (%.3f%%)",
+ length, counts[0],
+ (float) ((counts[0]*100) / (float) length));
+
+ for(i = 1; i < 11; i++)
+ {
+ total += (counts[i] * i);
+ }
+
+ /* dont want to divide by 0! --fl */
+ if(counts[0] != length)
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :Average depth: %.3f/%.3f Highest depth: %d",
+ (float) (total / (length - counts[0])),
+ (float) (total / length), deepest);
+
+ for(i = 0; i < 11; i++)
+ {
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :Nodes with %d entries: %d",
+ i, counts[i]);
+ }
+}
+
+
+static void
+count_hash(struct Client *source_p, dlink_list *table, int length, const char *name)
+{
+ int counts[11];
+ int deepest = 0;
+ int i;
+
+ memset(counts, 0, sizeof(counts));
+
+ for(i = 0; i < length; i++)
+ {
+ if(dlink_list_length(&table[i]) >= 10)
+ counts[10]++;
+ else
+ counts[dlink_list_length(&table[i])]++;
+
+ if(dlink_list_length(&table[i]) > deepest)
+ deepest = dlink_list_length(&table[i]);
+ }
+
+ output_hash(source_p, name, length, counts, deepest);
+}
+
+void
+hash_stats(struct Client *source_p)
+{
+ count_hash(source_p, channelTable, CH_MAX, "Channel");
+ sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
+ count_hash(source_p, clientTable, U_MAX, "Client");
+ sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
+ count_hash(source_p, idTable, U_MAX, "ID");
+ sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
+ count_hash(source_p, hostTable, HOST_MAX, "Hostname");
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * hook.c - code for dealing with the hook system
+ *
+ * This code is basically a slow leaking array. Events are simply just a
+ * position in this array. When hooks are added, events will be created if
+ * they dont exist - this means modules with hooks can be loaded in any
+ * order, and events are preserved through module reloads.
+ *
+ * Copyright (C) 2004-2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2004-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: hook.c 712 2006-02-06 04:42:14Z gxti $
+ */
+#include "stdinc.h"
+#include "memory.h"
+#include "tools.h"
+#include "hook.h"
+#include "irc_string.h"
+
+hook *hooks;
+
+#define HOOK_INCREMENT 1000
+
+int num_hooks = 0;
+int last_hook = 0;
+int max_hooks = HOOK_INCREMENT;
+
+#ifdef USE_IODEBUG_HOOKS
+int h_iosend_id;
+int h_iorecv_id;
+int h_iorecvctrl_id;
+#endif
+int h_burst_client;
+int h_burst_channel;
+int h_burst_finished;
+int h_server_introduced;
+int h_server_eob;
+int h_client_exit;
+int h_new_local_user;
+int h_new_remote_user;
+int h_introduce_client;
+
+void
+init_hook(void)
+{
+ hooks = MyMalloc(sizeof(hook) * HOOK_INCREMENT);
+
+#ifdef USE_IODEBUG_HOOKS
+ h_iosend_id = register_hook("iosend");
+ h_iorecv_id = register_hook("iorecv");
+ h_iorecvctrl_id = register_hook("iorecvctrl");
+#endif
+
+ h_burst_client = register_hook("burst_client");
+ h_burst_channel = register_hook("burst_channel");
+ h_burst_finished = register_hook("burst_finished");
+ h_server_introduced = register_hook("server_introduced");
+ h_server_eob = register_hook("server_eob");
+ h_client_exit = register_hook("client_exit");
+ h_umode_changed = register_hook("umode_changed");
+ h_new_local_user = register_hook("new_local_user");
+ h_new_remote_user = register_hook("new_remote_user");
+ h_introduce_client = register_hook("introduce_client");
+}
+
+/* grow_hooktable()
+ * Enlarges the hook table by HOOK_INCREMENT
+ */
+static void
+grow_hooktable(void)
+{
+ hook *newhooks;
+
+ newhooks = MyMalloc(sizeof(hook) * (max_hooks + HOOK_INCREMENT));
+ memcpy(newhooks, hooks, sizeof(hook) * num_hooks);
+
+ MyFree(hooks);
+ hooks = newhooks;
+ max_hooks += HOOK_INCREMENT;
+}
+
+/* find_freehookslot()
+ * Finds the next free slot in the hook table, given by an entry with
+ * h->name being NULL.
+ */
+static int
+find_freehookslot(void)
+{
+ int i;
+
+ if((num_hooks + 1) > max_hooks)
+ grow_hooktable();
+
+ for(i = 0; i < max_hooks; i++)
+ {
+ if(!hooks[i].name)
+ return i;
+ }
+
+ /* shouldnt ever get here */
+ return(max_hooks - 1);
+}
+
+/* find_hook()
+ * Finds an event in the hook table.
+ */
+static int
+find_hook(const char *name)
+{
+ int i;
+
+ for(i = 0; i < max_hooks; i++)
+ {
+ if(!hooks[i].name)
+ continue;
+
+ if(!irccmp(hooks[i].name, name))
+ return i;
+ }
+
+ return -1;
+}
+
+/* register_hook()
+ * Finds an events position in the hook table, creating it if it doesnt
+ * exist.
+ */
+int
+register_hook(const char *name)
+{
+ int i;
+
+ if((i = find_hook(name)) < 0)
+ {
+ i = find_freehookslot();
+ DupString(hooks[i].name, name);
+ num_hooks++;
+ }
+
+ return i;
+}
+
+/* add_hook()
+ * Adds a hook to an event in the hook table, creating event first if
+ * needed.
+ */
+void
+add_hook(const char *name, hookfn fn)
+{
+ int i;
+
+ i = register_hook(name);
+
+ dlinkAddAlloc(fn, &hooks[i].hooks);
+}
+
+/* remove_hook()
+ * Removes a hook from an event in the hook table.
+ */
+void
+remove_hook(const char *name, hookfn fn)
+{
+ int i;
+
+ if((i = find_hook(name)) < 0)
+ return;
+
+ dlinkFindDestroy(fn, &hooks[i].hooks);
+}
+
+/* call_hook()
+ * Calls functions from a given event in the hook table.
+ */
+void
+call_hook(int id, void *arg)
+{
+ hookfn fn;
+ dlink_node *ptr;
+
+ /* The ID we were passed is the position in the hook table of this
+ * hook
+ */
+ DLINK_FOREACH(ptr, hooks[id].hooks.head)
+ {
+ fn = ptr->data;
+ fn(arg);
+ }
+}
+
--- /dev/null
+/*
+ * charybdis: an advanced internet relay chat daemon (ircd).
+ * hostmask.c: Code to efficiently find IP & hostmask based configs.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis 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
+ *
+ * $Id: hostmask.c 2757 2006-11-10 22:58:15Z jilles $
+ */
+
+#include "stdinc.h"
+#include "memory.h"
+#include "ircd_defs.h"
+#include "s_conf.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "send.h"
+#include "irc_string.h"
+
+#ifdef IPV6
+static unsigned long hash_ipv6(struct sockaddr *, int);
+#endif
+static unsigned long hash_ipv4(struct sockaddr *, int);
+
+
+/* int parse_netmask(const char *, struct irc_sockaddr_storage *, int *);
+ * Input: A hostmask, or an IPV4/6 address.
+ * Output: An integer describing whether it is an IPV4, IPV6 address or a
+ * hostmask, an address(if it is an IP mask),
+ * a bitlength(if it is IP mask).
+ * Side effects: None
+ */
+int
+parse_netmask(const char *text, struct sockaddr *naddr, int *nb)
+{
+ char *ip = LOCAL_COPY(text);
+ char *ptr;
+ struct irc_sockaddr_storage *addr, xaddr;
+ int *b, xb;
+ if(nb == NULL)
+ b = &xb;
+ else
+ b = nb;
+
+ if(naddr == NULL)
+ addr = (struct irc_sockaddr_storage *)&xaddr;
+ else
+ addr = (struct irc_sockaddr_storage *)naddr;
+
+#ifdef IPV6
+ if(strchr(ip, ':'))
+ {
+ if((ptr = strchr(ip, '/')))
+ {
+ *ptr = '\0';
+ ptr++;
+ *b = atoi(ptr);
+ if(*b > 128)
+ *b = 128;
+ } else
+ *b = 128;
+ if(inetpton_sock(ip, (struct sockaddr *)addr) > 0)
+ return HM_IPV6;
+ else
+ return HM_HOST;
+ } else
+#endif
+ if(strchr(text, '.'))
+ {
+ if((ptr = strchr(ip, '/')))
+ {
+ *ptr = '\0';
+ ptr++;
+ *b = atoi(ptr);
+ if(*b > 32)
+ *b = 32;
+ } else
+ *b = 32;
+ if(inetpton_sock(ip, (struct sockaddr *)addr) > 0)
+ return HM_IPV4;
+ else
+ return HM_HOST;
+ }
+ return HM_HOST;
+}
+
+/* Hashtable stuff...now external as its used in m_stats.c */
+struct AddressRec *atable[ATABLE_SIZE];
+
+void
+init_host_hash(void)
+{
+ memset(&atable, 0, sizeof(atable));
+}
+
+/* unsigned long hash_ipv4(struct irc_sockaddr_storage*)
+ * Input: An IP address.
+ * Output: A hash value of the IP address.
+ * Side effects: None
+ */
+static unsigned long
+hash_ipv4(struct sockaddr *saddr, int bits)
+{
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+
+ if(bits != 0)
+ {
+ unsigned long av = ntohl(addr->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
+ return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
+ }
+
+ return 0;
+}
+
+/* unsigned long hash_ipv6(struct irc_sockaddr_storage*)
+ * Input: An IP address.
+ * Output: A hash value of the IP address.
+ * Side effects: None
+ */
+#ifdef IPV6
+static unsigned long
+hash_ipv6(struct sockaddr *saddr, int bits)
+{
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+ unsigned long v = 0, n;
+ for (n = 0; n < 16; n++)
+ {
+ if(bits >= 8)
+ {
+ v ^= addr->sin6_addr.s6_addr[n];
+ bits -= 8;
+ }
+ else if(bits)
+ {
+ v ^= addr->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
+ return v & (ATABLE_SIZE - 1);
+ }
+ else
+ return v & (ATABLE_SIZE - 1);
+ }
+ return v & (ATABLE_SIZE - 1);
+}
+#endif
+
+/* int hash_text(const char *start)
+ * Input: The start of the text to hash.
+ * Output: The hash of the string between 1 and (TH_MAX-1)
+ * Side-effects: None.
+ */
+static int
+hash_text(const char *start)
+{
+ const char *p = start;
+ unsigned long h = 0;
+
+ while(*p)
+ {
+ h = (h << 4) - (h + (unsigned char) ToLower(*p++));
+ }
+
+ return (h & (ATABLE_SIZE - 1));
+}
+
+/* unsigned long get_hash_mask(const char *)
+ * Input: The text to hash.
+ * Output: The hash of the string right of the first '.' past the last
+ * wildcard in the string.
+ * Side-effects: None.
+ */
+static unsigned long
+get_mask_hash(const char *text)
+{
+ const char *hp = "", *p;
+
+ for (p = text + strlen(text) - 1; p >= text; p--)
+ if(*p == '*' || *p == '?')
+ return hash_text(hp);
+ else if(*p == '.')
+ hp = p + 1;
+ return hash_text(text);
+}
+
+/* struct ConfItem* find_conf_by_address(const char*, struct irc_sockaddr_storage*,
+ * int type, int fam, const char *username)
+ * Input: The hostname, the address, the type of mask to find, the address
+ * family, the username.
+ * Output: The matching value with the highest precedence.
+ * Side-effects: None
+ * Note: Setting bit 0 of the type means that the username is ignored.
+ */
+struct ConfItem *
+find_conf_by_address(const char *name, const char *sockhost,
+ const char *orighost,
+ struct sockaddr *addr, int type, int fam,
+ const char *username)
+{
+ unsigned long hprecv = 0;
+ struct ConfItem *hprec = NULL;
+ struct AddressRec *arec;
+ int b;
+
+ if(username == NULL)
+ username = "";
+
+ if(addr)
+ {
+ /* Check for IPV6 matches... */
+#ifdef IPV6
+ if(fam == AF_INET6)
+ {
+
+ for (b = 128; b >= 0; b -= 16)
+ {
+ for (arec = atable[hash_ipv6(addr, b)]; arec; arec = arec->next)
+ if(arec->type == (type & ~0x1) &&
+ arec->masktype == HM_IPV6 &&
+ comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
+ arec->Mask.ipa.bits) && (type & 0x1
+ ||
+ match(arec->
+ username,
+ username))
+ && arec->precedence > hprecv)
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ }
+ }
+ else
+#endif
+ if(fam == AF_INET)
+ {
+ for (b = 32; b >= 0; b -= 8)
+ {
+ for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next)
+ if(arec->type == (type & ~0x1) &&
+ arec->masktype == HM_IPV4 &&
+ arec->precedence > hprecv &&
+ comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
+ arec->Mask.ipa.bits) &&
+ (type & 0x1 || match(arec->username, username)))
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ }
+ }
+ }
+
+ if(orighost != NULL)
+ {
+ const char *p;
+
+ for (p = orighost; p != NULL;)
+ {
+ for (arec = atable[hash_text(p)]; arec; arec = arec->next)
+
+ if((arec->type == (type & ~0x1)) &&
+ (arec->masktype == HM_HOST) &&
+ arec->precedence > hprecv &&
+ match(arec->Mask.hostname, orighost) &&
+ (type & 0x1 || match(arec->username, username)))
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ p = strchr(p, '.');
+ if(p != NULL)
+ p++;
+ else
+ break;
+ }
+ for (arec = atable[0]; arec; arec = arec->next)
+ {
+ if(arec->type == (type & ~0x1) &&
+ arec->masktype == HM_HOST &&
+ arec->precedence > hprecv &&
+ (match(arec->Mask.hostname, orighost) ||
+ (sockhost && match(arec->Mask.hostname, sockhost))) &&
+ (type & 0x1 || match(arec->username, username)))
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ }
+ }
+
+ if(name != NULL)
+ {
+ const char *p;
+ /* And yes - we have to check p after strchr and p after increment for
+ * NULL -kre */
+ for (p = name; p != NULL;)
+ {
+ for (arec = atable[hash_text(p)]; arec; arec = arec->next)
+ if((arec->type == (type & ~0x1)) &&
+ (arec->masktype == HM_HOST) &&
+ arec->precedence > hprecv &&
+ match(arec->Mask.hostname, name) &&
+ (type & 0x1 || match(arec->username, username)))
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ p = strchr(p, '.');
+ if(p != NULL)
+ p++;
+ else
+ break;
+ }
+ for (arec = atable[0]; arec; arec = arec->next)
+ {
+ if(arec->type == (type & ~0x1) &&
+ arec->masktype == HM_HOST &&
+ arec->precedence > hprecv &&
+ (match(arec->Mask.hostname, name) ||
+ (sockhost && match(arec->Mask.hostname, sockhost))) &&
+ (type & 0x1 || match(arec->username, username)))
+ {
+ hprecv = arec->precedence;
+ hprec = arec->aconf;
+ }
+ }
+ }
+ return hprec;
+}
+
+/* struct ConfItem* find_address_conf(const char*, const char*,
+ * struct irc_sockaddr_storage*, int);
+ * Input: The hostname, username, address, address family.
+ * Output: The applicable ConfItem.
+ * Side-effects: None
+ */
+struct ConfItem *
+find_address_conf(const char *host, const char *sockhost, const char *user,
+ const char *notildeuser, struct sockaddr *ip, int aftype)
+{
+ struct ConfItem *iconf, *kconf;
+ const char *vuser;
+
+ /* Find the best I-line... If none, return NULL -A1kmm */
+ if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user)))
+ return NULL;
+ /* Find what their visible username will be.
+ * Note that the username without tilde may contain one char more.
+ * -- jilles */
+ vuser = IsNoTilde(iconf) ? notildeuser : user;
+
+ /* If they are exempt from K-lines, return the best I-line. -A1kmm */
+ if(IsConfExemptKline(iconf))
+ return iconf;
+
+ /* Find the best K-line... -A1kmm */
+ kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user);
+
+ /* If they are K-lined, return the K-line */
+ if(kconf)
+ return kconf;
+
+ /* if theres a spoof, check it against klines.. */
+ if(IsConfDoSpoofIp(iconf))
+ {
+ char *p = strchr(iconf->name, '@');
+
+ /* note, we dont need to pass sockhost here, as its
+ * guaranteed to not match by whats above.. --anfl
+ */
+ if(p)
+ {
+ *p = '\0';
+ kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->name);
+ *p = '@';
+ }
+ else
+ kconf = find_conf_by_address(iconf->name, NULL, NULL, ip, CONF_KILL, aftype, vuser);
+
+ if(kconf)
+ return kconf;
+ }
+
+ /* if no_tilde, check the username without tilde against klines too
+ * -- jilles */
+ if(user != vuser)
+ {
+ kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser);
+ if(kconf)
+ return kconf;
+ }
+
+ /* hunt for a gline */
+ if(ConfigFileEntry.glines)
+ {
+ kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_GLINE, aftype, user);
+
+ if((kconf != NULL) && !IsConfExemptGline(iconf))
+ return kconf;
+ }
+
+ return iconf;
+}
+
+/* struct ConfItem* find_dline(struct irc_sockaddr_storage*, int)
+ * Input: An address, an address family.
+ * Output: The best matching D-line or exempt line.
+ * Side effects: None.
+ */
+struct ConfItem *
+find_dline(struct sockaddr *addr, int aftype)
+{
+ struct ConfItem *eline;
+ eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL);
+ if(eline)
+ return eline;
+ return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL);
+}
+
+/* void add_conf_by_address(const char*, int, const char *,
+ * struct ConfItem *aconf)
+ * Input:
+ * Output: None
+ * Side-effects: Adds this entry to the hash table.
+ */
+void
+add_conf_by_address(const char *address, int type, const char *username, struct ConfItem *aconf)
+{
+ static unsigned long prec_value = 0xFFFFFFFF;
+ int masktype, bits;
+ unsigned long hv;
+ struct AddressRec *arec;
+
+ if(address == NULL)
+ address = "/NOMATCH!/";
+ arec = MyMalloc(sizeof(struct AddressRec));
+ masktype = parse_netmask(address, (struct sockaddr *)&arec->Mask.ipa.addr, &bits);
+ arec->Mask.ipa.bits = bits;
+ arec->masktype = masktype;
+#ifdef IPV6
+ if(masktype == HM_IPV6)
+ {
+ /* We have to do this, since we do not re-hash for every bit -A1kmm. */
+ bits -= bits % 16;
+ arec->next = atable[(hv = hash_ipv6((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
+ atable[hv] = arec;
+ }
+ else
+#endif
+ if(masktype == HM_IPV4)
+ {
+ /* We have to do this, since we do not re-hash for every bit -A1kmm. */
+ bits -= bits % 8;
+ arec->next = atable[(hv = hash_ipv4((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
+ atable[hv] = arec;
+ }
+ else
+ {
+ arec->Mask.hostname = address;
+ arec->next = atable[(hv = get_mask_hash(address))];
+ atable[hv] = arec;
+ }
+ arec->username = username;
+ arec->aconf = aconf;
+ arec->precedence = prec_value--;
+ arec->type = type;
+}
+
+/* void delete_one_address(const char*, struct ConfItem*)
+ * Input: An address string, the associated ConfItem.
+ * Output: None
+ * Side effects: Deletes an address record. Frees the ConfItem if there
+ * is nothing referencing it, sets it as illegal otherwise.
+ */
+void
+delete_one_address_conf(const char *address, struct ConfItem *aconf)
+{
+ int masktype, bits;
+ unsigned long hv;
+ struct AddressRec *arec, *arecl = NULL;
+ struct irc_sockaddr_storage addr;
+ masktype = parse_netmask(address, (struct sockaddr *)&addr, &bits);
+#ifdef IPV6
+ if(masktype == HM_IPV6)
+ {
+ /* We have to do this, since we do not re-hash for every bit -A1kmm. */
+ bits -= bits % 16;
+ hv = hash_ipv6((struct sockaddr *)&addr, bits);
+ }
+ else
+#endif
+ if(masktype == HM_IPV4)
+ {
+ /* We have to do this, since we do not re-hash for every bit -A1kmm. */
+ bits -= bits % 8;
+ hv = hash_ipv4((struct sockaddr *)&addr, bits);
+ }
+ else
+ hv = get_mask_hash(address);
+ for (arec = atable[hv]; arec; arec = arec->next)
+ {
+ if(arec->aconf == aconf)
+ {
+ if(arecl)
+ arecl->next = arec->next;
+ else
+ atable[hv] = arec->next;
+ aconf->status |= CONF_ILLEGAL;
+ if(!aconf->clients)
+ free_conf(aconf);
+ MyFree(arec);
+ return;
+ }
+ arecl = arec;
+ }
+}
+
+/* void clear_out_address_conf(void)
+ * Input: None
+ * Output: None
+ * Side effects: Clears out all address records in the hash table,
+ * frees them, and frees the ConfItems if nothing references
+ * them, otherwise sets them as illegal.
+ */
+void
+clear_out_address_conf(void)
+{
+ int i;
+ struct AddressRec **store_next;
+ struct AddressRec *arec, *arecn;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ store_next = &atable[i];
+ for (arec = atable[i]; arec; arec = arecn)
+ {
+ arecn = arec->next;
+ /* We keep the temporary K-lines and destroy the
+ * permanent ones, just to be confusing :) -A1kmm */
+ if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
+ (arec->type != CONF_CLIENT && arec->type != CONF_EXEMPTDLINE))
+ {
+ *store_next = arec;
+ store_next = &arec->next;
+ }
+ else
+ {
+ arec->aconf->status |= CONF_ILLEGAL;
+ if(!arec->aconf->clients)
+ free_conf(arec->aconf);
+ MyFree(arec);
+ }
+ }
+ *store_next = NULL;
+ }
+}
+
+void
+clear_out_address_conf_bans(void)
+{
+ int i;
+ struct AddressRec **store_next;
+ struct AddressRec *arec, *arecn;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ store_next = &atable[i];
+ for (arec = atable[i]; arec; arec = arecn)
+ {
+ arecn = arec->next;
+ /* We keep the temporary K-lines and destroy the
+ * permanent ones, just to be confusing :) -A1kmm */
+ if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
+ (arec->type == CONF_CLIENT || arec->type == CONF_EXEMPTDLINE))
+ {
+ *store_next = arec;
+ store_next = &arec->next;
+ }
+ else
+ {
+ arec->aconf->status |= CONF_ILLEGAL;
+ if(!arec->aconf->clients)
+ free_conf(arec->aconf);
+ MyFree(arec);
+ }
+ }
+ *store_next = NULL;
+ }
+}
+
+
+/*
+ * show_iline_prefix()
+ *
+ * inputs - pointer to struct Client requesting output
+ * - pointer to struct ConfItem
+ * - name to which iline prefix will be prefixed to
+ * output - pointer to static string with prefixes listed in ascii form
+ * side effects - NONE
+ */
+char *
+show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name)
+{
+ static char prefix_of_host[USERLEN + 15];
+ char *prefix_ptr;
+
+ prefix_ptr = prefix_of_host;
+ if(IsNoTilde(aconf))
+ *prefix_ptr++ = '-';
+ if(IsLimitIp(aconf))
+ *prefix_ptr++ = '!';
+ if(IsNeedIdentd(aconf))
+ *prefix_ptr++ = '+';
+ if(IsPassIdentd(aconf))
+ *prefix_ptr++ = '$';
+ if(IsNoMatchIp(aconf))
+ *prefix_ptr++ = '%';
+ if(IsConfDoSpoofIp(aconf))
+ *prefix_ptr++ = '=';
+ if(MyOper(sptr) && IsConfExemptKline(aconf))
+ *prefix_ptr++ = '^';
+ if(MyOper(sptr) && IsConfExemptLimits(aconf))
+ *prefix_ptr++ = '>';
+ if(MyOper(sptr) && IsConfIdlelined(aconf))
+ *prefix_ptr++ = '<';
+ *prefix_ptr = '\0';
+ strncpy(prefix_ptr, name, USERLEN);
+ return (prefix_of_host);
+}
+
+/* report_auth()
+ *
+ * Inputs: pointer to client to report to
+ * Output: None
+ * Side effects: Reports configured auth{} blocks to client_p
+ */
+void
+report_auth(struct Client *client_p)
+{
+ char *name, *host, *pass, *user, *classname;
+ struct AddressRec *arec;
+ struct ConfItem *aconf;
+ int i, port;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ for (arec = atable[i]; arec; arec = arec->next)
+ if(arec->type == CONF_CLIENT)
+ {
+ aconf = arec->aconf;
+
+ if(!MyOper(client_p) && IsConfDoSpoofIp(aconf))
+ continue;
+
+ get_printable_conf(aconf, &name, &host, &pass, &user, &port,
+ &classname);
+
+ sendto_one_numeric(client_p, RPL_STATSILINE,
+ form_str(RPL_STATSILINE),
+ name, show_iline_prefix(client_p, aconf, user),
+ show_ip_conf(aconf, client_p) ? host : "255.255.255.255",
+ port, classname);
+ }
+}
+
+/* report_Klines()
+ *
+ * inputs - Client to report to, mask
+ * outputs -
+ * side effects - Reports configured K-lines to client_p.
+ */
+void
+report_Klines(struct Client *source_p)
+{
+ char *host, *pass, *user, *oper_reason;
+ struct AddressRec *arec;
+ struct ConfItem *aconf = NULL;
+ int i;
+
+ for (i = 0; i < ATABLE_SIZE; i++)
+ {
+ for (arec = atable[i]; arec; arec = arec->next)
+ {
+ if(arec->type == CONF_KILL)
+ {
+ aconf = arec->aconf;
+
+ /* its a tempkline, theyre reported elsewhere */
+ if(aconf->flags & CONF_FLAGS_TEMPORARY)
+ continue;
+
+ get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
+ sendto_one_numeric(source_p, RPL_STATSKLINE,
+ form_str(RPL_STATSKLINE),
+ 'K', host, user, pass,
+ oper_reason ? "|" : "",
+ oper_reason ? oper_reason : "");
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * irc_string.c: IRC string functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: irc_string.c 678 2006-02-03 20:25:01Z jilles $
+ */
+
+#include "stdinc.h"
+#include "sprintf_irc.h"
+#include "tools.h"
+#include "irc_string.h"
+#include "client.h"
+#include "memory.h"
+#include "setup.h"
+
+#ifndef INADDRSZ
+#define INADDRSZ 4
+#endif
+
+#ifdef IPV6
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ 16
+#endif
+#endif
+
+#ifndef INT16SZ
+#define INT16SZ 2
+#endif
+/*
+ * myctime - This is like standard ctime()-function, but it zaps away
+ * the newline from the end of that string. Also, it takes
+ * the time value as parameter, instead of pointer to it.
+ * Note that it is necessary to copy the string to alternate
+ * buffer (who knows how ctime() implements it, maybe it statically
+ * has newline there and never 'refreshes' it -- zapping that
+ * might break things in other places...)
+ *
+ *
+ * Thu Nov 24 18:22:48 1986
+ */
+const char *
+myctime(time_t value)
+{
+ static char buf[32];
+ char *p;
+
+ strcpy(buf, ctime(&value));
+ if((p = strchr(buf, '\n')) != NULL)
+ *p = '\0';
+ return buf;
+}
+
+
+/*
+ * clean_string - clean up a string possibly containing garbage
+ *
+ * *sigh* Before the kiddies find this new and exciting way of
+ * annoying opers, lets clean up what is sent to local opers
+ * -Dianora
+ */
+char *
+clean_string(char *dest, const unsigned char *src, size_t len)
+{
+ char *d = dest;
+ s_assert(0 != dest);
+ s_assert(0 != src);
+
+ if(dest == NULL || src == NULL)
+ return NULL;
+
+ len -= 3; /* allow for worst case, '^A\0' */
+
+ while(*src && (len > 0))
+ {
+ if(*src & 0x80) /* if high bit is set */
+ {
+ *d++ = '.';
+ --len;
+ }
+ else if(!IsPrint(*src)) /* if NOT printable */
+ {
+ *d++ = '^';
+ --len;
+ *d++ = 0x40 + *src; /* turn it into a printable */
+ }
+ else
+ *d++ = *src;
+ ++src;
+ --len;
+ }
+ *d = '\0';
+ return dest;
+}
+
+/*
+ * strip_tabs(dst, src, length)
+ *
+ * Copies src to dst, while converting all \t (tabs) into spaces.
+ *
+ * NOTE: jdc: I have a gut feeling there's a faster way to do this.
+ */
+char *
+strip_tabs(char *dest, const unsigned char *src, size_t len)
+{
+ char *d = dest;
+ /* Sanity check; we don't want anything nasty... */
+ s_assert(0 != dest);
+ s_assert(0 != src);
+
+ if(dest == NULL || src == NULL)
+ return NULL;
+
+ while(*src && (len > 0))
+ {
+ if(*src == '\t')
+ {
+ *d++ = ' '; /* Translate the tab into a space */
+ }
+ else
+ {
+ *d++ = *src; /* Copy src to dst */
+ }
+ ++src;
+ --len;
+ }
+ *d = '\0'; /* Null terminate, thanks and goodbye */
+ return dest;
+}
+
+/*
+ * strtoken - walk through a string of tokens, using a set of separators
+ * argv 9/90
+ *
+ */
+char *
+strtoken(char **save, char *str, const char *fs)
+{
+ char *pos = *save; /* keep last position across calls */
+ char *tmp;
+
+ if(str)
+ pos = str; /* new string scan */
+
+ while(pos && *pos && strchr(fs, *pos) != NULL)
+ ++pos; /* skip leading separators */
+
+ if(!pos || !*pos)
+ return (pos = *save = NULL); /* string contains only sep's */
+
+ tmp = pos; /* now, keep position of the token */
+
+ while(*pos && strchr(fs, *pos) == NULL)
+ ++pos; /* skip content of the token */
+
+ if(*pos)
+ *pos++ = '\0'; /* remove first sep after the token */
+ else
+ pos = NULL; /* end of string */
+
+ *save = pos;
+ return tmp;
+}
+
+static const char base64_table[] =
+ { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
+ };
+
+static const char base64_pad = '=';
+
+static const short base64_reverse_table[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+unsigned char *
+ircd_base64_encode(const unsigned char *str, int length)
+{
+ const unsigned char *current = str;
+ unsigned char *p;
+ unsigned char *result;
+
+ if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
+ return NULL;
+ }
+
+ result = MyMalloc(((length + 2) / 3) * 5);
+ p = result;
+
+ while (length > 2)
+ {
+ *p++ = base64_table[current[0] >> 2];
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
+ *p++ = base64_table[current[2] & 0x3f];
+
+ current += 3;
+ length -= 3;
+ }
+
+ if (length != 0) {
+ *p++ = base64_table[current[0] >> 2];
+ if (length > 1) {
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[(current[1] & 0x0f) << 2];
+ *p++ = base64_pad;
+ } else {
+ *p++ = base64_table[(current[0] & 0x03) << 4];
+ *p++ = base64_pad;
+ *p++ = base64_pad;
+ }
+ }
+ *p = '\0';
+ return result;
+}
+
+unsigned char *
+ircd_base64_decode(const unsigned char *str, int length, int *ret)
+{
+ const unsigned char *current = str;
+ int ch, i = 0, j = 0, k;
+ unsigned char *result;
+
+ result = MyMalloc(length + 1);
+
+ while ((ch = *current++) != '\0' && length-- > 0) {
+ if (ch == base64_pad) break;
+
+ ch = base64_reverse_table[ch];
+ if (ch < 0) continue;
+
+ switch(i % 4) {
+ case 0:
+ result[j] = ch << 2;
+ break;
+ case 1:
+ result[j++] |= ch >> 4;
+ result[j] = (ch & 0x0f) << 4;
+ break;
+ case 2:
+ result[j++] |= ch >>2;
+ result[j] = (ch & 0x03) << 6;
+ break;
+ case 3:
+ result[j++] |= ch;
+ break;
+ }
+ i++;
+ }
+
+ k = j;
+
+ if (ch == base64_pad) {
+ switch(i % 4) {
+ case 1:
+ free(result);
+ return NULL;
+ case 2:
+ k++;
+ case 3:
+ result[k++] = 0;
+ }
+ }
+ result[j] = '\0';
+
+ if(ret)
+ *ret = j;
+
+ return result;
+}
+
+/*
+ * From: Thomas Helvey <tomh@inxpress.net>
+ */
+static const char *IpQuadTab[] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
+ "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
+ "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
+ "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
+ "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
+ "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
+ "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
+ "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
+ "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
+ "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
+ "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
+ "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
+ "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
+ "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
+ "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
+ "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
+ "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
+ "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
+ "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
+ "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
+ "250", "251", "252", "253", "254", "255"
+};
+
+/*
+ * inetntoa - in_addr to string
+ * changed name to remove collision possibility and
+ * so behaviour is guaranteed to take a pointer arg.
+ * -avalon 23/11/92
+ * inet_ntoa -- returned the dotted notation of a given
+ * internet number
+ * argv 11/90).
+ * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
+ */
+
+const char *
+inetntoa(const char *in)
+{
+ static char buf[16];
+ char *bufptr = buf;
+ const unsigned char *a = (const unsigned char *) in;
+ const char *n;
+
+ n = IpQuadTab[*a++];
+ while(*n)
+ *bufptr++ = *n++;
+ *bufptr++ = '.';
+ n = IpQuadTab[*a++];
+ while(*n)
+ *bufptr++ = *n++;
+ *bufptr++ = '.';
+ n = IpQuadTab[*a++];
+ while(*n)
+ *bufptr++ = *n++;
+ *bufptr++ = '.';
+ n = IpQuadTab[*a];
+ while(*n)
+ *bufptr++ = *n++;
+ *bufptr = '\0';
+ return buf;
+}
+
+/*
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#define SPRINTF(x) ((size_t)ircsprintf x)
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char * src, char *dst, unsigned int size);
+#ifdef IPV6
+static const char *inet_ntop6(const u_char * src, char *dst, unsigned int size);
+#endif
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
+{
+ if(size < 16)
+ return NULL;
+ return strcpy(dst, inetntoa((const char *) src));
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+#ifdef IPV6
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct
+ {
+ int base, len;
+ }
+ best, cur;
+ u_int words[IN6ADDRSZ / INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for(i = 0; i < IN6ADDRSZ; i += 2)
+ words[i / 2] = (src[i] << 8) | src[i + 1];
+ best.base = -1;
+ cur.base = -1;
+ for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ {
+ if(words[i] == 0)
+ {
+ if(cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ }
+ else
+ {
+ if(cur.base != -1)
+ {
+ if(best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if(cur.base != -1)
+ {
+ if(best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if(best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+ {
+ /* Are we inside the best run of 0x00's? */
+ if(best.base != -1 && i >= best.base && i < (best.base + best.len))
+ {
+ if(i == best.base)
+ {
+ if(i == 0)
+ *tp++ = '0';
+ *tp++ = ':';
+ }
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if(i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if(i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
+ {
+ if(!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += SPRINTF((tp, "%x", words[i]));
+ }
+ /* Was it a trailing run of 0x00's? */
+ if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+
+ if((unsigned int) (tp - tmp) > size)
+ {
+ return (NULL);
+ }
+ return strcpy(dst, tmp);
+}
+#endif
+
+int
+inetpton_sock(const char *src, struct sockaddr *dst)
+{
+ if(inetpton(AF_INET, src, &((struct sockaddr_in *) dst)->sin_addr))
+ {
+ ((struct sockaddr_in *) dst)->sin_port = 0;
+ ((struct sockaddr_in *) dst)->sin_family = AF_INET;
+ SET_SS_LEN(*((struct irc_sockaddr_storage *) dst), sizeof(struct sockaddr_in));
+ return 1;
+ }
+#ifdef IPV6
+ else if(inetpton(AF_INET6, src, &((struct sockaddr_in6 *) dst)->sin6_addr))
+ {
+ ((struct sockaddr_in6 *) dst)->sin6_port = 0;
+ ((struct sockaddr_in6 *) dst)->sin6_family = AF_INET6;
+ SET_SS_LEN(*((struct irc_sockaddr_storage *) dst), sizeof(struct sockaddr_in6));
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+const char *
+inetntop_sock(struct sockaddr *src, char *dst, unsigned int size)
+{
+ switch (src->sa_family)
+ {
+ case AF_INET:
+ return (inetntop(AF_INET, &((struct sockaddr_in *) src)->sin_addr, dst, size));
+ break;
+#ifdef IPV6
+ case AF_INET6:
+ return (inetntop(AF_INET6, &((struct sockaddr_in6 *) src)->sin6_addr, dst, size));
+ break;
+#endif
+ default:
+ return NULL;
+ break;
+ }
+}
+
+/* char *
+ * inetntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inetntop(int af, const void *src, char *dst, unsigned int size)
+{
+ switch (af)
+ {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef IPV6
+ case AF_INET6:
+ if(IN6_IS_ADDR_V4MAPPED((const struct in6_addr *) src) ||
+ IN6_IS_ADDR_V4COMPAT((const struct in6_addr *) src))
+ return (inet_ntop4
+ ((const unsigned char *)
+ &((const struct in6_addr *) src)->s6_addr[12], dst, size));
+ else
+ return (inet_ntop6(src, dst, size));
+
+
+#endif
+ default:
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+/* int
+ * inetpton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ int saw_digit, octets, ch;
+ u_char tmp[INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while((ch = *src++) != '\0')
+ {
+
+ if(ch >= '0' && ch <= '9')
+ {
+ u_int new = *tp * 10 + (ch - '0');
+
+ if(new > 255)
+ return (0);
+ *tp = new;
+ if(!saw_digit)
+ {
+ if(++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ }
+ else if(ch == '.' && saw_digit)
+ {
+ if(octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ }
+ else
+ return (0);
+ }
+ if(octets < 4)
+ return (0);
+ memcpy(dst, tmp, INADDRSZ);
+ return (1);
+}
+
+#ifdef IPV6
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+
+static int
+inet_pton6(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char xdigits[] = "0123456789abcdef";
+ u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ tp = memset(tmp, '\0', IN6ADDRSZ);
+ endp = tp + IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if(*src == ':')
+ if(*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while((ch = tolower(*src++)) != '\0')
+ {
+ const char *pch;
+
+ pch = strchr(xdigits, ch);
+ if(pch != NULL)
+ {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if(val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if(ch == ':')
+ {
+ curtok = src;
+ if(!saw_xdigit)
+ {
+ if(colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ else if(*src == '\0')
+ {
+ return (0);
+ }
+ if(tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if(*src != '\0' && ch == '.')
+ {
+ if(((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0)
+ {
+ tp += INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ }
+ else
+ continue;
+ return (0);
+ }
+ if(saw_xdigit)
+ {
+ if(tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if(colonp != NULL)
+ {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if(tp == endp)
+ return (0);
+ for(i = 1; i <= n; i++)
+ {
+ endp[-i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if(tp != endp)
+ return (0);
+ memcpy(dst, tmp, IN6ADDRSZ);
+ return (1);
+}
+#endif
+int
+inetpton(af, src, dst)
+ int af;
+ const char *src;
+ void *dst;
+{
+ switch (af)
+ {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+#ifdef IPV6
+ case AF_INET6:
+ /* Somebody might have passed as an IPv4 address this is sick but it works */
+ if(inet_pton4(src, dst))
+ {
+ char tmp[HOSTIPLEN];
+ ircsprintf(tmp, "::ffff:%s", src);
+ return (inet_pton6(tmp, dst));
+ }
+ else
+ return (inet_pton6(src, dst));
+#endif
+ default:
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * strlcat and strlcpy were ripped from openssh 2.5.1p2
+ * They had the following Copyright info:
+ *
+ *
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef HAVE_STRLCAT
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz, dlen;
+
+ while(n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if(n == 0)
+ return (dlen + strlen(s));
+ while(*s != '\0')
+ {
+ if(n != 1)
+ {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+ return (dlen + (s - src)); /* count does not include NUL */
+}
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+ /* Copy as many bytes as will fit */
+ if(n != 0 && --n != 0)
+ {
+ do
+ {
+ if((*d++ = *s++) == 0)
+ break;
+ }
+ while(--n != 0);
+ }
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if(n == 0)
+ {
+ if(siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while(*s++)
+ ;
+ }
+
+ return (s - src - 1); /* count does not include NUL */
+}
+#endif
+
+char *
+strip_colour(char *string)
+{
+ char *c = string;
+ char *c2 = string;
+ char *last_non_space = NULL;
+ /* c is source, c2 is target */
+ for(; c && *c; c++)
+ switch (*c)
+ {
+ case 3:
+ if(isdigit(c[1]))
+ {
+ c++;
+ if(isdigit(c[1]))
+ c++;
+ if(c[1] == ',' && isdigit(c[2]))
+ {
+ c += 2;
+ if(isdigit(c[1]))
+ c++;
+ }
+ }
+ break;
+ case 2:
+ case 6:
+ case 7:
+ case 22:
+ case 23:
+ case 27:
+ case 31:
+ break;
+ case 32:
+ *c2++ = *c;
+ break;
+ default:
+ *c2++ = *c;
+ last_non_space = c2;
+ break;
+ }
+ *c2 = '\0';
+ if(last_non_space)
+ *last_non_space = '\0';
+ return string;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * ircd.c: Starts up and runs the ircd.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: ircd.c 3047 2006-12-26 23:18:05Z jilles $
+ */
+
+#include "stdinc.h"
+#include "setup.h"
+#include "config.h"
+
+#include "tools.h"
+#include "ircd.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "event.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd_signal.h"
+#include "sprintf_irc.h"
+#include "s_gline.h"
+#include "msg.h" /* msgtab */
+#include "hostmask.h"
+#include "numeric.h"
+#include "parse.h"
+#include "res.h"
+#include "restart.h"
+#include "s_auth.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h" /* try_connections */
+#include "s_user.h"
+#include "s_stats.h"
+#include "scache.h"
+#include "send.h"
+#include "supported.h"
+#include "whowas.h"
+#include "modules.h"
+#include "memory.h"
+#include "hook.h"
+#include "ircd_getopt.h"
+#include "balloc.h"
+#include "newconf.h"
+#include "patricia.h"
+#include "reject.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "cache.h"
+#include "monitor.h"
+#include "libcharybdis.h"
+#include "patchlevel.h"
+#include "serno.h"
+
+/*
+ * Try and find the correct name to use with getrlimit() for setting the max.
+ * number of files allowed to be open by this process.
+ */
+int _charybdis_data_version = CHARYBDIS_DV;
+
+extern int ServerRunning, initialVMTop;
+extern struct LocalUser meLocalUser;
+extern char **myargv;
+
+/*
+ * get_vm_top - get the operating systems notion of the resident set size
+ */
+static unsigned long
+get_vm_top(void)
+{
+ /*
+ * NOTE: sbrk is not part of the ANSI C library or the POSIX.1 standard
+ * however it seems that everyone defines it. Calling sbrk with a 0
+ * argument will return a pointer to the top of the process virtual
+ * memory without changing the process size, so this call should be
+ * reasonably safe (sbrk returns the new value for the top of memory).
+ * This code relies on the notion that the address returned will be an
+ * offset from 0 (NULL), so the result of sbrk is cast to a size_t and
+ * returned. We really shouldn't be using it here but...
+ */
+ void *vptr = sbrk(0);
+ return (unsigned long) vptr;
+}
+
+/*
+ * get_maxrss - get the operating systems notion of the resident set size
+ */
+unsigned long
+get_maxrss(void)
+{
+ return get_vm_top() - initialVMTop;
+}
+
+/*
+ * print_startup - print startup information
+ */
+static void
+print_startup(int pid)
+{
+ inotice("now running in %s mode from %s as pid %d ...",
+ !server_state_foreground ? "background" : "foreground",
+ ConfigFileEntry.dpath, pid);
+
+ /* let the parent process know the initialization was successful
+ * -- jilles */
+ if (!server_state_foreground)
+ write(0, ".", 1);
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+ open("/dev/null", O_RDWR);
+ dup2(0, 1);
+ dup2(0, 2);
+}
+
+static void
+ircd_log_cb(const char *str)
+{
+ ilog(L_MAIN, "%s", str);
+}
+
+/*
+ * Why EXIT_FAILURE here?
+ * Because if ircd_die_cb() is called it's because of a fatal
+ * error inside libcharybdis, and we don't know how to handle the
+ * exception, so it is logical to return a FAILURE exit code here.
+ * --nenolod
+ */
+static void
+ircd_die_cb(const char *str)
+{
+ /* Try to get the message out to currently logged in operators. */
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Server panic! %s", str);
+ inotice("server panic: %s", str);
+
+ unlink(pidFileName);
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * init_sys
+ *
+ * inputs - boot_daemon flag
+ * output - none
+ * side effects - if boot_daemon flag is not set, don't daemonize
+ */
+static void
+init_sys(void)
+{
+#if defined(RLIMIT_FD_MAX) && defined(HAVE_SYS_RLIMIT_H)
+ struct rlimit limit;
+
+ if(!getrlimit(RLIMIT_FD_MAX, &limit))
+ {
+
+ if(limit.rlim_max < MAXCONNECTIONS)
+ {
+ fprintf(stderr, "ircd fd table too big\n");
+ fprintf(stderr, "Hard Limit: %ld IRC max: %d\n",
+ (long) limit.rlim_max, MAXCONNECTIONS);
+ fprintf(stderr, "Fix MAXCONNECTIONS\n");
+ exit(-1);
+ }
+
+ limit.rlim_cur = limit.rlim_max; /* make soft limit the max */
+ if(setrlimit(RLIMIT_FD_MAX, &limit) == -1)
+ {
+ fprintf(stderr, "error setting max fd's to %ld\n", (long) limit.rlim_cur);
+ exit(EXIT_FAILURE);
+ }
+ }
+#endif /* RLIMIT_FD_MAX */
+}
+
+static int
+make_daemon(void)
+{
+ int pid;
+ int pip[2];
+ char c;
+
+ if (pipe(pip) < 0)
+ {
+ perror("pipe");
+ exit(EXIT_FAILURE);
+ }
+ dup2(pip[1], 0);
+ close(pip[1]);
+ if((pid = fork()) < 0)
+ {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+ else if(pid > 0)
+ {
+ close(0);
+ /* Wait for initialization to finish, successfully or
+ * unsuccessfully. Until this point the child may still
+ * write to stdout/stderr.
+ * -- jilles */
+ if (read(pip[0], &c, 1) > 0)
+ exit(EXIT_SUCCESS);
+ else
+ exit(EXIT_FAILURE);
+ }
+
+ close(pip[0]);
+ setsid();
+/* fclose(stdin);
+ fclose(stdout);
+ fclose(stderr); */
+
+ return 0;
+}
+
+static int printVersion = 0;
+
+struct lgetopt myopts[] = {
+ {"dlinefile", &ConfigFileEntry.dlinefile,
+ STRING, "File to use for dlines.conf"},
+ {"configfile", &ConfigFileEntry.configfile,
+ STRING, "File to use for ircd.conf"},
+ {"klinefile", &ConfigFileEntry.klinefile,
+ STRING, "File to use for kline.conf"},
+ {"xlinefile", &ConfigFileEntry.xlinefile,
+ STRING, "File to use for xline.conf"},
+ {"resvfile", &ConfigFileEntry.resvfile,
+ STRING, "File to use for resv.conf"},
+ {"logfile", &logFileName,
+ STRING, "File to use for ircd.log"},
+ {"pidfile", &pidFileName,
+ STRING, "File to use for process ID"},
+ {"foreground", &server_state_foreground,
+ YESNO, "Run in foreground (don't detach)"},
+ {"version", &printVersion,
+ YESNO, "Print version and exit"},
+ {"conftest", &testing_conf,
+ YESNO, "Test the configuration files and exit"},
+ {"help", NULL, USAGE, "Print this text"},
+ {NULL, NULL, STRING, NULL},
+};
+
+void
+set_time(void)
+{
+ struct timeval newtime;
+ newtime.tv_sec = 0;
+ newtime.tv_usec = 0;
+#ifdef HAVE_GETTIMEOFDAY
+ if(gettimeofday(&newtime, NULL) == -1)
+ {
+ ilog(L_MAIN, "Clock Failure (%d)", errno);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Clock Failure (%d), TS can be corrupted", errno);
+
+ restart("Clock Failure");
+ }
+#else
+ newtime.tv_sec = time(NULL);
+
+#endif
+ if(newtime.tv_sec < CurrentTime)
+ set_back_events(CurrentTime - newtime.tv_sec);
+
+ SystemTime.tv_sec = newtime.tv_sec;
+ SystemTime.tv_usec = newtime.tv_usec;
+}
+
+static void
+check_rehash(void *unused)
+{
+ /*
+ * Check to see whether we have to rehash the configuration ..
+ */
+ if(dorehash)
+ {
+ rehash(1);
+ dorehash = 0;
+ }
+
+ if(dorehashbans)
+ {
+ rehash_bans(1);
+ dorehashbans = 0;
+ }
+
+ if(doremotd)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Got signal SIGUSR1, reloading ircd motd file");
+ free_cachefile(user_motd);
+ user_motd = cache_file(MPATH, "ircd.motd", 0);
+ doremotd = 0;
+ }
+}
+
+void
+charybdis_io_loop(void)
+{
+ time_t delay;
+
+ while (ServerRunning)
+ {
+ /* Run pending events, then get the number of seconds to the next
+ * event
+ */
+
+ delay = eventNextTime();
+ if(delay <= CurrentTime)
+ eventRun();
+
+
+ comm_select(250);
+ }
+}
+
+/*
+ * initalialize_global_set_options
+ *
+ * inputs - none
+ * output - none
+ * side effects - This sets all global set options needed
+ */
+static void
+initialize_global_set_options(void)
+{
+ memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
+ /* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
+
+ GlobalSetOptions.maxclients = MAX_CLIENTS;
+ GlobalSetOptions.autoconn = 1;
+
+ GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
+ GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
+
+ if(ConfigFileEntry.default_floodcount)
+ GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount;
+ else
+ GlobalSetOptions.floodcount = 10;
+
+ split_servers = ConfigChannel.default_split_server_count;
+ split_users = ConfigChannel.default_split_user_count;
+
+ if(split_users && split_servers
+ && (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
+ {
+ splitmode = 1;
+ splitchecking = 1;
+ }
+
+ GlobalSetOptions.ident_timeout = IDENT_TIMEOUT;
+
+ strlcpy(GlobalSetOptions.operstring,
+ ConfigFileEntry.default_operstring,
+ sizeof(GlobalSetOptions.operstring));
+ strlcpy(GlobalSetOptions.adminstring,
+ ConfigFileEntry.default_adminstring,
+ sizeof(GlobalSetOptions.adminstring));
+
+ /* memset( &ConfigChannel, 0, sizeof(ConfigChannel)); */
+
+ /* End of global set options */
+
+}
+
+/*
+ * initialize_server_capabs
+ *
+ * inputs - none
+ * output - none
+ */
+static void
+initialize_server_capabs(void)
+{
+ default_server_capabs &= ~CAP_ZIP;
+}
+
+
+/*
+ * write_pidfile
+ *
+ * inputs - filename+path of pid file
+ * output - none
+ * side effects - write the pid of the ircd to filename
+ */
+static void
+write_pidfile(const char *filename)
+{
+ FILE *fb;
+ char buff[32];
+ if((fb = fopen(filename, "w")))
+ {
+ unsigned int pid = (unsigned int) getpid();
+
+ ircsnprintf(buff, sizeof(buff), "%u\n", pid);
+ if((fputs(buff, fb) == -1))
+ {
+ ilog(L_MAIN, "Error writing %u to pid file %s (%s)",
+ pid, filename, strerror(errno));
+ }
+ fclose(fb);
+ return;
+ }
+ else
+ {
+ ilog(L_MAIN, "Error opening pid file %s", filename);
+ }
+}
+
+/*
+ * check_pidfile
+ *
+ * inputs - filename+path of pid file
+ * output - none
+ * side effects - reads pid from pidfile and checks if ircd is in process
+ * list. if it is, gracefully exits
+ * -kre
+ */
+static void
+check_pidfile(const char *filename)
+{
+ FILE *fb;
+ char buff[32];
+ pid_t pidfromfile;
+
+ /* Don't do logging here, since we don't have log() initialised */
+ if((fb = fopen(filename, "r")))
+ {
+ if(fgets(buff, 20, fb) != NULL)
+ {
+ pidfromfile = atoi(buff);
+ if(!kill(pidfromfile, 0))
+ {
+ printf("ircd: daemon is already running\n");
+ exit(-1);
+ }
+ }
+ fclose(fb);
+ }
+}
+
+/*
+ * setup_corefile
+ *
+ * inputs - nothing
+ * output - nothing
+ * side effects - setups corefile to system limits.
+ * -kre
+ */
+static void
+setup_corefile(void)
+{
+#ifdef HAVE_SYS_RESOURCE_H
+ struct rlimit rlim; /* resource limits */
+
+ /* Set corefilesize to maximum */
+ if(!getrlimit(RLIMIT_CORE, &rlim))
+ {
+ rlim.rlim_cur = rlim.rlim_max;
+ setrlimit(RLIMIT_CORE, &rlim);
+ }
+#endif
+}
+
+/*
+ * main
+ *
+ * Initializes the IRCd.
+ *
+ * Inputs - number of commandline args, args themselves
+ * Outputs - none
+ * Side Effects - this is where the ircd gets going right now
+ */
+int
+main(int argc, char *argv[])
+{
+ int fd;
+
+ /* Check to see if the user is running us as root, which is a nono */
+ if(geteuid() == 0)
+ {
+ fprintf(stderr, "Don't run ircd as root!!!\n");
+ return -1;
+ }
+
+ /*
+ * save server boot time right away, so getrusage works correctly
+ */
+ set_time();
+ /*
+ * Setup corefile size immediately after boot -kre
+ */
+ setup_corefile();
+
+ /*
+ * set initialVMTop before we allocate any memory
+ */
+ initialVMTop = get_vm_top();
+
+ ServerRunning = 0;
+ /* It ain't random, but it ought to be a little harder to guess */
+ srand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));
+ memset(&me, 0, sizeof(me));
+ memset(&meLocalUser, 0, sizeof(meLocalUser));
+ me.localClient = &meLocalUser;
+
+ /* Make sure all lists are zeroed */
+ memset(&unknown_list, 0, sizeof(unknown_list));
+ memset(&lclient_list, 0, sizeof(lclient_list));
+ memset(&serv_list, 0, sizeof(serv_list));
+ memset(&global_serv_list, 0, sizeof(global_serv_list));
+ memset(&local_oper_list, 0, sizeof(local_oper_list));
+ memset(&oper_list, 0, sizeof(oper_list));
+
+ dlinkAddTail(&me, &me.node, &global_client_list);
+
+ memset((void *) &Count, 0, sizeof(Count));
+ memset((void *) &ServerInfo, 0, sizeof(ServerInfo));
+ memset((void *) &AdminInfo, 0, sizeof(AdminInfo));
+
+ /* Initialise the channel capability usage counts... */
+ init_chcap_usage_counts();
+
+ ConfigFileEntry.dpath = DPATH;
+ ConfigFileEntry.configfile = CPATH; /* Server configuration file */
+ ConfigFileEntry.klinefile = KPATH; /* Server kline file */
+ ConfigFileEntry.dlinefile = DLPATH; /* dline file */
+ ConfigFileEntry.xlinefile = XPATH;
+ ConfigFileEntry.resvfile = RESVPATH;
+ ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
+ myargv = argv;
+ umask(077); /* better safe than sorry --SRB */
+
+ parseargs(&argc, &argv, myopts);
+
+ if(printVersion)
+ {
+ printf("ircd: version %s\n", ircd_version);
+ exit(EXIT_SUCCESS);
+ }
+
+ if(chdir(ConfigFileEntry.dpath))
+ {
+ fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ setup_signals();
+
+#ifdef __CYGWIN__
+ server_state_foreground = 1;
+#endif
+
+ if (testing_conf)
+ server_state_foreground = 1;
+
+ /* Make sure fd 0, 1 and 2 are in use -- jilles */
+ do
+ {
+ fd = open("/dev/null", O_RDWR);
+ } while (fd < 2 && fd != -1);
+ if (fd > 2)
+ close(fd);
+ else if (fd == -1)
+ exit(1);
+
+ /* Check if there is pidfile and daemon already running */
+ if(!testing_conf)
+ {
+ check_pidfile(pidFileName);
+
+ if(!server_state_foreground)
+ make_daemon();
+ inotice("starting %s ...", ircd_version);
+ }
+
+ /* Init the event subsystem */
+ libcharybdis_init(ircd_log_cb, restart, ircd_die_cb);
+ init_sys();
+
+ fdlist_init();
+ if(!server_state_foreground)
+ {
+ comm_close_all();
+ }
+
+ init_main_logfile();
+ init_patricia();
+ newconf_init();
+ init_s_conf();
+ init_s_newconf();
+ init_hash();
+ clear_scache_hash_table(); /* server cache name table */
+ init_host_hash();
+ clear_hash_parse();
+ init_client();
+ initUser();
+ init_hook();
+ init_channels();
+ initclass();
+ initwhowas();
+ init_stats();
+ init_reject();
+ init_cache();
+ init_monitor();
+ init_isupport();
+ load_all_modules(1);
+#ifndef STATIC_MODULES
+ load_core_modules(1);
+#endif
+ init_auth(); /* Initialise the auth code */
+ init_resolver(); /* Needs to be setup before the io loop */
+
+ if (testing_conf)
+ fprintf(stderr, "\nBeginning config test\n");
+ read_conf_files(YES); /* cold start init conf files */
+ rehash_bans(0);
+#ifndef STATIC_MODULES
+
+ mod_add_path(MODULE_DIR);
+ mod_add_path(MODULE_DIR "/autoload");
+#endif
+
+ initialize_server_capabs(); /* Set up default_server_capabs */
+ initialize_global_set_options();
+
+ if(ServerInfo.name == NULL)
+ {
+ ierror("no server name specified in serverinfo block.");
+ return -1;
+ }
+ strlcpy(me.name, ServerInfo.name, sizeof(me.name));
+
+ if(ServerInfo.sid[0] == '\0')
+ {
+ ierror("no server sid specified in serverinfo block.");
+ return -2;
+ }
+ strcpy(me.id, ServerInfo.sid);
+ init_uid();
+
+ /* serverinfo{} description must exist. If not, error out. */
+ if(ServerInfo.description == NULL)
+ {
+ ierror("no server description specified in serverinfo block.");
+ return -3;
+ }
+ strlcpy(me.info, ServerInfo.description, sizeof(me.info));
+
+ if (testing_conf)
+ {
+ fprintf(stderr, "\nConfig testing complete.\n");
+ fflush(stderr);
+ return 0; /* Why? We want the launcher to exit out. */
+ }
+
+ me.from = &me;
+ me.servptr = &me;
+ SetMe(&me);
+ make_server(&me);
+ me.serv->up = me.name;
+ startup_time = CurrentTime;
+ add_to_client_hash(me.name, &me);
+ add_to_id_hash(me.id, &me);
+
+ dlinkAddAlloc(&me, &global_serv_list);
+
+ construct_umodebuf();
+
+ check_class();
+ write_pidfile(pidFileName);
+ load_help();
+ open_logfiles();
+
+ ilog(L_MAIN, "Server Ready");
+
+ eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME);
+
+ /* We want try_connections to be called as soon as possible now! -- adrian */
+ /* No, 'cause after a restart it would cause all sorts of nick collides */
+ /* um. by waiting even longer, that just means we have even *more*
+ * nick collisions. what a stupid idea. set an event for the IO loop --fl
+ */
+ eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
+ eventAddOnce("try_connections_startup", try_connections, NULL, 0);
+
+ eventAddIsh("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);
+
+ /* Setup the timeout check. I'll shift it later :) -- adrian */
+ eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);
+
+ eventAdd("check_rehash", check_rehash, NULL, 1);
+
+ if(ConfigServerHide.links_delay > 0)
+ eventAdd("cache_links", cache_links, NULL,
+ ConfigServerHide.links_delay);
+ else
+ ConfigServerHide.links_disabled = 1;
+
+ if(splitmode)
+ eventAdd("check_splitmode", check_splitmode, NULL, 2);
+
+ ServerRunning = 1;
+
+ print_startup(getpid());
+
+ charybdis_io_loop();
+
+ return 0;
+}
--- /dev/null
+/* src/ircd_lexer.l
+ *
+ * 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
+ *
+ * $Id: ircd_lexer.l 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+%option case-insensitive
+%option noyywrap
+%option nounput
+
+%{
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#define WE_ARE_MEMORY_C
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "common.h"
+#include "config.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "newconf.h"
+
+#include "y.tab.h"
+
+int yylex(void);
+
+/* here to fixup gcc 3.3 errors */
+int yyget_lineno(void);
+FILE *yyget_in(void);
+FILE *yyget_out(void);
+int yyget_leng(void);
+char *yyget_text(void);
+void yyset_lineno(int line_number);
+void yyset_in(FILE * in_str);
+void yyset_out(FILE * out_str);
+int yyget_debug(void);
+void yyset_debug(int bdebug);
+int yylex_destroy(void);
+
+
+#define MAX_INCLUDE_DEPTH 10
+
+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+int include_stack_ptr=0;
+int lineno = 1;
+void ccomment(void);
+void cinclude(void);
+void hashcomment(void);
+int ieof(void);
+int lineno_stack[MAX_INCLUDE_DEPTH];
+char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE];
+char conffilebuf[IRCD_BUFSIZE+1];
+char *current_file = conffilebuf;
+
+FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
+
+char linebuf[512];
+
+#undef YY_INPUT
+
+#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
+
+#define YY_INPUT(buf,result,max_size) \
+ if (!(result = conf_fgets(buf, max_size, conf_fbfile_in))) \
+ YY_FATAL_ERROR("input in flex scanner failed");
+%}
+
+ws [ \t]*
+digit [0-9]
+comment #.*
+qstring \"[^\"\n]*[\"\n]
+string [a-zA-Z_\~][a-zA-Z0-9_]*
+include \.include{ws}(\<.*\>|\".*\")
+
+%%
+{include} { cinclude(); }
+"/*" { ccomment(); }
+\n.* { strcpy(linebuf, yytext+1); lineno++; yyless(1); }
+
+{ws} ;
+{comment} { hashcomment(); }
+
+{digit}+ { yylval.number = atoi(yytext); return NUMBER; }
+
+{qstring} {
+ if(yytext[yyleng-2] == '\\')
+ {
+ yyless(yyleng-1); /* return last quote */
+ yymore(); /* append next string */
+ }
+ else
+ {
+ strcpy(yylval.string, yytext + 1);
+ if(yylval.string[yyleng-2] != '"')
+ ilog(L_MAIN, "Unterminated character string");
+ else
+ {
+ int i,j;
+ yylval.string[yyleng-2] = '\0'; /* remove close
+ * quote
+ */
+
+ for (j=i=0 ;yylval.string[i] != '\0'; i++,j++)
+ {
+ if (yylval.string[i] != '\\')
+ {
+ yylval.string[j] = yylval.string[i];
+ }
+ else
+ {
+ i++;
+ if (yylval.string[i] == '\0') /* XXX
+ * should not
+ * happen
+ */
+ {
+ ilog(L_MAIN,
+ "Unterminated character string");
+ break;
+ }
+ yylval.string[j] = yylval.string[i];
+ }
+ }
+ yylval.string[j] = '\0';
+ return QSTRING;
+ }
+ }
+ }
+
+
+loadmodule { return LOADMODULE; }
+{string} {
+ strcpy(yylval.string, yytext);
+ yylval.string[yyleng] = '\0';
+ return STRING;
+ }
+
+\.\. { return TWODOTS; }
+. { return yytext[0]; }
+<<EOF>> { if (ieof()) yyterminate(); }
+%%
+
+/* C-comment ignoring routine -kre*/
+void ccomment()
+{
+ int c;
+
+ /* log(L_NOTICE, "got comment"); */
+ while (1)
+ {
+ while ((c = input()) != '*' && c != EOF)
+ if (c == '\n') ++lineno;
+ if (c == '*')
+ {
+ while ((c = input()) == '*');
+ if (c == '/')
+ break;
+ }
+ if (c == EOF)
+ {
+ YY_FATAL_ERROR("EOF in comment");
+ /* XXX hack alert this disables
+ * the stupid unused function warning
+ * gcc generates
+ */
+ yy_fatal_error("EOF in comment");
+ break;
+ }
+ }
+}
+
+void cinclude(void)
+{
+ char *c;
+ if ((c = strchr(yytext, '<')) == NULL)
+ *strchr(c = strchr(yytext, '"') + 1, '"') = 0;
+ else
+ *strchr(++c, '>') = 0;
+
+ /* do stacking and co. */
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ conf_report_error("Includes nested too deep (max is %d)", MAX_INCLUDE_DEPTH);
+ else
+ {
+ FILE *tmp_fbfile_in;
+
+ tmp_fbfile_in = fopen(c, "r");
+
+ if (tmp_fbfile_in == NULL)
+ {
+ /* if its not found in PREFIX, look in ETCPATH */
+ char fnamebuf[IRCD_BUFSIZE];
+
+ snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", ETCPATH, c);
+ tmp_fbfile_in = fopen(fnamebuf, "r");
+
+ /* wasnt found there either.. error. */
+ if(tmp_fbfile_in == NULL)
+ {
+ conf_report_error("Include %s: %s.", c, strerror(errno));
+ return;
+ }
+ }
+ lineno_stack[include_stack_ptr] = lineno;
+ lineno = 1;
+ inc_fbfile_in[include_stack_ptr] = conf_fbfile_in;
+ strcpy(conffile_stack[include_stack_ptr], c);
+ current_file = conffile_stack[include_stack_ptr];
+ include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+ conf_fbfile_in = tmp_fbfile_in;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ }
+}
+
+int ieof(void)
+{
+ if (include_stack_ptr)
+ fclose(conf_fbfile_in);
+ if (--include_stack_ptr < 0)
+ {
+ /* We will now exit the lexer - restore init values if we get /rehash
+ * later and reenter lexer -kre */
+ include_stack_ptr = 0;
+ lineno = 1;
+ return 1;
+ }
+ /* switch buffer */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ lineno = lineno_stack[include_stack_ptr];
+ conf_fbfile_in = inc_fbfile_in[include_stack_ptr];
+
+ if(include_stack_ptr)
+ current_file = conffile_stack[include_stack_ptr];
+ else
+ current_file = conffilebuf;
+
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ return 0;
+}
+
+/* #-comment style, look for #include */
+#define INCLUDE "#include"
+
+void hashcomment(void)
+{
+ if (strlen(yytext) < sizeof(INCLUDE) - 1)
+ return;
+
+ if (!strncasecmp(yytext, INCLUDE, sizeof(INCLUDE) - 1))
+ yyerror("You probably meant '.include', skipping");
+}
--- /dev/null
+/* This code is in the public domain.
+ * $Nightmare: nightmare/src/main/parser.y,v 1.2.2.1.2.1 2002/07/02 03:42:10 ejb Exp $
+ * $Id: ircd_parser.y 871 2006-02-18 21:56:00Z nenolod $
+ */
+
+%{
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#define WE_ARE_MEMORY_C
+#include "stdinc.h"
+#include "setup.h"
+#include "common.h"
+#include "ircd_defs.h"
+#include "config.h"
+#include "client.h"
+#include "modules.h"
+#include "newconf.h"
+
+#define YY_NO_UNPUT
+
+int yyparse();
+int yyerror(const char *);
+int yylex();
+
+static time_t conf_find_time(char*);
+
+static struct {
+ const char * name;
+ const char * plural;
+ time_t val;
+} ircd_times[] = {
+ {"second", "seconds", 1},
+ {"minute", "minutes", 60},
+ {"hour", "hours", 60 * 60},
+ {"day", "days", 60 * 60 * 24},
+ {"week", "weeks", 60 * 60 * 24 * 7},
+ {"fortnight", "fortnights", 60 * 60 * 24 * 14},
+ {"month", "months", 60 * 60 * 24 * 7 * 4},
+ {"year", "years", 60 * 60 * 24 * 365},
+ /* ok-- we now do sizes here too. they aren't times, but
+ it's close enough */
+ {"byte", "bytes", 1},
+ {"kb", NULL, 1024},
+ {"kbyte", "kbytes", 1024},
+ {"kilobyte", "kilebytes", 1024},
+ {"mb", NULL, 1024 * 1024},
+ {"mbyte", "mbytes", 1024 * 1024},
+ {"megabyte", "megabytes", 1024 * 1024},
+ {NULL, NULL, 0},
+};
+
+time_t conf_find_time(char *name)
+{
+ int i;
+
+ for (i = 0; ircd_times[i].name; i++)
+ {
+ if (strcasecmp(ircd_times[i].name, name) == 0 ||
+ (ircd_times[i].plural && strcasecmp(ircd_times[i].plural, name) == 0))
+ return ircd_times[i].val;
+ }
+
+ return 0;
+}
+
+static struct
+{
+ const char *word;
+ int yesno;
+} yesno[] = {
+ {"yes", 1},
+ {"no", 0},
+ {"true", 1},
+ {"false", 0},
+ {"on", 1},
+ {"off", 0},
+ {NULL, 0}
+};
+
+static int conf_get_yesno_value(char *str)
+{
+ int i;
+
+ for (i = 0; yesno[i].word; i++)
+ {
+ if (strcasecmp(str, yesno[i].word) == 0)
+ {
+ return yesno[i].yesno;
+ }
+ }
+
+ return -1;
+}
+
+static void free_cur_list(conf_parm_t* list)
+{
+ switch (list->type & CF_MTYPE)
+ {
+ case CF_STRING:
+ case CF_QSTRING:
+ MyFree(list->v.string);
+ break;
+ case CF_LIST:
+ free_cur_list(list->v.list);
+ break;
+ default: break;
+ }
+
+ if (list->next)
+ free_cur_list(list->next);
+}
+
+
+conf_parm_t * cur_list = NULL;
+
+static void add_cur_list_cpt(conf_parm_t *new)
+{
+ if (cur_list == NULL)
+ {
+ cur_list = MyMalloc(sizeof(conf_parm_t));
+ cur_list->type |= CF_FLIST;
+ cur_list->v.list = new;
+ }
+ else
+ {
+ new->next = cur_list->v.list;
+ cur_list->v.list = new;
+ }
+}
+
+static void add_cur_list(int type, char *str, int number)
+{
+ conf_parm_t *new;
+
+ new = MyMalloc(sizeof(conf_parm_t));
+ new->next = NULL;
+ new->type = type;
+
+ switch(type)
+ {
+ case CF_INT:
+ case CF_TIME:
+ case CF_YESNO:
+ new->v.number = number;
+ break;
+ case CF_STRING:
+ case CF_QSTRING:
+ DupString(new->v.string, str);
+ break;
+ }
+
+ add_cur_list_cpt(new);
+}
+
+
+%}
+
+%union {
+ int number;
+ char string[IRCD_BUFSIZE + 1];
+ conf_parm_t * conf_parm;
+}
+
+%token LOADMODULE TWODOTS
+
+%token <string> QSTRING STRING
+%token <number> NUMBER
+
+%type <string> qstring string
+%type <number> number timespec
+%type <conf_parm> oneitem single itemlist
+
+%start conf
+
+%%
+
+conf:
+ | conf conf_item
+ | error
+ ;
+
+conf_item: block
+ | loadmodule
+ ;
+
+block: string
+ {
+ conf_start_block($1, NULL);
+ }
+ '{' block_items '}' ';'
+ {
+ if (conf_cur_block)
+ conf_end_block(conf_cur_block);
+ }
+ | string qstring
+ {
+ conf_start_block($1, $2);
+ }
+ '{' block_items '}' ';'
+ {
+ if (conf_cur_block)
+ conf_end_block(conf_cur_block);
+ }
+ ;
+
+block_items: block_items block_item
+ | block_item
+ ;
+
+block_item: string '=' itemlist ';'
+ {
+ conf_call_set(conf_cur_block, $1, cur_list, CF_LIST);
+ free_cur_list(cur_list);
+ cur_list = NULL;
+ }
+ ;
+
+itemlist: itemlist ',' single
+ | single
+ ;
+
+single: oneitem
+ {
+ add_cur_list_cpt($1);
+ }
+ | oneitem TWODOTS oneitem
+ {
+ /* "1 .. 5" meaning 1,2,3,4,5 - only valid for integers */
+ if (($1->type & CF_MTYPE) != CF_INT ||
+ ($3->type & CF_MTYPE) != CF_INT)
+ {
+ conf_report_error("Both arguments in '..' notation must be integers.");
+ break;
+ }
+ else
+ {
+ int i;
+
+ for (i = $1->v.number; i <= $3->v.number; i++)
+ {
+ add_cur_list(CF_INT, 0, i);
+ }
+ }
+ }
+ ;
+
+oneitem: qstring
+ {
+ $$ = MyMalloc(sizeof(conf_parm_t));
+ $$->type = CF_QSTRING;
+ DupString($$->v.string, $1);
+ }
+ | timespec
+ {
+ $$ = MyMalloc(sizeof(conf_parm_t));
+ $$->type = CF_TIME;
+ $$->v.number = $1;
+ }
+ | number
+ {
+ $$ = MyMalloc(sizeof(conf_parm_t));
+ $$->type = CF_INT;
+ $$->v.number = $1;
+ }
+ | string
+ {
+ /* a 'string' could also be a yes/no value ..
+ so pass it as that, if so */
+ int val = conf_get_yesno_value($1);
+
+ $$ = MyMalloc(sizeof(conf_parm_t));
+
+ if (val != -1)
+ {
+ $$->type = CF_YESNO;
+ $$->v.number = val;
+ }
+ else
+ {
+ $$->type = CF_STRING;
+ DupString($$->v.string, $1);
+ }
+ }
+ ;
+
+loadmodule:
+ LOADMODULE QSTRING
+ {
+#ifndef STATIC_MODULES
+ char *m_bn;
+
+ m_bn = irc_basename((char *) $2);
+
+ if (findmodule_byname(m_bn) == -1)
+ load_one_module($2, 0);
+#endif
+ }
+ ';'
+ ;
+
+qstring: QSTRING { strcpy($$, $1); } ;
+string: STRING { strcpy($$, $1); } ;
+number: NUMBER { $$ = $1; } ;
+
+timespec: number string
+ {
+ time_t t;
+
+ if ((t = conf_find_time($2)) == 0)
+ {
+ conf_report_error("Unrecognised time type/size '%s'", $2);
+ t = 1;
+ }
+
+ $$ = $1 * t;
+ }
+ | timespec timespec
+ {
+ $$ = $1 + $2;
+ }
+ | timespec number
+ {
+ $$ = $1 + $2;
+ }
+ ;
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, src/ircd_signal.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * 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.
+ *
+ * $Id: ircd_signal.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "ircd_signal.h"
+#include "ircd.h" /* dorehash */
+#include "restart.h" /* server_reboot */
+#include "s_log.h"
+#include "memory.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "client.h"
+#include "send.h"
+
+/*
+ * dummy_handler - don't know if this is really needed but if alarm is still
+ * being used we probably will
+ */
+static void
+dummy_handler(int sig)
+{
+ /* Empty */
+}
+
+
+static void
+sigchld_handler(int sig)
+{
+ int status;
+ waitpid(-1, &status, WNOHANG);
+}
+/*
+ * sigterm_handler - exit the server
+ */
+static void
+sigterm_handler(int sig)
+{
+ /* XXX we had a flush_connections() here - we should close all the
+ * connections and flush data. read server_reboot() for my explanation.
+ * -- adrian
+ */
+ ilog(L_MAIN, "Server killed By SIGTERM");
+ exit(-1);
+}
+
+/*
+ * sighup_handler - reread the server configuration
+ */
+static void
+sighup_handler(int sig)
+{
+ dorehash = 1;
+}
+
+/*
+ * sigusr1_handler - reread the motd file
+ */
+static void
+sigusr1_handler(int sig)
+{
+ doremotd = 1;
+}
+
+static void
+sigusr2_handler(int sig)
+{
+ dorehashbans = 1;
+}
+
+/*
+ * sigint_handler - restart the server
+ */
+static void
+sigint_handler(int sig)
+{
+ static int restarting = 0;
+
+ if(server_state_foreground)
+ {
+ ilog(L_MAIN, "Server exiting on SIGINT");
+ exit(0);
+ }
+ else
+ {
+ ilog(L_MAIN, "Server Restarting on SIGINT");
+ if(restarting == 0)
+ {
+ restarting = 1;
+ server_reboot();
+ }
+ }
+}
+
+/*
+ * setup_signals - initialize signal handlers for server
+ */
+void
+setup_signals()
+{
+ struct sigaction act;
+
+ act.sa_flags = 0;
+ act.sa_handler = SIG_IGN;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGPIPE);
+ sigaddset(&act.sa_mask, SIGALRM);
+#ifdef SIGTRAP
+ sigaddset(&act.sa_mask, SIGTRAP);
+#endif
+
+# ifdef SIGWINCH
+ sigaddset(&act.sa_mask, SIGWINCH);
+ sigaction(SIGWINCH, &act, 0);
+# endif
+ sigaction(SIGPIPE, &act, 0);
+#ifdef SIGTRAP
+ sigaction(SIGTRAP, &act, 0);
+#endif
+
+ act.sa_handler = dummy_handler;
+ sigaction(SIGALRM, &act, 0);
+
+ act.sa_handler = sighup_handler;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGHUP);
+ sigaction(SIGHUP, &act, 0);
+
+ act.sa_handler = sigint_handler;
+ sigaddset(&act.sa_mask, SIGINT);
+ sigaction(SIGINT, &act, 0);
+
+ act.sa_handler = sigterm_handler;
+ sigaddset(&act.sa_mask, SIGTERM);
+ sigaction(SIGTERM, &act, 0);
+
+ act.sa_handler = sigusr1_handler;
+ sigaddset(&act.sa_mask, SIGUSR1);
+ sigaction(SIGUSR1, &act, 0);
+
+ act.sa_handler = sigusr2_handler;
+ sigaddset(&act.sa_mask, SIGUSR2);
+ sigaction(SIGUSR2, &act, 0);
+
+ act.sa_handler = sigchld_handler;
+ sigaddset(&act.sa_mask, SIGCHLD);
+ sigaction(SIGCHLD, &act, 0);
+
+}
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * ircd_state.c: Functions for backing up and synchronizing IRCd's state
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: main.c 867 2006-02-16 14:25:09Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "setup.h"
+#include "config.h"
+
+#include "client.h"
+#include "tools.h"
+#include "tools.h"
+#include "ircd.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "event.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd_signal.h"
+#include "sprintf_irc.h"
+#include "s_gline.h"
+#include "msg.h" /* msgtab */
+#include "hostmask.h"
+#include "numeric.h"
+#include "parse.h"
+#include "res.h"
+#include "restart.h"
+#include "s_auth.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h" /* try_connections */
+#include "s_user.h"
+#include "s_stats.h"
+#include "scache.h"
+#include "send.h"
+#include "whowas.h"
+#include "modules.h"
+#include "memory.h"
+#include "hook.h"
+#include "ircd_getopt.h"
+#include "balloc.h"
+#include "newconf.h"
+#include "patricia.h"
+#include "reject.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "cache.h"
+#include "monitor.h"
+#include "libcharybdis.h"
+#include "patchlevel.h"
+#include "serno.h"
+
+dlink_list lclient_list = { NULL, NULL, 0 };
+dlink_list global_client_list = { NULL, NULL, 0 };
+dlink_list global_channel_list = { NULL, NULL, 0 };
+
+dlink_list unknown_list; /* unknown clients ON this server only */
+dlink_list serv_list; /* local servers to this server ONLY */
+dlink_list global_serv_list; /* global servers on the network */
+dlink_list local_oper_list; /* our opers, duplicated in lclient_list */
+dlink_list oper_list; /* network opers */
+
+/* /quote set variables */
+struct SetOptions GlobalSetOptions;
+
+/* configuration set from ircd.conf */
+struct config_file_entry ConfigFileEntry;
+/* server info set from ircd.conf */
+struct server_info ServerInfo;
+/* admin info set from ircd.conf */
+struct admin_info AdminInfo;
+
+struct Counter Count;
+
+struct timeval SystemTime;
+int ServerRunning; /* GLOBAL - server execution state */
+struct Client me; /* That's me */
+struct LocalUser meLocalUser; /* That's also part of me */
+
+time_t startup_time;
+
+int default_server_capabs = CAP_MASK;
+
+int splitmode;
+int splitchecking;
+int split_users;
+int split_servers;
+int eob_count;
+
+unsigned long initialVMTop = 0; /* top of virtual memory at init */
+const char *logFileName = LPATH;
+const char *pidFileName = PPATH;
+
+char **myargv;
+int dorehash = 0;
+int dorehashbans = 0;
+int doremotd = 0;
+int kline_queued = 0;
+int server_state_foreground = 0;
+int opers_see_all_users = 0;
+
+int testing_conf = 0;
+
+struct config_channel_entry ConfigChannel;
+BlockHeap *channel_heap;
+BlockHeap *ban_heap;
+BlockHeap *topic_heap;
+BlockHeap *member_heap;
+
+BlockHeap *client_heap = NULL;
+BlockHeap *lclient_heap = NULL;
+BlockHeap *pclient_heap = NULL;
+
+char current_uid[IDLEN];
+
+/* patricia */
+BlockHeap *prefix_heap;
+BlockHeap *node_heap;
+BlockHeap *patricia_heap;
+
+BlockHeap *linebuf_heap;
+
+BlockHeap *dnode_heap;
+
+#ifdef NOTYET
+
+void charybdis_initstate(struct IRCdState *self)
+{
+
+}
+
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * kdparse.c: Parses K and D lines.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: kdparse.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "hostmask.h"
+#include "client.h"
+#include "irc_string.h"
+#include "memory.h"
+#include "hash.h"
+
+/* conf_add_fields()
+ *
+ * inputs - pointer to config item, host/pass/user/operreason fields
+ * output - NONE
+ * side effects - update respective fields with pointers
+ */
+static void
+conf_add_fields(struct ConfItem *aconf, const char *host_field,
+ const char *pass_field, const char *user_field,
+ const char *operreason_field)
+{
+ if(host_field != NULL)
+ DupString(aconf->host, host_field);
+ if(pass_field != NULL)
+ DupString(aconf->passwd, pass_field);
+ if(user_field != NULL)
+ DupString(aconf->user, user_field);
+ if(operreason_field != NULL)
+ DupString(aconf->spasswd, operreason_field);
+}
+
+/*
+ * parse_k_file
+ * Inputs - pointer to line to parse
+ * Output - NONE
+ * Side Effects - Parse one new style K line
+ */
+
+void
+parse_k_file(FILE * file)
+{
+ struct ConfItem *aconf;
+ char *user_field = NULL;
+ char *reason_field = NULL;
+ char *operreason_field = NULL;
+ char *host_field = NULL;
+ char line[BUFSIZE];
+ char *p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if((p = strchr(line, '\n')) != NULL)
+ *p = '\0';
+
+ if((*line == '\0') || (*line == '#'))
+ continue;
+
+ user_field = getfield(line);
+ if(EmptyString(user_field))
+ continue;
+
+ host_field = getfield(NULL);
+ if(EmptyString(host_field))
+ continue;
+
+ reason_field = getfield(NULL);
+ if(EmptyString(reason_field))
+ continue;
+
+ operreason_field = getfield(NULL);
+
+ aconf = make_conf();
+ aconf->status = CONF_KILL;
+ conf_add_fields(aconf, host_field, reason_field,
+ user_field, operreason_field);
+
+ if(aconf->host != NULL)
+ add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf);
+ }
+}
+
+/*
+ * parse_d_file
+ * Inputs - pointer to line to parse
+ * Output - NONE
+ * Side Effects - Parse one new style D line
+ */
+
+void
+parse_d_file(FILE * file)
+{
+ struct ConfItem *aconf;
+ char *reason_field = NULL;
+ char *host_field = NULL;
+ char *operreason_field = NULL;
+ char line[BUFSIZE];
+ char *p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if((p = strchr(line, '\n')))
+ *p = '\0';
+
+ if((*line == '\0') || (line[0] == '#'))
+ continue;
+
+ host_field = getfield(line);
+ if(EmptyString(host_field))
+ continue;
+
+ reason_field = getfield(NULL);
+ if(EmptyString(reason_field))
+ continue;
+
+ operreason_field = getfield(NULL);
+
+ aconf = make_conf();
+ aconf->status = CONF_DLINE;
+ conf_add_fields(aconf, host_field, reason_field, "", operreason_field);
+ conf_add_d_conf(aconf);
+ }
+}
+
+void
+parse_x_file(FILE * file)
+{
+ struct ConfItem *aconf;
+ char *gecos_field = NULL;
+ char *reason_field = NULL;
+ char line[BUFSIZE];
+ char *p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if((p = strchr(line, '\n')))
+ *p = '\0';
+
+ if((*line == '\0') || (line[0] == '#'))
+ continue;
+
+ gecos_field = getfield(line);
+ if(EmptyString(gecos_field))
+ continue;
+
+ /* field for xline types, which no longer exist */
+ getfield(NULL);
+
+ reason_field = getfield(NULL);
+ if(EmptyString(reason_field))
+ continue;
+
+ /* sanity checking */
+ if((find_xline(gecos_field, 0) != NULL) ||
+ (strchr(reason_field, ':') != NULL))
+ continue;
+
+ aconf = make_conf();
+ aconf->status = CONF_XLINE;
+
+ DupString(aconf->name, gecos_field);
+ DupString(aconf->passwd, reason_field);
+
+ dlinkAddAlloc(aconf, &xline_conf_list);
+ }
+}
+
+void
+parse_resv_file(FILE * file)
+{
+ struct ConfItem *aconf;
+ char *reason_field;
+ char *host_field;
+ char line[BUFSIZE];
+ char *p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if((p = strchr(line, '\n')))
+ *p = '\0';
+
+ if((*line == '\0') || (line[0] == '#'))
+ continue;
+
+ host_field = getfield(line);
+ if(EmptyString(host_field))
+ continue;
+
+ reason_field = getfield(NULL);
+ if(EmptyString(reason_field))
+ continue;
+
+ if(IsChannelName(host_field))
+ {
+ if(hash_find_resv(host_field))
+ continue;
+
+ aconf = make_conf();
+ aconf->status = CONF_RESV_CHANNEL;
+ aconf->port = 0;
+
+ DupString(aconf->name, host_field);
+ DupString(aconf->passwd, reason_field);
+ add_to_resv_hash(aconf->name, aconf);
+ }
+ else if(clean_resv_nick(host_field))
+ {
+ if(find_nick_resv(host_field))
+ continue;
+
+ aconf = make_conf();
+ aconf->status = CONF_RESV_NICK;
+ aconf->port = 0;
+
+ DupString(aconf->name, host_field);
+ DupString(aconf->passwd, reason_field);
+ dlinkAddAlloc(aconf, &resv_conf_list);
+ }
+ }
+}
+
+/*
+ * getfield
+ *
+ * inputs - input buffer
+ * output - next field
+ * side effects - field breakup for ircd.conf file.
+ */
+char *
+getfield(char *newline)
+{
+ static char *line = NULL;
+ char *end, *field;
+
+ if(newline != NULL)
+ line = newline;
+
+ if(line == NULL)
+ return (NULL);
+
+ field = line;
+
+ /* XXX make this skip to first " if present */
+ if(*field == '"')
+ field++;
+ else
+ return (NULL); /* mal-formed field */
+
+ end = strchr(line, ',');
+
+ while(1)
+ {
+ /* no trailing , - last field */
+ if(end == NULL)
+ {
+ end = line + strlen(line);
+ line = NULL;
+
+ if(*end == '"')
+ {
+ *end = '\0';
+ return field;
+ }
+ else
+ return NULL;
+ }
+ else
+ {
+ /* look for a ", to mark the end of a field.. */
+ if(*(end - 1) == '"')
+ {
+ line = end + 1;
+ end--;
+ *end = '\0';
+ return field;
+ }
+
+ /* search for the next ',' */
+ end++;
+ end = strchr(end, ',');
+ }
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * listener.c: Listens on a port.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: listener.c 1675 2006-06-15 22:32:23Z jilles $
+ */
+
+#include "stdinc.h"
+#include "setup.h"
+#include "listener.h"
+#include "client.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "ircd_defs.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_stats.h"
+#include "send.h"
+#include "memory.h"
+#include "s_auth.h"
+#include "reject.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+#if defined(NO_IN6ADDR_ANY) && defined(IPV6)
+static const struct in6_addr in6addr_any =
+{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
+#endif
+
+static PF accept_connection;
+
+static listener_t *ListenerPollList = NULL;
+
+static listener_t *
+make_listener(struct irc_sockaddr_storage *addr)
+{
+ listener_t *listener = (listener_t *) MyMalloc(sizeof(listener_t));
+ s_assert(0 != listener);
+
+ listener->name = me.name;
+ listener->fd = -1;
+ memcpy(&listener->addr, addr, sizeof(struct irc_sockaddr_storage));
+ listener->next = NULL;
+ return listener;
+}
+
+void
+free_listener(listener_t *listener)
+{
+ s_assert(NULL != listener);
+ if(listener == NULL)
+ return;
+ /*
+ * remove from listener list
+ */
+ if(listener == ListenerPollList)
+ ListenerPollList = listener->next;
+ else
+ {
+ listener_t *prev = ListenerPollList;
+ for (; prev; prev = prev->next)
+ {
+ if(listener == prev->next)
+ {
+ prev->next = listener->next;
+ break;
+ }
+ }
+ }
+
+ /* free */
+ MyFree(listener);
+}
+
+#define PORTNAMELEN 6 /* ":31337" */
+
+/*
+ * get_listener_name - return displayable listener name and port
+ * returns "host.foo.org:6667" for a given listener
+ */
+const char *
+get_listener_name(const listener_t *listener)
+{
+ static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4];
+ int port = 0;
+
+ s_assert(NULL != listener);
+ if(listener == NULL)
+ return NULL;
+
+#ifdef IPV6
+ if(listener->addr.ss_family == AF_INET6)
+ port = ntohs(((const struct sockaddr_in6 *)&listener->addr)->sin6_port);
+ else
+#endif
+ port = ntohs(((const struct sockaddr_in *)&listener->addr)->sin_port);
+
+ ircsnprintf(buf, sizeof(buf), "%s[%s/%u]", me.name, listener->name, port);
+ return buf;
+}
+
+/*
+ * show_ports - send port listing to a client
+ * inputs - pointer to client to show ports to
+ * output - none
+ * side effects - show ports
+ */
+void
+show_ports(struct Client *source_p)
+{
+ listener_t *listener = 0;
+
+ for (listener = ListenerPollList; listener; listener = listener->next)
+ {
+ sendto_one_numeric(source_p, RPL_STATSPLINE,
+ form_str(RPL_STATSPLINE), 'P',
+#ifdef IPV6
+ ntohs(listener->addr.ss_family == AF_INET ? ((struct sockaddr_in *)&listener->addr)->sin_port :
+ ((struct sockaddr_in6 *)&listener->addr)->sin6_port),
+#else
+ ntohs(((struct sockaddr_in *)&listener->addr)->sin_port),
+#endif
+ IsOperAdmin(source_p) ? listener->name : me.name,
+ listener->ref_count, (listener->active) ? "active" : "disabled");
+ }
+}
+
+/*
+ * inetport - create a listener socket in the AF_INET or AF_INET6 domain,
+ * bind it to the port given in 'port' and listen to it
+ * returns true (1) if successful false (0) on error.
+ *
+ * If the operating system has a define for SOMAXCONN, use it, otherwise
+ * use RATBOX_SOMAXCONN
+ */
+#ifdef SOMAXCONN
+#undef RATBOX_SOMAXCONN
+#define RATBOX_SOMAXCONN SOMAXCONN
+#endif
+
+static int
+inetport(listener_t *listener)
+{
+ int fd;
+ int opt = 1;
+
+ /*
+ * At first, open a new socket
+ */
+
+ fd = comm_socket(listener->addr.ss_family, SOCK_STREAM, 0, "Listener socket");
+
+#ifdef IPV6
+ if(listener->addr.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr;
+ if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
+ {
+ inetntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost));
+ listener->name = listener->vhost;
+ }
+ } else
+#endif
+ {
+ struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr;
+ if(in->sin_addr.s_addr != INADDR_ANY)
+ {
+ inetntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
+ listener->name = listener->vhost;
+ }
+ }
+
+
+ if(fd == -1)
+ {
+ report_error("opening listener socket %s:%s",
+ get_listener_name(listener),
+ get_listener_name(listener), errno);
+ return 0;
+ }
+ else if((HARD_FDLIMIT - 10) < fd)
+ {
+ report_error("no more connections left for listener %s:%s",
+ get_listener_name(listener),
+ get_listener_name(listener), errno);
+ comm_close(fd);
+ return 0;
+ }
+ /*
+ * XXX - we don't want to do all this crap for a listener
+ * set_sock_opts(listener);
+ */
+ if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
+ {
+ report_error("setting SO_REUSEADDR for listener %s:%s",
+ get_listener_name(listener),
+ get_listener_name(listener), errno);
+ comm_close(fd);
+ return 0;
+ }
+
+ /*
+ * Bind a port to listen for new connections if port is non-null,
+ * else assume it is already open and try get something from it.
+ */
+
+ if(bind(fd, (struct sockaddr *) &listener->addr, GET_SS_LEN(listener->addr)))
+ {
+ report_error("binding listener socket %s:%s",
+ get_listener_name(listener),
+ get_listener_name(listener), errno);
+ comm_close(fd);
+ return 0;
+ }
+
+ if(listen(fd, RATBOX_SOMAXCONN))
+ {
+ report_error("listen failed for %s:%s",
+ get_listener_name(listener),
+ get_listener_name(listener), errno);
+ comm_close(fd);
+ return 0;
+ }
+
+ listener->fd = fd;
+
+ /* Listen completion events are READ events .. */
+
+ accept_connection(fd, listener);
+ return 1;
+}
+
+static listener_t *
+find_listener(struct irc_sockaddr_storage *addr)
+{
+ listener_t *listener = NULL;
+ listener_t *last_closed = NULL;
+
+ for (listener = ListenerPollList; listener; listener = listener->next)
+ {
+ if(addr->ss_family != listener->addr.ss_family)
+ continue;
+
+ switch(addr->ss_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
+ struct sockaddr_in *lin4 = (struct sockaddr_in *)&listener->addr;
+ if(in4->sin_addr.s_addr == lin4->sin_addr.s_addr &&
+ in4->sin_port == lin4->sin_port )
+ {
+ if(listener->fd == -1)
+ last_closed = listener;
+ else
+ return(listener);
+ }
+ break;
+ }
+#ifdef IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
+ struct sockaddr_in6 *lin6 =(struct sockaddr_in6 *)&listener->addr;
+ if(IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &lin6->sin6_addr) &&
+ in6->sin6_port == lin6->sin6_port)
+ {
+ if(listener->fd == -1)
+ last_closed = listener;
+ else
+ return(listener);
+ }
+ break;
+
+ }
+#endif
+
+ default:
+ break;
+ }
+ }
+ return last_closed;
+}
+
+
+/*
+ * add_listener- create a new listener
+ * port - the port number to listen on
+ * vhost_ip - if non-null must contain a valid IP address string in
+ * the format "255.255.255.255"
+ */
+void
+add_listener(int port, const char *vhost_ip, int family)
+{
+ listener_t *listener;
+ struct irc_sockaddr_storage vaddr;
+
+ /*
+ * if no port in conf line, don't bother
+ */
+ if(port == 0)
+ return;
+ memset(&vaddr, 0, sizeof(vaddr));
+ vaddr.ss_family = family;
+
+ if(vhost_ip != NULL)
+ {
+ if(family == AF_INET)
+ {
+ if(inetpton(family, vhost_ip, &((struct sockaddr_in *)&vaddr)->sin_addr) <= 0)
+ return;
+ }
+#ifdef IPV6
+ else
+ {
+ if(inetpton(family, vhost_ip, &((struct sockaddr_in6 *)&vaddr)->sin6_addr) <= 0)
+ return;
+
+ }
+#endif
+ } else
+ {
+ switch(family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)&vaddr)->sin_addr.s_addr = INADDR_ANY;
+ break;
+#ifdef IPV6
+ case AF_INET6:
+ memcpy(&((struct sockaddr_in6 *)&vaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr));
+ break;
+ default:
+ return;
+#endif
+ }
+ }
+ switch(family)
+ {
+ case AF_INET:
+ SET_SS_LEN(vaddr, sizeof(struct sockaddr_in));
+ ((struct sockaddr_in *)&vaddr)->sin_port = htons(port);
+ break;
+#ifdef IPV6
+ case AF_INET6:
+ SET_SS_LEN(vaddr, sizeof(struct sockaddr_in6));
+ ((struct sockaddr_in6 *)&vaddr)->sin6_port = htons(port);
+ break;
+#endif
+ default:
+ break;
+ }
+ if((listener = find_listener(&vaddr)))
+ {
+ if(listener->fd > -1)
+ return;
+ }
+ else
+ {
+ listener = make_listener(&vaddr);
+ listener->next = ListenerPollList;
+ ListenerPollList = listener;
+ }
+
+ listener->fd = -1;
+
+ if(inetport(listener))
+ listener->active = 1;
+ else
+ close_listener(listener);
+}
+
+/*
+ * close_listener - close a single listener
+ */
+void
+close_listener(listener_t *listener)
+{
+ s_assert(listener != NULL);
+ if(listener == NULL)
+ return;
+ if(listener->fd >= 0)
+ {
+ comm_close(listener->fd);
+ listener->fd = -1;
+ }
+
+ listener->active = 0;
+
+ if(listener->ref_count)
+ return;
+
+ free_listener(listener);
+}
+
+/*
+ * close_listeners - close and free all listeners that are not being used
+ */
+void
+close_listeners()
+{
+ listener_t *listener;
+ listener_t *listener_next = 0;
+ /*
+ * close all 'extra' listening ports we have
+ */
+ for (listener = ListenerPollList; listener; listener = listener_next)
+ {
+ listener_next = listener->next;
+ close_listener(listener);
+ }
+}
+
+#define DLINE_WARNING "ERROR :You have been D-lined.\r\n"
+
+/*
+ * add_connection - creates a client which has just connected to us on
+ * the given fd. The sockhost field is initialized with the ip# of the host.
+ * The client is sent to the auth module for verification, and not put in
+ * any client list yet.
+ */
+static void
+add_connection(listener_t *listener, int fd, struct sockaddr *sai)
+{
+ struct Client *new_client;
+ s_assert(NULL != listener);
+
+ /*
+ * get the client socket name from the socket
+ * the client has already been checked out in accept_connection
+ */
+ new_client = make_client(NULL);
+
+ memcpy(&new_client->localClient->ip, sai, sizeof(struct irc_sockaddr_storage));
+
+ /*
+ * copy address to 'sockhost' as a string, copy it to host too
+ * so we have something valid to put into error messages...
+ */
+ inetntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost,
+ sizeof(new_client->sockhost));
+
+
+ strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));
+
+#ifdef IPV6
+ if(new_client->localClient->ip.ss_family == AF_INET6 && ConfigFileEntry.dot_in_ip6_addr == 1)
+ {
+ strlcat(new_client->host, ".", sizeof(new_client->host));
+ }
+#endif
+
+ new_client->localClient->fd = fd;
+
+ new_client->localClient->listener = listener;
+ ++listener->ref_count;
+
+ if(check_reject(new_client))
+ return;
+ start_auth(new_client);
+}
+
+
+static void
+accept_connection(int pfd, void *data)
+{
+ static time_t last_oper_notice = 0;
+
+ struct irc_sockaddr_storage sai;
+ socklen_t addrlen = sizeof(sai);
+ int fd;
+ listener_t *listener = data;
+ struct ConfItem *aconf;
+ char buf[BUFSIZE];
+
+ s_assert(listener != NULL);
+ if(listener == NULL)
+ return;
+ /*
+ * There may be many reasons for error return, but
+ * in otherwise correctly working environment the
+ * probable cause is running out of file descriptors
+ * (EMFILE, ENFILE or others?). The man pages for
+ * accept don't seem to list these as possible,
+ * although it's obvious that it may happen here.
+ * Thus no specific errors are tested at this
+ * point, just assume that connections cannot
+ * be accepted until some old is closed first.
+ */
+
+ fd = comm_accept(listener->fd, (struct sockaddr *)&sai, &addrlen);
+ if(fd < 0)
+ {
+ /* Re-register a new IO request for the next accept .. */
+ comm_setselect(listener->fd, FDLIST_SERVICE,
+ COMM_SELECT_READ, accept_connection, listener, 0);
+ return;
+ }
+
+ /* This needs to be done here, otherwise we break dlines */
+ mangle_mapped_sockaddr((struct sockaddr *)&sai);
+
+ /*
+ * check for connection limit
+ */
+ if((MAXCONNECTIONS - 10) < fd)
+ {
+ ++ServerStats->is_ref;
+ /*
+ * slow down the whining to opers bit
+ */
+ if((last_oper_notice + 20) <= CurrentTime)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "All connections in use. (%s)",
+ get_listener_name(listener));
+ last_oper_notice = CurrentTime;
+ }
+
+ write(fd, "ERROR :All connections in use\r\n", 32);
+ comm_close(fd);
+ /* Re-register a new IO request for the next accept .. */
+ comm_setselect(listener->fd, FDLIST_SERVICE,
+ COMM_SELECT_READ, accept_connection, listener, 0);
+ return;
+ }
+
+ /* Do an initial check we aren't connecting too fast or with too many
+ * from this IP... */
+ if((aconf = conf_connect_allowed((struct sockaddr *)&sai, sai.ss_family)) != NULL)
+ {
+ ServerStats->is_ref++;
+
+ if(ConfigFileEntry.dline_with_reason)
+ {
+ if (ircsnprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", aconf->passwd) >= (sizeof(buf)-1))
+ {
+ buf[sizeof(buf) - 3] = '\r';
+ buf[sizeof(buf) - 2] = '\n';
+ buf[sizeof(buf) - 1] = '\0';
+ }
+ }
+ else
+ ircsprintf(buf, "ERROR :You have been D-lined.\r\n");
+
+ write(fd, buf, strlen(buf));
+ comm_close(fd);
+
+ /* Re-register a new IO request for the next accept .. */
+ comm_setselect(listener->fd, FDLIST_SERVICE,
+ COMM_SELECT_READ, accept_connection, listener, 0);
+ return;
+ }
+
+ ServerStats->is_ac++;
+ add_connection(listener, fd, (struct sockaddr *)&sai);
+
+ /* Re-register a new IO request for the next accept .. */
+ comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
+ accept_connection, listener, 0);
+}
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, src/match.c
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * 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.
+ *
+ * $Id: match.c 708 2006-02-05 22:44:03Z jilles $
+ *
+ */
+#include "stdinc.h"
+#include "config.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+
+/*
+ * Compare if a given string (name) matches the given
+ * mask (which can contain wild cards: '*' - match any
+ * number of chars, '?' - match any single character.
+ *
+ * return 1, if match
+ * 0, if no match
+ *
+ * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
+ * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
+ */
+
+/** Check a string against a mask.
+ * This test checks using traditional IRC wildcards only: '*' means
+ * match zero or more characters of any type; '?' means match exactly
+ * one character of any type.
+ *
+ * @param[in] mask Wildcard-containing mask.
+ * @param[in] name String to check against \a mask.
+ * @return Zero if \a mask matches \a name, non-zero if no match.
+ */
+int match(const char *mask, const char *name)
+{
+ const char *m = mask, *n = name;
+ const char *m_tmp = mask, *n_tmp = name;
+ int star_p;
+
+ s_assert(mask != NULL);
+ s_assert(name != NULL);
+
+ for (;;)
+ {
+ switch (*m)
+ {
+ case '\0':
+ if (!*n)
+ return 1;
+ backtrack:
+ if (m_tmp == mask)
+ return 0;
+ m = m_tmp;
+ n = ++n_tmp;
+ break;
+ case '*':
+ case '?':
+ for (star_p = 0;; m++)
+ {
+ if (*m == '*')
+ star_p = 1;
+ else if (*m == '?')
+ {
+ if (!*n++)
+ goto backtrack;
+ }
+ else
+ break;
+ }
+ if (star_p)
+ {
+ if (!*m)
+ return 1;
+ else
+ {
+ m_tmp = m;
+ for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++);
+ }
+ }
+ /* and fall through */
+ default:
+ if (!*n)
+ return (*m != '\0' ? 0 : 1);
+ if (ToLower(*m) != ToLower(*n))
+ goto backtrack;
+ m++;
+ n++;
+ break;
+ }
+ }
+}
+
+/** Check a string against a mask.
+ * This test checks using traditional IRC wildcards only: '*' means
+ * match zero or more characters of any type; '?' means match exactly
+ * one character of any type; '#' means match exactly one character
+ * that is a number.
+ *
+ * This function supports escaping, so that a wildcard may be matched
+ * exactly.
+ *
+ * @param[in] mask Wildcard-containing mask.
+ * @param[in] name String to check against \a mask.
+ * @return Zero if \a mask matches \a name, non-zero if no match.
+ */
+int match_esc(const char *mask, const char *name)
+{
+ const char *m = mask, *n = name;
+ const char *m_tmp = mask, *n_tmp = name;
+ int star_p;
+
+ s_assert(mask != NULL);
+ s_assert(name != NULL);
+
+ for (;;)
+ {
+ switch (*m)
+ {
+ case '\0':
+ if (!*n)
+ return 1;
+ backtrack:
+ if (m_tmp == mask)
+ return 0;
+ m = m_tmp;
+ n = ++n_tmp;
+ break;
+ case '\\':
+ m++;
+ /* allow escaping to force capitalization */
+ if (*m++ != *n++)
+ goto backtrack;
+ break;
+ case '*':
+ case '?':
+ for (star_p = 0;; m++)
+ {
+ if (*m == '*')
+ star_p = 1;
+ else if (*m == '?')
+ {
+ if (!*n++)
+ goto backtrack;
+ }
+ else
+ break;
+ }
+ if (star_p)
+ {
+ if (!*m)
+ return 1;
+ else if (*m == '\\')
+ {
+ m_tmp = ++m;
+ if (!*m)
+ return 0;
+ for (n_tmp = n; *n && *n != *m; n++);
+ }
+ else if (*m == '#')
+ {
+ m_tmp = m;
+ for (n_tmp = n; *n && !IsDigit(*n); n++);
+ }
+ else if (*m == '@')
+ {
+ m_tmp = m;
+ for (n_tmp = n; *n && !IsLetter(*n); n++);
+ }
+ else
+ {
+ m_tmp = m;
+ for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++);
+ }
+ }
+ /* and fall through */
+ default:
+ if (!*n)
+ return (*m != '\0' ? 0 : 1);
+ if (*m == '#')
+ {
+ if (!IsDigit(*n))
+ goto backtrack;
+ }
+ else if (*m == '@')
+ {
+ if (!IsLetter(*n))
+ goto backtrack;
+ }
+ else if (ToLower(*m) != ToLower(*n))
+ goto backtrack;
+ m++;
+ n++;
+ break;
+ }
+ }
+}
+
+int comp_with_mask(void *addr, void *dest, u_int mask)
+{
+ if (memcmp(addr, dest, mask / 8) == 0)
+ {
+ int n = mask / 8;
+ int m = ((-1) << (8 - (mask % 8)));
+ if (mask % 8 == 0 || (((u_char *) addr)[n] & m) == (((u_char *) dest)[n] & m))
+ {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask)
+{
+ void *iaddr = NULL;
+ void *idest = NULL;
+
+ if (addr->sa_family == AF_INET)
+ {
+ iaddr = &((struct sockaddr_in *)addr)->sin_addr;
+ idest = &((struct sockaddr_in *)dest)->sin_addr;
+ }
+#ifdef IPV6
+ else
+ {
+ iaddr = &((struct sockaddr_in6 *)addr)->sin6_addr;
+ idest = &((struct sockaddr_in6 *)dest)->sin6_addr;
+
+ }
+#endif
+
+ return (comp_with_mask(iaddr, idest, mask));
+}
+
+/*
+ * match_ips()
+ *
+ * Input - cidr ip mask, address
+ */
+int match_ips(const char *s1, const char *s2)
+{
+ struct irc_sockaddr_storage ipaddr, maskaddr;
+ char mask[BUFSIZE];
+ char address[HOSTLEN + 1];
+ char *len;
+ void *ipptr, *maskptr;
+ int cidrlen, aftype;
+
+ strcpy(mask, s1);
+ strcpy(address, s2);
+
+ len = strrchr(mask, '/');
+ if (len == NULL)
+ return 0;
+
+ *len++ = '\0';
+
+ cidrlen = atoi(len);
+ if (cidrlen == 0)
+ return 0;
+
+#ifdef IPV6
+ if (strchr(mask, ':') && strchr(address, ':'))
+ {
+ aftype = AF_INET6;
+ ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
+ maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
+ }
+ else
+#endif
+ if (!strchr(mask, ':') && !strchr(address, ':'))
+ {
+ aftype = AF_INET;
+ ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
+ maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
+ }
+ else
+ return 0;
+
+ inetpton(aftype, address, ipptr);
+ inetpton(aftype, mask, maskptr);
+ if (comp_with_mask(ipptr, maskptr, cidrlen))
+ return 1;
+ else
+ return 0;
+}
+
+/* match_cidr()
+ *
+ * Input - mask, address
+ * Ouput - 1 = Matched 0 = Did not match
+ */
+
+int match_cidr(const char *s1, const char *s2)
+{
+ struct irc_sockaddr_storage ipaddr, maskaddr;
+ char mask[BUFSIZE];
+ char address[NICKLEN + USERLEN + HOSTLEN + 6];
+ char *ipmask;
+ char *ip;
+ char *len;
+ void *ipptr, *maskptr;
+ int cidrlen, aftype;
+
+ strcpy(mask, s1);
+ strcpy(address, s2);
+
+ ipmask = strrchr(mask, '@');
+ if (ipmask == NULL)
+ return 0;
+
+ *ipmask++ = '\0';
+
+ ip = strrchr(address, '@');
+ if (ip == NULL)
+ return 0;
+ *ip++ = '\0';
+
+
+ len = strrchr(ipmask, '/');
+ if (len == NULL)
+ return 0;
+
+ *len++ = '\0';
+
+ cidrlen = atoi(len);
+ if (cidrlen == 0)
+ return 0;
+
+#ifdef IPV6
+ if (strchr(ip, ':') && strchr(ipmask, ':'))
+ {
+ aftype = AF_INET6;
+ ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
+ maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
+ }
+ else
+#endif
+ if (!strchr(ip, ':') && !strchr(ipmask, ':'))
+ {
+ aftype = AF_INET;
+ ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
+ maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
+ }
+ else
+ return 0;
+
+ inetpton(aftype, ip, ipptr);
+ inetpton(aftype, ipmask, maskptr);
+ if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address))
+ return 1;
+ else
+ return 0;
+}
+
+/* collapse()
+ *
+ * collapses a string containing multiple *'s.
+ */
+char *collapse(char *pattern)
+{
+ char *p = pattern, *po = pattern;
+ char c;
+ int f = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ while ((c = *p++))
+ {
+ if (c == '*')
+ {
+ if (!(f & 1))
+ *po++ = '*';
+ f |= 1;
+ }
+ else
+ {
+ *po++ = c;
+ f &= ~1;
+ }
+ }
+ *po++ = 0;
+
+ return pattern;
+}
+
+/* collapse_esc()
+ *
+ * The collapse() function with support for escaping characters
+ */
+char *collapse_esc(char *pattern)
+{
+ char *p = pattern, *po = pattern;
+ char c;
+ int f = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ while ((c = *p++))
+ {
+ if (!(f & 2) && c == '*')
+ {
+ if (!(f & 1))
+ *po++ = '*';
+ f |= 1;
+ }
+ else if (!(f & 2) && c == '\\')
+ {
+ *po++ = '\\';
+ f |= 2;
+ }
+ else
+ {
+ *po++ = c;
+ f &= ~3;
+ }
+ }
+ *po++ = 0;
+ return pattern;
+}
+
+/*
+ * irccmp - case insensitive comparison of two 0 terminated strings.
+ *
+ * returns 0, if s1 equal to s2
+ * <0, if s1 lexicographically less than s2
+ * >0, if s1 lexicographically greater than s2
+ */
+int irccmp(const char *s1, const char *s2)
+{
+ const unsigned char *str1 = (const unsigned char *)s1;
+ const unsigned char *str2 = (const unsigned char *)s2;
+ int res;
+
+ s_assert(s1 != NULL);
+ s_assert(s2 != NULL);
+
+ while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
+ {
+ if (*str1 == '\0')
+ return 0;
+ str1++;
+ str2++;
+ }
+ return (res);
+}
+
+int ircncmp(const char *s1, const char *s2, int n)
+{
+ const unsigned char *str1 = (const unsigned char *)s1;
+ const unsigned char *str2 = (const unsigned char *)s2;
+ int res;
+ s_assert(s1 != NULL);
+ s_assert(s2 != NULL);
+
+ while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
+ {
+ str1++;
+ str2++;
+ n--;
+ if (n == 0 || (*str1 == '\0' && *str2 == '\0'))
+ return 0;
+ }
+ return (res);
+}
+
+const unsigned char ToLowerTab[] = {
+ 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
+ 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f,
+ ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
+ '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ ':', ';', '<', '=', '>', '?',
+ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
+ '_',
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
+ 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+ 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
+ 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+ 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
+ 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+const unsigned char ToUpperTab[] = {
+ 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
+ 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f,
+ ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
+ '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
+ 0x5f,
+ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
+ 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+ 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
+ 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+ 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
+ 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+/*
+ * CharAttrs table
+ *
+ * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
+ * for channel names
+ */
+const unsigned int CharAttrs[] = {
+/* 0 */ CNTRL_C,
+/* 1 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 2 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
+/* 3 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
+/* 4 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 5 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 6 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 7 BEL */ CNTRL_C | NONEOS_C,
+/* 8 \b */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 9 \t */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
+/* 10 \n */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
+/* 11 \v */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
+/* 12 \f */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
+/* 13 \r */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
+/* 14 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 15 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 16 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 17 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 18 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 19 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 20 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 21 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 22 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
+/* 23 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 24 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 25 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 26 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 27 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 28 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 29 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 30 */ CNTRL_C | CHAN_C | NONEOS_C,
+/* 31 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
+/* SP */ PRINT_C | SPACE_C,
+/* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
+/* " */ PRINT_C | CHAN_C | NONEOS_C,
+/* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C,
+/* $ */ PRINT_C | CHAN_C | NONEOS_C | USER_C,
+/* % */ PRINT_C | CHAN_C | NONEOS_C,
+/* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C,
+/* ' */ PRINT_C | CHAN_C | NONEOS_C,
+/* ( */ PRINT_C | CHAN_C | NONEOS_C,
+/* ) */ PRINT_C | CHAN_C | NONEOS_C,
+/* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C | SERV_C,
+/* + */ PRINT_C | CHAN_C | NONEOS_C,
+/* , */ PRINT_C | NONEOS_C,
+/* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C,
+/* / */ PRINT_C | CHAN_C | NONEOS_C,
+/* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 3 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 4 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 5 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 6 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 7 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 8 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* 9 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* : */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
+/* ; */ PRINT_C | CHAN_C | NONEOS_C,
+/* < */ PRINT_C | CHAN_C | NONEOS_C,
+/* = */ PRINT_C | CHAN_C | NONEOS_C,
+/* > */ PRINT_C | CHAN_C | NONEOS_C,
+/* ? */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
+/* @ */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
+/* A */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* B */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* C */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* D */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* E */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* F */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* G */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* H */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* I */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* J */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* K */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* L */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* M */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* N */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* O */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* P */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* Q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* R */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* S */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* T */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* U */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* V */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* W */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* X */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* Y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* Z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* [ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* \ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* ] */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* ^ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* _ */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* ` */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* a */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* b */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* c */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* d */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* e */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* f */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* g */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* h */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* i */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* j */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* k */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* l */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* m */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* n */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* o */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* p */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* r */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* s */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* t */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* u */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* v */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* w */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* x */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
+/* { */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* | */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* } */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
+/* ~ */ PRINT_C | ALPHA_C | CHAN_C | NONEOS_C | USER_C,
+/* del */ CHAN_C | NONEOS_C,
+/* 0x80 */ CHAN_C | NONEOS_C,
+/* 0x81 */ CHAN_C | NONEOS_C,
+/* 0x82 */ CHAN_C | NONEOS_C,
+/* 0x83 */ CHAN_C | NONEOS_C,
+/* 0x84 */ CHAN_C | NONEOS_C,
+/* 0x85 */ CHAN_C | NONEOS_C,
+/* 0x86 */ CHAN_C | NONEOS_C,
+/* 0x87 */ CHAN_C | NONEOS_C,
+/* 0x88 */ CHAN_C | NONEOS_C,
+/* 0x89 */ CHAN_C | NONEOS_C,
+/* 0x8A */ CHAN_C | NONEOS_C,
+/* 0x8B */ CHAN_C | NONEOS_C,
+/* 0x8C */ CHAN_C | NONEOS_C,
+/* 0x8D */ CHAN_C | NONEOS_C,
+/* 0x8E */ CHAN_C | NONEOS_C,
+/* 0x8F */ CHAN_C | NONEOS_C,
+/* 0x90 */ CHAN_C | NONEOS_C,
+/* 0x91 */ CHAN_C | NONEOS_C,
+/* 0x92 */ CHAN_C | NONEOS_C,
+/* 0x93 */ CHAN_C | NONEOS_C,
+/* 0x94 */ CHAN_C | NONEOS_C,
+/* 0x95 */ CHAN_C | NONEOS_C,
+/* 0x96 */ CHAN_C | NONEOS_C,
+/* 0x97 */ CHAN_C | NONEOS_C,
+/* 0x98 */ CHAN_C | NONEOS_C,
+/* 0x99 */ CHAN_C | NONEOS_C,
+/* 0x9A */ CHAN_C | NONEOS_C,
+/* 0x9B */ CHAN_C | NONEOS_C,
+/* 0x9C */ CHAN_C | NONEOS_C,
+/* 0x9D */ CHAN_C | NONEOS_C,
+/* 0x9E */ CHAN_C | NONEOS_C,
+/* 0x9F */ CHAN_C | NONEOS_C,
+/* 0xA0 */ CHAN_C | FCHAN_C | NONEOS_C,
+/* 0xA1 */ CHAN_C | NONEOS_C,
+/* 0xA2 */ CHAN_C | NONEOS_C,
+/* 0xA3 */ CHAN_C | NONEOS_C,
+/* 0xA4 */ CHAN_C | NONEOS_C,
+/* 0xA5 */ CHAN_C | NONEOS_C,
+/* 0xA6 */ CHAN_C | NONEOS_C,
+/* 0xA7 */ CHAN_C | NONEOS_C,
+/* 0xA8 */ CHAN_C | NONEOS_C,
+/* 0xA9 */ CHAN_C | NONEOS_C,
+/* 0xAA */ CHAN_C | NONEOS_C,
+/* 0xAB */ CHAN_C | NONEOS_C,
+/* 0xAC */ CHAN_C | NONEOS_C,
+/* 0xAD */ CHAN_C | NONEOS_C,
+/* 0xAE */ CHAN_C | NONEOS_C,
+/* 0xAF */ CHAN_C | NONEOS_C,
+/* 0xB0 */ CHAN_C | NONEOS_C,
+/* 0xB1 */ CHAN_C | NONEOS_C,
+/* 0xB2 */ CHAN_C | NONEOS_C,
+/* 0xB3 */ CHAN_C | NONEOS_C,
+/* 0xB4 */ CHAN_C | NONEOS_C,
+/* 0xB5 */ CHAN_C | NONEOS_C,
+/* 0xB6 */ CHAN_C | NONEOS_C,
+/* 0xB7 */ CHAN_C | NONEOS_C,
+/* 0xB8 */ CHAN_C | NONEOS_C,
+/* 0xB9 */ CHAN_C | NONEOS_C,
+/* 0xBA */ CHAN_C | NONEOS_C,
+/* 0xBB */ CHAN_C | NONEOS_C,
+/* 0xBC */ CHAN_C | NONEOS_C,
+/* 0xBD */ CHAN_C | NONEOS_C,
+/* 0xBE */ CHAN_C | NONEOS_C,
+/* 0xBF */ CHAN_C | NONEOS_C,
+/* 0xC0 */ CHAN_C | NONEOS_C,
+/* 0xC1 */ CHAN_C | NONEOS_C,
+/* 0xC2 */ CHAN_C | NONEOS_C,
+/* 0xC3 */ CHAN_C | NONEOS_C,
+/* 0xC4 */ CHAN_C | NONEOS_C,
+/* 0xC5 */ CHAN_C | NONEOS_C,
+/* 0xC6 */ CHAN_C | NONEOS_C,
+/* 0xC7 */ CHAN_C | NONEOS_C,
+/* 0xC8 */ CHAN_C | NONEOS_C,
+/* 0xC9 */ CHAN_C | NONEOS_C,
+/* 0xCA */ CHAN_C | NONEOS_C,
+/* 0xCB */ CHAN_C | NONEOS_C,
+/* 0xCC */ CHAN_C | NONEOS_C,
+/* 0xCD */ CHAN_C | NONEOS_C,
+/* 0xCE */ CHAN_C | NONEOS_C,
+/* 0xCF */ CHAN_C | NONEOS_C,
+/* 0xD0 */ CHAN_C | NONEOS_C,
+/* 0xD1 */ CHAN_C | NONEOS_C,
+/* 0xD2 */ CHAN_C | NONEOS_C,
+/* 0xD3 */ CHAN_C | NONEOS_C,
+/* 0xD4 */ CHAN_C | NONEOS_C,
+/* 0xD5 */ CHAN_C | NONEOS_C,
+/* 0xD6 */ CHAN_C | NONEOS_C,
+/* 0xD7 */ CHAN_C | NONEOS_C,
+/* 0xD8 */ CHAN_C | NONEOS_C,
+/* 0xD9 */ CHAN_C | NONEOS_C,
+/* 0xDA */ CHAN_C | NONEOS_C,
+/* 0xDB */ CHAN_C | NONEOS_C,
+/* 0xDC */ CHAN_C | NONEOS_C,
+/* 0xDD */ CHAN_C | NONEOS_C,
+/* 0xDE */ CHAN_C | NONEOS_C,
+/* 0xDF */ CHAN_C | NONEOS_C,
+/* 0xE0 */ CHAN_C | NONEOS_C,
+/* 0xE1 */ CHAN_C | NONEOS_C,
+/* 0xE2 */ CHAN_C | NONEOS_C,
+/* 0xE3 */ CHAN_C | NONEOS_C,
+/* 0xE4 */ CHAN_C | NONEOS_C,
+/* 0xE5 */ CHAN_C | NONEOS_C,
+/* 0xE6 */ CHAN_C | NONEOS_C,
+/* 0xE7 */ CHAN_C | NONEOS_C,
+/* 0xE8 */ CHAN_C | NONEOS_C,
+/* 0xE9 */ CHAN_C | NONEOS_C,
+/* 0xEA */ CHAN_C | NONEOS_C,
+/* 0xEB */ CHAN_C | NONEOS_C,
+/* 0xEC */ CHAN_C | NONEOS_C,
+/* 0xED */ CHAN_C | NONEOS_C,
+/* 0xEE */ CHAN_C | NONEOS_C,
+/* 0xEF */ CHAN_C | NONEOS_C,
+/* 0xF0 */ CHAN_C | NONEOS_C,
+/* 0xF1 */ CHAN_C | NONEOS_C,
+/* 0xF2 */ CHAN_C | NONEOS_C,
+/* 0xF3 */ CHAN_C | NONEOS_C,
+/* 0xF4 */ CHAN_C | NONEOS_C,
+/* 0xF5 */ CHAN_C | NONEOS_C,
+/* 0xF6 */ CHAN_C | NONEOS_C,
+/* 0xF7 */ CHAN_C | NONEOS_C,
+/* 0xF8 */ CHAN_C | NONEOS_C,
+/* 0xF9 */ CHAN_C | NONEOS_C,
+/* 0xFA */ CHAN_C | NONEOS_C,
+/* 0xFB */ CHAN_C | NONEOS_C,
+/* 0xFC */ CHAN_C | NONEOS_C,
+/* 0xFD */ CHAN_C | NONEOS_C,
+/* 0xFE */ CHAN_C | NONEOS_C,
+/* 0xFF */ CHAN_C | NONEOS_C
+};
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, src/messages.tab
+ * Copyright (C) 1992 Darren Reed
+ *
+ * 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.
+ *
+ * $Id: messages.tab 2731 2006-11-09 23:53:43Z jilles $
+ */
+
+static const char * replies[] = {
+/* 000 */ NULL,
+/* 001 RPL_WELCOME, */ ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s",
+/* 002 RPL_YOURHOST,*/ ":%s 002 %s :Your host is %s, running version %s",
+/* 003 RPL_CREATED, */ ":%s 003 %s :This server was created %s",
+/* 004 RPL_MYINFO, */ ":%s 004 %s %s %s %s biklmnopstveqrcgzjfILPQF bkloveqjfI",
+/* 005 RPL_ISUPPORT, */ "%s :are supported by this server",
+/* 006 */ NULL,
+/* 007 */ NULL,
+/* 008 RPL_SNOMASK */ ":%s 008 %s %s :Server notice mask",
+/* 009 */ NULL,
+/* 010 RPL_REDIR, */ ":%s 010 %s %s %d :Please use this Server/Port instead",
+/* 011 */ NULL,
+/* 012 */ NULL,
+/* 013 */ NULL,
+/* 014 */ NULL,
+/* 015 RPL_MAP */ ":%s 015 %s :%s",
+/* 016 */ NULL,
+/* 017 RPL_MAPEND */ ":%s 017 %s :End of /MAP",
+/* 018 */ NULL,
+/* 019 */ NULL,
+/* 020 */ NULL,
+/* 021 */ NULL,
+/* 022 */ NULL,
+/* 023 */ NULL,
+/* 024 */ NULL,
+/* 025 */ NULL,
+/* 026 */ NULL,
+/* 027 */ NULL,
+/* 028 */ NULL,
+/* 029 */ NULL,
+/* 030 */ NULL,
+/* 031 */ NULL,
+/* 032 */ NULL,
+/* 033 */ NULL,
+/* 034 */ NULL,
+/* 035 */ NULL,
+/* 036 */ NULL,
+/* 037 */ NULL,
+/* 038 */ NULL,
+/* 039 */ NULL,
+/* 040 */ NULL,
+/* 041 */ NULL,
+/* 042 */ NULL,
+/* 043 RPL_SAVENICK */ "%s :Nick collision, forcing nick change to your unique ID",
+/* 044 */ NULL,
+/* 045 */ NULL,
+/* 046 */ NULL,
+/* 047 */ NULL,
+/* 048 */ NULL,
+/* 049 */ NULL,
+/* 050 */ NULL,
+/* 051 */ NULL,
+/* 052 */ NULL,
+/* 053 */ NULL,
+/* 054 */ NULL,
+/* 055 */ NULL,
+/* 056 */ NULL,
+/* 057 */ NULL,
+/* 058 */ NULL,
+/* 059 */ NULL,
+/* 060 */ NULL,
+/* 061 */ NULL,
+/* 062 */ NULL,
+/* 063 */ NULL,
+/* 064 */ NULL,
+/* 065 */ NULL,
+/* 066 */ NULL,
+/* 067 */ NULL,
+/* 068 */ NULL,
+/* 069 */ NULL,
+/* 070 */ NULL,
+/* 071 */ NULL,
+/* 072 */ NULL,
+/* 073 */ NULL,
+/* 074 */ NULL,
+/* 075 */ NULL,
+/* 076 */ NULL,
+/* 077 */ NULL,
+/* 078 */ NULL,
+/* 079 */ NULL,
+/* 080 */ NULL,
+/* 081 */ NULL,
+/* 082 */ NULL,
+/* 083 */ NULL,
+/* 084 */ NULL,
+/* 085 */ NULL,
+/* 086 */ NULL,
+/* 087 */ NULL,
+/* 088 */ NULL,
+/* 089 */ NULL,
+/* 090 */ NULL,
+/* 091 */ NULL,
+/* 092 */ NULL,
+/* 093 */ NULL,
+/* 094 */ NULL,
+/* 095 */ NULL,
+/* 096 */ NULL,
+/* 097 */ NULL,
+/* 098 */ NULL,
+/* 099 */ NULL,
+/* 100 */ NULL,
+/* 101 */ NULL,
+/* 102 */ NULL,
+/* 103 */ NULL,
+/* 104 */ NULL,
+/* 105 */ NULL,
+/* 106 */ NULL,
+/* 107 */ NULL,
+/* 108 */ NULL,
+/* 109 */ NULL,
+/* 110 */ NULL,
+/* 111 */ NULL,
+/* 112 */ NULL,
+/* 113 */ NULL,
+/* 114 */ NULL,
+/* 115 */ NULL,
+/* 116 */ NULL,
+/* 117 */ NULL,
+/* 118 */ NULL,
+/* 119 */ NULL,
+/* 120 */ NULL,
+/* 121 */ NULL,
+/* 122 */ NULL,
+/* 123 */ NULL,
+/* 124 */ NULL,
+/* 125 */ NULL,
+/* 126 */ NULL,
+/* 127 */ NULL,
+/* 128 */ NULL,
+/* 129 */ NULL,
+/* 130 */ NULL,
+/* 131 */ NULL,
+/* 132 */ NULL,
+/* 133 */ NULL,
+/* 134 */ NULL,
+/* 135 */ NULL,
+/* 136 */ NULL,
+/* 137 */ NULL,
+/* 138 */ NULL,
+/* 139 */ NULL,
+/* 140 */ NULL,
+/* 141 */ NULL,
+/* 142 */ NULL,
+/* 143 */ NULL,
+/* 144 */ NULL,
+/* 145 */ NULL,
+/* 146 */ NULL,
+/* 147 */ NULL,
+/* 148 */ NULL,
+/* 149 */ NULL,
+/* 150 */ NULL,
+/* 151 */ NULL,
+/* 152 */ NULL,
+/* 153 */ NULL,
+/* 154 */ NULL,
+/* 155 */ NULL,
+/* 156 */ NULL,
+/* 157 */ NULL,
+/* 158 */ NULL,
+/* 159 */ NULL,
+/* 160 */ NULL,
+/* 161 */ NULL,
+/* 162 */ NULL,
+/* 163 */ NULL,
+/* 164 */ NULL,
+/* 165 */ NULL,
+/* 166 */ NULL,
+/* 167 */ NULL,
+/* 168 */ NULL,
+/* 169 */ NULL,
+/* 170 */ NULL,
+/* 171 */ NULL,
+/* 172 */ NULL,
+/* 173 */ NULL,
+/* 174 */ NULL,
+/* 175 */ NULL,
+/* 176 */ NULL,
+/* 177 */ NULL,
+/* 178 */ NULL,
+/* 179 */ NULL,
+/* 180 */ NULL,
+/* 181 */ NULL,
+/* 182 */ NULL,
+/* 183 */ NULL,
+/* 184 */ NULL,
+/* 185 */ NULL,
+/* 186 */ NULL,
+/* 187 */ NULL,
+/* 188 */ NULL,
+/* 189 */ NULL,
+/* 190 */ NULL,
+/* 191 */ NULL,
+/* 192 */ NULL,
+/* 193 */ NULL,
+/* 194 */ NULL,
+/* 195 */ NULL,
+/* 196 */ NULL,
+/* 197 */ NULL,
+/* 198 */ NULL,
+/* 199 */ NULL,
+/* 200 RPL_TRACELINK, */ "Link %s %s %s",
+/* 201 RPL_TRACECONNECTING, */ "Try. %s %s",
+/* 202 RPL_TRACEHANDSHAKE, */ "H.S. %s %s",
+/* 203 RPL_TRACEUNKNOWN, */ "???? %s %s (%s) %d",
+/* 204 RPL_TRACEOPERATOR, */ "Oper %s %s (%s) %lu %lu",
+/* 205 RPL_TRACEUSER, */ "User %s %s (%s) %lu %lu",
+/* 206 RPL_TRACESERVER, */ "Serv %s %dS %dC %s %s!%s@%s %lu",
+/* 207 */ NULL,
+/* 208 RPL_TRACENEWTYPE, */ "<newtype> 0 %s",
+/* 209 RPL_TRACECLASS, */ "Class %s %d",
+/* 210 */ NULL,
+/* 211 RPL_STATSLINKINFO, */ NULL,
+/* 212 RPL_STATSCOMMANDS, */ "%s %u %u :%u",
+/* 213 RPL_STATSCLINE, */ "C %s %s %s %d %s",
+/* 214 RPL_STATSNLINE, */ NULL,
+/* 215 RPL_STATSILINE, */ "I %s * %s@%s %d %s",
+/* 216 RPL_STATSKLINE, */ "%c %s * %s :%s%s%s",
+/* 217 RPL_STATSQLINE, */ "%c %d %s :%s",
+/* 218 RPL_STATSYLINE, */ "Y %s %d %d %d %u %d.%d %d.%d %u",
+/* 219 RPL_ENDOFSTATS, */ "%c :End of /STATS report",
+/* 220 RPL_STATSPLINE, */ "%c %d %s %d :%s",
+/* 221 RPL_UMODEIS, */ ":%s 221 %s %s",
+/* 222 */ NULL,
+/* 223 */ NULL,
+/* 224 */ NULL,
+/* 225 RPL_STATSDLINE*/ "%c %s :%s%s%s",
+/* 226 */ NULL,
+/* 227 */ NULL,
+/* 228 */ NULL,
+/* 229 */ NULL,
+/* 230 */ NULL,
+/* 231 */ NULL,
+/* 232 */ NULL,
+/* 233 */ NULL,
+/* 234 RPL_SERVLIST, */ NULL,
+/* 235 RPL_SERVLISTEND, */ NULL,
+/* 236 */ NULL,
+/* 237 */ NULL,
+/* 238 */ NULL,
+/* 239 */ NULL,
+/* 240 */ NULL,
+/* 241 RPL_STATSLLINE, */ "L %s * %s 0 -1",
+/* 242 RPL_STATSUPTIME,*/ ":Server Up %d days, %d:%02d:%02d",
+/* 243 RPL_STATSOLINE, */ "O %s@%s * %s %s %s",
+/* 244 RPL_STATSHLINE, */ "H %s * %s 0 -1",
+/* 245 RPL_STATSSLINE, */ NULL,
+/* 246 */ NULL,
+/* 247 RPL_STATSXLINE, */ "%c %d %s :%s",
+
+/* 248 RPL_STATSULINE, */ "U %s %s@%s %s",
+/* 249 RPL_STATSDEBUG */ NULL,
+/* 250 RPL_STATSCONN, */ ":Highest connection count: %d (%d clients) (%d connections received)",
+/* 251 RPL_LUSERCLIENT, */ ":There are %d users and %d invisible on %d servers",
+/* 252 RPL_LUSEROP, */ "%d :IRC Operators online",
+/* 253 RPL_LUSERUNKNOWN, */ "%d :unknown connection(s)",
+/* 254 RPL_LUSERCHANNELS, */ "%d :channels formed",
+/* 255 RPL_LUSERME, */ ":I have %d clients and %d servers",
+/* 256 RPL_ADMINME, */ ":%s 256 %s :Administrative info about %s",
+/* 257 RPL_ADMINLOC1, */ ":%s 257 %s :%s",
+/* 258 RPL_ADMINLOC2, */ ":%s 258 %s :%s",
+/* 259 RPL_ADMINEMAIL, */ ":%s 259 %s :%s",
+/* 260 */ NULL,
+/* 261 RPL_TRACELOG, */ NULL,
+/* 262 RPL_ENDOFTRACE, */ "%s :End of TRACE",
+/* 263 RPL_LOAD2HI, */
+":%s 263 %s %s :Server load is temporarily too heavy. Please wait a while and try again.",
+/* 264 */ NULL,
+/* 265 RPL_LOCALUSERS, */ "%d %d :Current local users %d, max %d",
+/* 266 RPL_GLOBALUSERS, */ "%d %d :Current global users %d, max %d",
+/* 267 */ NULL,
+/* 268 */ NULL,
+/* 269 */ NULL,
+/* 270 */ NULL,
+/* 271 */ NULL,
+/* 272 */ NULL,
+/* 273 */ NULL,
+/* 274 */ NULL,
+/* 275 */ NULL,
+/* 276 */ NULL,
+/* 277 */ NULL,
+/* 278 */ NULL,
+/* 279 */ NULL,
+/* 280 */ NULL,
+/* 281 RPL_ACCEPTLIST, */ ":%s 281 %s %s",
+/* 282 RPL_ENDOFACCEPT */ ":%s 282 %s :End of /ACCEPT list.",
+/* 283 */ NULL,
+/* 284 */ NULL,
+/* 285 */ NULL,
+/* 286 */ NULL,
+/* 287 */ NULL,
+/* 288 */ NULL,
+/* 289 */ NULL,
+/* 290 */ NULL,
+/* 291 */ NULL,
+/* 292 */ NULL,
+/* 293 */ NULL,
+/* 294 */ NULL,
+/* 295 */ NULL,
+/* 296 */ NULL,
+/* 297 */ NULL,
+/* 298 */ NULL,
+/* 299 */ NULL,
+/* 300 RPL_NONE, */ NULL,
+/* 301 RPL_AWAY, */ "%s :%s",
+/* 302 RPL_USERHOST, */ ":%s 302 %s :%s",
+/* 303 RPL_ISON, */ ":%s 303 %s :",
+/* 304 RPL_TEXT, */ NULL,
+/* 305 RPL_UNAWAY, */ ":%s 305 %s :You are no longer marked as being away",
+/* 306 RPL_NOWAWAY, */ ":%s 306 %s :You have been marked as being away",
+/* 307 */ NULL,
+/* 308 */ NULL,
+/* 309 */ NULL,
+/* 310 */ NULL,
+/* 311 RPL_WHOISUSER, */ "%s %s %s * :%s",
+/* 312 RPL_WHOISSERVER, */ "%s %s :%s",
+/* 313 RPL_WHOISOPERATOR, */ "%s :%s",
+/* 314 RPL_WHOWASUSER, */ ":%s 314 %s %s %s %s * :%s",
+/* 315 RPL_ENDOFWHO, */ ":%s 315 %s %s :End of /WHO list.",
+/* 316 RPL_WHOISCHANOP, */ NULL,
+/* 317 RPL_WHOISIDLE, */ "%s %d %d :seconds idle, signon time",
+/* 318 RPL_ENDOFWHOIS, */ "%s :End of /WHOIS list.",
+/* 319 RPL_WHOISCHANNELS, */ ":%s 319 %s %s :",
+/* 320 */ NULL,
+/* 321 RPL_LISTSTART, */ ":%s 321 %s Channel :Users Name",
+/* 322 RPL_LIST, */ ":%s 322 %s %s %d :%s",
+/* 323 RPL_LISTEND, */ ":%s 323 %s :End of /LIST",
+/* 324 RPL_CHANNELMODEIS, */ ":%s 324 %s %s %s",
+/* 325 */ NULL,
+/* 326 */ NULL,
+/* 327 */ NULL,
+/* 328 */ NULL,
+/* 329 RPL_CREATIONTIME, */ ":%s 329 %s %s %lu",
+/* 330 RPL_WHOISLOGGEDIN */ ":%s 330 %s %s %s :is logged in as",
+/* 331 RPL_NOTOPIC, */ ":%s 331 %s %s :No topic is set.",
+/* 332 RPL_TOPIC, */ ":%s 332 %s %s :%s",
+/* 333 RPL_TOPICWHOTIME, */ ":%s 333 %s %s %s %lu",
+/* 334 */ NULL,
+/* 335 */ NULL,
+/* 336 */ NULL,
+/* 337 */ NULL,
+/* 338 RPL_WHOISACTUALLY, */ "%s %s :actually using host",
+/* 339 */ NULL,
+/* 340 */ NULL,
+/* 341 RPL_INVITING, */ ":%s 341 %s %s %s",
+/* 342 RPL_SUMMONING, */ NULL,
+/* 343 */ NULL,
+/* 344 */ NULL,
+/* 345 */ NULL,
+/* 346 RPL_INVEXLIST */ ":%s 346 %s %s %s %s %lu",
+/* 347 RPL_ENDOFINVEXLIST */ ":%s 347 %s %s :End of Channel Invite List",
+/* 348 RPL_EXCEPTLIST */ ":%s 348 %s %s %s %s %lu",
+/* 349 RPL_ENDOFEXCEPTLIST */ ":%s 349 %s %s :End of Channel Exception List",
+/* 350 */ NULL,
+/* 351 RPL_VERSION, */ "%s(%s). %s :%s TS%dow %s",
+/* 352 RPL_WHOREPLY, */ ":%s 352 %s %s %s %s %s %s %s :%d %s",
+/* 353 RPL_NAMREPLY, */ ":%s 353 %s %s %s :",
+/* 354 */ NULL,
+/* 355 */ NULL,
+/* 356 */ NULL,
+/* 357 */ NULL,
+/* 358 */ NULL,
+/* 359 */ NULL,
+/* 360 RPL_WHOWASREAL, */ ":%s 360 %s %s :was connecting from *@%s %s",
+/* 361 RPL_KILLDONE, */ NULL,
+/* 362 RPL_CLOSING, */ ":%s 362 %s %s :Closed. Status = %d",
+/* 363 RPL_CLOSEEND, */ ":%s 363 %s %d :Connections Closed",
+/* 364 RPL_LINKS, */ "%s %s :%d %s",
+/* 365 RPL_ENDOFLINKS, */ "%s :End of /LINKS list.",
+/* 366 RPL_ENDOFNAMES, */ ":%s 366 %s %s :End of /NAMES list.",
+/* 367 RPL_BANLIST, */ ":%s 367 %s %s %s %s %lu",
+/* 368 RPL_ENDOFBANLIST, */ ":%s 368 %s %s :End of Channel Ban List",
+/* 369 RPL_ENDOFWHOWAS, */ ":%s 369 %s %s :End of WHOWAS",
+/* 370 */ NULL,
+/* 371 RPL_INFO, */ ":%s",
+/* 372 RPL_MOTD, */ ":%s 372 %s :- %s",
+/* 373 RPL_INFOSTART, */ NULL,
+/* 374 RPL_ENDOFINFO, */ ":End of /INFO list.",
+/* 375 RPL_MOTDSTART, */ ":%s 375 %s :- %s Message of the Day - ",
+/* 376 RPL_ENDOFMOTD, */ ":%s 376 %s :End of /MOTD command.",
+/* 377 */ NULL,
+/* 378 RPL_WHOISHOST, */ "%s :is connecting from *@%s %s",
+/* 379 */ NULL,
+/* 380 */ NULL,
+/* 381 RPL_YOUREOPER, */ ":%s 381 %s :Here I am with a brain the size of a planet, and they want me to bring them coffee. I think I'll just kill myself...",
+/* 382 RPL_REHASHING, */ ":%s 382 %s %s :Rehashing",
+/* 383 */ NULL,
+/* 384 RPL_MYPORTIS, */ NULL,
+/* 385 RPL_NOTOPERANYMORE, */ NULL,
+/* 386 RPL_RSACHALLENGE, */ ":%s 386 %s :%s",
+/* 387 */ NULL,
+/* 388 */ NULL,
+/* 389 */ NULL,
+/* 390 */ NULL,
+/* 391 RPL_TIME, */ "%s :%s",
+/* 392 */ NULL,
+/* 393 */ NULL,
+/* 394 */ NULL,
+/* 395 */ NULL,
+/* 396 */ NULL,
+/* 397 */ NULL,
+/* 398 */ NULL,
+/* 399 */ NULL,
+/* 400 */ NULL,
+/* 401 ERR_NOSUCHNICK, */ "%s :No such nick/channel",
+/* 402 ERR_NOSUCHSERVER, */ "%s :No such server",
+/* 403 ERR_NOSUCHCHANNEL, */ "%s :No such channel",
+/* 404 ERR_CANNOTSENDTOCHAN, */ "%s :Cannot send to channel",
+/* 405 ERR_TOOMANYCHANNELS, */ ":%s 405 %s %s :You have joined too many channels",
+/* 406 ERR_WASNOSUCHNICK, */ ":%s 406 %s %s :There was no such nickname",
+/* 407 ERR_TOOMANYTARGETS, */ ":%s 407 %s %s :Too many recipients.",
+/* 408 */ NULL,
+/* 409 ERR_NOORIGIN, */ ":%s 409 %s :No origin specified",
+/* 410 ERR_INVALIDCAPCMD */ ":%s 410 %s %s :Invalid CAP subcommand",
+/* 411 ERR_NORECIPIENT, */ ":%s 411 %s :No recipient given (%s)",
+/* 412 ERR_NOTEXTTOSEND, */ ":%s 412 %s :No text to send",
+/* 413 ERR_NOTOPLEVEL, */ "%s :No toplevel domain specified",
+/* 414 ERR_WILDTOPLEVEL, */ "%s :Wildcard in toplevel Domain",
+/* 415 */ NULL,
+/* 416 ERR_TOOMANYMATCHES */ ":%s 416 %s %s :output too large, truncated",
+/* 417 */ NULL,
+/* 418 */ NULL,
+/* 419 */ NULL,
+/* 420 */ NULL,
+/* 421 ERR_UNKNOWNCOMMAND, */ ":%s 421 %s %s :Unknown command",
+/* 422 ERR_NOMOTD, */ ":%s 422 %s :MOTD File is missing",
+/* 423 ERR_NOADMININFO, */ NULL,
+/* 424 ERR_FILEERROR, */ NULL,
+/* 425 */ NULL,
+/* 426 */ NULL,
+/* 427 */ NULL,
+/* 428 */ NULL,
+/* 429 */ NULL,
+/* 430 */ NULL,
+/* 431 ERR_NONICKNAMEGIVEN, */ ":%s 431 %s :No nickname given",
+/* 432 ERR_ERRONEUSNICKNAME, */ ":%s 432 %s %s :Erroneous Nickname",
+/* 433 ERR_NICKNAMEINUSE, */ ":%s 433 %s %s :Nickname is already in use.",
+/* 434 */ NULL,
+/* 435 ERR_BANNICKCHANGE */ "%s %s :Cannot change nickname while banned on channel",
+/* 436 ERR_NICKCOLLISION, */ "%s :Nickname collision KILL",
+/* 437 ERR_UNAVAILRESOURCE, */ ":%s 437 %s %s :Nick/channel is temporarily unavailable",
+/* 438 ERR_NICKTOOFAST */ ":%s 438 %s %s %s :Nick change too fast. Please wait %d seconds.",
+/* 439 */ NULL,
+/* 440 ERR_SERVICESDOWN, */ "%s :Services are currently unavailable",
+/* 441 ERR_USERNOTINCHANNEL, */ "%s %s :They aren't on that channel",
+/* 442 ERR_NOTONCHANNEL, */ "%s :You're not on that channel",
+/* 443 ERR_USERONCHANNEL, */ "%s %s :is already on channel",
+/* 444 ERR_NOLOGIN, */ NULL,
+/* 445 ERR_SUMMONDISABLED, */ NULL,
+/* 446 ERR_USERSDISABLED, */ NULL,
+/* 447 */ NULL,
+/* 448 */ NULL,
+/* 449 */ NULL,
+/* 450 */ NULL,
+/* 451 ERR_NOTREGISTERED, */ ":%s 451 * :You have not registered",
+/* 452 */ NULL,
+/* 453 */ NULL,
+/* 454 */ NULL,
+/* 455 */ NULL,
+/* 456 ERR_ACCEPTFULL */ ":%s 456 %s :Accept list is full",
+/* 457 ERR_ACCEPTEXIST */ ":%s 457 %s %s :is already on your accept list",
+/* 458 ERR_ACCEPTNOT */ ":%s 458 %s %s :is not on your accept list",
+/* 459 */ NULL,
+/* 460 */ NULL,
+/* 461 ERR_NEEDMOREPARAMS, */ ":%s 461 %s %s :Not enough parameters",
+/* 462 ERR_ALREADYREGISTRED, */ ":%s 462 %s :You may not reregister",
+/* 463 ERR_NOPERMFORHOST, */ NULL,
+/* 464 ERR_PASSWDMISMATCH, */ ":%s 464 %s :Password Incorrect",
+/* 465 ERR_YOUREBANNEDCREEP, */ ":%s 465 %s :You are banned from this server- %s",
+/* 466 ERR_YOUWILLBEBANNED, */ NULL,
+/* 467 ERR_KEYSET, */ NULL,
+/* 468 */ NULL,
+/* 469 */ NULL,
+/* 470 ERR_LINKCHANNEL */ "%s %s :Forwarding to another channel",
+/* 471 ERR_CHANNELISFULL, */ ":%s 471 %s %s :Cannot join channel (+l)",
+/* 472 ERR_UNKNOWNMODE , */ ":%s 472 %s %c :is unknown mode char to me",
+/* 473 ERR_INVITEONLYCHAN, */ ":%s 473 %s %s :Cannot join channel (+i)",
+/* 474 ERR_BANNEDFROMCHAN, */ ":%s 474 %s %s :Cannot join channel (+b)",
+/* 475 ERR_BADCHANNELKEY, */ ":%s 475 %s %s :Cannot join channel (+k)",
+/* 476 ERR_BADCHANMASK, */ NULL,
+/* 477 ERR_NEEDREGGEDNICK */ ":%s 477 %s %s :Cannot join channel (+r)",
+/* 478 ERR_BANLISTFULL, */ ":%s 478 %s %s %s :Channel ban list is full",
+/* 479 ERR_BADCHANNAME */ "%s :Illegal channel name",
+/* 480 ERR_THROTTLE */ ":%s 480 %s %s :Cannot join channel (throttle exceeded)",
+/* 481 ERR_NOPRIVILEGES, */ ":Permission Denied - You're not an IRC operator",
+/* 482 ERR_CHANOPRIVSNEEDED, */ ":%s 482 %s %s :You're not channel operator",
+/* 483 ERR_CANTKILLSERVER, */ ":You can't kill a server!",
+/* 484 ERR_ISCHANSERVICE */ ":%s 484 %s %s %s :Cannot kill, kick or deop a network service",
+/* 485 ERR_BANNEDNICK, */ NULL,
+/* 486 ERR_NONONREG */ "%s :You must log in with services to message this user",
+/* 487 */ NULL,
+/* 488 */ NULL,
+/* 489 ERR_VOICENEEDED */ ":%s 489 %s %s :You're neither voiced nor channel operator",
+/* 490 */ NULL,
+/* 491 ERR_NOOPERHOST, */ ":%s 491 %s :Only few of mere mortals may try to enter the twilight zone",
+/* 492 */ NULL,
+/* 493 */ NULL,
+/* 494 */ NULL,
+/* 495 */ NULL,
+/* 496 */ NULL,
+/* 497 */ NULL,
+/* 498 */ NULL,
+/* 499 */ NULL,
+/* 500 */ NULL,
+/* 501 ERR_UMODEUNKNOWNFLAG, */ ":%s 501 %s :Unknown MODE flag",
+/* 502 ERR_USERSDONTMATCH, */ ":%s 502 %s :Can't change mode for other users",
+/* 503 ERR_GHOSTEDCLIENT, */ NULL,
+/* 504 ERR_USERNOTONSERV, */ ":%s 504 %s %s :User is not on this server",
+/* 505 */ NULL,
+/* 506 */ NULL,
+/* 507 */ NULL,
+/* 508 */ NULL,
+/* 509 */ NULL,
+/* 510 */ NULL,
+/* 511 */ NULL,
+/* 512 */ NULL,
+/* 513 ERR_WRONGPONG */ ":%s 513 %s :To connect type /QUOTE PONG %08lX",
+/* 514 */ NULL,
+/* 515 */ NULL,
+/* 516 */ NULL,
+/* 517 */ NULL,
+/* 518 */ NULL,
+/* 519 */ NULL,
+/* 520 */ NULL,
+/* 521 */ NULL,
+/* 522 */ NULL,
+/* 523 */ NULL,
+/* 524 ERR_HELPNOTFOUND, */ ":%s 524 %s %s :Help not found",
+/* 525 */ NULL,
+/* 526 */ NULL,
+/* 527 */ NULL,
+/* 528 */ NULL,
+/* 529 */ NULL,
+/* 530 */ NULL,
+/* 531 */ NULL,
+/* 532 */ NULL,
+/* 533 */ NULL,
+/* 534 */ NULL,
+/* 535 */ NULL,
+/* 536 */ NULL,
+/* 537 */ NULL,
+/* 538 */ NULL,
+/* 539 */ NULL,
+/* 540 */ NULL,
+/* 541 */ NULL,
+/* 542 */ NULL,
+/* 543 */ NULL,
+/* 544 */ NULL,
+/* 545 */ NULL,
+/* 546 */ NULL,
+/* 547 */ NULL,
+/* 548 */ NULL,
+/* 549 */ NULL,
+/* 550 */ NULL,
+/* 551 */ NULL,
+/* 552 */ NULL,
+/* 553 */ NULL,
+/* 554 */ NULL,
+/* 555 */ NULL,
+/* 556 */ NULL,
+/* 557 */ NULL,
+/* 558 */ NULL,
+/* 559 */ NULL,
+/* 560 */ NULL,
+/* 561 */ NULL,
+/* 562 */ NULL,
+/* 563 */ NULL,
+/* 564 */ NULL,
+/* 565 */ NULL,
+/* 566 */ NULL,
+/* 567 */ NULL,
+/* 568 */ NULL,
+/* 569 */ NULL,
+/* 570 */ NULL,
+/* 571 */ NULL,
+/* 572 */ NULL,
+/* 573 */ NULL,
+/* 574 */ NULL,
+/* 575 */ NULL,
+/* 576 */ NULL,
+/* 577 */ NULL,
+/* 578 */ NULL,
+/* 579 */ NULL,
+/* 580 */ NULL,
+/* 581 */ NULL,
+/* 582 */ NULL,
+/* 583 */ NULL,
+/* 584 */ NULL,
+/* 585 */ NULL,
+/* 586 */ NULL,
+/* 587 */ NULL,
+/* 588 */ NULL,
+/* 589 */ NULL,
+/* 590 */ NULL,
+/* 591 */ NULL,
+/* 592 */ NULL,
+/* 593 */ NULL,
+/* 594 */ NULL,
+/* 595 */ NULL,
+/* 596 */ NULL,
+/* 597 */ NULL,
+/* 598 */ NULL,
+/* 599 */ NULL,
+/* 600 */ NULL,
+/* 601 */ NULL,
+/* 602 */ NULL,
+/* 603 */ NULL,
+/* 604 */ NULL,
+/* 605 */ NULL,
+/* 606 */ NULL,
+/* 607 */ NULL,
+/* 608 */ NULL, /* Do not use -- Reserved for WATCH -Rak */
+/* 609 */ NULL,
+/* 610 */ NULL,
+/* 611 */ NULL,
+/* 612 */ NULL,
+/* 613 */ NULL,
+/* 614 */ NULL,
+/* 615 */ NULL,
+/* 616 */ NULL,
+/* 617 */ NULL,
+/* 618 */ NULL,
+/* 619 */ NULL,
+/* 620 */ NULL,
+/* 621 */ NULL,
+/* 622 */ NULL,
+/* 623 */ NULL,
+/* 624 */ NULL,
+/* 625 */ NULL,
+/* 626 */ NULL,
+/* 627 */ NULL,
+/* 628 */ NULL,
+/* 629 */ NULL,
+/* 630 */ NULL,
+/* 631 */ NULL,
+/* 632 */ NULL,
+/* 633 */ NULL,
+/* 634 */ NULL,
+/* 635 */ NULL,
+/* 636 */ NULL,
+/* 637 */ NULL,
+/* 638 */ NULL,
+/* 639 */ NULL,
+/* 640 */ NULL,
+/* 641 */ NULL,
+/* 642 */ NULL,
+/* 643 */ NULL,
+/* 644 */ NULL,
+/* 645 */ NULL,
+/* 646 */ NULL,
+/* 647 */ NULL,
+/* 648 */ NULL,
+/* 649 */ NULL,
+/* 650 */ NULL,
+/* 651 */ NULL,
+/* 652 */ NULL,
+/* 653 */ NULL,
+/* 654 */ NULL,
+/* 655 */ NULL,
+/* 656 */ NULL,
+/* 657 */ NULL,
+/* 658 */ NULL,
+/* 659 */ NULL,
+/* 660 */ NULL,
+/* 661 */ NULL,
+/* 662 */ NULL,
+/* 663 */ NULL,
+/* 664 */ NULL,
+/* 665 */ NULL,
+/* 666 */ NULL,
+/* 667 */ NULL,
+/* 668 */ NULL,
+/* 669 */ NULL,
+/* 670 */ NULL,
+/* 671 */ NULL,
+/* 672 */ NULL,
+/* 673 */ NULL,
+/* 674 */ NULL,
+/* 675 */ NULL,
+/* 676 */ NULL,
+/* 677 */ NULL,
+/* 678 */ NULL,
+/* 679 */ NULL,
+/* 680 */ NULL,
+/* 681 */ NULL,
+/* 682 */ NULL,
+/* 683 */ NULL,
+/* 684 */ NULL,
+/* 685 */ NULL,
+/* 686 */ NULL,
+/* 687 */ NULL,
+/* 688 */ NULL,
+/* 689 */ NULL,
+/* 690 */ NULL,
+/* 691 */ NULL,
+/* 692 */ NULL,
+/* 693 */ NULL,
+/* 694 */ NULL,
+/* 695 */ NULL,
+/* 696 */ NULL,
+/* 697 */ NULL,
+/* 698 */ NULL,
+/* 699 */ NULL,
+/* 700 */ NULL,
+/* 701 */ NULL,
+/* 702 RPL_MODLIST, */ ":%s 702 %s %s 0x%x %s %s",
+/* 703 RPL_ENDOFMODLIST, */ ":%s 703 %s :End of /MODLIST.",
+/* 704 RPL_HELPSTART, */ ":%s 704 %s %s :%s",
+/* 705 RPL_HELPTXT, */ ":%s 705 %s %s :%s",
+/* 706 RPL_ENDOFHELP, */ ":%s 706 %s %s :End of /HELP.",
+/* 707 ERR_TARGCHANGE */ ":%s 707 %s %s :Targets changing too fast, message dropped",
+/* 708 RPL_ETRACEFULL */ ":%s 708 %s %s %s %s %s %s %s %s :%s",
+/* 709 RPL_ETRACE */ ":%s 709 %s %s %s %s %s %s %s :%s",
+/* 710 RPL_KNOCK */ ":%s 710 %s %s %s!%s@%s :has asked for an invite.",
+/* 711 RPL_KNOCKDLVR */ ":%s 711 %s %s :Your KNOCK has been delivered.",
+/* 712 ERR_TOOMANYKNOCK */ ":%s 712 %s %s :Too many KNOCKs (%s).",
+/* 713 ERR_CHANOPEN */ "%s :Channel is open.",
+/* 714 ERR_KNOCKONCHAN */ ":%s 714 %s %s :You are already on that channel.",
+/* 715 ERR_KNOCKDISABLED */ ":%s 715 %s :KNOCKs are disabled.",
+/* 716 ERR_TARGUMODEG */ "%s :is in +g mode (server-side ignore.)",
+/* 717 RPL_TARGNOTIFY */ "%s :has been informed that you messaged them.",
+/* 718 RPL_UMODEGMSG */ ":%s 718 %s %s %s@%s :is messaging you, and you have umode +g.",
+/* 719 */ NULL,
+/* 720 RPL_OMOTDSTART */ ":%s 720 %s :Start of OPER MOTD",
+/* 721 RPL_OMOTD */ ":%s 721 %s :%s",
+/* 722 RPL_ENDOFOMOTD */ ":%s 722 %s :End of OPER MOTD",
+/* 723 ERR_NOPRIVS */ ":%s 723 %s %s :Insufficient oper privs",
+/* 724 RPL_TESTMASK */ NULL, /* Used in 1.x and 2.0.x */
+/* 725 RPL_TESTLINE */ ":%s 725 %s %c %ld %s :%s",
+/* 726 RPL_NOTESTLINE */ ":%s 726 %s %s :No matches",
+/* 727 RPL_TESTMASKGECOS */ ":%s 727 %s %d %d %s!%s@%s %s :Local/remote clients match",
+/* 728 */ NULL,
+/* 729 */ NULL,
+/* 730 RPL_MONONLINE */ ":%s 730 %s :%s",
+/* 731 RPL_MONOFFLINE */ ":%s 731 %s :%s",
+/* 732 RPL_MONLIST */ ":%s 732 %s :%s",
+/* 733 RPL_ENDOFMONLIST */ ":%s 733 %s :End of MONITOR list",
+/* 734 ERR_MONLISTFULL */ ":%s 734 %s %d %s :Monitor list is full",
+/* 735 */ NULL,
+/* 736 */ NULL,
+/* 737 */ NULL,
+/* 738 */ NULL,
+/* 739 */ NULL,
+/* 740 */ ":%s 740 %s :%s",
+/* 741 */ ":%s 741 %s :End of CHALLENGE",
+/* 742 */ NULL,
+/* 743 */ NULL,
+/* 744 */ NULL,
+/* 745 */ NULL,
+/* 746 */ NULL,
+/* 747 */ NULL,
+/* 748 */ NULL,
+/* 749 */ NULL,
+/* 750 RPL_SCANMATCHED */ "%d :matches",
+/* 751 RPL_SCANUMODES */ "%s %s %s %s %s %s :%s",
+/* 752 */ NULL,
+/* 753 */ NULL,
+/* 754 */ NULL,
+/* 755 */ NULL,
+/* 756 */ NULL,
+/* 757 */ NULL,
+/* 758 */ NULL,
+/* 759 */ NULL,
+/* 760 */ NULL,
+/* 761 */ NULL,
+/* 762 */ NULL,
+/* 763 */ NULL,
+/* 764 */ NULL,
+/* 765 */ NULL,
+/* 766 */ NULL,
+/* 767 */ NULL,
+/* 768 */ NULL,
+/* 769 */ NULL,
+/* 770 */ NULL,
+/* 771 */ NULL,
+/* 772 */ NULL,
+/* 773 */ NULL,
+/* 774 */ NULL,
+/* 775 */ NULL,
+/* 776 */ NULL,
+/* 777 */ NULL,
+/* 778 */ NULL,
+/* 779 */ NULL,
+/* 780 */ NULL,
+/* 781 */ NULL,
+/* 782 */ NULL,
+/* 783 */ NULL,
+/* 784 */ NULL,
+/* 785 */ NULL,
+/* 786 */ NULL,
+/* 787 */ NULL,
+/* 788 */ NULL,
+/* 789 */ NULL,
+/* 790 */ NULL,
+/* 791 */ NULL,
+/* 792 */ NULL,
+/* 793 */ NULL,
+/* 794 */ NULL,
+/* 795 */ NULL,
+/* 796 */ NULL,
+/* 797 */ NULL,
+/* 798 */ NULL,
+/* 799 */ NULL,
+/* 800 */ NULL,
+/* 801 */ NULL,
+/* 802 */ NULL,
+/* 803 */ NULL,
+/* 804 */ NULL,
+/* 805 */ NULL,
+/* 806 */ NULL,
+/* 807 */ NULL,
+/* 808 */ NULL,
+/* 809 */ NULL,
+/* 810 */ NULL,
+/* 811 */ NULL,
+/* 812 */ NULL,
+/* 813 */ NULL,
+/* 814 */ NULL,
+/* 815 */ NULL,
+/* 816 */ NULL,
+/* 817 */ NULL,
+/* 818 */ NULL,
+/* 819 */ NULL,
+/* 820 */ NULL,
+/* 821 */ NULL,
+/* 822 */ NULL,
+/* 823 */ NULL,
+/* 824 */ NULL,
+/* 825 */ NULL,
+/* 826 */ NULL,
+/* 827 */ NULL,
+/* 828 */ NULL,
+/* 829 */ NULL,
+/* 830 */ NULL,
+/* 831 */ NULL,
+/* 832 */ NULL,
+/* 833 */ NULL,
+/* 834 */ NULL,
+/* 835 */ NULL,
+/* 836 */ NULL,
+/* 837 */ NULL,
+/* 838 */ NULL,
+/* 839 */ NULL,
+/* 840 */ NULL,
+/* 841 */ NULL,
+/* 842 */ NULL,
+/* 843 */ NULL,
+/* 844 */ NULL,
+/* 845 */ NULL,
+/* 846 */ NULL,
+/* 847 */ NULL,
+/* 848 */ NULL,
+/* 849 */ NULL,
+/* 850 */ NULL,
+/* 851 */ NULL,
+/* 852 */ NULL,
+/* 853 */ NULL,
+/* 854 */ NULL,
+/* 855 */ NULL,
+/* 856 */ NULL,
+/* 857 */ NULL,
+/* 858 */ NULL,
+/* 859 */ NULL,
+/* 860 */ NULL,
+/* 861 */ NULL,
+/* 862 */ NULL,
+/* 863 */ NULL,
+/* 864 */ NULL,
+/* 865 */ NULL,
+/* 866 */ NULL,
+/* 867 */ NULL,
+/* 868 */ NULL,
+/* 869 */ NULL,
+/* 870 */ NULL,
+/* 871 */ NULL,
+/* 872 */ NULL,
+/* 873 */ NULL,
+/* 874 */ NULL,
+/* 875 */ NULL,
+/* 876 */ NULL,
+/* 877 */ NULL,
+/* 878 */ NULL,
+/* 879 */ NULL,
+/* 880 */ NULL,
+/* 881 */ NULL,
+/* 882 */ NULL,
+/* 883 */ NULL,
+/* 884 */ NULL,
+/* 885 */ NULL,
+/* 886 */ NULL,
+/* 887 */ NULL,
+/* 888 */ NULL,
+/* 889 */ NULL,
+/* 890 */ NULL,
+/* 891 */ NULL,
+/* 892 */ NULL,
+/* 893 */ NULL,
+/* 894 */ NULL,
+/* 895 */ NULL,
+/* 896 */ NULL,
+/* 897 */ NULL,
+/* 898 */ NULL,
+/* 899 */ NULL,
+/* 900 RPL_LOGGEDIN */ ":%s 900 %s %s!%s@%s %s :You are now logged in as %s.",
+/* 901 RPL_LOGGEDOUT */ ":%s 901 %s %s!%s@%s :You are now logged out.",
+/* 902 ERR_NICKLOCKED */ ":%s 902 %s :You must use a nick assigned to you.",
+/* 903 RPL_SASLSUCCESS */ ":%s 903 %s :SASL authentication successful",
+/* 904 ERR_SASLFAIL */ ":%s 904 %s :SASL authentication failed",
+/* 905 ERR_SASLTOOLONG */ ":%s 905 %s :SASL message too long",
+/* 906 ERR_SASLABORTED */ ":%s 906 %s :SASL authentication aborted",
+/* 907 ERR_SASLALREADY */ ":%s 907 %s :You have already completed SASL authentication",
+/* 908 */ NULL,
+/* 909 */ NULL,
+/* 910 */ NULL,
+/* 911 */ NULL,
+/* 912 */ NULL,
+/* 913 */ NULL,
+/* 914 */ NULL,
+/* 915 */ NULL,
+/* 916 */ NULL,
+/* 917 */ NULL,
+/* 918 */ NULL,
+/* 919 */ NULL,
+/* 920 */ NULL,
+/* 921 */ NULL,
+/* 922 */ NULL,
+/* 923 */ NULL,
+/* 924 */ NULL,
+/* 925 */ NULL,
+/* 926 */ NULL,
+/* 927 */ NULL,
+/* 928 */ NULL,
+/* 929 */ NULL,
+/* 930 */ NULL,
+/* 931 */ NULL,
+/* 932 */ NULL,
+/* 933 */ NULL,
+/* 934 */ NULL,
+/* 935 */ NULL,
+/* 936 */ NULL,
+/* 937 */ NULL,
+/* 938 */ NULL,
+/* 939 */ NULL,
+/* 940 */ NULL,
+/* 941 */ NULL,
+/* 942 */ NULL,
+/* 943 */ NULL,
+/* 944 */ NULL,
+/* 945 */ NULL,
+/* 946 */ NULL,
+/* 947 */ NULL,
+/* 948 */ NULL,
+/* 949 */ NULL,
+/* 950 */ NULL,
+/* 951 */ NULL,
+/* 952 */ NULL,
+/* 953 */ NULL,
+/* 954 */ NULL,
+/* 955 */ NULL,
+/* 956 */ NULL,
+/* 957 */ NULL,
+/* 958 */ NULL,
+/* 959 */ NULL,
+/* 960 */ NULL,
+/* 961 */ NULL,
+/* 962 */ NULL,
+/* 963 */ NULL,
+/* 964 */ NULL,
+/* 965 */ NULL,
+/* 966 */ NULL,
+/* 967 */ NULL,
+/* 968 */ NULL,
+/* 969 */ NULL,
+/* 970 */ NULL,
+/* 971 */ NULL,
+/* 972 */ NULL,
+/* 973 */ NULL,
+/* 974 */ NULL,
+/* 975 */ NULL,
+/* 976 */ NULL,
+/* 977 */ NULL,
+/* 978 */ NULL,
+/* 979 */ NULL,
+/* 980 */ NULL,
+/* 981 */ NULL,
+/* 982 */ NULL,
+/* 983 */ NULL,
+/* 984 */ NULL,
+/* 985 */ NULL,
+/* 986 */ NULL,
+/* 987 */ NULL,
+/* 988 */ NULL,
+/* 989 */ NULL,
+/* 990 */ NULL,
+/* 991 */ NULL,
+/* 992 */ NULL,
+/* 993 */ NULL,
+/* 994 */ NULL,
+/* 995 */ NULL,
+/* 996 */ NULL,
+/* 997 */ NULL,
+/* 998 */ NULL,
+/* 999 LAST ERR_LAST_ERR_MSG,*/ ":%s 999 %s :Last Error Message"
+};
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * modules.c: A module loader.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: modules.c 1509 2006-05-28 02:35:58Z nenolod $
+ */
+
+#include "stdinc.h"
+
+
+#include "modules.h"
+#include "s_log.h"
+#include "ircd.h"
+#include "client.h"
+#include "send.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "numeric.h"
+#include "parse.h"
+#include "ircd_defs.h"
+#include "irc_string.h"
+#include "memory.h"
+#include "tools.h"
+#include "sprintf_irc.h"
+
+
+
+/* -TimeMr14C:
+ * I have moved the dl* function definitions and
+ * the two functions (load_a_module / unload_a_module) to the
+ * file dynlink.c
+ * And also made the necessary changes to those functions
+ * to comply with shl_load and friends.
+ * In this file, to keep consistency with the makefile,
+ * I added the ability to load *.sl files, too.
+ * 27/02/2002
+ */
+
+#ifndef STATIC_MODULES
+
+struct module **modlist = NULL;
+
+static const char *core_module_table[] = {
+ "m_die",
+ "m_error",
+ "m_join",
+ "m_kick",
+ "m_kill",
+ "m_message",
+ "m_mode",
+ "m_nick",
+ "m_part",
+ "m_quit",
+ "m_server",
+ "m_sjoin",
+ "m_squit",
+ NULL
+};
+
+#define MODS_INCREMENT 10
+int num_mods = 0;
+int max_mods = MODS_INCREMENT;
+
+static dlink_list mod_paths;
+
+static int mo_modload(struct Client *, struct Client *, int, const char **);
+static int mo_modlist(struct Client *, struct Client *, int, const char **);
+static int mo_modreload(struct Client *, struct Client *, int, const char **);
+static int mo_modunload(struct Client *, struct Client *, int, const char **);
+static int mo_modrestart(struct Client *, struct Client *, int, const char **);
+
+struct Message modload_msgtab = {
+ "MODLOAD", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modload, 2}}
+};
+
+struct Message modunload_msgtab = {
+ "MODUNLOAD", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modunload, 2}}
+};
+
+struct Message modreload_msgtab = {
+ "MODRELOAD", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modreload, 2}}
+};
+
+struct Message modlist_msgtab = {
+ "MODLIST", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modlist, 0}}
+};
+
+struct Message modrestart_msgtab = {
+ "MODRESTART", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modrestart, 0}}
+};
+
+extern struct Message error_msgtab;
+
+void
+modules_init(void)
+{
+ mod_add_cmd(&modload_msgtab);
+ mod_add_cmd(&modunload_msgtab);
+ mod_add_cmd(&modreload_msgtab);
+ mod_add_cmd(&modlist_msgtab);
+ mod_add_cmd(&modrestart_msgtab);
+
+ /* Add the default paths we look in to the module system --nenolod */
+ mod_add_path(MODPATH);
+ mod_add_path(AUTOMODPATH);
+}
+
+/* mod_find_path()
+ *
+ * input - path
+ * output - none
+ * side effects - returns a module path from path
+ */
+static struct module_path *
+mod_find_path(const char *path)
+{
+ dlink_node *ptr;
+ struct module_path *mpath;
+
+ DLINK_FOREACH(ptr, mod_paths.head)
+ {
+ mpath = ptr->data;
+
+ if(!strcmp(path, mpath->path))
+ return mpath;
+ }
+
+ return NULL;
+}
+
+/* mod_add_path
+ *
+ * input - path
+ * ouput -
+ * side effects - adds path to list
+ */
+void
+mod_add_path(const char *path)
+{
+ struct module_path *pathst;
+
+ if(mod_find_path(path))
+ return;
+
+ pathst = MyMalloc(sizeof(struct module_path));
+
+ strcpy(pathst->path, path);
+ dlinkAddAlloc(pathst, &mod_paths);
+}
+
+/* mod_clear_paths()
+ *
+ * input -
+ * output -
+ * side effects - clear the lists of paths
+ */
+void
+mod_clear_paths(void)
+{
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
+ {
+ MyFree(ptr->data);
+ free_dlink_node(ptr);
+ }
+
+ mod_paths.head = mod_paths.tail = NULL;
+ mod_paths.length = 0;
+}
+
+/* irc_basename
+ *
+ * input -
+ * output -
+ * side effects -
+ */
+char *
+irc_basename(const char *path)
+{
+ char *mod_basename = MyMalloc(strlen(path) + 1);
+ const char *s;
+
+ if(!(s = strrchr(path, '/')))
+ s = path;
+ else
+ s++;
+
+ (void) strcpy(mod_basename, s);
+ return mod_basename;
+}
+
+/* findmodule_byname
+ *
+ * input -
+ * output -
+ * side effects -
+ */
+
+int
+findmodule_byname(const char *name)
+{
+ int i;
+
+ for (i = 0; i < num_mods; i++)
+ {
+ if(!irccmp(modlist[i]->name, name))
+ return i;
+ }
+ return -1;
+}
+
+/* load_all_modules()
+ *
+ * input -
+ * output -
+ * side effects -
+ */
+void
+load_all_modules(int warn)
+{
+ DIR *system_module_dir = NULL;
+ struct dirent *ldirent = NULL;
+ char module_fq_name[PATH_MAX + 1];
+ int len;
+
+ modules_init();
+
+ modlist = (struct module **) MyMalloc(sizeof(struct module) * (MODS_INCREMENT));
+
+ max_mods = MODS_INCREMENT;
+
+ system_module_dir = opendir(AUTOMODPATH);
+
+ if(system_module_dir == NULL)
+ {
+ ilog(L_MAIN, "Could not load modules from %s: %s", AUTOMODPATH, strerror(errno));
+ return;
+ }
+
+ while ((ldirent = readdir(system_module_dir)) != NULL)
+ {
+ len = strlen(ldirent->d_name);
+ if((len > 3) && !strcmp(ldirent->d_name+len-3, SHARED_SUFFIX))
+ {
+ (void) ircsnprintf(module_fq_name, sizeof(module_fq_name), "%s/%s", AUTOMODPATH, ldirent->d_name);
+ (void) load_a_module(module_fq_name, warn, 0);
+ }
+
+ }
+ (void) closedir(system_module_dir);
+}
+
+/* load_core_modules()
+ *
+ * input -
+ * output -
+ * side effects - core modules are loaded, if any fail, kill ircd
+ */
+void
+load_core_modules(int warn)
+{
+ char module_name[MAXPATHLEN];
+ int i;
+
+
+ for (i = 0; core_module_table[i]; i++)
+ {
+ ircsnprintf(module_name, sizeof(module_name), "%s/%s%s", MODPATH,
+ core_module_table[i], SHARED_SUFFIX);
+
+ if(load_a_module(module_name, warn, 1) == -1)
+ {
+ ilog(L_MAIN,
+ "Error loading core module %s%s: terminating ircd",
+ core_module_table[i], SHARED_SUFFIX);
+ exit(0);
+ }
+ }
+}
+
+/* load_one_module()
+ *
+ * input -
+ * output -
+ * side effects -
+ */
+int
+load_one_module(const char *path, int coremodule)
+{
+ char modpath[MAXPATHLEN];
+ dlink_node *pathst;
+ struct module_path *mpath;
+
+ struct stat statbuf;
+
+ if (server_state_foreground == 1)
+ inotice("loading module %s ...", path);
+
+ DLINK_FOREACH(pathst, mod_paths.head)
+ {
+ mpath = pathst->data;
+
+ ircsnprintf(modpath, sizeof(modpath), "%s/%s", mpath->path, path);
+ if((strstr(modpath, "../") == NULL) && (strstr(modpath, "/..") == NULL))
+ {
+ if(stat(modpath, &statbuf) == 0)
+ {
+ if(S_ISREG(statbuf.st_mode))
+ {
+ /* Regular files only please */
+ if(coremodule)
+ return load_a_module(modpath, 1, 1);
+ else
+ return load_a_module(modpath, 1, 0);
+ }
+ }
+
+ }
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot locate module %s", path);
+ return -1;
+}
+
+
+/* load a module .. */
+static int
+mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
+{
+ char *m_bn;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ m_bn = irc_basename(parv[1]);
+
+ if(findmodule_byname(m_bn) != -1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is already loaded",
+ me.name, source_p->name, m_bn);
+ MyFree(m_bn);
+ return 0;
+ }
+
+ load_one_module(parv[1], 0);
+
+ MyFree(m_bn);
+
+ return 0;
+}
+
+
+/* unload a module .. */
+static int
+mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
+{
+ char *m_bn;
+ int modindex;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ m_bn = irc_basename(parv[1]);
+
+ if((modindex = findmodule_byname(m_bn)) == -1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn);
+ MyFree(m_bn);
+ return 0;
+ }
+
+ if(modlist[modindex]->core == 1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
+ me.name, source_p->name, m_bn);
+ MyFree(m_bn);
+ return 0;
+ }
+
+ if(unload_one_module(m_bn, 1) == -1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn);
+ }
+ MyFree(m_bn);
+ return 0;
+}
+
+/* unload and load in one! */
+static int
+mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
+{
+ char *m_bn;
+ int modindex;
+ int check_core;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ m_bn = irc_basename(parv[1]);
+
+ if((modindex = findmodule_byname(m_bn)) == -1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn);
+ MyFree(m_bn);
+ return 0;
+ }
+
+ check_core = modlist[modindex]->core;
+
+ if(unload_one_module(m_bn, 1) == -1)
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :Module %s is not loaded", me.name, source_p->name, m_bn);
+ MyFree(m_bn);
+ return 0;
+ }
+
+ if((load_one_module(parv[1], check_core) == -1) && check_core)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Error reloading core module: %s: terminating ircd", parv[1]);
+ ilog(L_MAIN, "Error loading core module %s: terminating ircd", parv[1]);
+ exit(0);
+ }
+
+ MyFree(m_bn);
+ return 0;
+}
+
+/* list modules .. */
+static int
+mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
+{
+ int i;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ for (i = 0; i < num_mods; i++)
+ {
+ if(parc > 1)
+ {
+ if(match(parv[1], modlist[i]->name))
+ {
+ sendto_one(source_p, form_str(RPL_MODLIST),
+ me.name, source_p->name,
+ modlist[i]->name,
+ modlist[i]->address,
+ modlist[i]->version, modlist[i]->core ? "(core)" : "");
+ }
+ }
+ else
+ {
+ sendto_one(source_p, form_str(RPL_MODLIST),
+ me.name, source_p->name, modlist[i]->name,
+ modlist[i]->address, modlist[i]->version,
+ modlist[i]->core ? "(core)" : "");
+ }
+ }
+
+ sendto_one(source_p, form_str(RPL_ENDOFMODLIST), me.name, source_p->name);
+ return 0;
+}
+
+/* unload and reload all modules */
+static int
+mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
+{
+ int modnum;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS),
+ me.name, source_p->name, "admin");
+ return 0;
+ }
+
+ sendto_one(source_p, ":%s NOTICE %s :Reloading all modules", me.name, parv[0]);
+
+ modnum = num_mods;
+ while (num_mods)
+ unload_one_module(modlist[0]->name, 0);
+
+ load_all_modules(0);
+ load_core_modules(0);
+ rehash(0);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Module Restart: %d modules unloaded, %d modules loaded",
+ modnum, num_mods);
+ ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
+ return 0;
+}
+
+
+
+#ifndef RTLD_NOW
+#define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
+#endif
+
+#ifdef CHARYBDIS_PROFILE
+# ifndef RTLD_PROFILE
+# warning libdl may not support profiling, sucks. :(
+# define RTLD_PROFILE 0
+# endif
+#endif
+
+static void increase_modlist(void);
+
+#define MODS_INCREMENT 10
+
+static char unknown_ver[] = "<unknown>";
+
+/* This file contains the core functions to use dynamic libraries.
+ * -TimeMr14C
+ */
+
+
+#ifdef HAVE_MACH_O_DYLD_H
+/*
+** jmallett's dl*(3) shims for NSModule(3) systems.
+*/
+#include <mach-o/dyld.h>
+
+#ifndef HAVE_DLOPEN
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
+#endif
+
+void undefinedErrorHandler(const char *);
+NSModule multipleErrorHandler(NSSymbol, NSModule, NSModule);
+void linkEditErrorHandler(NSLinkEditErrors, int, const char *, const char *);
+char *dlerror(void);
+void *dlopen(char *, int);
+int dlclose(void *);
+void *dlsym(void *, char *);
+
+static int firstLoad = TRUE;
+static int myDlError;
+static char *myErrorTable[] = { "Loading file as object failed\n",
+ "Loading file as object succeeded\n",
+ "Not a valid shared object\n",
+ "Architecture of object invalid on this architecture\n",
+ "Invalid or corrupt image\n",
+ "Could not access object\n",
+ "NSCreateObjectFileImageFromFile failed\n",
+ NULL
+};
+
+void
+undefinedErrorHandler(const char *symbolName)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Undefined symbol: %s", symbolName);
+ ilog(L_MAIN, "Undefined symbol: %s", symbolName);
+ return;
+}
+
+NSModule
+multipleErrorHandler(NSSymbol s, NSModule old, NSModule new)
+{
+ /* XXX
+ ** This results in substantial leaking of memory... Should free one
+ ** module, maybe?
+ */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Symbol `%s' found in `%s' and `%s'",
+ NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
+ ilog(L_MAIN, "Symbol `%s' found in `%s' and `%s'",
+ NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
+ /* We return which module should be considered valid, I believe */
+ return new;
+}
+
+void
+linkEditErrorHandler(NSLinkEditErrors errorClass, int errnum,
+ const char *fileName, const char *errorString)
+{
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link editor error: %s for %s", errorString, fileName);
+ ilog(L_MAIN, "Link editor error: %s for %s", errorString, fileName);
+ return;
+}
+
+char *
+dlerror(void)
+{
+ return myDlError == NSObjectFileImageSuccess ? NULL : myErrorTable[myDlError % 7];
+}
+
+void *
+dlopen(char *filename, int unused)
+{
+ NSObjectFileImage myImage;
+ NSModule myModule;
+
+ if(firstLoad)
+ {
+ /*
+ ** If we are loading our first symbol (huzzah!) we should go ahead
+ ** and install link editor error handling!
+ */
+ NSLinkEditErrorHandlers linkEditorErrorHandlers;
+
+ linkEditorErrorHandlers.undefined = undefinedErrorHandler;
+ linkEditorErrorHandlers.multiple = multipleErrorHandler;
+ linkEditorErrorHandlers.linkEdit = linkEditErrorHandler;
+ NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers);
+ firstLoad = FALSE;
+ }
+ myDlError = NSCreateObjectFileImageFromFile(filename, &myImage);
+ if(myDlError != NSObjectFileImageSuccess)
+ {
+ return NULL;
+ }
+ myModule = NSLinkModule(myImage, filename, NSLINKMODULE_OPTION_PRIVATE);
+ return (void *) myModule;
+}
+
+int
+dlclose(void *myModule)
+{
+ NSUnLinkModule(myModule, FALSE);
+ return 0;
+}
+
+void *
+dlsym(void *myModule, char *mySymbolName)
+{
+ NSSymbol mySymbol;
+
+ mySymbol = NSLookupSymbolInModule((NSModule) myModule, mySymbolName);
+ return NSAddressOfSymbol(mySymbol);
+}
+#endif
+#endif
+
+
+/*
+ * HPUX dl compat functions
+ */
+#if defined(HAVE_SHL_LOAD) && !defined(HAVE_DLOPEN)
+#define RTLD_LAZY BIND_DEFERRED
+#define RTLD_GLOBAL DYNAMIC_PATH
+#define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
+#define dlclose(handle) shl_unload((shl_t)(handle))
+#define dlsym(handle,name) hpux_dlsym(handle,name)
+#define dlerror() strerror(errno)
+
+static void *
+hpux_dlsym(void *handle, char *name)
+{
+ void *sym_addr;
+ if(!shl_findsym((shl_t *) & handle, name, TYPE_UNDEFINED, &sym_addr))
+ return sym_addr;
+ return NULL;
+}
+
+#endif
+
+/* unload_one_module()
+ *
+ * inputs - name of module to unload
+ * - 1 to say modules unloaded, 0 to not
+ * output - 0 if successful, -1 if error
+ * side effects - module is unloaded
+ */
+int
+unload_one_module(const char *name, int warn)
+{
+ int modindex;
+
+ if((modindex = findmodule_byname(name)) == -1)
+ return -1;
+
+ /*
+ ** XXX - The type system in C does not allow direct conversion between
+ ** data and function pointers, but as it happens, most C compilers will
+ ** safely do this, however it is a theoretical overlow to cast as we
+ ** must do here. I have library functions to take care of this, but
+ ** despite being more "correct" for the C language, this is more
+ ** practical. Removing the abuse of the ability to cast ANY pointer
+ ** to and from an integer value here will break some compilers.
+ ** -jmallett
+ */
+ /* Left the comment in but the code isn't here any more -larne */
+ switch (modlist[modindex]->mapi_version)
+ {
+ case 1:
+ {
+ struct mapi_mheader_av1 *mheader = modlist[modindex]->mapi_header;
+ if(mheader->mapi_command_list)
+ {
+ struct Message **m;
+ for (m = mheader->mapi_command_list; *m; ++m)
+ mod_del_cmd(*m);
+ }
+
+ /* hook events are never removed, we simply lose the
+ * ability to call them --fl
+ */
+ if(mheader->mapi_hfn_list)
+ {
+ mapi_hfn_list_av1 *m;
+ for (m = mheader->mapi_hfn_list; m->hapi_name; ++m)
+ remove_hook(m->hapi_name, m->fn);
+ }
+
+ if(mheader->mapi_unregister)
+ mheader->mapi_unregister();
+ break;
+ }
+ default:
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Unknown/unsupported MAPI version %d when unloading %s!",
+ modlist[modindex]->mapi_version, modlist[modindex]->name);
+ ilog(L_MAIN, "Unknown/unsupported MAPI version %d when unloading %s!",
+ modlist[modindex]->mapi_version, modlist[modindex]->name);
+ break;
+ }
+
+ dlclose(modlist[modindex]->address);
+
+ MyFree(modlist[modindex]->name);
+ memcpy(&modlist[modindex], &modlist[modindex + 1],
+ sizeof(struct module) * ((num_mods - 1) - modindex));
+
+ if(num_mods != 0)
+ num_mods--;
+
+ if(warn == 1)
+ {
+ ilog(L_MAIN, "Module %s unloaded", name);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Module %s unloaded", name);
+ }
+
+ return 0;
+}
+
+
+/*
+ * load_a_module()
+ *
+ * inputs - path name of module, int to notice, int of core
+ * output - -1 if error 0 if success
+ * side effects - loads a module if successful
+ */
+int
+load_a_module(const char *path, int warn, int core)
+{
+ void *tmpptr = NULL;
+
+ char *mod_basename;
+ const char *ver;
+
+ int *mapi_version;
+
+ mod_basename = irc_basename(path);
+
+#ifdef CHARYBDIS_PROFILE
+ tmpptr = dlopen(path, RTLD_NOW | RTLD_PROFILE);
+#else
+ tmpptr = dlopen(path, RTLD_NOW);
+#endif
+
+ if(tmpptr == NULL)
+ {
+ const char *err = dlerror();
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Error loading module %s: %s", mod_basename, err);
+ ilog(L_MAIN, "Error loading module %s: %s", mod_basename, err);
+ MyFree(mod_basename);
+ return -1;
+ }
+
+
+ /*
+ * _mheader is actually a struct mapi_mheader_*, but mapi_version
+ * is always the first member of this structure, so we treate it
+ * as a single int in order to determine the API version.
+ * -larne.
+ */
+ mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "_mheader");
+ if((mapi_version == NULL
+ && (mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "__mheader")) == NULL)
+ || MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Data format error: module %s has no MAPI header.",
+ mod_basename);
+ ilog(L_MAIN, "Data format error: module %s has no MAPI header.", mod_basename);
+ (void) dlclose(tmpptr);
+ MyFree(mod_basename);
+ return -1;
+ }
+
+ switch (MAPI_VERSION(*mapi_version))
+ {
+ case 1:
+ {
+ struct mapi_mheader_av1 *mheader = (struct mapi_mheader_av1 *) mapi_version; /* see above */
+ if(mheader->mapi_register && (mheader->mapi_register() == -1))
+ {
+ ilog(L_MAIN, "Module %s indicated failure during load.",
+ mod_basename);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Module %s indicated failure during load.",
+ mod_basename);
+ dlclose(tmpptr);
+ MyFree(mod_basename);
+ return -1;
+ }
+ if(mheader->mapi_command_list)
+ {
+ struct Message **m;
+ for (m = mheader->mapi_command_list; *m; ++m)
+ mod_add_cmd(*m);
+ }
+
+ if(mheader->mapi_hook_list)
+ {
+ mapi_hlist_av1 *m;
+ for (m = mheader->mapi_hook_list; m->hapi_name; ++m)
+ *m->hapi_id = register_hook(m->hapi_name);
+ }
+
+ if(mheader->mapi_hfn_list)
+ {
+ mapi_hfn_list_av1 *m;
+ for (m = mheader->mapi_hfn_list; m->hapi_name; ++m)
+ add_hook(m->hapi_name, m->fn);
+ }
+
+ ver = mheader->mapi_module_version;
+ break;
+ }
+
+ default:
+ ilog(L_MAIN, "Module %s has unknown/unsupported MAPI version %d.",
+ mod_basename, MAPI_VERSION(*mapi_version));
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Module %s has unknown/unsupported MAPI version %d.",
+ mod_basename, *mapi_version);
+ dlclose(tmpptr);
+ MyFree(mod_basename);
+ return -1;
+ }
+
+ if(ver == NULL)
+ ver = unknown_ver;
+
+ increase_modlist();
+
+ modlist[num_mods] = MyMalloc(sizeof(struct module));
+ modlist[num_mods]->address = tmpptr;
+ modlist[num_mods]->version = ver;
+ modlist[num_mods]->core = core;
+ DupString(modlist[num_mods]->name, mod_basename);
+ modlist[num_mods]->mapi_header = mapi_version;
+ modlist[num_mods]->mapi_version = MAPI_VERSION(*mapi_version);
+ num_mods++;
+
+ if(warn == 1)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
+ mod_basename, ver, MAPI_VERSION(*mapi_version),
+ (unsigned long) tmpptr);
+ ilog(L_MAIN, "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
+ mod_basename, ver, MAPI_VERSION(*mapi_version), (unsigned long) tmpptr);
+ }
+ MyFree(mod_basename);
+ return 0;
+}
+
+/*
+ * increase_modlist
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects - expand the size of modlist if necessary
+ */
+static void
+increase_modlist(void)
+{
+ struct module **new_modlist = NULL;
+
+ if((num_mods + 1) < max_mods)
+ return;
+
+ new_modlist = (struct module **) MyMalloc(sizeof(struct module) *
+ (max_mods + MODS_INCREMENT));
+ memcpy((void *) new_modlist, (void *) modlist, sizeof(struct module) * num_mods);
+
+ MyFree(modlist);
+ modlist = new_modlist;
+ max_mods += MODS_INCREMENT;
+}
+
+#else /* STATIC_MODULES */
+
+/* load_all_modules()
+ *
+ * input -
+ * output -
+ * side effects - all the msgtabs are added for static modules
+ */
+void
+load_all_modules(int warn)
+{
+ load_static_modules();
+}
+
+#endif /* STATIC_MODULES */
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * monitor.c - Code for server-side notify lists
+ *
+ * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
+ * Copyright (C) 2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: monitor.c 312 2005-11-07 10:47:33Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "memory.h"
+#include "balloc.h"
+#include "monitor.h"
+#include "hash.h"
+#include "event.h"
+#include "numeric.h"
+
+static struct monitor *monitorTable[MONITOR_HASH_SIZE];
+BlockHeap *monitor_heap;
+
+static void cleanup_monitor(void *unused);
+
+void
+init_monitor(void)
+{
+ monitor_heap = BlockHeapCreate(sizeof(struct monitor), MONITOR_HEAP_SIZE);
+ eventAddIsh("cleanup_monitor", cleanup_monitor, NULL, 3600);
+}
+
+static inline unsigned int
+hash_monitor_nick(const char *name)
+{
+ return fnv_hash_upper((const unsigned char *) name, MONITOR_HASH_BITS);
+}
+
+struct monitor *
+find_monitor(const char *name, int add)
+{
+ struct monitor *monptr;
+
+ unsigned int hashv = hash_monitor_nick(name);
+
+ for(monptr = monitorTable[hashv]; monptr; monptr = monptr->hnext)
+ {
+ if(!irccmp(monptr->name, name))
+ return monptr;
+ }
+
+ if(add)
+ {
+ monptr = BlockHeapAlloc(monitor_heap);
+ strlcpy(monptr->name, name, sizeof(monptr->name));
+
+ monptr->hnext = monitorTable[hashv];
+ monitorTable[hashv] = monptr;
+
+ return monptr;
+ }
+
+ return NULL;
+}
+
+/* monitor_signon()
+ *
+ * inputs - client who has just connected
+ * outputs -
+ * side effects - notifies any clients monitoring this nickname that it has
+ * connected to the network
+ */
+void
+monitor_signon(struct Client *client_p)
+{
+ char buf[USERHOST_REPLYLEN];
+ struct monitor *monptr = find_monitor(client_p->name, 0);
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ /* noones watching this nick */
+ if(monptr == NULL)
+ return;
+
+ ircsnprintf(buf, sizeof(buf), "%s!%s@%s",
+ client_p->name, client_p->username, client_p->host);
+
+ DLINK_FOREACH(ptr, monptr->users.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p, form_str(RPL_MONONLINE),
+ me.name, target_p->name, buf);
+ }
+}
+
+/* monitor_signoff()
+ *
+ * inputs - client who is exiting
+ * outputs -
+ * side effects - notifies any clients monitoring this nickname that it has
+ * left the network
+ */
+void
+monitor_signoff(struct Client *client_p)
+{
+ struct monitor *monptr = find_monitor(client_p->name, 0);
+ dlink_node *ptr;
+
+ /* noones watching this nick */
+ if(monptr == NULL)
+ return;
+
+ DLINK_FOREACH(ptr, monptr->users.head)
+ {
+ sendto_one(ptr->data, form_str(RPL_MONOFFLINE),
+ me.name, ((struct Client *) ptr->data)->name, client_p->name);
+ }
+}
+
+void
+clear_monitor(struct Client *client_p)
+{
+ struct monitor *monptr;
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->monitor_list.head)
+ {
+ monptr = ptr->data;
+
+ /* we leave the actual entry around with no users, itll be
+ * cleaned up periodically by cleanup_monitor() --anfl
+ */
+ dlinkFindDestroy(client_p, &monptr->users);
+ free_dlink_node(ptr);
+ }
+
+ client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;
+ client_p->localClient->monitor_list.length = 0;
+}
+
+static void
+cleanup_monitor(void *unused)
+{
+ struct monitor *last_ptr = NULL;
+ struct monitor *next_ptr, *ptr;
+ int i;
+
+ for(i = 0; i < MONITOR_HASH_SIZE; i++)
+ {
+ last_ptr = NULL;
+ for(ptr = monitorTable[i]; ptr; ptr = next_ptr)
+ {
+ next_ptr = ptr->hnext;
+
+ if(!dlink_list_length(&ptr->users))
+ {
+ if(last_ptr)
+ last_ptr->hnext = next_ptr;
+ else
+ monitorTable[i] = next_ptr;
+
+ BlockHeapFree(monitor_heap, ptr);
+ }
+ else
+ last_ptr = ptr;
+ }
+ }
+}
--- /dev/null
+/* This code is in the public domain.
+ * $Id: newconf.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#endif
+
+#include "memory.h"
+#include "newconf.h"
+#include "tools.h"
+#include "ircd_defs.h"
+#include "sprintf_irc.h"
+#include "common.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "s_user.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "setup.h"
+#include "modules.h"
+#include "listener.h"
+#include "hostmask.h"
+#include "s_serv.h"
+#include "event.h"
+#include "hash.h"
+#include "cache.h"
+#include "ircd.h"
+#include "snomask.h"
+#include "blacklist.h"
+
+#define CF_TYPE(x) ((x) & CF_MTYPE)
+
+struct TopConf *conf_cur_block;
+static char *conf_cur_block_name;
+
+static dlink_list conf_items;
+
+static struct ConfItem *yy_aconf = NULL;
+
+static struct Class *yy_class = NULL;
+
+static struct remote_conf *yy_shared = NULL;
+static struct server_conf *yy_server = NULL;
+
+static dlink_list yy_aconf_list;
+static dlink_list yy_oper_list;
+static dlink_list yy_shared_list;
+static dlink_list yy_cluster_list;
+static struct oper_conf *yy_oper = NULL;
+
+static struct alias_entry *yy_alias = NULL;
+
+static char *yy_blacklist_host = NULL;
+static char *yy_blacklist_reason = NULL;
+
+static const char *
+conf_strtype(int type)
+{
+ switch (type & CF_MTYPE)
+ {
+ case CF_INT:
+ return "integer value";
+ case CF_STRING:
+ return "unquoted string";
+ case CF_YESNO:
+ return "yes/no value";
+ case CF_QSTRING:
+ return "quoted string";
+ case CF_TIME:
+ return "time/size value";
+ default:
+ return "unknown type";
+ }
+}
+
+int
+add_top_conf(const char *name, int (*sfunc) (struct TopConf *),
+ int (*efunc) (struct TopConf *), struct ConfEntry *items)
+{
+ struct TopConf *tc;
+
+ tc = MyMalloc(sizeof(struct TopConf));
+
+ DupString(tc->tc_name, name);
+ tc->tc_sfunc = sfunc;
+ tc->tc_efunc = efunc;
+ tc->tc_entries = items;
+
+ dlinkAddAlloc(tc, &conf_items);
+ return 0;
+}
+
+struct TopConf *
+find_top_conf(const char *name)
+{
+ dlink_node *d;
+ struct TopConf *tc;
+
+ DLINK_FOREACH(d, conf_items.head)
+ {
+ tc = d->data;
+ if(strcasecmp(tc->tc_name, name) == 0)
+ return tc;
+ }
+
+ return NULL;
+}
+
+
+struct ConfEntry *
+find_conf_item(const struct TopConf *top, const char *name)
+{
+ struct ConfEntry *cf;
+ dlink_node *d;
+
+ if(top->tc_entries)
+ {
+ int i;
+
+ for(i = 0; top->tc_entries[i].cf_type; i++)
+ {
+ cf = &top->tc_entries[i];
+
+ if(!strcasecmp(cf->cf_name, name))
+ return cf;
+ }
+ }
+
+ DLINK_FOREACH(d, top->tc_items.head)
+ {
+ cf = d->data;
+ if(strcasecmp(cf->cf_name, name) == 0)
+ return cf;
+ }
+
+ return NULL;
+}
+
+int
+remove_top_conf(char *name)
+{
+ struct TopConf *tc;
+ dlink_node *ptr;
+
+ if((tc = find_top_conf(name)) == NULL)
+ return -1;
+
+ if((ptr = dlinkFind(tc, &conf_items)) == NULL)
+ return -1;
+
+ dlinkDestroy(ptr, &conf_items);
+ MyFree(tc->tc_name);
+ MyFree(tc);
+
+ return 0;
+}
+
+static void
+conf_set_serverinfo_name(void *data)
+{
+ if(ServerInfo.name == NULL)
+ {
+ const char *s;
+ int dots = 0;
+
+ for(s = data; *s != '\0'; s++)
+ {
+ if(!IsServChar(*s))
+ {
+ conf_report_error("Ignoring serverinfo::name "
+ "-- bogus servername.");
+ return;
+ }
+ else if(*s == '.')
+ ++dots;
+ }
+
+ if(!dots)
+ {
+ conf_report_error("Ignoring serverinfo::name -- must contain '.'");
+ return;
+ }
+
+ s = data;
+
+ if(IsDigit(*s))
+ {
+ conf_report_error("Ignoring serverinfo::name -- cannot begin with digit.");
+ return;
+ }
+
+ /* the ircd will exit() in main() if we dont set one */
+ if(strlen(s) <= HOSTLEN)
+ DupString(ServerInfo.name, (char *) data);
+ }
+}
+
+static void
+conf_set_serverinfo_sid(void *data)
+{
+ char *sid = data;
+
+ if(ServerInfo.sid[0] == '\0')
+ {
+ if(!IsDigit(sid[0]) || !IsIdChar(sid[1]) ||
+ !IsIdChar(sid[2]) || sid[3] != '\0')
+ {
+ conf_report_error("Ignoring serverinfo::sid "
+ "-- bogus sid.");
+ return;
+ }
+
+ strcpy(ServerInfo.sid, sid);
+ }
+}
+
+static void
+conf_set_serverinfo_network_name(void *data)
+{
+ char *p;
+
+ if((p = strchr((char *) data, ' ')))
+ *p = '\0';
+
+ MyFree(ServerInfo.network_name);
+ DupString(ServerInfo.network_name, (char *) data);
+}
+
+static void
+conf_set_serverinfo_vhost(void *data)
+{
+ if(inetpton(AF_INET, (char *) data, &ServerInfo.ip.sin_addr) <= 0)
+ {
+ conf_report_error("Invalid netmask for server IPv4 vhost (%s)", (char *) data);
+ return;
+ }
+ ServerInfo.ip.sin_family = AF_INET;
+ ServerInfo.specific_ipv4_vhost = 1;
+}
+
+static void
+conf_set_serverinfo_vhost6(void *data)
+{
+#ifdef IPV6
+ if(inetpton(AF_INET6, (char *) data, &ServerInfo.ip6.sin6_addr) <= 0)
+ {
+ conf_report_error("Invalid netmask for server IPv6 vhost (%s)", (char *) data);
+ return;
+ }
+
+ ServerInfo.specific_ipv6_vhost = 1;
+ ServerInfo.ip6.sin6_family = AF_INET6;
+#else
+ conf_report_error("Warning -- ignoring serverinfo::vhost6 -- IPv6 support not available.");
+#endif
+}
+
+static void
+conf_set_modules_module(void *data)
+{
+#ifndef STATIC_MODULES
+ char *m_bn;
+
+ m_bn = irc_basename((char *) data);
+
+ if(findmodule_byname(m_bn) != -1)
+ return;
+
+ load_one_module((char *) data, 0);
+
+ MyFree(m_bn);
+#else
+ conf_report_error("Ignoring modules::module -- loadable module support not present.");
+#endif
+}
+
+static void
+conf_set_modules_path(void *data)
+{
+#ifndef STATIC_MODULES
+ mod_add_path((char *) data);
+#else
+ conf_report_error("Ignoring modules::path -- loadable module support not present.");
+#endif
+}
+
+struct mode_table
+{
+ const char *name;
+ int mode;
+};
+
+/* *INDENT-OFF* */
+static struct mode_table umode_table[] = {
+ {"callerid", UMODE_CALLERID },
+ {"deaf", UMODE_DEAF },
+ {"invisible", UMODE_INVISIBLE },
+ {"locops", UMODE_LOCOPS },
+ {"noforward", UMODE_NOFORWARD },
+ {"regonlymsg", UMODE_REGONLYMSG},
+ {"servnotice", UMODE_SERVNOTICE},
+ {"wallop", UMODE_WALLOP },
+ {"operwall", UMODE_OPERWALL },
+ {NULL, 0}
+};
+
+static struct mode_table flag_table[] = {
+ {"encrypted", OPER_ENCRYPTED },
+ {"local_kill", OPER_LOCKILL },
+ {"global_kill", OPER_GLOBKILL|OPER_LOCKILL },
+ {"remote", OPER_REMOTE },
+ {"kline", OPER_KLINE },
+ {"unkline", OPER_UNKLINE },
+ {"gline", OPER_GLINE },
+ {"nick_changes", OPER_NICKS },
+ {"rehash", OPER_REHASH },
+ {"die", OPER_DIE },
+ {"admin", OPER_ADMIN },
+ {"hidden_admin", OPER_HADMIN },
+ {"xline", OPER_XLINE },
+ {"operwall", OPER_OPERWALL },
+ {"oper_spy", OPER_SPY },
+ {"hidden_oper", OPER_INVIS },
+ {"remoteban", OPER_REMOTEBAN },
+ {NULL, 0}
+};
+
+static struct mode_table auth_table[] = {
+ {"encrypted", CONF_FLAGS_ENCRYPTED },
+ {"spoof_notice", CONF_FLAGS_SPOOF_NOTICE },
+ {"exceed_limit", CONF_FLAGS_NOLIMIT },
+ {"dnsbl_exempt", CONF_FLAGS_EXEMPTDNSBL },
+ {"kline_exempt", CONF_FLAGS_EXEMPTKLINE },
+ {"gline_exempt", CONF_FLAGS_EXEMPTGLINE },
+ {"flood_exempt", CONF_FLAGS_EXEMPTFLOOD },
+ {"spambot_exempt", CONF_FLAGS_EXEMPTSPAMBOT },
+ {"shide_exempt", CONF_FLAGS_EXEMPTSHIDE },
+ {"jupe_exempt", CONF_FLAGS_EXEMPTJUPE },
+ {"resv_exempt", CONF_FLAGS_EXEMPTRESV },
+ {"no_tilde", CONF_FLAGS_NO_TILDE },
+ {"need_ident", CONF_FLAGS_NEED_IDENTD },
+ {"have_ident", CONF_FLAGS_NEED_IDENTD },
+ {"need_sasl", CONF_FLAGS_NEED_SASL },
+ {NULL, 0}
+};
+
+static struct mode_table connect_table[] = {
+ { "autoconn", SERVER_AUTOCONN },
+ { "compressed", SERVER_COMPRESSED },
+ { "encrypted", SERVER_ENCRYPTED },
+ { "topicburst", SERVER_TB },
+ { NULL, 0 },
+};
+
+static struct mode_table cluster_table[] = {
+ { "kline", SHARED_PKLINE },
+ { "tkline", SHARED_TKLINE },
+ { "unkline", SHARED_UNKLINE },
+ { "locops", SHARED_LOCOPS },
+ { "xline", SHARED_PXLINE },
+ { "txline", SHARED_TXLINE },
+ { "unxline", SHARED_UNXLINE },
+ { "resv", SHARED_PRESV },
+ { "tresv", SHARED_TRESV },
+ { "unresv", SHARED_UNRESV },
+ { "all", CLUSTER_ALL },
+ {NULL, 0}
+};
+
+static struct mode_table shared_table[] =
+{
+ { "kline", SHARED_PKLINE|SHARED_TKLINE },
+ { "xline", SHARED_PXLINE|SHARED_TXLINE },
+ { "resv", SHARED_PRESV|SHARED_TRESV },
+ { "tkline", SHARED_TKLINE },
+ { "unkline", SHARED_UNKLINE },
+ { "txline", SHARED_TXLINE },
+ { "unxline", SHARED_UNXLINE },
+ { "tresv", SHARED_TRESV },
+ { "unresv", SHARED_UNRESV },
+ { "locops", SHARED_LOCOPS },
+ { "rehash", SHARED_REHASH },
+ { "all", SHARED_ALL },
+ { "none", 0 },
+ {NULL, 0}
+};
+/* *INDENT-ON* */
+
+static int
+find_umode(struct mode_table *tab, const char *name)
+{
+ int i;
+
+ for (i = 0; tab[i].name; i++)
+ {
+ if(strcmp(tab[i].name, name) == 0)
+ return tab[i].mode;
+ }
+
+ return -1;
+}
+
+static void
+set_modes_from_table(int *modes, const char *whatis, struct mode_table *tab, conf_parm_t * args)
+{
+ for (; args; args = args->next)
+ {
+ const char *umode;
+ int dir = 1;
+ int mode;
+
+ if((args->type & CF_MTYPE) != CF_STRING)
+ {
+ conf_report_error("Warning -- %s is not a string; ignoring.", whatis);
+ continue;
+ }
+
+ umode = args->v.string;
+
+ if(*umode == '~')
+ {
+ dir = 0;
+ umode++;
+ }
+
+ mode = find_umode(tab, umode);
+
+ if(mode == -1)
+ {
+ conf_report_error("Warning -- unknown %s %s.", whatis, args->v.string);
+ continue;
+ }
+
+ if(mode)
+ {
+ if(dir)
+ *modes |= mode;
+ else
+ *modes &= ~mode;
+ }
+ else
+ *modes = 0;
+ }
+}
+
+static int
+conf_begin_oper(struct TopConf *tc)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(yy_oper != NULL)
+ {
+ free_oper_conf(yy_oper);
+ yy_oper = NULL;
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_oper_list.head)
+ {
+ free_oper_conf(ptr->data);
+ dlinkDestroy(ptr, &yy_oper_list);
+ }
+
+ yy_oper = make_oper_conf();
+ yy_oper->flags |= OPER_ENCRYPTED|OPER_OPERWALL|OPER_REMOTEBAN;
+
+ return 0;
+}
+
+static int
+conf_end_oper(struct TopConf *tc)
+{
+ struct oper_conf *yy_tmpoper;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(conf_cur_block_name != NULL)
+ {
+ if(strlen(conf_cur_block_name) > OPERNICKLEN)
+ conf_cur_block_name[OPERNICKLEN] = '\0';
+
+ DupString(yy_oper->name, conf_cur_block_name);
+ }
+
+ if(EmptyString(yy_oper->name))
+ {
+ conf_report_error("Ignoring operator block -- missing name.");
+ return 0;
+ }
+
+#ifdef HAVE_LIBCRYPTO
+ if(EmptyString(yy_oper->passwd) && EmptyString(yy_oper->rsa_pubkey_file))
+#else
+ if(EmptyString(yy_oper->passwd))
+#endif
+ {
+ conf_report_error("Ignoring operator block for %s -- missing password",
+ yy_oper->name);
+ return 0;
+ }
+
+ /* now, yy_oper_list contains a stack of oper_conf's with just user
+ * and host in, yy_oper contains the rest of the information which
+ * we need to copy into each element in yy_oper_list
+ */
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_oper_list.head)
+ {
+ yy_tmpoper = ptr->data;
+
+ DupString(yy_tmpoper->name, yy_oper->name);
+
+ /* could be an rsa key instead.. */
+ if(!EmptyString(yy_oper->passwd))
+ DupString(yy_tmpoper->passwd, yy_oper->passwd);
+
+ yy_tmpoper->flags = yy_oper->flags;
+ yy_tmpoper->umodes = yy_oper->umodes;
+ yy_tmpoper->snomask = yy_oper->snomask;
+
+#ifdef HAVE_LIBCRYPTO
+ if(yy_oper->rsa_pubkey_file)
+ {
+ BIO *file;
+
+ if((file = BIO_new_file(yy_oper->rsa_pubkey_file, "r")) == NULL)
+ {
+ conf_report_error("Ignoring operator block for %s -- "
+ "rsa_public_key_file cant be opened",
+ yy_tmpoper->name);
+ return 0;
+ }
+
+ yy_tmpoper->rsa_pubkey =
+ (RSA *) PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
+
+ BIO_set_close(file, BIO_CLOSE);
+ BIO_free(file);
+
+ if(yy_tmpoper->rsa_pubkey == NULL)
+ {
+ conf_report_error("Ignoring operator block for %s -- "
+ "rsa_public_key_file key invalid; check syntax",
+ yy_tmpoper->name);
+ return 0;
+ }
+ }
+#endif
+
+ /* all is ok, put it on oper_conf_list */
+ dlinkMoveNode(ptr, &yy_oper_list, &oper_conf_list);
+ }
+
+ free_oper_conf(yy_oper);
+ yy_oper = NULL;
+
+ return 0;
+}
+
+static void
+conf_set_oper_flags(void *data)
+{
+ conf_parm_t *args = data;
+
+ set_modes_from_table(&yy_oper->flags, "flag", flag_table, args);
+}
+
+static void
+conf_set_oper_user(void *data)
+{
+ struct oper_conf *yy_tmpoper;
+ char *p;
+ char *host = (char *) data;
+
+ yy_tmpoper = make_oper_conf();
+
+ if((p = strchr(host, '@')))
+ {
+ *p++ = '\0';
+
+ DupString(yy_tmpoper->username, host);
+ DupString(yy_tmpoper->host, p);
+ }
+ else
+ {
+
+ DupString(yy_tmpoper->username, "*");
+ DupString(yy_tmpoper->host, host);
+ }
+
+ if(EmptyString(yy_tmpoper->username) || EmptyString(yy_tmpoper->host))
+ {
+ conf_report_error("Ignoring user -- missing username/host");
+ free_oper_conf(yy_tmpoper);
+ return;
+ }
+
+ dlinkAddAlloc(yy_tmpoper, &yy_oper_list);
+}
+
+static void
+conf_set_oper_password(void *data)
+{
+ if(yy_oper->passwd)
+ {
+ memset(yy_oper->passwd, 0, strlen(yy_oper->passwd));
+ MyFree(yy_oper->passwd);
+ }
+
+ DupString(yy_oper->passwd, (char *) data);
+}
+
+static void
+conf_set_oper_rsa_public_key_file(void *data)
+{
+#ifdef HAVE_LIBCRYPTO
+ MyFree(yy_oper->rsa_pubkey_file);
+ DupString(yy_oper->rsa_pubkey_file, (char *) data);
+#else
+ conf_report_error("Warning -- ignoring rsa_public_key_file (OpenSSL support not available");
+#endif
+}
+
+static void
+conf_set_oper_umodes(void *data)
+{
+ set_modes_from_table(&yy_oper->umodes, "umode", umode_table, data);
+}
+
+static void
+conf_set_oper_snomask(void *data)
+{
+ yy_oper->snomask = parse_snobuf_to_mask(0, (const char *) data);
+}
+
+static int
+conf_begin_class(struct TopConf *tc)
+{
+ if(yy_class)
+ free_class(yy_class);
+
+ yy_class = make_class();
+ return 0;
+}
+
+static int
+conf_end_class(struct TopConf *tc)
+{
+ if(conf_cur_block_name != NULL)
+ DupString(yy_class->class_name, conf_cur_block_name);
+
+ if(EmptyString(yy_class->class_name))
+ {
+ conf_report_error("Ignoring connect block -- missing name.");
+ return 0;
+ }
+
+ add_class(yy_class);
+ yy_class = NULL;
+ return 0;
+}
+
+static void
+conf_set_class_ping_time(void *data)
+{
+ yy_class->ping_freq = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_cidr_bitlen(void *data)
+{
+#ifdef IPV6
+ unsigned int maxsize = 128;
+#else
+ unsigned int maxsize = 32;
+#endif
+ if(*(unsigned int *) data > maxsize)
+ conf_report_error
+ ("class::cidr_bitlen argument exceeds maxsize (%d > %d) - ignoring.",
+ *(unsigned int *) data, maxsize);
+ else
+ yy_class->cidr_bitlen = *(unsigned int *) data;
+
+}
+static void
+conf_set_class_number_per_cidr(void *data)
+{
+ yy_class->cidr_amount = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_number_per_ip(void *data)
+{
+ yy_class->max_local = *(unsigned int *) data;
+}
+
+
+static void
+conf_set_class_number_per_ip_global(void *data)
+{
+ yy_class->max_global = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_number_per_ident(void *data)
+{
+ yy_class->max_ident = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_connectfreq(void *data)
+{
+ yy_class->con_freq = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_max_number(void *data)
+{
+ yy_class->max_total = *(unsigned int *) data;
+}
+
+static void
+conf_set_class_sendq(void *data)
+{
+ yy_class->max_sendq = *(unsigned int *) data;
+}
+
+static char *listener_address;
+
+static int
+conf_begin_listen(struct TopConf *tc)
+{
+ MyFree(listener_address);
+ listener_address = NULL;
+ return 0;
+}
+
+static int
+conf_end_listen(struct TopConf *tc)
+{
+ MyFree(listener_address);
+ listener_address = NULL;
+ return 0;
+}
+
+static void
+conf_set_listen_port(void *data)
+{
+ conf_parm_t *args = data;
+ for (; args; args = args->next)
+ {
+ if((args->type & CF_MTYPE) != CF_INT)
+ {
+ conf_report_error
+ ("listener::port argument is not an integer " "-- ignoring.");
+ continue;
+ }
+ if(listener_address == NULL)
+ {
+ add_listener(args->v.number, listener_address, AF_INET);
+#ifdef IPV6
+ add_listener(args->v.number, listener_address, AF_INET6);
+#endif
+ }
+ else
+ {
+ int family;
+#ifdef IPV6
+ if(strchr(listener_address, ':') != NULL)
+ family = AF_INET6;
+ else
+#endif
+ family = AF_INET;
+
+ add_listener(args->v.number, listener_address, family);
+
+ }
+
+ }
+}
+
+static void
+conf_set_listen_address(void *data)
+{
+ MyFree(listener_address);
+ DupString(listener_address, data);
+}
+
+static int
+conf_begin_auth(struct TopConf *tc)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(yy_aconf)
+ free_conf(yy_aconf);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_aconf_list.head)
+ {
+ free_conf(ptr->data);
+ dlinkDestroy(ptr, &yy_aconf_list);
+ }
+
+ yy_aconf = make_conf();
+ yy_aconf->status = CONF_CLIENT;
+
+ return 0;
+}
+
+static int
+conf_end_auth(struct TopConf *tc)
+{
+ struct ConfItem *yy_tmp;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ if(EmptyString(yy_aconf->name))
+ DupString(yy_aconf->name, "NOMATCH");
+
+ /* didnt even get one ->host? */
+ if(EmptyString(yy_aconf->host))
+ {
+ conf_report_error("Ignoring auth block -- missing user@host");
+ return 0;
+ }
+
+ /* so the stacking works in order.. */
+ collapse(yy_aconf->user);
+ collapse(yy_aconf->host);
+ conf_add_class_to_conf(yy_aconf);
+ add_conf_by_address(yy_aconf->host, CONF_CLIENT, yy_aconf->user, yy_aconf);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_aconf_list.head)
+ {
+ yy_tmp = ptr->data;
+
+ if(yy_aconf->passwd)
+ DupString(yy_tmp->passwd, yy_aconf->passwd);
+
+ /* this will always exist.. */
+ DupString(yy_tmp->name, yy_aconf->name);
+
+ if(yy_aconf->className)
+ DupString(yy_tmp->className, yy_aconf->className);
+
+ yy_tmp->flags = yy_aconf->flags;
+ yy_tmp->port = yy_aconf->port;
+
+ collapse(yy_tmp->user);
+ collapse(yy_tmp->host);
+
+ conf_add_class_to_conf(yy_tmp);
+
+ add_conf_by_address(yy_tmp->host, CONF_CLIENT, yy_tmp->user, yy_tmp);
+ dlinkDestroy(ptr, &yy_aconf_list);
+ }
+
+ yy_aconf = NULL;
+ return 0;
+}
+
+static void
+conf_set_auth_user(void *data)
+{
+ struct ConfItem *yy_tmp;
+ char *p;
+
+ /* The first user= line doesn't allocate a new conf */
+ if(!EmptyString(yy_aconf->host))
+ {
+ yy_tmp = make_conf();
+ yy_tmp->status = CONF_CLIENT;
+ }
+ else
+ yy_tmp = yy_aconf;
+
+ if((p = strchr(data, '@')))
+ {
+ *p++ = '\0';
+
+ DupString(yy_tmp->user, data);
+ DupString(yy_tmp->host, p);
+ }
+ else
+ {
+ DupString(yy_tmp->user, "*");
+ DupString(yy_tmp->host, data);
+ }
+
+ if(yy_aconf != yy_tmp)
+ dlinkAddAlloc(yy_tmp, &yy_aconf_list);
+}
+
+static void
+conf_set_auth_passwd(void *data)
+{
+ if(yy_aconf->passwd)
+ memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
+ MyFree(yy_aconf->passwd);
+ DupString(yy_aconf->passwd, data);
+}
+
+static void
+conf_set_auth_spoof(void *data)
+{
+ char *p;
+ char *user = NULL;
+ char *host = NULL;
+
+ host = data;
+
+ /* user@host spoof */
+ if((p = strchr(host, '@')) != NULL)
+ {
+ *p = '\0';
+ user = data;
+ host = p+1;
+
+ if(EmptyString(user))
+ {
+ conf_report_error("Warning -- spoof ident empty.");
+ return;
+ }
+
+ if(strlen(user) > USERLEN)
+ {
+ conf_report_error("Warning -- spoof ident length invalid.");
+ return;
+ }
+
+ if(!valid_username(user))
+ {
+ conf_report_error("Warning -- invalid spoof (ident).");
+ return;
+ }
+
+ /* this must be restored! */
+ *p = '@';
+ }
+
+ if(EmptyString(host))
+ {
+ conf_report_error("Warning -- spoof host empty.");
+ return;
+ }
+
+ if(strlen(host) > HOSTLEN)
+ {
+ conf_report_error("Warning -- spoof host length invalid.");
+ return;
+ }
+
+ if(!valid_hostname(host))
+ {
+ conf_report_error("Warning -- invalid spoof (host).");
+ return;
+ }
+
+ MyFree(yy_aconf->name);
+ DupString(yy_aconf->name, data);
+ yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
+}
+
+static void
+conf_set_auth_flags(void *data)
+{
+ conf_parm_t *args = data;
+
+ set_modes_from_table((int *) &yy_aconf->flags, "flag", auth_table, args);
+}
+
+static void
+conf_set_auth_redir_serv(void *data)
+{
+ yy_aconf->flags |= CONF_FLAGS_REDIR;
+ MyFree(yy_aconf->name);
+ DupString(yy_aconf->name, data);
+}
+
+static void
+conf_set_auth_redir_port(void *data)
+{
+ int port = *(unsigned int *) data;
+
+ yy_aconf->flags |= CONF_FLAGS_REDIR;
+ yy_aconf->port = port;
+}
+
+static void
+conf_set_auth_class(void *data)
+{
+ MyFree(yy_aconf->className);
+ DupString(yy_aconf->className, data);
+}
+
+/* ok, shared_oper handles the stacking, shared_flags handles adding
+ * things.. so all we need to do when we start and end a shared block, is
+ * clean up anything thats been left over.
+ */
+static int
+conf_cleanup_shared(struct TopConf *tc)
+{
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_shared_list.head)
+ {
+ free_remote_conf(ptr->data);
+ dlinkDestroy(ptr, &yy_shared_list);
+ }
+
+ if(yy_shared != NULL)
+ {
+ free_remote_conf(yy_shared);
+ yy_shared = NULL;
+ }
+
+ return 0;
+}
+
+static void
+conf_set_shared_oper(void *data)
+{
+ conf_parm_t *args = data;
+ const char *username;
+ char *p;
+
+ if(yy_shared != NULL)
+ free_remote_conf(yy_shared);
+
+ yy_shared = make_remote_conf();
+
+ if(args->next != NULL)
+ {
+ if((args->type & CF_MTYPE) != CF_QSTRING)
+ {
+ conf_report_error("Ignoring shared::oper -- server is not a qstring");
+ return;
+ }
+
+ DupString(yy_shared->server, args->v.string);
+ args = args->next;
+ }
+ else
+ DupString(yy_shared->server, "*");
+
+ if((args->type & CF_MTYPE) != CF_QSTRING)
+ {
+ conf_report_error("Ignoring shared::oper -- oper is not a qstring");
+ return;
+ }
+
+ if((p = strchr(args->v.string, '@')) == NULL)
+ {
+ conf_report_error("Ignoring shard::oper -- oper is not a user@host");
+ return;
+ }
+
+ username = args->v.string;
+ *p++ = '\0';
+
+ if(EmptyString(p))
+ DupString(yy_shared->host, "*");
+ else
+ DupString(yy_shared->host, p);
+
+ if(EmptyString(username))
+ DupString(yy_shared->username, "*");
+ else
+ DupString(yy_shared->username, username);
+
+ dlinkAddAlloc(yy_shared, &yy_shared_list);
+ yy_shared = NULL;
+}
+
+static void
+conf_set_shared_flags(void *data)
+{
+ conf_parm_t *args = data;
+ int flags = 0;
+ dlink_node *ptr, *next_ptr;
+
+ if(yy_shared != NULL)
+ free_remote_conf(yy_shared);
+
+ set_modes_from_table(&flags, "flag", shared_table, args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_shared_list.head)
+ {
+ yy_shared = ptr->data;
+
+ yy_shared->flags = flags;
+ dlinkDestroy(ptr, &yy_shared_list);
+ dlinkAddTail(yy_shared, &yy_shared->node, &shared_conf_list);
+ }
+
+ yy_shared = NULL;
+}
+
+static int
+conf_begin_connect(struct TopConf *tc)
+{
+ if(yy_server)
+ free_server_conf(yy_server);
+
+ yy_server = make_server_conf();
+ yy_server->port = PORTNUM;
+
+ if(conf_cur_block_name != NULL)
+ DupString(yy_server->name, conf_cur_block_name);
+
+ return 0;
+}
+
+static int
+conf_end_connect(struct TopConf *tc)
+{
+ if(EmptyString(yy_server->name))
+ {
+ conf_report_error("Ignoring connect block -- missing name.");
+ return 0;
+ }
+
+ if(ServerInfo.name != NULL && !irccmp(ServerInfo.name, yy_server->name))
+ {
+ conf_report_error("Ignoring connect block for %s -- name is equal to my own name.",
+ yy_server->name);
+ return 0;
+ }
+
+ if(EmptyString(yy_server->passwd) || EmptyString(yy_server->spasswd))
+ {
+ conf_report_error("Ignoring connect block for %s -- missing password.",
+ yy_server->name);
+ return 0;
+ }
+
+ if(EmptyString(yy_server->host))
+ {
+ conf_report_error("Ignoring connect block for %s -- missing host.",
+ yy_server->name);
+ return 0;
+ }
+
+#ifndef HAVE_LIBZ
+ if(ServerConfCompressed(yy_server))
+ {
+ conf_report_error("Ignoring connect::flags::compressed -- zlib not available.");
+ yy_server->flags &= ~SERVER_COMPRESSED;
+ }
+#endif
+
+ add_server_conf(yy_server);
+ dlinkAdd(yy_server, &yy_server->node, &server_conf_list);
+
+ yy_server = NULL;
+ return 0;
+}
+
+static void
+conf_set_connect_host(void *data)
+{
+ MyFree(yy_server->host);
+ DupString(yy_server->host, data);
+ if (strchr(yy_server->host, ':'))
+ yy_server->aftype = AF_INET6;
+}
+
+static void
+conf_set_connect_vhost(void *data)
+{
+ if(inetpton_sock(data, (struct sockaddr *)&yy_server->my_ipnum) <= 0)
+ {
+ conf_report_error("Invalid netmask for server vhost (%s)",
+ (char *) data);
+ return;
+ }
+
+ yy_server->flags |= SERVER_VHOSTED;
+}
+
+static void
+conf_set_connect_send_password(void *data)
+{
+ if(yy_server->spasswd)
+ {
+ memset(yy_server->spasswd, 0, strlen(yy_server->spasswd));
+ MyFree(yy_server->spasswd);
+ }
+
+ DupString(yy_server->spasswd, data);
+}
+
+static void
+conf_set_connect_accept_password(void *data)
+{
+ if(yy_server->passwd)
+ {
+ memset(yy_server->passwd, 0, strlen(yy_server->passwd));
+ MyFree(yy_server->passwd);
+ }
+ DupString(yy_server->passwd, data);
+}
+
+static void
+conf_set_connect_port(void *data)
+{
+ int port = *(unsigned int *) data;
+
+ if(port < 1)
+ port = PORTNUM;
+
+ yy_server->port = port;
+}
+
+static void
+conf_set_connect_aftype(void *data)
+{
+ char *aft = data;
+
+ if(strcasecmp(aft, "ipv4") == 0)
+ yy_server->aftype = AF_INET;
+#ifdef IPV6
+ else if(strcasecmp(aft, "ipv6") == 0)
+ yy_server->aftype = AF_INET6;
+#endif
+ else
+ conf_report_error("connect::aftype '%s' is unknown.", aft);
+}
+
+static void
+conf_set_connect_flags(void *data)
+{
+ conf_parm_t *args = data;
+
+ /* note, we allow them to set compressed, then remove it later if
+ * they do and LIBZ isnt available
+ */
+ set_modes_from_table(&yy_server->flags, "flag", connect_table, args);
+}
+
+static void
+conf_set_connect_hub_mask(void *data)
+{
+ struct remote_conf *yy_hub;
+
+ if(EmptyString(yy_server->name))
+ return;
+
+ yy_hub = make_remote_conf();
+ yy_hub->flags = CONF_HUB;
+
+ DupString(yy_hub->host, data);
+ DupString(yy_hub->server, yy_server->name);
+ dlinkAdd(yy_hub, &yy_hub->node, &hubleaf_conf_list);
+}
+
+static void
+conf_set_connect_leaf_mask(void *data)
+{
+ struct remote_conf *yy_leaf;
+
+ if(EmptyString(yy_server->name))
+ return;
+
+ yy_leaf = make_remote_conf();
+ yy_leaf->flags = CONF_LEAF;
+
+ DupString(yy_leaf->host, data);
+ DupString(yy_leaf->server, yy_server->name);
+ dlinkAdd(yy_leaf, &yy_leaf->node, &hubleaf_conf_list);
+}
+
+static void
+conf_set_connect_class(void *data)
+{
+ MyFree(yy_server->class_name);
+ DupString(yy_server->class_name, data);
+}
+
+static void
+conf_set_exempt_ip(void *data)
+{
+ struct ConfItem *yy_tmp;
+
+ if(parse_netmask(data, NULL, NULL) == HM_HOST)
+ {
+ conf_report_error("Ignoring exempt -- invalid exempt::ip.");
+ return;
+ }
+
+ yy_tmp = make_conf();
+ DupString(yy_tmp->passwd, "*");
+ DupString(yy_tmp->host, data);
+ yy_tmp->status = CONF_EXEMPTDLINE;
+ add_conf_by_address(yy_tmp->host, CONF_EXEMPTDLINE, NULL, yy_tmp);
+}
+
+static int
+conf_cleanup_cluster(struct TopConf *tc)
+{
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_cluster_list.head)
+ {
+ free_remote_conf(ptr->data);
+ dlinkDestroy(ptr, &yy_cluster_list);
+ }
+
+ if(yy_shared != NULL)
+ {
+ free_remote_conf(yy_shared);
+ yy_shared = NULL;
+ }
+
+ return 0;
+}
+
+static void
+conf_set_cluster_name(void *data)
+{
+ if(yy_shared != NULL)
+ free_remote_conf(yy_shared);
+
+ yy_shared = make_remote_conf();
+ DupString(yy_shared->server, data);
+ dlinkAddAlloc(yy_shared, &yy_cluster_list);
+
+ yy_shared = NULL;
+}
+
+static void
+conf_set_cluster_flags(void *data)
+{
+ conf_parm_t *args = data;
+ int flags = 0;
+ dlink_node *ptr, *next_ptr;
+
+ if(yy_shared != NULL)
+ free_remote_conf(yy_shared);
+
+ set_modes_from_table(&flags, "flag", cluster_table, args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, yy_cluster_list.head)
+ {
+ yy_shared = ptr->data;
+ yy_shared->flags = flags;
+ dlinkAddTail(yy_shared, &yy_shared->node, &cluster_conf_list);
+ dlinkDestroy(ptr, &yy_cluster_list);
+ }
+
+ yy_shared = NULL;
+}
+
+static void
+conf_set_general_havent_read_conf(void *data)
+{
+ if(*(unsigned int *) data)
+ {
+ conf_report_error("You haven't read your config file properly.");
+ conf_report_error
+ ("There is a line in the example conf that will kill your server if not removed.");
+ conf_report_error
+ ("Consider actually reading/editing the conf file, and removing this line.");
+ if (!testing_conf)
+ exit(0);
+ }
+}
+
+static void
+conf_set_general_hide_error_messages(void *data)
+{
+ char *val = data;
+
+ if(strcasecmp(val, "yes") == 0)
+ ConfigFileEntry.hide_error_messages = 2;
+ else if(strcasecmp(val, "opers") == 0)
+ ConfigFileEntry.hide_error_messages = 1;
+ else if(strcasecmp(val, "no") == 0)
+ ConfigFileEntry.hide_error_messages = 0;
+ else
+ conf_report_error("Invalid setting '%s' for general::hide_error_messages.", val);
+}
+
+static void
+conf_set_general_kline_delay(void *data)
+{
+ ConfigFileEntry.kline_delay = *(unsigned int *) data;
+
+ /* THIS MUST BE HERE to stop us being unable to check klines */
+ kline_queued = 0;
+}
+
+static void
+conf_set_general_stats_k_oper_only(void *data)
+{
+ char *val = data;
+
+ if(strcasecmp(val, "yes") == 0)
+ ConfigFileEntry.stats_k_oper_only = 2;
+ else if(strcasecmp(val, "masked") == 0)
+ ConfigFileEntry.stats_k_oper_only = 1;
+ else if(strcasecmp(val, "no") == 0)
+ ConfigFileEntry.stats_k_oper_only = 0;
+ else
+ conf_report_error("Invalid setting '%s' for general::stats_k_oper_only.", val);
+}
+
+static void
+conf_set_general_stats_i_oper_only(void *data)
+{
+ char *val = data;
+
+ if(strcasecmp(val, "yes") == 0)
+ ConfigFileEntry.stats_i_oper_only = 2;
+ else if(strcasecmp(val, "masked") == 0)
+ ConfigFileEntry.stats_i_oper_only = 1;
+ else if(strcasecmp(val, "no") == 0)
+ ConfigFileEntry.stats_i_oper_only = 0;
+ else
+ conf_report_error("Invalid setting '%s' for general::stats_i_oper_only.", val);
+}
+
+static void
+conf_set_general_compression_level(void *data)
+{
+#ifdef HAVE_LIBZ
+ ConfigFileEntry.compression_level = *(unsigned int *) data;
+
+ if((ConfigFileEntry.compression_level < 1) || (ConfigFileEntry.compression_level > 9))
+ {
+ conf_report_error
+ ("Invalid general::compression_level %d -- using default.",
+ ConfigFileEntry.compression_level);
+ ConfigFileEntry.compression_level = 0;
+ }
+#else
+ conf_report_error("Ignoring general::compression_level -- zlib not available.");
+#endif
+}
+
+static void
+conf_set_general_default_umodes(void *data)
+{
+ char *pm;
+ int what = MODE_ADD, flag;
+
+ ConfigFileEntry.default_umodes = 0;
+ for (pm = (char *) data; *pm; pm++)
+ {
+ switch (*pm)
+ {
+ case '+':
+ what = MODE_ADD;
+ break;
+ case '-':
+ what = MODE_DEL;
+ break;
+
+ /* don't allow +o */
+ case 'o':
+ case 'S':
+ case ' ':
+ break;
+
+ default:
+ if ((flag = user_modes[(unsigned char) *pm]))
+ {
+ /* Proper value has probably not yet been set
+ * so don't check oper_only_umodes -- jilles */
+ if (what == MODE_ADD)
+ ConfigFileEntry.default_umodes |= flag;
+ else
+ ConfigFileEntry.default_umodes &= ~flag;
+ }
+ break;
+ }
+ }
+}
+
+static void
+conf_set_general_oper_umodes(void *data)
+{
+ set_modes_from_table(&ConfigFileEntry.oper_umodes, "umode", umode_table, data);
+}
+
+static void
+conf_set_general_oper_only_umodes(void *data)
+{
+ set_modes_from_table(&ConfigFileEntry.oper_only_umodes, "umode", umode_table, data);
+}
+
+static void
+conf_set_general_oper_snomask(void *data)
+{
+ char *pm;
+ int what = MODE_ADD, flag;
+
+ ConfigFileEntry.oper_snomask = 0;
+ for (pm = (char *) data; *pm; pm++)
+ {
+ switch (*pm)
+ {
+ case '+':
+ what = MODE_ADD;
+ break;
+ case '-':
+ what = MODE_DEL;
+ break;
+
+ default:
+ if ((flag = snomask_modes[(unsigned char) *pm]))
+ {
+ if (what == MODE_ADD)
+ ConfigFileEntry.oper_snomask |= flag;
+ else
+ ConfigFileEntry.oper_snomask &= ~flag;
+ }
+ break;
+ }
+ }
+}
+
+static void
+conf_set_serverhide_links_delay(void *data)
+{
+ int val = *(unsigned int *) data;
+
+ if((val > 0) && ConfigServerHide.links_disabled == 1)
+ {
+ eventAddIsh("cache_links", cache_links, NULL, val);
+ ConfigServerHide.links_disabled = 0;
+ }
+ else if(val != ConfigServerHide.links_delay)
+ eventUpdate("cache_links", val);
+
+ ConfigServerHide.links_delay = val;
+}
+
+static int
+conf_begin_service(struct TopConf *tc)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ target_p->flags &= ~FLAGS_SERVICE;
+ }
+
+ return 0;
+}
+
+static void
+conf_set_service_name(void *data)
+{
+ struct Client *target_p;
+ const char *s;
+ char *tmp;
+ int dots = 0;
+
+ for(s = data; *s != '\0'; s++)
+ {
+ if(!IsServChar(*s))
+ {
+ conf_report_error("Ignoring service::name "
+ "-- bogus servername.");
+ return;
+ }
+ else if(*s == '.')
+ dots++;
+ }
+
+ if(!dots)
+ {
+ conf_report_error("Ignoring service::name -- must contain '.'");
+ return;
+ }
+
+ DupString(tmp, data);
+ dlinkAddAlloc(tmp, &service_list);
+
+ if((target_p = find_server(NULL, tmp)))
+ target_p->flags |= FLAGS_SERVICE;
+}
+
+static int
+alias_hash(const char *p)
+{
+ int hash_val = 0;
+
+ while (*p)
+ {
+ hash_val += ((int) (*p) & 0xDF);
+ p++;
+ }
+
+ return (hash_val % MAX_MSG_HASH);
+}
+
+static int
+conf_begin_alias(struct TopConf *tc)
+{
+ yy_alias = MyMalloc(sizeof(struct alias_entry));
+
+ if (conf_cur_block_name != NULL)
+ DupString(yy_alias->name, conf_cur_block_name);
+
+ yy_alias->flags = 0;
+ yy_alias->hits = 0;
+
+ return 0;
+}
+
+static int
+conf_end_alias(struct TopConf *tc)
+{
+ int hashval;
+
+ if (yy_alias == NULL)
+ return -1;
+
+ if (yy_alias->name == NULL)
+ {
+ conf_report_error("Ignoring alias -- must have a name.");
+
+ MyFree(yy_alias);
+
+ return -1;
+ }
+
+ if (yy_alias->target == NULL)
+ {
+ conf_report_error("Ignoring alias -- must have a target.");
+
+ MyFree(yy_alias);
+
+ return -1;
+ }
+
+ hashval = alias_hash(yy_alias->name);
+
+ dlinkAddAlloc(yy_alias, &alias_hash_table[hashval]);
+
+ return 0;
+}
+
+static void
+conf_set_alias_name(void *data)
+{
+ if (data == NULL || yy_alias == NULL) /* this shouldn't ever happen */
+ return;
+
+ DupString(yy_alias->name, data);
+}
+
+static void
+conf_set_alias_target(void *data)
+{
+ if (data == NULL || yy_alias == NULL) /* this shouldn't ever happen */
+ return;
+
+ DupString(yy_alias->target, data);
+}
+
+static void
+conf_set_blacklist_host(void *data)
+{
+ DupString(yy_blacklist_host, data);
+}
+
+static void
+conf_set_blacklist_reason(void *data)
+{
+ DupString(yy_blacklist_reason, data);
+
+ if (yy_blacklist_host && yy_blacklist_reason)
+ {
+ new_blacklist(yy_blacklist_host, yy_blacklist_reason);
+ MyFree(yy_blacklist_host);
+ MyFree(yy_blacklist_reason);
+ yy_blacklist_host = NULL;
+ yy_blacklist_reason = NULL;
+ }
+}
+
+/* public functions */
+
+
+void
+conf_report_error(const char *fmt, ...)
+{
+ va_list ap;
+ char msg[IRCD_BUFSIZE + 1] = { 0 };
+
+ va_start(ap, fmt);
+ ircvsnprintf(msg, IRCD_BUFSIZE, fmt, ap);
+ va_end(ap);
+
+ if (testing_conf)
+ {
+ fprintf(stderr, "\"%s\", line %d: %s\n", current_file, lineno + 1, msg);
+ return;
+ }
+
+ ierror("\"%s\", line %d: %s", current_file, lineno + 1, msg);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "\"%s\", line %d: %s", current_file, lineno + 1, msg);
+}
+
+int
+conf_start_block(char *block, char *name)
+{
+ if((conf_cur_block = find_top_conf(block)) == NULL)
+ {
+ conf_report_error("Configuration block '%s' is not defined.", block);
+ return -1;
+ }
+
+ if(name)
+ DupString(conf_cur_block_name, name);
+ else
+ conf_cur_block_name = NULL;
+
+ if(conf_cur_block->tc_sfunc)
+ if(conf_cur_block->tc_sfunc(conf_cur_block) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+conf_end_block(struct TopConf *tc)
+{
+ if(tc->tc_efunc)
+ return tc->tc_efunc(tc);
+
+ MyFree(conf_cur_block_name);
+ return 0;
+}
+
+static void
+conf_set_generic_int(void *data, void *location)
+{
+ *((int *) location) = *((unsigned int *) data);
+}
+
+static void
+conf_set_generic_string(void *data, int len, void *location)
+{
+ char **loc = location;
+ char *input = data;
+
+ if(len && strlen(input) > len)
+ input[len] = '\0';
+
+ MyFree(*loc);
+ DupString(*loc, input);
+}
+
+int
+conf_call_set(struct TopConf *tc, char *item, conf_parm_t * value, int type)
+{
+ struct ConfEntry *cf;
+ conf_parm_t *cp;
+
+ if(!tc)
+ return -1;
+
+ if((cf = find_conf_item(tc, item)) == NULL)
+ {
+ conf_report_error
+ ("Non-existant configuration setting %s::%s.", tc->tc_name, (char *) item);
+ return -1;
+ }
+
+ /* if it takes one thing, make sure they only passed one thing,
+ and handle as needed. */
+ if(value->type & CF_FLIST && !cf->cf_type & CF_FLIST)
+ {
+ conf_report_error
+ ("Option %s::%s does not take a list of values.", tc->tc_name, item);
+ return -1;
+ }
+
+ cp = value->v.list;
+
+
+ if(CF_TYPE(value->v.list->type) != CF_TYPE(cf->cf_type))
+ {
+ /* if it expects a string value, but we got a yesno,
+ * convert it back
+ */
+ if((CF_TYPE(value->v.list->type) == CF_YESNO) &&
+ (CF_TYPE(cf->cf_type) == CF_STRING))
+ {
+ value->v.list->type = CF_STRING;
+
+ if(cp->v.number == 1)
+ DupString(cp->v.string, "yes");
+ else
+ DupString(cp->v.string, "no");
+ }
+
+ /* maybe it's a CF_TIME and they passed CF_INT --
+ should still be valid */
+ else if(!((CF_TYPE(value->v.list->type) == CF_INT) &&
+ (CF_TYPE(cf->cf_type) == CF_TIME)))
+ {
+ conf_report_error
+ ("Wrong type for %s::%s (expected %s, got %s)",
+ tc->tc_name, (char *) item,
+ conf_strtype(cf->cf_type), conf_strtype(value->v.list->type));
+ return -1;
+ }
+ }
+
+ if(cf->cf_type & CF_FLIST)
+ {
+#if 0
+ if(cf->cf_arg)
+ conf_set_generic_list(value->v.list, cf->cf_arg);
+ else
+#endif
+ /* just pass it the extended argument list */
+ cf->cf_func(value->v.list);
+ }
+ else
+ {
+ /* it's old-style, needs only one arg */
+ switch (cf->cf_type)
+ {
+ case CF_INT:
+ case CF_TIME:
+ case CF_YESNO:
+ if(cf->cf_arg)
+ conf_set_generic_int(&cp->v.number, cf->cf_arg);
+ else
+ cf->cf_func(&cp->v.number);
+ break;
+ case CF_STRING:
+ case CF_QSTRING:
+ if(EmptyString(cp->v.string))
+ conf_report_error("Ignoring %s::%s -- empty field",
+ tc->tc_name, item);
+ else if(cf->cf_arg)
+ conf_set_generic_string(cp->v.string, cf->cf_len, cf->cf_arg);
+ else
+ cf->cf_func(cp->v.string);
+ break;
+ }
+ }
+
+
+ return 0;
+}
+
+int
+add_conf_item(const char *topconf, const char *name, int type, void (*func) (void *))
+{
+ struct TopConf *tc;
+ struct ConfEntry *cf;
+
+ if((tc = find_top_conf(topconf)) == NULL)
+ return -1;
+
+ if((cf = find_conf_item(tc, name)) != NULL)
+ return -1;
+
+ cf = MyMalloc(sizeof(struct ConfEntry));
+
+ DupString(cf->cf_name, name);
+ cf->cf_type = type;
+ cf->cf_func = func;
+ cf->cf_arg = NULL;
+
+ dlinkAddAlloc(cf, &tc->tc_items);
+
+ return 0;
+}
+
+int
+remove_conf_item(const char *topconf, const char *name)
+{
+ struct TopConf *tc;
+ struct ConfEntry *cf;
+ dlink_node *ptr;
+
+ if((tc = find_top_conf(topconf)) == NULL)
+ return -1;
+
+ if((cf = find_conf_item(tc, name)) == NULL)
+ return -1;
+
+ if((ptr = dlinkFind(cf, &tc->tc_items)) == NULL)
+ return -1;
+
+ dlinkDestroy(ptr, &tc->tc_items);
+ MyFree(cf);
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+static struct ConfEntry conf_serverinfo_table[] =
+{
+ { "description", CF_QSTRING, NULL, 0, &ServerInfo.description },
+ { "network_desc", CF_QSTRING, NULL, 0, &ServerInfo.network_desc },
+ { "hub", CF_YESNO, NULL, 0, &ServerInfo.hub },
+ { "use_ts6", CF_YESNO, NULL, 0, &ServerInfo.use_ts6 },
+
+ { "network_name", CF_QSTRING, conf_set_serverinfo_network_name, 0, NULL },
+ { "name", CF_QSTRING, conf_set_serverinfo_name, 0, NULL },
+ { "sid", CF_QSTRING, conf_set_serverinfo_sid, 0, NULL },
+ { "vhost", CF_QSTRING, conf_set_serverinfo_vhost, 0, NULL },
+ { "vhost6", CF_QSTRING, conf_set_serverinfo_vhost6, 0, NULL },
+
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_admin_table[] =
+{
+ { "name", CF_QSTRING, NULL, 200, &AdminInfo.name },
+ { "description",CF_QSTRING, NULL, 200, &AdminInfo.description },
+ { "email", CF_QSTRING, NULL, 200, &AdminInfo.email },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_log_table[] =
+{
+ { "fname_userlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_userlog },
+ { "fname_fuserlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_fuserlog },
+ { "fname_operlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_operlog },
+ { "fname_foperlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_foperlog },
+ { "fname_serverlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_serverlog },
+ { "fname_killlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_killlog },
+ { "fname_glinelog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_glinelog },
+ { "fname_klinelog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_klinelog },
+ { "fname_operspylog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_operspylog },
+ { "fname_ioerrorlog", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.fname_ioerrorlog },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_operator_table[] =
+{
+ { "rsa_public_key_file", CF_QSTRING, conf_set_oper_rsa_public_key_file, 0, NULL },
+ { "flags", CF_STRING | CF_FLIST, conf_set_oper_flags, 0, NULL },
+ { "umodes", CF_STRING | CF_FLIST, conf_set_oper_umodes, 0, NULL },
+ { "snomask", CF_QSTRING, conf_set_oper_snomask, 0, NULL },
+ { "user", CF_QSTRING, conf_set_oper_user, 0, NULL },
+ { "password", CF_QSTRING, conf_set_oper_password, 0, NULL },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_class_table[] =
+{
+ { "ping_time", CF_TIME, conf_set_class_ping_time, 0, NULL },
+ { "cidr_bitlen", CF_INT, conf_set_class_cidr_bitlen, 0, NULL },
+ { "number_per_cidr", CF_INT, conf_set_class_number_per_cidr, 0, NULL },
+ { "number_per_ip", CF_INT, conf_set_class_number_per_ip, 0, NULL },
+ { "number_per_ip_global", CF_INT,conf_set_class_number_per_ip_global, 0, NULL },
+ { "number_per_ident", CF_INT, conf_set_class_number_per_ident, 0, NULL },
+ { "connectfreq", CF_TIME, conf_set_class_connectfreq, 0, NULL },
+ { "max_number", CF_INT, conf_set_class_max_number, 0, NULL },
+ { "sendq", CF_TIME, conf_set_class_sendq, 0, NULL },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_auth_table[] =
+{
+ { "user", CF_QSTRING, conf_set_auth_user, 0, NULL },
+ { "password", CF_QSTRING, conf_set_auth_passwd, 0, NULL },
+ { "class", CF_QSTRING, conf_set_auth_class, 0, NULL },
+ { "spoof", CF_QSTRING, conf_set_auth_spoof, 0, NULL },
+ { "redirserv", CF_QSTRING, conf_set_auth_redir_serv, 0, NULL },
+ { "redirport", CF_INT, conf_set_auth_redir_port, 0, NULL },
+ { "flags", CF_STRING | CF_FLIST, conf_set_auth_flags, 0, NULL },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_connect_table[] =
+{
+ { "send_password", CF_QSTRING, conf_set_connect_send_password, 0, NULL },
+ { "accept_password", CF_QSTRING, conf_set_connect_accept_password, 0, NULL },
+ { "flags", CF_STRING | CF_FLIST, conf_set_connect_flags, 0, NULL },
+ { "host", CF_QSTRING, conf_set_connect_host, 0, NULL },
+ { "vhost", CF_QSTRING, conf_set_connect_vhost, 0, NULL },
+ { "port", CF_INT, conf_set_connect_port, 0, NULL },
+ { "aftype", CF_STRING, conf_set_connect_aftype, 0, NULL },
+ { "hub_mask", CF_QSTRING, conf_set_connect_hub_mask, 0, NULL },
+ { "leaf_mask", CF_QSTRING, conf_set_connect_leaf_mask, 0, NULL },
+ { "class", CF_QSTRING, conf_set_connect_class, 0, NULL },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_general_table[] =
+{
+ { "oper_only_umodes", CF_STRING | CF_FLIST, conf_set_general_oper_only_umodes, 0, NULL },
+ { "oper_umodes", CF_STRING | CF_FLIST, conf_set_general_oper_umodes, 0, NULL },
+ { "oper_snomask", CF_QSTRING, conf_set_general_oper_snomask, 0, NULL },
+ { "compression_level", CF_INT, conf_set_general_compression_level, 0, NULL },
+ { "havent_read_conf", CF_YESNO, conf_set_general_havent_read_conf, 0, NULL },
+ { "hide_error_messages",CF_STRING, conf_set_general_hide_error_messages,0, NULL },
+ { "kline_delay", CF_TIME, conf_set_general_kline_delay, 0, NULL },
+ { "stats_k_oper_only", CF_STRING, conf_set_general_stats_k_oper_only, 0, NULL },
+ { "stats_i_oper_only", CF_STRING, conf_set_general_stats_i_oper_only, 0, NULL },
+ { "default_umodes", CF_QSTRING, conf_set_general_default_umodes, 0, NULL },
+
+ { "default_operstring", CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.default_operstring },
+ { "default_adminstring",CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.default_adminstring },
+ { "servicestring", CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.servicestring },
+ { "egdpool_path", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.egdpool_path },
+ { "kline_reason", CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.kline_reason },
+ { "identify_service", CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.identifyservice },
+ { "identify_command", CF_QSTRING, NULL, REALLEN, &ConfigFileEntry.identifycommand },
+ { "servlink_path", CF_QSTRING, NULL, MAXPATHLEN, &ConfigFileEntry.servlink_path },
+
+ { "anti_spam_exit_message_time", CF_TIME, NULL, 0, &ConfigFileEntry.anti_spam_exit_message_time },
+ { "disable_fake_channels", CF_YESNO, NULL, 0, &ConfigFileEntry.disable_fake_channels },
+ { "min_nonwildcard_simple", CF_INT, NULL, 0, &ConfigFileEntry.min_nonwildcard_simple },
+ { "non_redundant_klines", CF_YESNO, NULL, 0, &ConfigFileEntry.non_redundant_klines },
+ { "tkline_expire_notices", CF_YESNO, NULL, 0, &ConfigFileEntry.tkline_expire_notices },
+
+ { "anti_nick_flood", CF_YESNO, NULL, 0, &ConfigFileEntry.anti_nick_flood },
+ { "burst_away", CF_YESNO, NULL, 0, &ConfigFileEntry.burst_away },
+ { "caller_id_wait", CF_TIME, NULL, 0, &ConfigFileEntry.caller_id_wait },
+ { "client_exit", CF_YESNO, NULL, 0, &ConfigFileEntry.client_exit },
+ { "client_flood", CF_INT, NULL, 0, &ConfigFileEntry.client_flood },
+ { "collision_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc },
+ { "connect_timeout", CF_TIME, NULL, 0, &ConfigFileEntry.connect_timeout },
+ { "default_floodcount", CF_INT, NULL, 0, &ConfigFileEntry.default_floodcount },
+ { "disable_auth", CF_YESNO, NULL, 0, &ConfigFileEntry.disable_auth },
+ { "dot_in_ip6_addr", CF_YESNO, NULL, 0, &ConfigFileEntry.dot_in_ip6_addr },
+ { "dots_in_ident", CF_INT, NULL, 0, &ConfigFileEntry.dots_in_ident },
+ { "failed_oper_notice", CF_YESNO, NULL, 0, &ConfigFileEntry.failed_oper_notice },
+ { "glines", CF_YESNO, NULL, 0, &ConfigFileEntry.glines },
+ { "gline_min_cidr", CF_INT, NULL, 0, &ConfigFileEntry.gline_min_cidr },
+ { "gline_min_cidr6", CF_INT, NULL, 0, &ConfigFileEntry.gline_min_cidr6 },
+ { "gline_time", CF_TIME, NULL, 0, &ConfigFileEntry.gline_time },
+ { "global_snotices", CF_YESNO, NULL, 0, &ConfigFileEntry.global_snotices },
+ { "idletime", CF_TIME, NULL, 0, &ConfigFileEntry.idletime },
+ { "hide_spoof_ips", CF_YESNO, NULL, 0, &ConfigFileEntry.hide_spoof_ips },
+ { "dline_with_reason", CF_YESNO, NULL, 0, &ConfigFileEntry.dline_with_reason },
+ { "kline_with_reason", CF_YESNO, NULL, 0, &ConfigFileEntry.kline_with_reason },
+ { "map_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.map_oper_only },
+ { "max_accept", CF_INT, NULL, 0, &ConfigFileEntry.max_accept },
+ { "max_monitor", CF_INT, NULL, 0, &ConfigFileEntry.max_monitor },
+ { "max_nick_time", CF_TIME, NULL, 0, &ConfigFileEntry.max_nick_time },
+ { "max_nick_changes", CF_INT, NULL, 0, &ConfigFileEntry.max_nick_changes },
+ { "max_targets", CF_INT, NULL, 0, &ConfigFileEntry.max_targets },
+ { "min_nonwildcard", CF_INT, NULL, 0, &ConfigFileEntry.min_nonwildcard },
+ { "nick_delay", CF_TIME, NULL, 0, &ConfigFileEntry.nick_delay },
+ { "no_oper_flood", CF_YESNO, NULL, 0, &ConfigFileEntry.no_oper_flood },
+ { "operspy_admin_only", CF_YESNO, NULL, 0, &ConfigFileEntry.operspy_admin_only },
+ { "operspy_dont_care_user_info", CF_YESNO, NULL, 0, &ConfigFileEntry.operspy_dont_care_user_info },
+ { "pace_wait", CF_TIME, NULL, 0, &ConfigFileEntry.pace_wait },
+ { "pace_wait_simple", CF_TIME, NULL, 0, &ConfigFileEntry.pace_wait_simple },
+ { "ping_cookie", CF_YESNO, NULL, 0, &ConfigFileEntry.ping_cookie },
+ { "reject_after_count", CF_INT, NULL, 0, &ConfigFileEntry.reject_after_count },
+ { "reject_ban_time", CF_TIME, NULL, 0, &ConfigFileEntry.reject_ban_time },
+ { "reject_duration", CF_TIME, NULL, 0, &ConfigFileEntry.reject_duration },
+ { "short_motd", CF_YESNO, NULL, 0, &ConfigFileEntry.short_motd },
+ { "stats_c_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_c_oper_only },
+ { "stats_e_disabled", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_e_disabled },
+ { "stats_h_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_h_oper_only },
+ { "stats_o_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_o_oper_only },
+ { "stats_P_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_P_oper_only },
+ { "stats_y_oper_only", CF_YESNO, NULL, 0, &ConfigFileEntry.stats_y_oper_only },
+ { "target_change", CF_YESNO, NULL, 0, &ConfigFileEntry.target_change },
+ { "ts_max_delta", CF_TIME, NULL, 0, &ConfigFileEntry.ts_max_delta },
+ { "use_egd", CF_YESNO, NULL, 0, &ConfigFileEntry.use_egd },
+ { "ts_warn_delta", CF_TIME, NULL, 0, &ConfigFileEntry.ts_warn_delta },
+ { "use_whois_actually", CF_YESNO, NULL, 0, &ConfigFileEntry.use_whois_actually },
+ { "warn_no_nline", CF_YESNO, NULL, 0, &ConfigFileEntry.warn_no_nline },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_channel_table[] =
+{
+ { "default_split_user_count", CF_INT, NULL, 0, &ConfigChannel.default_split_user_count },
+ { "default_split_server_count", CF_INT, NULL, 0, &ConfigChannel.default_split_server_count },
+ { "burst_topicwho", CF_YESNO, NULL, 0, &ConfigChannel.burst_topicwho },
+ { "invite_ops_only", CF_YESNO, NULL, 0, &ConfigChannel.invite_ops_only },
+ { "kick_on_split_riding", CF_YESNO, NULL, 0, &ConfigChannel.kick_on_split_riding },
+ { "knock_delay", CF_TIME, NULL, 0, &ConfigChannel.knock_delay },
+ { "knock_delay_channel",CF_TIME, NULL, 0, &ConfigChannel.knock_delay_channel },
+ { "max_bans", CF_INT, NULL, 0, &ConfigChannel.max_bans },
+ { "max_bans_large", CF_INT, NULL, 0, &ConfigChannel.max_bans_large },
+ { "max_chans_per_user", CF_INT, NULL, 0, &ConfigChannel.max_chans_per_user },
+ { "no_create_on_split", CF_YESNO, NULL, 0, &ConfigChannel.no_create_on_split },
+ { "no_join_on_split", CF_YESNO, NULL, 0, &ConfigChannel.no_join_on_split },
+ { "use_except", CF_YESNO, NULL, 0, &ConfigChannel.use_except },
+ { "use_invex", CF_YESNO, NULL, 0, &ConfigChannel.use_invex },
+ { "use_knock", CF_YESNO, NULL, 0, &ConfigChannel.use_knock },
+ { "use_forward", CF_YESNO, NULL, 0, &ConfigChannel.use_forward },
+ { "\0", 0, NULL, 0, NULL }
+};
+
+static struct ConfEntry conf_serverhide_table[] =
+{
+ { "disable_hidden", CF_YESNO, NULL, 0, &ConfigServerHide.disable_hidden },
+ { "flatten_links", CF_YESNO, NULL, 0, &ConfigServerHide.flatten_links },
+ { "hidden", CF_YESNO, NULL, 0, &ConfigServerHide.hidden },
+ { "links_delay", CF_TIME, conf_set_serverhide_links_delay, 0, NULL },
+ { "\0", 0, NULL, 0, NULL }
+};
+/* *INDENT-ON* */
+
+void
+newconf_init()
+{
+ add_top_conf("modules", NULL, NULL, NULL);
+ add_conf_item("modules", "path", CF_QSTRING, conf_set_modules_path);
+ add_conf_item("modules", "module", CF_QSTRING, conf_set_modules_module);
+
+ add_top_conf("serverinfo", NULL, NULL, conf_serverinfo_table);
+ add_top_conf("admin", NULL, NULL, conf_admin_table);
+ add_top_conf("log", NULL, NULL, conf_log_table);
+ add_top_conf("operator", conf_begin_oper, conf_end_oper, conf_operator_table);
+ add_top_conf("class", conf_begin_class, conf_end_class, conf_class_table);
+
+ add_top_conf("listen", conf_begin_listen, conf_end_listen, NULL);
+ add_conf_item("listen", "port", CF_INT | CF_FLIST, conf_set_listen_port);
+ add_conf_item("listen", "ip", CF_QSTRING, conf_set_listen_address);
+ add_conf_item("listen", "host", CF_QSTRING, conf_set_listen_address);
+
+ add_top_conf("auth", conf_begin_auth, conf_end_auth, conf_auth_table);
+
+ add_top_conf("shared", conf_cleanup_shared, conf_cleanup_shared, NULL);
+ add_conf_item("shared", "oper", CF_QSTRING|CF_FLIST, conf_set_shared_oper);
+ add_conf_item("shared", "flags", CF_STRING | CF_FLIST, conf_set_shared_flags);
+
+ add_top_conf("connect", conf_begin_connect, conf_end_connect, conf_connect_table);
+
+ add_top_conf("exempt", NULL, NULL, NULL);
+ add_conf_item("exempt", "ip", CF_QSTRING, conf_set_exempt_ip);
+
+ add_top_conf("cluster", conf_cleanup_cluster, conf_cleanup_cluster, NULL);
+ add_conf_item("cluster", "name", CF_QSTRING, conf_set_cluster_name);
+ add_conf_item("cluster", "flags", CF_STRING | CF_FLIST, conf_set_cluster_flags);
+
+ add_top_conf("general", NULL, NULL, conf_general_table);
+ add_top_conf("channel", NULL, NULL, conf_channel_table);
+ add_top_conf("serverhide", NULL, NULL, conf_serverhide_table);
+
+ add_top_conf("service", conf_begin_service, NULL, NULL);
+ add_conf_item("service", "name", CF_QSTRING, conf_set_service_name);
+
+ add_top_conf("alias", conf_begin_alias, conf_end_alias, NULL);
+ add_conf_item("alias", "name", CF_QSTRING, conf_set_alias_name);
+ add_conf_item("alias", "target", CF_QSTRING, conf_set_alias_target);
+
+ add_top_conf("blacklist", NULL, NULL, NULL);
+ add_conf_item("blacklist", "host", CF_QSTRING, conf_set_blacklist_host);
+ add_conf_item("blacklist", "reject_reason", CF_QSTRING, conf_set_blacklist_reason);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * numeric.c: Numeric handling functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: numeric.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "setup.h"
+#include "config.h"
+#include "s_conf.h"
+#include "numeric.h"
+#include "irc_string.h"
+#include "common.h" /* NULL cripes */
+#include "memory.h"
+
+#include "messages.tab"
+
+/*
+ * form_str
+ *
+ * inputs - numeric
+ * output - corresponding string
+ * side effects - NONE
+ */
+const char *
+form_str(int numeric)
+{
+ const char *num_ptr;
+
+ s_assert(-1 < numeric);
+ s_assert(numeric < ERR_LAST_ERR_MSG);
+ s_assert(0 != replies[numeric]);
+
+ if(numeric > ERR_LAST_ERR_MSG)
+ numeric = ERR_LAST_ERR_MSG;
+ if(numeric < 0)
+ numeric = ERR_LAST_ERR_MSG;
+
+ num_ptr = replies[numeric];
+ if(num_ptr == NULL)
+ num_ptr = replies[ERR_LAST_ERR_MSG];
+
+ return (num_ptr);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * packet.c: Packet handlers.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: packet.c 262 2005-09-22 00:38:45Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "client.h"
+#include "common.h"
+#include "ircd.h"
+#include "parse.h"
+#include "packet.h"
+#include "irc_string.h"
+#include "memory.h"
+#include "hook.h"
+#include "send.h"
+
+static char readBuf[READBUF_SIZE];
+static void client_dopacket(struct Client *client_p, char *buffer, size_t length);
+
+
+/*
+ * parse_client_queued - parse client queued messages
+ */
+static void
+parse_client_queued(struct Client *client_p)
+{
+ int dolen = 0;
+ int checkflood = 1;
+
+ if(IsAnyDead(client_p))
+ return;
+
+ if(IsUnknown(client_p))
+ {
+ int i = 0;
+
+ for (;;)
+ {
+ /* rate unknown clients at MAX_FLOOD per loop */
+ if(i >= MAX_FLOOD)
+ break;
+
+ dolen = linebuf_get(&client_p->localClient->
+ buf_recvq, readBuf, READBUF_SIZE,
+ LINEBUF_COMPLETE, LINEBUF_PARSED);
+
+ if(dolen <= 0 || IsDead(client_p))
+ break;
+
+ client_dopacket(client_p, readBuf, dolen);
+ i++;
+
+ /* He's dead cap'n */
+ if(IsAnyDead(client_p))
+ return;
+ /* if theyve dropped out of the unknown state, break and move
+ * to the parsing for their appropriate status. --fl
+ */
+ if(!IsUnknown(client_p))
+ break;
+
+ }
+ }
+
+ if(IsAnyServer(client_p) || IsExemptFlood(client_p))
+ {
+ while (!IsAnyDead(client_p) && (dolen = linebuf_get(&client_p->localClient->buf_recvq,
+ readBuf, READBUF_SIZE, LINEBUF_COMPLETE,
+ LINEBUF_PARSED)) > 0)
+ {
+ client_dopacket(client_p, readBuf, dolen);
+ }
+ }
+ else if(IsClient(client_p))
+ {
+
+ if(IsOper(client_p) && ConfigFileEntry.no_oper_flood)
+ checkflood = 0;
+ /*
+ * Handle flood protection here - if we exceed our flood limit on
+ * messages in this loop, we simply drop out of the loop prematurely.
+ * -- adrian
+ */
+ for (;;)
+ {
+ /* This flood protection works as follows:
+ *
+ * A client is given allow_read lines to send to the server. Every
+ * time a line is parsed, sent_parsed is increased. sent_parsed
+ * is decreased by 1 every time flood_recalc is called.
+ *
+ * Thus a client can 'burst' allow_read lines to the server, any
+ * excess lines will be parsed one per flood_recalc() call.
+ *
+ * Therefore a client will be penalised more if they keep flooding,
+ * as sent_parsed will always hover around the allow_read limit
+ * and no 'bursts' will be permitted.
+ */
+ if(checkflood)
+ {
+ if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
+ break;
+ }
+
+ /* allow opers 4 times the amount of messages as users. why 4?
+ * why not. :) --fl_
+ */
+ else if(client_p->localClient->sent_parsed >= (4 * client_p->localClient->allow_read))
+ break;
+
+ dolen = linebuf_get(&client_p->localClient->
+ buf_recvq, readBuf, READBUF_SIZE,
+ LINEBUF_COMPLETE, LINEBUF_PARSED);
+
+ if(!dolen)
+ break;
+
+ client_dopacket(client_p, readBuf, dolen);
+ if(IsAnyDead(client_p))
+ return;
+ client_p->localClient->sent_parsed++;
+ }
+ }
+}
+
+/* flood_endgrace()
+ *
+ * marks the end of the clients grace period
+ */
+void
+flood_endgrace(struct Client *client_p)
+{
+ SetFloodDone(client_p);
+
+ /* Drop their flood limit back down */
+ client_p->localClient->allow_read = MAX_FLOOD;
+
+ /* sent_parsed could be way over MAX_FLOOD but under MAX_FLOOD_BURST,
+ * so reset it.
+ */
+ client_p->localClient->sent_parsed = 0;
+}
+
+/*
+ * flood_recalc
+ *
+ * recalculate the number of allowed flood lines. this should be called
+ * once a second on any given client. We then attempt to flush some data.
+ */
+void
+flood_recalc(int fd, void *data)
+{
+ struct Client *client_p = data;
+ struct LocalUser *lclient_p = client_p->localClient;
+
+ /* This can happen in the event that the client detached. */
+ if(!lclient_p)
+ return;
+
+ /* allow a bursting client their allocation per second, allow
+ * a client whos flooding an extra 2 per second
+ */
+ if(IsFloodDone(client_p))
+ lclient_p->sent_parsed -= 2;
+ else
+ lclient_p->sent_parsed = 0;
+
+ if(lclient_p->sent_parsed < 0)
+ lclient_p->sent_parsed = 0;
+
+ if(--lclient_p->actually_read < 0)
+ lclient_p->actually_read = 0;
+
+ parse_client_queued(client_p);
+
+ if(IsAnyDead(client_p))
+ return;
+
+ /* and finally, reset the flood check */
+ comm_setflush(fd, 1000, flood_recalc, client_p);
+}
+
+/*
+ * read_ctrl_packet - Read a 'packet' of data from a servlink control
+ * link and process it.
+ */
+void
+read_ctrl_packet(int fd, void *data)
+{
+ struct Client *server = data;
+ struct LocalUser *lserver = server->localClient;
+ struct SlinkRpl *reply;
+ int length = 0;
+ unsigned char tmp[2];
+ unsigned char *len = tmp;
+ struct SlinkRplDef *replydef;
+#ifdef USE_IODEBUG_HOOKS
+ hook_data_int hdata;
+#endif
+
+ s_assert(lserver != NULL);
+ if(IsAnyDead(server))
+ return;
+
+ reply = &lserver->slinkrpl;
+
+
+ if(!reply->command)
+ {
+ reply->gotdatalen = 0;
+ reply->readdata = 0;
+ reply->data = NULL;
+
+ length = read(fd, tmp, 1);
+
+ if(length <= 0)
+ {
+ if((length == -1) && ignoreErrno(errno))
+ goto nodata;
+ error_exit_client(server, length);
+ return;
+ }
+
+ reply->command = tmp[0];
+ }
+
+ for (replydef = slinkrpltab; replydef->handler; replydef++)
+ {
+ if((int)replydef->replyid == reply->command)
+ break;
+ }
+
+ /* we should be able to trust a local slink process...
+ * and if it sends an invalid command, that's a bug.. */
+ s_assert(replydef->handler);
+
+ if((replydef->flags & SLINKRPL_FLAG_DATA) && (reply->gotdatalen < 2))
+ {
+ /* we need a datalen u16 which we don't have yet... */
+ length = read(fd, len, (2 - reply->gotdatalen));
+ if(length <= 0)
+ {
+ if((length == -1) && ignoreErrno(errno))
+ goto nodata;
+ error_exit_client(server, length);
+ return;
+ }
+
+ if(reply->gotdatalen == 0)
+ {
+ reply->datalen = *len << 8;
+ reply->gotdatalen++;
+ length--;
+ len++;
+ }
+ if(length && (reply->gotdatalen == 1))
+ {
+ reply->datalen |= *len;
+ reply->gotdatalen++;
+ if(reply->datalen > 0)
+ reply->data = MyMalloc(reply->datalen);
+ }
+
+ if(reply->gotdatalen < 2)
+ return; /* wait for more data */
+ }
+
+ if(reply->readdata < reply->datalen) /* try to get any remaining data */
+ {
+ length = read(fd, (reply->data + reply->readdata),
+ (reply->datalen - reply->readdata));
+ if(length <= 0)
+ {
+ if((length == -1) && ignoreErrno(errno))
+ goto nodata;
+ error_exit_client(server, length);
+ return;
+ }
+
+ reply->readdata += length;
+ if(reply->readdata < reply->datalen)
+ return; /* wait for more data */
+ }
+
+#ifdef USE_IODEBUG_HOOKS
+ hdata.client = server;
+ hdata.arg1 = NULL;
+ hdata.arg2 = reply->command;
+ hdata.data = NULL;
+ call_hook(h_iorecvctrl_id, &hdata);
+#endif
+
+ /* we now have the command and any data, pass it off to the handler */
+ (*replydef->handler) (reply->command, reply->datalen, reply->data, server);
+
+ /* reset SlinkRpl */
+ if(reply->datalen > 0)
+ MyFree(reply->data);
+ reply->command = 0;
+
+ if(IsAnyDead(server))
+ return;
+
+ nodata:
+ /* If we get here, we need to register for another COMM_SELECT_READ */
+ comm_setselect(fd, FDLIST_SERVER, COMM_SELECT_READ, read_ctrl_packet, server, 0);
+}
+
+/*
+ * read_packet - Read a 'packet' of data from a connection and process it.
+ */
+void
+read_packet(int fd, void *data)
+{
+ struct Client *client_p = data;
+ struct LocalUser *lclient_p = client_p->localClient;
+ int length = 0;
+ int lbuf_len;
+
+ int binary = 0;
+#ifdef USE_IODEBUG_HOOKS
+ hook_data_int hdata;
+#endif
+ if(IsAnyDead(client_p))
+ return;
+
+ /*
+ * Read some data. We *used to* do anti-flood protection here, but
+ * I personally think it makes the code too hairy to make sane.
+ * -- adrian
+ */
+ length = read(client_p->localClient->fd, readBuf, READBUF_SIZE);
+
+ if(length <= 0)
+ {
+ if((length == -1) && ignoreErrno(errno))
+ {
+ comm_setselect(client_p->localClient->fd, FDLIST_IDLECLIENT,
+ COMM_SELECT_READ, read_packet, client_p, 0);
+ return;
+ }
+ error_exit_client(client_p, length);
+ return;
+ }
+
+#ifdef USE_IODEBUG_HOOKS
+ hdata.client = client_p;
+ hdata.arg1 = readBuf;
+ hdata.arg2 = length;
+ call_hook(h_iorecv_id, &hdata);
+#endif
+
+ if(client_p->localClient->lasttime < CurrentTime)
+ client_p->localClient->lasttime = CurrentTime;
+ client_p->flags &= ~FLAGS_PINGSENT;
+
+ /*
+ * Before we even think of parsing what we just read, stick
+ * it on the end of the receive queue and do it when its
+ * turn comes around.
+ */
+ if(IsHandshake(client_p) || IsUnknown(client_p))
+ binary = 1;
+
+ lbuf_len = linebuf_parse(&client_p->localClient->buf_recvq, readBuf, length, binary);
+
+ lclient_p->actually_read += lbuf_len;
+
+ if(IsAnyDead(client_p))
+ return;
+
+ /* Attempt to parse what we have */
+ parse_client_queued(client_p);
+
+ if(IsAnyDead(client_p))
+ return;
+
+ /* Check to make sure we're not flooding */
+ if(!IsAnyServer(client_p) &&
+ (linebuf_alloclen(&client_p->localClient->buf_recvq) > ConfigFileEntry.client_flood))
+ {
+ if(!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
+ {
+ exit_client(client_p, client_p, client_p, "Excess Flood");
+ return;
+ }
+ }
+
+ /* If we get here, we need to register for another COMM_SELECT_READ */
+ if(PARSE_AS_SERVER(client_p))
+ {
+ comm_setselect(client_p->localClient->fd, FDLIST_SERVER, COMM_SELECT_READ,
+ read_packet, client_p, 0);
+ }
+ else
+ {
+ comm_setselect(client_p->localClient->fd, FDLIST_IDLECLIENT,
+ COMM_SELECT_READ, read_packet, client_p, 0);
+ }
+}
+
+/*
+ * client_dopacket - copy packet to client buf and parse it
+ * client_p - pointer to client structure for which the buffer data
+ * applies.
+ * buffer - pointr to the buffer containing the newly read data
+ * length - number of valid bytes of data in the buffer
+ *
+ * Note:
+ * It is implicitly assumed that dopacket is called only
+ * with client_p of "local" variation, which contains all the
+ * necessary fields (buffer etc..)
+ */
+void
+client_dopacket(struct Client *client_p, char *buffer, size_t length)
+{
+ s_assert(client_p != NULL);
+ s_assert(buffer != NULL);
+
+ if(client_p == NULL || buffer == NULL)
+ return;
+ if(IsAnyDead(client_p))
+ return;
+ /*
+ * Update messages received
+ */
+ ++me.localClient->receiveM;
+ ++client_p->localClient->receiveM;
+
+ /*
+ * Update bytes received
+ */
+ client_p->localClient->receiveB += length;
+
+ if(client_p->localClient->receiveB > 1023)
+ {
+ client_p->localClient->receiveK += (client_p->localClient->receiveB >> 10);
+ client_p->localClient->receiveB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
+ }
+
+ me.localClient->receiveB += length;
+
+ if(me.localClient->receiveB > 1023)
+ {
+ me.localClient->receiveK += (me.localClient->receiveB >> 10);
+ me.localClient->receiveB &= 0x03ff;
+ }
+
+ parse(client_p, buffer, buffer + length);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * parse.c: The message parser.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: parse.c 2723 2006-11-09 23:35:48Z jilles $
+ */
+
+#include "stdinc.h"
+#include "parse.h"
+#include "client.h"
+#include "channel.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_log.h"
+#include "s_stats.h"
+#include "send.h"
+#include "msg.h"
+#include "s_conf.h"
+#include "memory.h"
+#include "s_serv.h"
+#include "packet.h"
+
+/*
+ * NOTE: parse() should not be called recursively by other functions!
+ */
+static char *sender;
+
+/* parv[0] == source, and parv[LAST] == NULL */
+static char *para[MAXPARA + 2];
+
+static void cancel_clients(struct Client *, struct Client *, char *);
+static void remove_unknown(struct Client *, char *, char *);
+
+static void do_numeric(char[], struct Client *, struct Client *, int, char **);
+static void do_alias(struct alias_entry *, struct Client *, char *);
+
+static int handle_command(struct Message *, struct Client *, struct Client *, int, const char**);
+
+static int cmd_hash(const char *p);
+static struct Message *hash_parse(const char *);
+static struct alias_entry *alias_parse(const char *);
+
+struct MessageHash *msg_hash_table[MAX_MSG_HASH];
+
+static char buffer[1024];
+
+dlink_list alias_hash_table[MAX_MSG_HASH];
+
+/* turn a string into a parc/parv pair */
+
+
+static inline int
+string_to_array(char *string, char **parv)
+{
+ char *p, *buf = string;
+ int x = 1;
+
+ parv[x] = NULL;
+ while (*buf == ' ') /* skip leading spaces */
+ buf++;
+ if(*buf == '\0') /* ignore all-space args */
+ return x;
+
+ do
+ {
+ if(*buf == ':') /* Last parameter */
+ {
+ buf++;
+ parv[x++] = buf;
+ parv[x] = NULL;
+ return x;
+ }
+ else
+ {
+ parv[x++] = buf;
+ parv[x] = NULL;
+ if((p = strchr(buf, ' ')) != NULL)
+ {
+ *p++ = '\0';
+ buf = p;
+ }
+ else
+ return x;
+ }
+ while (*buf == ' ')
+ buf++;
+ if(*buf == '\0')
+ return x;
+ }
+ /* we can go upto parv[MAXPARA], as parv[0] is taken by source */
+ while (x < MAXPARA);
+
+ if(*p == ':')
+ p++;
+
+ parv[x++] = p;
+ parv[x] = NULL;
+ return x;
+}
+
+/* parse()
+ *
+ * given a raw buffer, parses it and generates parv, parc and sender
+ */
+void
+parse(struct Client *client_p, char *pbuffer, char *bufend)
+{
+ struct Client *from = client_p;
+ char *ch;
+ char *s;
+ char *end;
+ int i = 1;
+ char *numeric = 0;
+ struct Message *mptr;
+
+ s_assert(MyConnect(client_p));
+ s_assert(client_p->localClient->fd >= 0);
+ if(IsAnyDead(client_p))
+ return;
+
+ for (ch = pbuffer; *ch == ' '; ch++) /* skip spaces */
+ /* null statement */ ;
+
+ para[0] = from->name;
+
+ if(*ch == ':')
+ {
+ ch++;
+
+ /* point sender to the sender param */
+ sender = ch;
+
+ if((s = strchr(ch, ' ')))
+ {
+ *s = '\0';
+ s++;
+ ch = s;
+ }
+
+ if(*sender && IsServer(client_p))
+ {
+ from = find_any_client(sender);
+
+ /* didnt find any matching client, issue a kill */
+ if(from == NULL)
+ {
+ ServerStats->is_unpf++;
+ remove_unknown(client_p, sender, pbuffer);
+ return;
+ }
+
+ para[0] = from->name;
+
+ /* fake direction, hmm. */
+ if(from->from != client_p)
+ {
+ ServerStats->is_wrdi++;
+ cancel_clients(client_p, from, pbuffer);
+ return;
+ }
+ }
+ while (*ch == ' ')
+ ch++;
+ }
+
+ if(*ch == '\0')
+ {
+ ServerStats->is_empt++;
+ return;
+ }
+
+ /* at this point there must be some sort of command parameter */
+
+ /*
+ * Extract the command code from the packet. Point s to the end
+ * of the command code and calculate the length using pointer
+ * arithmetic. Note: only need length for numerics and *all*
+ * numerics must have parameters and thus a space after the command
+ * code. -avalon
+ */
+
+ /* EOB is 3 chars long but is not a numeric */
+
+ if(*(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */
+ IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
+ {
+ mptr = NULL;
+ numeric = ch;
+ ServerStats->is_num++;
+ s = ch + 3; /* I know this is ' ' from above if */
+ *s++ = '\0'; /* blow away the ' ', and point s to next part */
+ }
+ else
+ {
+ int ii = 0;
+
+ if((s = strchr(ch, ' ')))
+ *s++ = '\0';
+
+ mptr = hash_parse(ch);
+
+ /* no command or its encap only, error */
+ if(!mptr || !mptr->cmd)
+ {
+ /*
+ * Note: Give error message *only* to recognized
+ * persons. It's a nightmare situation to have
+ * two programs sending "Unknown command"'s or
+ * equivalent to each other at full blast....
+ * If it has got to person state, it at least
+ * seems to be well behaving. Perhaps this message
+ * should never be generated, though... --msa
+ * Hm, when is the buffer empty -- if a command
+ * code has been found ?? -Armin
+ */
+ if(pbuffer[0] != '\0')
+ {
+ if (IsPerson(client_p))
+ {
+ struct alias_entry *aptr = alias_parse(ch);
+ if (aptr != NULL)
+ {
+ do_alias(aptr, client_p, s);
+ return;
+ }
+ }
+ if(IsPerson(from))
+ {
+ sendto_one(from, form_str(ERR_UNKNOWNCOMMAND),
+ me.name, from->name, ch);
+ }
+ }
+ ServerStats->is_unco++;
+ return;
+ }
+
+ ii = bufend - ((s) ? s : ch);
+ mptr->bytes += ii;
+ }
+
+ end = bufend - 1;
+
+ /* XXX this should be done before parse() is called */
+ if(*end == '\n')
+ *end-- = '\0';
+ if(*end == '\r')
+ *end = '\0';
+
+ if(s != NULL)
+ i = string_to_array(s, para);
+
+ if(mptr == NULL)
+ {
+ do_numeric(numeric, client_p, from, i, para);
+ return;
+ }
+
+ if(handle_command(mptr, client_p, from, i, /* XXX discards const!!! */ (const char **)para) < -1)
+ {
+ char *p;
+ for (p = pbuffer; p <= end; p += 8)
+ {
+ /* HACK HACK */
+ /* Its expected this nasty code can be removed
+ * or rewritten later if still needed.
+ */
+ if((unsigned long) (p + 8) > (unsigned long) end)
+ {
+ for (; p <= end; p++)
+ {
+ ilog(L_MAIN, "%02x |%c", p[0], p[0]);
+ }
+ }
+ else
+ ilog(L_MAIN,
+ "%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c",
+ p[0], p[1], p[2], p[3], p[4], p[5],
+ p[6], p[7], p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ }
+ }
+
+}
+
+/*
+ * handle_command
+ *
+ * inputs - pointer to message block
+ * - pointer to client
+ * - pointer to client message is from
+ * - count of number of args
+ * - pointer to argv[] array
+ * output - -1 if error from server
+ * side effects -
+ */
+static int
+handle_command(struct Message *mptr, struct Client *client_p,
+ struct Client *from, int i, const char** hpara)
+{
+ struct MessageEntry ehandler;
+ MessageHandler handler = 0;
+ char squitreason[80];
+
+ if(IsAnyDead(client_p))
+ return -1;
+
+ if(IsServer(client_p))
+ mptr->rcount++;
+
+ mptr->count++;
+
+ /* New patch to avoid server flooding from unregistered connects
+ - Pie-Man 07/27/2000 */
+
+ if(!IsRegistered(client_p))
+ {
+ /* if its from a possible server connection
+ * ignore it.. more than likely its a header thats sneaked through
+ */
+
+ if(IsAnyServer(client_p) && !(mptr->flags & MFLG_UNREG))
+ return (1);
+ }
+
+ ehandler = mptr->handlers[from->handler];
+ handler = ehandler.handler;
+
+ /* check right amount of params is passed... --is */
+ if(i < ehandler.min_para ||
+ (ehandler.min_para && EmptyString(hpara[ehandler.min_para - 1])))
+ {
+ if(!IsServer(client_p))
+ {
+ sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
+ me.name,
+ EmptyString(client_p->name) ? "*" : client_p->name,
+ mptr->cmd);
+ if(MyClient(client_p))
+ return (1);
+ else
+ return (-1);
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Dropping server %s due to (invalid) command '%s'"
+ " with only %d arguments (expecting %d).",
+ client_p->name, mptr->cmd, i, ehandler.min_para);
+ ilog(L_SERVER,
+ "Insufficient parameters (%d < %d) for command '%s' from %s.",
+ i, ehandler.min_para, mptr->cmd, client_p->name);
+ snprintf(squitreason, sizeof squitreason,
+ "Insufficient parameters (%d < %d) for command '%s'",
+ i, ehandler.min_para, mptr->cmd);
+ exit_client(client_p, client_p, client_p, squitreason);
+ return (-1);
+ }
+
+ (*handler) (client_p, from, i, hpara);
+ return (1);
+}
+
+void
+handle_encap(struct Client *client_p, struct Client *source_p,
+ const char *command, int parc, const char *parv[])
+{
+ struct Message *mptr;
+ struct MessageEntry ehandler;
+ MessageHandler handler = 0;
+
+ parv[0] = source_p->name;
+
+ mptr = hash_parse(command);
+
+ if(mptr == NULL || mptr->cmd == NULL)
+ return;
+
+ ehandler = mptr->handlers[ENCAP_HANDLER];
+ handler = ehandler.handler;
+
+ if(parc < ehandler.min_para ||
+ (ehandler.min_para && EmptyString(parv[ehandler.min_para - 1])))
+ return;
+
+ (*handler) (client_p, source_p, parc, parv);
+}
+
+/*
+ * clear_hash_parse()
+ *
+ * inputs -
+ * output - NONE
+ * side effects - MUST MUST be called at startup ONCE before
+ * any other keyword hash routine is used.
+ *
+ */
+void
+clear_hash_parse()
+{
+ memset(msg_hash_table, 0, sizeof(msg_hash_table));
+}
+
+/* mod_add_cmd
+ *
+ * inputs - command name
+ * - pointer to struct Message
+ * output - none
+ * side effects - load this one command name
+ * msg->count msg->bytes is modified in place, in
+ * modules address space. Might not want to do that...
+ */
+void
+mod_add_cmd(struct Message *msg)
+{
+ struct MessageHash *ptr;
+ struct MessageHash *last_ptr = NULL;
+ struct MessageHash *new_ptr;
+ int msgindex;
+
+ s_assert(msg != NULL);
+ if(msg == NULL)
+ return;
+
+ msgindex = cmd_hash(msg->cmd);
+
+ for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
+ {
+ if(strcasecmp(msg->cmd, ptr->cmd) == 0)
+ return; /* Its already added */
+ last_ptr = ptr;
+ }
+
+ new_ptr = (struct MessageHash *) MyMalloc(sizeof(struct MessageHash));
+
+ new_ptr->next = NULL;
+ DupString(new_ptr->cmd, msg->cmd);
+ new_ptr->msg = msg;
+
+ msg->count = 0;
+ msg->rcount = 0;
+ msg->bytes = 0;
+
+ if(last_ptr == NULL)
+ msg_hash_table[msgindex] = new_ptr;
+ else
+ last_ptr->next = new_ptr;
+}
+
+/* mod_del_cmd
+ *
+ * inputs - command name
+ * output - none
+ * side effects - unload this one command name
+ */
+void
+mod_del_cmd(struct Message *msg)
+{
+ struct MessageHash *ptr;
+ struct MessageHash *last_ptr = NULL;
+ int msgindex;
+
+ s_assert(msg != NULL);
+ if(msg == NULL)
+ return;
+
+ msgindex = cmd_hash(msg->cmd);
+
+ for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
+ {
+ if(strcasecmp(msg->cmd, ptr->cmd) == 0)
+ {
+ MyFree(ptr->cmd);
+ if(last_ptr != NULL)
+ last_ptr->next = ptr->next;
+ else
+ msg_hash_table[msgindex] = ptr->next;
+ MyFree(ptr);
+ return;
+ }
+ last_ptr = ptr;
+ }
+}
+
+/* hash_parse
+ *
+ * inputs - command name
+ * output - pointer to struct Message
+ * side effects -
+ */
+static struct Message *
+hash_parse(const char *cmd)
+{
+ struct MessageHash *ptr;
+ int msgindex;
+
+ msgindex = cmd_hash(cmd);
+
+ for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
+ {
+ if(strcasecmp(cmd, ptr->cmd) == 0)
+ return (ptr->msg);
+ }
+
+ return NULL;
+}
+
+/* alias_parse
+ *
+ * inputs - command name
+ * output - pointer to struct Message
+ * side effects -
+ */
+static struct alias_entry *
+alias_parse(const char *cmd)
+{
+ dlink_node *ptr;
+ int msgindex;
+
+ msgindex = cmd_hash(cmd);
+
+ DLINK_FOREACH(ptr, alias_hash_table[msgindex].head)
+ {
+ struct alias_entry *ent = (struct alias_entry *) ptr->data;
+
+ if(strcasecmp(cmd, ent->name) == 0)
+ return ent;
+ }
+
+ return NULL;
+}
+
+/*
+ * hash
+ *
+ * inputs - char string
+ * output - hash index
+ * side effects - NONE
+ *
+ * BUGS - This a HORRIBLE hash function
+ */
+static int
+cmd_hash(const char *p)
+{
+ int hash_val = 0;
+
+ while (*p)
+ {
+ hash_val += ((int) (*p) & 0xDF);
+ p++;
+ }
+
+ return (hash_val % MAX_MSG_HASH);
+}
+
+/*
+ * report_messages
+ *
+ * inputs - pointer to client to report to
+ * output - NONE
+ * side effects - NONE
+ */
+void
+report_messages(struct Client *source_p)
+{
+ int i;
+ struct MessageHash *ptr;
+ dlink_node *pptr;
+
+ for (i = 0; i < MAX_MSG_HASH; i++)
+ {
+ for (ptr = msg_hash_table[i]; ptr; ptr = ptr->next)
+ {
+ s_assert(ptr->msg != NULL);
+ s_assert(ptr->cmd != NULL);
+
+ sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
+ form_str(RPL_STATSCOMMANDS),
+ ptr->cmd, ptr->msg->count,
+ ptr->msg->bytes, ptr->msg->rcount);
+ }
+
+ DLINK_FOREACH(pptr, alias_hash_table[i].head)
+ {
+ struct alias_entry *aptr = (struct alias_entry *) pptr->data;
+
+ s_assert(aptr->name != NULL);
+
+ sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
+ form_str(RPL_STATSCOMMANDS),
+ aptr->name, aptr->hits, 0, 0);
+ }
+ }
+}
+
+/* cancel_clients()
+ *
+ * inputs - client who sent us the message, client with fake
+ * direction, command
+ * outputs - a given warning about the fake direction
+ * side effects -
+ */
+static void
+cancel_clients(struct Client *client_p, struct Client *source_p, char *cmd)
+{
+ /* ok, fake prefix happens naturally during a burst on a nick
+ * collision with TS5, we cant kill them because one client has to
+ * survive, so we just send an error.
+ */
+ if(IsServer(source_p) || IsMe(source_p))
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Message for %s[%s] from %s",
+ source_p->name, source_p->from->name,
+ get_server_name(client_p, SHOW_IP));
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Message for %s[%s@%s!%s] from %s (TS, ignored)",
+ source_p->name,
+ source_p->username,
+ source_p->host,
+ source_p->from->name,
+ get_server_name(client_p, SHOW_IP));
+ }
+}
+
+/* remove_unknown()
+ *
+ * inputs - client who gave us message, supposed sender, buffer
+ * output -
+ * side effects - kills issued for clients, squits for servers
+ */
+static void
+remove_unknown(struct Client *client_p, char *lsender, char *lbuffer)
+{
+ int slen = strlen(lsender);
+
+ /* meepfoo is a nickname (KILL)
+ * #XXXXXXXX is a UID (KILL)
+ * #XX is a SID (SQUIT)
+ * meep.foo is a server (SQUIT)
+ */
+ if((IsDigit(lsender[0]) && slen == 3) ||
+ (strchr(lsender, '.') != NULL))
+ {
+ sendto_realops_snomask(SNO_DEBUG, L_ALL,
+ "Unknown prefix (%s) from %s, Squitting %s",
+ lbuffer, get_server_name(client_p, SHOW_IP), lsender);
+
+ sendto_one(client_p,
+ ":%s SQUIT %s :(Unknown prefix (%s) from %s)",
+ get_id(&me, client_p), lsender,
+ lbuffer, client_p->name);
+ }
+ else
+ sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)",
+ get_id(&me, client_p), lsender, me.name);
+}
+
+
+
+/*
+ *
+ * parc number of arguments ('sender' counted as one!)
+ * parv[0] pointer to 'sender' (may point to empty string) (not used)
+ * parv[1]..parv[parc-1]
+ * pointers to additional parameters, this is a NULL
+ * terminated list (parv[parc] == NULL).
+ *
+ * *WARNING*
+ * Numerics are mostly error reports. If there is something
+ * wrong with the message, just *DROP* it! Don't even think of
+ * sending back a neat error message -- big danger of creating
+ * a ping pong error message...
+ */
+static void
+do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int parc, char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+
+ if(parc < 2 || !IsServer(source_p))
+ return;
+
+ /* Remap low number numerics. */
+ if(numeric[0] == '0')
+ numeric[0] = '1';
+
+ /*
+ * Prepare the parameter portion of the message into 'buffer'.
+ * (Because the buffer is twice as large as the message buffer
+ * for the socket, no overflow can occur here... ...on current
+ * assumptions--bets are off, if these are changed --msa)
+ * Note: if buffer is non-empty, it will begin with SPACE.
+ */
+ if(parc > 1)
+ {
+ char *t = buffer; /* Current position within the buffer */
+ int i;
+ int tl; /* current length of presently being built string in t */
+ for (i = 2; i < (parc - 1); i++)
+ {
+ tl = ircsprintf(t, " %s", parv[i]);
+ t += tl;
+ }
+ ircsprintf(t, " :%s", parv[parc - 1]);
+ }
+
+ if((target_p = find_client(parv[1])) != NULL)
+ {
+ if(IsMe(target_p))
+ {
+ /*
+ * We shouldn't get numerics sent to us,
+ * any numerics we do get indicate a bug somewhere..
+ */
+ /* ugh. this is here because of nick collisions. when two servers
+ * relink, they burst each other their nicks, then perform collides.
+ * if there is a nick collision, BOTH servers will kill their own
+ * nicks, and BOTH will kill the other servers nick, which wont exist,
+ * because it will have been already killed by the local server.
+ *
+ * unfortunately, as we cant guarantee other servers will do the
+ * "right thing" on a nick collision, we have to keep both kills.
+ * ergo we need to ignore ERR_NOSUCHNICK. --fl_
+ */
+ /* quick comment. This _was_ tried. i.e. assume the other servers
+ * will do the "right thing" and kill a nick that is colliding.
+ * unfortunately, it did not work. --Dianora
+ */
+ /* note, now we send PING on server connect, we can
+ * also get ERR_NOSUCHSERVER..
+ */
+ if(atoi(numeric) != ERR_NOSUCHNICK &&
+ atoi(numeric) != ERR_NOSUCHSERVER)
+ sendto_realops_snomask(SNO_GENERAL, L_ADMIN,
+ "*** %s(via %s) sent a %s numeric to me: %s",
+ source_p->name,
+ client_p->name, numeric, buffer);
+ return;
+ }
+ else if(target_p->from == client_p)
+ {
+ /* This message changed direction (nick collision?)
+ * ignore it.
+ */
+ return;
+ }
+
+ /* csircd will send out unknown umode flag for +a (admin), drop it here. */
+ if((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p))
+ return;
+
+ /* Fake it for server hiding, if its our client */
+ sendto_one(target_p, ":%s %s %s%s",
+ get_id(source_p, target_p), numeric,
+ get_id(target_p, target_p), buffer);
+ return;
+ }
+ else if((chptr = find_channel(parv[1])) != NULL)
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s %s %s %s",
+ source_p->name, numeric, chptr->chname, buffer);
+}
+
+static void do_alias(struct alias_entry *aptr, struct Client *source_p, char *text)
+{
+ char *p;
+ struct Client *target_p;
+
+ if (!IsFloodDone(source_p) && source_p->localClient->receiveM > 20)
+ flood_endgrace(source_p);
+
+ p = strchr(aptr->target, '@');
+ if (p != NULL)
+ {
+ /* user@server */
+ target_p = find_server(NULL, p + 1);
+ if (target_p != NULL && IsMe(target_p))
+ target_p = NULL;
+ }
+ else
+ {
+ /* nick, must be +S */
+ target_p = find_named_person(aptr->target);
+ if (target_p != NULL && !IsService(target_p))
+ target_p = NULL;
+ }
+
+ if (target_p == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_SERVICESDOWN, form_str(ERR_SERVICESDOWN), aptr->target);
+ return;
+ }
+
+ if (text != NULL && *text == ':')
+ text++;
+ if (text == NULL || *text == '\0')
+ {
+ sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
+ return;
+ }
+
+ /* increment the hitcounter on this alias */
+ aptr->hits++;
+
+ sendto_one(target_p, ":%s PRIVMSG %s :%s",
+ get_id(source_p, target_p),
+ p != NULL ? aptr->target : get_id(target_p, target_p),
+ text);
+}
+
+int
+m_not_oper(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
+ return 0;
+}
+
+int
+m_unregistered(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ /* bit of a hack.
+ * I don't =really= want to waste a bit in a flag
+ * number_of_nick_changes is only really valid after the client
+ * is fully registered..
+ */
+ if(client_p->localClient->number_of_nick_changes == 0)
+ {
+ sendto_one(client_p, form_str(ERR_NOTREGISTERED), me.name);
+ client_p->localClient->number_of_nick_changes++;
+ }
+
+ return 0;
+}
+
+int
+m_registered(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ sendto_one(client_p, form_str(ERR_ALREADYREGISTRED), me.name, source_p->name);
+ return 0;
+}
+
+int
+m_ignore(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ return 0;
+}
--- /dev/null
+/*
+ * Yanked out of Net::Patricia by Aaron Sethman <androsyn@ratbox.org>
+ *
+ * $Id: patricia.c 1110 2006-03-29 22:55:25Z nenolod $
+ * Dave Plonka <plonka@doit.wisc.edu>
+ *
+ * This product includes software developed by the University of Michigan,
+ * Merit Network, Inc., and their contributors.
+ *
+ * This file had been called "radix.c" in the MRT sources.
+ *
+ * I renamed it to "patricia.c" since it's not an implementation of a general
+ * radix trie. Also I pulled in various requirements from "prefix.c" and
+ * "demo.c" so that it could be used as a standalone API.
+ *
+ * This product includes software developed by the University of Michigan, Merit
+ * Network, Inc., and their contributors.
+ *
+ */
+
+
+#include "stdinc.h"
+#include "config.h"
+#include "ircd_defs.h"
+#include "patricia.h"
+#include "balloc.h"
+
+extern BlockHeap *prefix_heap;
+extern BlockHeap *node_heap;
+extern BlockHeap *patricia_heap;
+
+/* Enable both of these to debug patricia.c
+ * #define NOTYET 1
+ * #define PATRICIA_DEBUG 1
+ */
+
+#define PREFIX_HEAP_COUNT 1024
+#define NODE_HEAP_COUNT 1024
+#define PATRICIA_HEAP_COUNT 128
+
+void
+init_patricia(void)
+{
+ prefix_heap = BlockHeapCreate(sizeof(prefix_t), PREFIX_HEAP_COUNT);
+ node_heap = BlockHeapCreate(sizeof(patricia_node_t), NODE_HEAP_COUNT);
+ patricia_heap = BlockHeapCreate(sizeof(patricia_tree_t), PATRICIA_HEAP_COUNT);
+}
+
+/* prefix_tochar
+ * convert prefix information to bytes
+ */
+static u_char *
+prefix_tochar(prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return (NULL);
+
+ return ((u_char *) & prefix->add.sin);
+}
+
+#if 0
+static int
+comp_with_mask(void *addr, void *dest, u_int mask)
+{
+
+ if( /* mask/8 == 0 || */ memcmp(addr, dest, mask / 8) == 0)
+ {
+ int n = mask / 8;
+ int m = ((-1) << (8 - (mask % 8)));
+
+ if(mask % 8 == 0 || (((u_char *) addr)[n] & m) == (((u_char *) dest)[n] & m))
+ return (1);
+ }
+ return (0);
+}
+#endif
+#ifdef NOTYET
+static char *
+prefix_toa2x(prefix_t * prefix, char *buf, int buf_len, int with_len)
+{
+ static char tmp[6];
+ if(prefix == NULL)
+ {
+ strcpy(buf, "(NULL)");
+ return (buf);
+ }
+ inet_ntop(prefix->family, &prefix->add.sin, buf, buf_len);
+ if(with_len)
+ {
+ ircsnprintf(tmp, sizeof(tmp), "/%d", prefix->bitlen);
+ strcat(buf, tmp);
+ }
+ return (buf);
+}
+
+/* prefix_toa2
+ * convert prefix information to ascii string
+ */
+
+static char *
+prefix_toa2(prefix_t * prefix, char *buff, int buf_len)
+{
+ return (prefix_toa2x(prefix, buff, buf_len, 0));
+}
+static char *
+prefix_toa(prefix_t * prefix)
+{
+#ifdef IPV6
+ static char buf[INET6_ADDRSTRLEN + 6];
+#else
+ static char buf[16 + 6];
+#endif
+ return (prefix_toa2(prefix, buf, sizeof(buf)));
+}
+#endif
+static prefix_t *
+New_Prefix2(int family, void *dest, int bitlen, prefix_t * prefix)
+{
+ int dynamic_allocated = 0;
+#ifdef IPV6
+ int default_bitlen = 128;
+#else
+ int default_bitlen = 32;
+#endif
+
+#ifdef IPV6
+ if(family == AF_INET6)
+ {
+ default_bitlen = 128;
+ if(prefix == NULL)
+ {
+ prefix = BlockHeapAlloc(prefix_heap);
+ dynamic_allocated++;
+ }
+ memcpy(&prefix->add.sin6, dest, 16);
+ }
+ else
+#endif /* IPV6 */
+ if(family == AF_INET)
+ {
+ if(prefix == NULL)
+ {
+ prefix = BlockHeapAlloc(prefix_heap);
+ dynamic_allocated++;
+ }
+ memcpy(&prefix->add.sin, dest, 4);
+ }
+ else
+ {
+ return (NULL);
+ }
+
+ prefix->bitlen = (bitlen >= 0) ? bitlen : default_bitlen;
+ prefix->family = family;
+ prefix->ref_count = 0;
+ if(dynamic_allocated)
+ {
+ prefix->ref_count++;
+ }
+ return (prefix);
+}
+
+static prefix_t *
+New_Prefix(int family, void *dest, int bitlen)
+{
+ return (New_Prefix2(family, dest, bitlen, NULL));
+}
+
+/* ascii2prefix
+ */
+static prefix_t *
+ascii2prefix(int family, const char *string)
+{
+ long bitlen, maxbitlen = 0;
+ char *cp;
+ struct in_addr sinaddr;
+#ifdef IPV6
+ struct in6_addr sinaddr6;
+#endif /* IPV6 */
+ int result;
+ char save[MAXLINE];
+
+ if(string == NULL)
+ return (NULL);
+
+ /* easy way to handle both families */
+ if(family == 0)
+ {
+ family = AF_INET;
+#ifdef IPV6
+ if(strchr(string, ':'))
+ family = AF_INET6;
+#endif /* IPV6 */
+ }
+ if(family == AF_INET)
+ {
+ maxbitlen = 32;
+ }
+#ifdef IPV6
+ else if(family == AF_INET6)
+ {
+ maxbitlen = 128;
+ }
+#endif /* IPV6 */
+
+ if((cp = strchr(string, '/')) != NULL)
+ {
+ bitlen = atol(cp + 1);
+ /* *cp = '\0'; */
+ /* copy the string to save. Avoid destroying the string */
+ assert(cp - string < MAXLINE);
+ memcpy(save, string, cp - string);
+ save[cp - string] = '\0';
+ string = save;
+ if(bitlen <= 0 || bitlen > maxbitlen)
+ bitlen = maxbitlen;
+ }
+ else
+ {
+ bitlen = maxbitlen;
+ }
+
+ if(family == AF_INET)
+ {
+ if((result = inetpton(AF_INET, string, &sinaddr)) <= 0)
+ return (NULL);
+ return (New_Prefix(AF_INET, &sinaddr, bitlen));
+ }
+#ifdef IPV6
+ else if(family == AF_INET6)
+ {
+ if((result = inetpton(AF_INET6, string, &sinaddr6)) <= 0)
+ return (NULL);
+ return (New_Prefix(AF_INET6, &sinaddr6, bitlen));
+ }
+#endif /* IPV6 */
+ else
+ return (NULL);
+}
+
+static prefix_t *
+Ref_Prefix(prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return (NULL);
+ if(prefix->ref_count == 0)
+ {
+ /* make a copy in case of a static prefix */
+ return (New_Prefix2(prefix->family, &prefix->add, prefix->bitlen, NULL));
+ }
+ prefix->ref_count++;
+ return (prefix);
+}
+
+static void
+Deref_Prefix(prefix_t * prefix)
+{
+ if(prefix == NULL)
+ return;
+ /* for secure programming, raise an assert. no static prefix can call this */
+ assert(prefix->ref_count > 0);
+
+ prefix->ref_count--;
+ assert(prefix->ref_count >= 0);
+ if(prefix->ref_count <= 0)
+ {
+ BlockHeapFree(prefix_heap, prefix);
+ return;
+ }
+}
+
+/* } */
+
+/* #define PATRICIA_DEBUG 1 */
+
+static int num_active_patricia = 0;
+
+/* these routines support continuous mask only */
+
+patricia_tree_t *
+New_Patricia(int maxbits)
+{
+ patricia_tree_t *patricia = BlockHeapAlloc(patricia_heap);
+
+ patricia->maxbits = maxbits;
+ patricia->head = NULL;
+ patricia->num_active_node = 0;
+ assert(maxbits <= PATRICIA_MAXBITS); /* XXX */
+ num_active_patricia++;
+ return (patricia);
+}
+
+
+/*
+ * if func is supplied, it will be called as func(node->data)
+ * before deleting the node
+ */
+
+void
+Clear_Patricia(patricia_tree_t * patricia, void_fn_t func)
+{
+ assert(patricia);
+ if(patricia->head)
+ {
+
+ patricia_node_t *Xstack[PATRICIA_MAXBITS + 1];
+ patricia_node_t **Xsp = Xstack;
+ patricia_node_t *Xrn = patricia->head;
+
+ while (Xrn)
+ {
+ patricia_node_t *l = Xrn->l;
+ patricia_node_t *r = Xrn->r;
+
+ if(Xrn->prefix)
+ {
+ Deref_Prefix(Xrn->prefix);
+ if(Xrn->data && func)
+ func(Xrn->data);
+ }
+ else
+ {
+ assert(Xrn->data == NULL);
+ }
+ BlockHeapFree(node_heap, Xrn);
+ patricia->num_active_node--;
+
+ if(l)
+ {
+ if(r)
+ {
+ *Xsp++ = r;
+ }
+ Xrn = l;
+ }
+ else if(r)
+ {
+ Xrn = r;
+ }
+ else if(Xsp != Xstack)
+ {
+ Xrn = *(--Xsp);
+ }
+ else
+ {
+ Xrn = (patricia_node_t *) 0;
+ }
+ }
+ }
+ assert(patricia->num_active_node == 0);
+ BlockHeapFree(patricia_heap, patricia);
+}
+
+
+void
+Destroy_Patricia(patricia_tree_t * patricia, void_fn_t func)
+{
+ Clear_Patricia(patricia, func);
+ num_active_patricia--;
+}
+
+
+/*
+ * if func is supplied, it will be called as func(node->prefix, node->data)
+ */
+
+void
+patricia_process(patricia_tree_t * patricia, void_fn_t func)
+{
+ patricia_node_t *node;
+ assert(func);
+
+ PATRICIA_WALK(patricia->head, node)
+ {
+ func(node->prefix, node->data);
+ }
+ PATRICIA_WALK_END;
+}
+
+patricia_node_t *
+patricia_search_exact(patricia_tree_t * patricia, prefix_t * prefix)
+{
+ patricia_node_t *node;
+ u_char *addr;
+ u_int bitlen;
+
+ assert(patricia);
+ assert(prefix);
+ assert(prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL)
+ return (NULL);
+
+ node = patricia->head;
+ addr = prefix_touchar(prefix);
+ bitlen = prefix->bitlen;
+
+ while (node->bit < bitlen)
+ {
+
+ if(BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_search_exact: take right %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr,
+ "patricia_search_exact: take right at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else
+ {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_search_exact: take left %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr,
+ "patricia_search_exact: take left at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ if(node == NULL)
+ return (NULL);
+ }
+
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr, "patricia_search_exact: stop at %s/%d %d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen, node->bit);
+ else
+ fprintf(stderr, "patricia_search_exact: stop at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ if(node->bit > bitlen || node->prefix == NULL)
+ return (NULL);
+ assert(node->bit == bitlen);
+ assert(node->bit == node->prefix->bitlen);
+ if(comp_with_mask(prefix_tochar(node->prefix), prefix_tochar(prefix), bitlen))
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_search_exact: found %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ return (NULL);
+}
+
+/* if inclusive != 0, "best" may be the given prefix itself */
+patricia_node_t *
+patricia_search_best2(patricia_tree_t * patricia, prefix_t * prefix, int inclusive)
+{
+ patricia_node_t *node;
+ patricia_node_t *stack[PATRICIA_MAXBITS + 1];
+ u_char *addr;
+ u_int bitlen;
+ int cnt = 0;
+
+ assert(patricia);
+ assert(prefix);
+ assert(prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL)
+ return (NULL);
+
+ node = patricia->head;
+ addr = prefix_touchar(prefix);
+ bitlen = prefix->bitlen;
+
+ while (node->bit < bitlen)
+ {
+
+ if(node->prefix)
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_search_best: push %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ stack[cnt++] = node;
+ }
+
+ if(BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_search_best: take right %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr,
+ "patricia_search_best: take right at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else
+ {
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_search_best: take left %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr,
+ "patricia_search_best: take left at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ if(node == NULL)
+ break;
+ }
+
+ if(inclusive && node && node->prefix)
+ stack[cnt++] = node;
+
+#ifdef PATRICIA_DEBUG
+ if(node == NULL)
+ fprintf(stderr, "patricia_search_best: stop at null\n");
+ else if(node->prefix)
+ fprintf(stderr, "patricia_search_best: stop at %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr, "patricia_search_best: stop at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+
+ if(cnt <= 0)
+ return (NULL);
+
+ while (--cnt >= 0)
+ {
+ node = stack[cnt];
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_search_best: pop %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ if(comp_with_mask(prefix_tochar(node->prefix),
+ prefix_tochar(prefix), node->prefix->bitlen))
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_search_best: found %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ }
+ return (NULL);
+}
+
+
+patricia_node_t *
+patricia_search_best(patricia_tree_t * patricia, prefix_t * prefix)
+{
+ return (patricia_search_best2(patricia, prefix, 1));
+}
+
+
+patricia_node_t *
+patricia_lookup(patricia_tree_t * patricia, prefix_t * prefix)
+{
+ patricia_node_t *node, *new_node, *parent, *glue;
+ u_char *addr, *test_addr;
+ u_int bitlen, check_bit, differ_bit;
+ unsigned int i, j, r;
+
+ assert(patricia);
+ assert(prefix);
+ assert(prefix->bitlen <= patricia->maxbits);
+
+ if(patricia->head == NULL)
+ {
+ node = BlockHeapAlloc(node_heap);
+ node->bit = prefix->bitlen;
+ node->prefix = Ref_Prefix(prefix);
+ node->parent = NULL;
+ node->l = node->r = NULL;
+ node->data = NULL;
+ patricia->head = node;
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_lookup: new_node #0 %s/%d (head)\n",
+ prefix_toa(prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ patricia->num_active_node++;
+ return (node);
+ }
+
+ addr = prefix_touchar(prefix);
+ bitlen = prefix->bitlen;
+ node = patricia->head;
+
+ while (node->bit < bitlen || node->prefix == NULL)
+ {
+
+ if(node->bit < patricia->maxbits &&
+ BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ {
+ if(node->r == NULL)
+ break;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_lookup: take right %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr, "patricia_lookup: take right at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->r;
+ }
+ else
+ {
+ if(node->l == NULL)
+ break;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr,
+ "patricia_lookup: take left %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr, "patricia_lookup: take left at %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ node = node->l;
+ }
+
+ assert(node);
+ }
+
+ assert(node->prefix);
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_lookup: stop at %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+
+ test_addr = prefix_touchar(node->prefix);
+ /* find the first bit different */
+ check_bit = (node->bit < bitlen) ? node->bit : bitlen;
+ differ_bit = 0;
+ for (i = 0; i * 8 < check_bit; i++)
+ {
+ if((r = (addr[i] ^ test_addr[i])) == 0)
+ {
+ differ_bit = (i + 1) * 8;
+ continue;
+ }
+ /* I know the better way, but for now */
+ for (j = 0; j < 8; j++)
+ {
+ if(BIT_TEST(r, (0x80 >> j)))
+ break;
+ }
+ /* must be found */
+ assert(j < 8);
+ differ_bit = i * 8 + j;
+ break;
+ }
+ if(differ_bit > check_bit)
+ differ_bit = check_bit;
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_lookup: differ_bit %d\n", differ_bit);
+#endif /* PATRICIA_DEBUG */
+
+ parent = node->parent;
+ while (parent && parent->bit >= differ_bit)
+ {
+ node = parent;
+ parent = node->parent;
+#ifdef PATRICIA_DEBUG
+ if(node->prefix)
+ fprintf(stderr, "patricia_lookup: up to %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+ else
+ fprintf(stderr, "patricia_lookup: up to %d\n", node->bit);
+#endif /* PATRICIA_DEBUG */
+ }
+
+ if(differ_bit == bitlen && node->bit == bitlen)
+ {
+ if(node->prefix)
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_lookup: found %s/%d\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (node);
+ }
+ node->prefix = Ref_Prefix(prefix);
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_lookup: new node #1 %s/%d (glue mod)\n",
+ prefix_toa(prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ assert(node->data == NULL);
+ return (node);
+ }
+
+ new_node = BlockHeapAlloc(node_heap);
+ new_node->bit = prefix->bitlen;
+ new_node->prefix = Ref_Prefix(prefix);
+ new_node->parent = NULL;
+ new_node->l = new_node->r = NULL;
+ new_node->data = NULL;
+ patricia->num_active_node++;
+
+ if(node->bit == differ_bit)
+ {
+ new_node->parent = node;
+ if(node->bit < patricia->maxbits &&
+ BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
+ {
+ assert(node->r == NULL);
+ node->r = new_node;
+ }
+ else
+ {
+ assert(node->l == NULL);
+ node->l = new_node;
+ }
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_lookup: new_node #2 %s/%d (child)\n",
+ prefix_toa(prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ return (new_node);
+ }
+
+ if(bitlen == differ_bit)
+ {
+ if(bitlen < patricia->maxbits &&
+ BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07)))
+ {
+ new_node->r = node;
+ }
+ else
+ {
+ new_node->l = node;
+ }
+ new_node->parent = node->parent;
+ if(node->parent == NULL)
+ {
+ assert(patricia->head == node);
+ patricia->head = new_node;
+ }
+ else if(node->parent->r == node)
+ {
+ node->parent->r = new_node;
+ }
+ else
+ {
+ node->parent->l = new_node;
+ }
+ node->parent = new_node;
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_lookup: new_node #3 %s/%d (parent)\n",
+ prefix_toa(prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ }
+ else
+ {
+ glue = BlockHeapAlloc(node_heap);
+ glue->bit = differ_bit;
+ glue->prefix = NULL;
+ glue->parent = node->parent;
+ glue->data = NULL;
+ patricia->num_active_node++;
+ if(differ_bit < patricia->maxbits &&
+ BIT_TEST(addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07)))
+ {
+ glue->r = new_node;
+ glue->l = node;
+ }
+ else
+ {
+ glue->r = node;
+ glue->l = new_node;
+ }
+ new_node->parent = glue;
+
+ if(node->parent == NULL)
+ {
+ assert(patricia->head == node);
+ patricia->head = glue;
+ }
+ else if(node->parent->r == node)
+ {
+ node->parent->r = glue;
+ }
+ else
+ {
+ node->parent->l = glue;
+ }
+ node->parent = glue;
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr,
+ "patricia_lookup: new_node #4 %s/%d (glue+node)\n",
+ prefix_toa(prefix), prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ }
+ return (new_node);
+}
+
+
+void
+patricia_remove(patricia_tree_t * patricia, patricia_node_t * node)
+{
+ patricia_node_t *parent, *child;
+
+ assert(patricia);
+ assert(node);
+
+ if(node->r && node->l)
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_remove: #0 %s/%d (r & l)\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+
+ /* this might be a placeholder node -- have to check and make sure
+ * there is a prefix aossciated with it ! */
+ if(node->prefix != NULL)
+ Deref_Prefix(node->prefix);
+ node->prefix = NULL;
+ /* Also I needed to clear data pointer -- masaki */
+ node->data = NULL;
+ return;
+ }
+
+ if(node->r == NULL && node->l == NULL)
+ {
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_remove: #1 %s/%d (!r & !l)\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ parent = node->parent;
+ Deref_Prefix(node->prefix);
+ BlockHeapFree(node_heap, node);
+ patricia->num_active_node--;
+
+ if(parent == NULL)
+ {
+ assert(patricia->head == node);
+ patricia->head = NULL;
+ return;
+ }
+
+ if(parent->r == node)
+ {
+ parent->r = NULL;
+ child = parent->l;
+ }
+ else
+ {
+ assert(parent->l == node);
+ parent->l = NULL;
+ child = parent->r;
+ }
+
+ if(parent->prefix)
+ return;
+
+ /* we need to remove parent too */
+
+ if(parent->parent == NULL)
+ {
+ assert(patricia->head == parent);
+ patricia->head = child;
+ }
+ else if(parent->parent->r == parent)
+ {
+ parent->parent->r = child;
+ }
+ else
+ {
+ assert(parent->parent->l == parent);
+ parent->parent->l = child;
+ }
+ child->parent = parent->parent;
+ BlockHeapFree(node_heap, parent);
+ patricia->num_active_node--;
+ return;
+ }
+#ifdef PATRICIA_DEBUG
+ fprintf(stderr, "patricia_remove: #2 %s/%d (r ^ l)\n",
+ prefix_toa(node->prefix), node->prefix->bitlen);
+#endif /* PATRICIA_DEBUG */
+ if(node->r)
+ {
+ child = node->r;
+ }
+ else
+ {
+ assert(node->l);
+ child = node->l;
+ }
+ parent = node->parent;
+ child->parent = parent;
+
+ Deref_Prefix(node->prefix);
+ BlockHeapFree(node_heap, node);
+ patricia->num_active_node--;
+
+ if(parent == NULL)
+ {
+ assert(patricia->head == node);
+ patricia->head = child;
+ return;
+ }
+
+ if(parent->r == node)
+ {
+ parent->r = child;
+ }
+ else
+ {
+ assert(parent->l == node);
+ parent->l = child;
+ }
+}
+
+patricia_node_t *
+make_and_lookup_ip(patricia_tree_t * tree, struct sockaddr *in, int bitlen)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+ void *ipptr = NULL;
+#ifdef IPV6
+ if(in->sa_family == AF_INET6)
+ ipptr = &((struct sockaddr_in6 *)in)->sin6_addr;
+ else
+#endif
+ ipptr = &((struct sockaddr_in *)in)->sin_addr;
+
+ prefix = New_Prefix(in->sa_family, ipptr, bitlen);
+
+ if(prefix == NULL)
+ return NULL;
+
+ node = patricia_lookup(tree, prefix);
+
+
+
+ Deref_Prefix(prefix);
+ return (node);
+}
+
+
+patricia_node_t *
+make_and_lookup(patricia_tree_t * tree, const char *string)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+
+ if((prefix = ascii2prefix(AF_INET, string)) != NULL)
+ {
+ node = patricia_lookup(tree, prefix);
+ }
+ else
+#ifdef IPV6
+ if((prefix = ascii2prefix(AF_INET6, string)) != NULL)
+ {
+ node = patricia_lookup(tree, prefix);
+ }
+ else
+#endif
+ return NULL;
+#ifdef PATRICIA_DEBUG
+ printf("make_and_lookup: %s/%d\n", prefix_toa(prefix), prefix->bitlen);
+#endif
+ Deref_Prefix(prefix);
+ return (node);
+}
+
+#ifdef NOTYET
+static patricia_node_t *
+try_search_exact(patricia_tree_t * tree, char *string)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+ if((prefix = ascii2prefix(AF_INET, string)) != NULL)
+ {
+ node = patricia_search_exact(tree, prefix);
+ Deref_Prefix(prefix);
+ return (node);
+ }
+#ifdef IPV6
+ else if((prefix = ascii2prefix(AF_INET6, string)) != NULL)
+ {
+ node = patricia_search_exact(tree, prefix);
+ Deref_Prefix(prefix);
+ return (node);
+ }
+#endif
+ else
+ return NULL;
+}
+
+void
+lookup_then_remove(patricia_tree_t * tree, char *string)
+{
+ patricia_node_t *node;
+
+ if((node = try_search_exact(tree, string)))
+ patricia_remove(tree, node);
+}
+#endif
+
+patricia_node_t *
+match_ip(patricia_tree_t * tree, struct sockaddr *ip)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+ void *ipptr;
+ unsigned int len;
+ int family;
+#ifndef IPV6
+ len = 32;
+ family = AF_INET;
+ ipptr = &((struct sockaddr_in *)ip)->sin_addr;
+#else
+ if(ip->sa_family == AF_INET6)
+ {
+ len = 128;
+ family = AF_INET6;
+ ipptr = &((struct sockaddr_in6 *)ip)->sin6_addr;
+ } else {
+ len = 32;
+ family = AF_INET;
+ ipptr = &((struct sockaddr_in *)ip)->sin_addr;
+ }
+#endif
+
+ if((prefix = New_Prefix(family, ipptr, len)) != NULL)
+ {
+ node = patricia_search_best(tree, prefix);
+ Deref_Prefix(prefix);
+ return (node);
+ }
+ return NULL;
+}
+
+patricia_node_t *
+match_string(patricia_tree_t * tree, const char *string)
+{
+ patricia_node_t *node;
+ prefix_t *prefix;
+
+ if((prefix = ascii2prefix(AF_INET, string)) != NULL)
+ {
+ node = patricia_search_best(tree, prefix);
+ Deref_Prefix(prefix);
+ }
+ else
+#ifdef IPV6
+ if((prefix = ascii2prefix(AF_INET6, string)) != NULL)
+ {
+ node = patricia_search_best(tree, prefix);
+ Deref_Prefix(prefix);
+ }
+ else
+#endif
+ return NULL;
+ return node;
+}
+
+patricia_node_t *
+match_exact_string(patricia_tree_t * tree, const char *string)
+{
+ prefix_t *prefix;
+ patricia_node_t *node;
+ if((prefix = ascii2prefix(AF_INET, string)) != NULL)
+ {
+ node = patricia_search_exact(tree, prefix);
+ Deref_Prefix(prefix);
+ }
+ else
+#ifdef IPV6
+ if((prefix = ascii2prefix(AF_INET6, string)) != NULL)
+ {
+ node = patricia_search_exact(tree, prefix);
+ Deref_Prefix(prefix);
+ }
+ else
+#endif
+ return NULL;
+ return node;
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd
+ * reject.c: reject users with prejudice
+ *
+ * Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2003-2005 ircd-ratbox 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
+ *
+ * $Id: reject.c 849 2006-02-15 01:33:43Z jilles $
+ */
+
+#include "stdinc.h"
+#include "config.h"
+#include "patricia.h"
+#include "client.h"
+#include "s_conf.h"
+#include "event.h"
+#include "tools.h"
+#include "reject.h"
+#include "s_stats.h"
+#include "msg.h"
+
+static patricia_tree_t *reject_tree;
+dlink_list delay_exit;
+static dlink_list reject_list;
+
+struct reject_data
+{
+ dlink_node rnode;
+ time_t time;
+ unsigned int count;
+};
+
+static void
+reject_exit(void *unused)
+{
+ struct Client *client_p;
+ dlink_node *ptr, *ptr_next;
+
+ DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head)
+ {
+ client_p = ptr->data;
+ if(IsDead(client_p))
+ continue;
+
+ /* this MUST be here, to prevent the possibility
+ * sendto_one() generates a write error, and then a client
+ * ends up on the dead_list and the abort_list --fl
+ *
+ * new disconnect notice stolen from ircu --nenolod
+ * no, this only happens when someone's IP has some
+ * ban on it and rejects them rather longer than the
+ * ircu message suggests --jilles
+ */
+ if(!IsIOError(client_p))
+ sendto_one(client_p, "ERROR :Closing Link: %s (*** Banned (cache))", client_p->host);
+
+ close_connection(client_p);
+ SetDead(client_p);
+ dlinkAddAlloc(client_p, &dead_list);
+ }
+
+ delay_exit.head = delay_exit.tail = NULL;
+ delay_exit.length = 0;
+}
+
+static void
+reject_expires(void *unused)
+{
+ dlink_node *ptr, *next;
+ patricia_node_t *pnode;
+ struct reject_data *rdata;
+
+ DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
+ {
+ pnode = ptr->data;
+ rdata = pnode->data;
+
+ if(rdata->time + ConfigFileEntry.reject_duration > CurrentTime)
+ continue;
+
+ dlinkDelete(ptr, &reject_list);
+ MyFree(rdata);
+ patricia_remove(reject_tree, pnode);
+ }
+}
+
+void
+init_reject(void)
+{
+ reject_tree = New_Patricia(PATRICIA_BITS);
+ eventAdd("reject_exit", reject_exit, NULL, DELAYED_EXIT_TIME);
+ eventAdd("reject_expires", reject_expires, NULL, 60);
+}
+
+
+void
+add_reject(struct Client *client_p)
+{
+ patricia_node_t *pnode;
+ struct reject_data *rdata;
+
+ /* Reject is disabled */
+ if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0)
+ return;
+
+ if((pnode = match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL)
+ {
+ rdata = pnode->data;
+ rdata->time = CurrentTime;
+ rdata->count++;
+ }
+ else
+ {
+ int bitlen = 32;
+#ifdef IPV6
+ if(client_p->localClient->ip.ss_family == AF_INET6)
+ bitlen = 128;
+#endif
+ pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);
+ pnode->data = rdata = MyMalloc(sizeof(struct reject_data));
+ dlinkAddTail(pnode, &rdata->rnode, &reject_list);
+ rdata->time = CurrentTime;
+ rdata->count = 1;
+ }
+}
+
+int
+check_reject(struct Client *client_p)
+{
+ patricia_node_t *pnode;
+ struct reject_data *rdata;
+
+ /* Reject is disabled */
+ if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
+ ConfigFileEntry.reject_duration == 0)
+ return 0;
+
+ pnode = match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip);
+ if(pnode != NULL)
+ {
+ rdata = pnode->data;
+
+ rdata->time = CurrentTime;
+ if(rdata->count > ConfigFileEntry.reject_after_count)
+ {
+ ServerStats->is_rej++;
+ SetReject(client_p);
+ comm_setselect(client_p->localClient->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0);
+ SetClosing(client_p);
+ dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit);
+ return 1;
+ }
+ }
+ /* Caller does what it wants */
+ return 0;
+}
+
+void
+flush_reject(void)
+{
+ dlink_node *ptr, *next;
+ patricia_node_t *pnode;
+ struct reject_data *rdata;
+
+ DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
+ {
+ pnode = ptr->data;
+ rdata = pnode->data;
+ dlinkDelete(ptr, &reject_list);
+ MyFree(rdata);
+ patricia_remove(reject_tree, pnode);
+ }
+}
+
+int
+remove_reject(const char *ip)
+{
+ patricia_node_t *pnode;
+
+ /* Reject is disabled */
+ if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
+ ConfigFileEntry.reject_duration == 0)
+ return -1;
+
+ if((pnode = match_string(reject_tree, ip)) != NULL)
+ {
+ struct reject_data *rdata = pnode->data;
+ dlinkDelete(&rdata->rnode, &reject_list);
+ MyFree(rdata);
+ patricia_remove(reject_tree, pnode);
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * A rewrite of Darren Reeds original res.c As there is nothing
+ * left of Darrens original code, this is now licensed by the hybrid group.
+ * (Well, some of the function names are the same, and bits of the structs..)
+ * You can use it where it is useful, free even. Buy us a beer and stuff.
+ *
+ * The authors takes no responsibility for any damage or loss
+ * of property which results from the use of this software.
+ *
+ * $Id: res.c 2023 2006-09-02 23:47:27Z jilles $
+ * from Hybrid Id: res.c 459 2006-02-12 22:21:37Z db $
+ *
+ * July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
+ * added callbacks and reference counting of returned hostents.
+ * --Bleep (Thomas Helvey <tomh@inxpress.net>)
+ *
+ * This was all needlessly complicated for irc. Simplified. No more hostent
+ * All we really care about is the IP -> hostname mappings. Thats all.
+ *
+ * Apr 28, 2003 --cryogen and Dianora
+ *
+ * DNS server flooding lessened, AAAA-or-A lookup removed, ip6.int support
+ * removed, various robustness fixes
+ *
+ * 2006 --jilles and nenolod
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "common.h"
+#include "ircd.h"
+#include "commio.h"
+#include "res.h"
+#include "reslib.h"
+#include "tools.h"
+#include "event.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "numeric.h"
+#include "client.h" /* SNO_* */
+
+#if (CHAR_BIT != 8)
+#error this code needs to be able to address individual octets
+#endif
+
+static PF res_readreply;
+
+#define MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
+#define RES_MAXALIASES 35 /* maximum aliases allowed */
+#define RES_MAXADDRS 35 /* maximum addresses allowed */
+#define AR_TTL 600 /* TTL in seconds for dns cache entries */
+
+/* RFC 1104/1105 wasn't very helpful about what these fields
+ * should be named, so for now, we'll just name them this way.
+ * we probably should look at what named calls them or something.
+ */
+#define TYPE_SIZE (size_t)2
+#define CLASS_SIZE (size_t)2
+#define TTL_SIZE (size_t)4
+#define RDLENGTH_SIZE (size_t)2
+#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
+
+typedef enum
+{
+ REQ_IDLE, /* We're doing not much at all */
+ REQ_PTR, /* Looking up a PTR */
+ REQ_A, /* Looking up an A or AAAA */
+ REQ_CNAME /* We got a CNAME in response, we better get a real answer next */
+} request_state;
+
+struct reslist
+{
+ dlink_node node;
+ int id;
+ int sent; /* number of requests sent */
+ request_state state; /* State the resolver machine is in */
+ time_t ttl;
+ char type;
+ char queryname[128]; /* name currently being queried */
+ char retries; /* retry counter */
+ char sends; /* number of sends (>1 means resent) */
+ char resend; /* send flag. 0 == dont resend */
+ time_t sentat;
+ time_t timeout;
+ struct irc_sockaddr_storage addr;
+ char *name;
+ struct DNSQuery *query; /* query callback for this request */
+};
+
+static int res_fd;
+static dlink_list request_list = { NULL, NULL, 0 };
+
+static void rem_request(struct reslist *request);
+static struct reslist *make_request(struct DNSQuery *query);
+static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request, int);
+static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *,
+ struct reslist *request);
+static void query_name(struct reslist *request);
+static int send_res_msg(const char *buf, int len, int count);
+static void resend_query(struct reslist *request);
+static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob);
+static int proc_answer(struct reslist *request, HEADER * header, char *, char *);
+static struct reslist *find_id(int id);
+static struct DNSReply *make_dnsreply(struct reslist *request);
+
+extern struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
+extern int irc_nscount;
+extern char irc_domain[HOSTLEN + 1];
+
+
+/*
+ * int
+ * res_ourserver(inp)
+ * looks up "inp" in irc_nsaddr_list[]
+ * returns:
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ * revised for ircd, cryogen(stu) may03
+ */
+static int res_ourserver(const struct irc_sockaddr_storage *inp)
+{
+#ifdef IPV6
+ struct sockaddr_in6 *v6;
+ struct sockaddr_in6 *v6in = (struct sockaddr_in6 *)inp;
+#endif
+ struct sockaddr_in *v4;
+ struct sockaddr_in *v4in = (struct sockaddr_in *)inp;
+ int ns;
+
+ for (ns = 0; ns < irc_nscount; ns++)
+ {
+ const struct irc_sockaddr_storage *srv = &irc_nsaddr_list[ns];
+#ifdef IPV6
+ v6 = (struct sockaddr_in6 *)srv;
+#endif
+ v4 = (struct sockaddr_in *)srv;
+
+ /* could probably just memcmp(srv, inp, srv.ss_len) here
+ * but we'll air on the side of caution - stu
+ */
+ switch (srv->ss_family)
+ {
+#ifdef IPV6
+ case AF_INET6:
+ if (srv->ss_family == inp->ss_family)
+ if (v6->sin6_port == v6in->sin6_port)
+ if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
+ sizeof(struct in6_addr)) == 0) ||
+ (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
+ sizeof(struct in6_addr)) == 0))
+ return 1;
+ break;
+#endif
+ case AF_INET:
+ if (srv->ss_family == inp->ss_family)
+ if (v4->sin_port == v4in->sin_port)
+ if ((v4->sin_addr.s_addr == INADDR_ANY)
+ || (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
+ return 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * timeout_query_list - Remove queries from the list which have been
+ * there too long without being resolved.
+ */
+static time_t timeout_query_list(time_t now)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct reslist *request;
+ time_t next_time = 0;
+ time_t timeout = 0;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
+ {
+ request = ptr->data;
+ timeout = request->sentat + request->timeout;
+
+ if (now >= timeout)
+ {
+ if (--request->retries <= 0)
+ {
+ (*request->query->callback) (request->query->ptr, NULL);
+ rem_request(request);
+ continue;
+ }
+ else
+ {
+ request->sentat = now;
+ request->timeout += request->timeout;
+ resend_query(request);
+ }
+ }
+
+ if ((next_time == 0) || timeout < next_time)
+ {
+ next_time = timeout;
+ }
+ }
+
+ return (next_time > now) ? next_time : (now + AR_TTL);
+}
+
+/*
+ * timeout_resolver - check request list
+ */
+static void timeout_resolver(void *notused)
+{
+ timeout_query_list(CurrentTime);
+}
+
+/*
+ * start_resolver - do everything we need to read the resolv.conf file
+ * and initialize the resolver file descriptor if needed
+ */
+static void start_resolver(void)
+{
+ irc_res_init();
+
+ if (res_fd <= 0) /* there isn't any such thing as fd 0, that's just a myth. */
+ {
+ if ((res_fd = comm_socket(irc_nsaddr_list[0].ss_family, SOCK_DGRAM, 0,
+ "UDP resolver socket")) == -1)
+ return;
+
+ /* At the moment, the resolver FD data is global .. */
+ comm_setselect(res_fd, FDLIST_NONE, COMM_SELECT_READ, res_readreply, NULL, 0);
+ eventAdd("timeout_resolver", timeout_resolver, NULL, 1);
+ }
+}
+
+/*
+ * init_resolver - initialize resolver and resolver library
+ */
+void init_resolver(void)
+{
+#ifdef HAVE_SRAND48
+ srand48(CurrentTime);
+#endif
+ start_resolver();
+}
+
+/*
+ * restart_resolver - reread resolv.conf, reopen socket
+ */
+void restart_resolver(void)
+{
+ comm_close(res_fd);
+ res_fd = -1;
+ eventDelete(timeout_resolver, NULL); /* -ddosen */
+ start_resolver();
+}
+
+/*
+ * add_local_domain - Add the domain to hostname, if it is missing
+ * (as suggested by eps@TOASTER.SFSU.EDU)
+ */
+void add_local_domain(char *hname, size_t size)
+{
+ /* try to fix up unqualified names */
+ if (strchr(hname, '.') == NULL)
+ {
+ if (irc_domain[0])
+ {
+ size_t len = strlen(hname);
+
+ if ((strlen(irc_domain) + len + 2) < size)
+ {
+ hname[len++] = '.';
+ strcpy(hname + len, irc_domain);
+ }
+ }
+ }
+}
+
+/*
+ * rem_request - remove a request from the list.
+ * This must also free any memory that has been allocated for
+ * temporary storage of DNS results.
+ */
+static void rem_request(struct reslist *request)
+{
+ dlinkDelete(&request->node, &request_list);
+ MyFree(request->name);
+ MyFree(request);
+}
+
+/*
+ * make_request - Create a DNS request record for the server.
+ */
+static struct reslist *make_request(struct DNSQuery *query)
+{
+ struct reslist *request = MyMalloc(sizeof(struct reslist));
+
+ request->sentat = CurrentTime;
+ request->retries = 3;
+ request->resend = 1;
+ request->timeout = 4; /* start at 4 and exponential inc. */
+ request->query = query;
+ request->state = REQ_IDLE;
+
+ dlinkAdd(request, &request->node, &request_list);
+
+ return request;
+}
+
+/*
+ * delete_resolver_queries - cleanup outstanding queries
+ * for which there no longer exist clients or conf lines.
+ */
+void delete_resolver_queries(const struct DNSQuery *query)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct reslist *request;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
+ {
+ if ((request = ptr->data) != NULL)
+ {
+ if (query == request->query)
+ rem_request(request);
+ }
+ }
+}
+
+/*
+ * send_res_msg - sends msg to all nameservers found in the "_res" structure.
+ * This should reflect /etc/resolv.conf. We will get responses
+ * which arent needed but is easier than checking to see if nameserver
+ * isnt present. Returns number of messages successfully sent to
+ * nameservers or -1 if no successful sends.
+ */
+static int send_res_msg(const char *msg, int len, int rcount)
+{
+ int i;
+ int sent = 0;
+ int max_queries = IRCD_MIN(irc_nscount, rcount);
+
+ /* RES_PRIMARY option is not implemented
+ * if (res.options & RES_PRIMARY || 0 == max_queries)
+ */
+ if (max_queries == 0)
+ max_queries = 1;
+
+ for (i = 0; i < max_queries; i++)
+ {
+ if (sendto(res_fd, msg, len, 0,
+ (struct sockaddr *)&(irc_nsaddr_list[i]),
+ GET_SS_LEN(irc_nsaddr_list[i])) == len)
+ ++sent;
+ }
+
+ return (sent);
+}
+
+/*
+ * find_id - find a dns request id (id is determined by dn_mkquery)
+ */
+static struct reslist *find_id(int id)
+{
+ dlink_node *ptr;
+ struct reslist *request;
+
+ DLINK_FOREACH(ptr, request_list.head)
+ {
+ request = ptr->data;
+
+ if (request->id == id)
+ return (request);
+ }
+
+ return (NULL);
+}
+
+/*
+ * gethost_byname_type - get host address from name
+ *
+ */
+void gethost_byname_type(const char *name, struct DNSQuery *query, int type)
+{
+ assert(name != 0);
+ do_query_name(query, name, NULL, type);
+}
+
+/*
+ * gethost_byaddr - get host name from address
+ */
+void gethost_byaddr(const struct irc_sockaddr_storage *addr, struct DNSQuery *query)
+{
+ do_query_number(query, addr, NULL);
+}
+
+/*
+ * do_query_name - nameserver lookup name
+ */
+static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request,
+ int type)
+{
+ char host_name[HOSTLEN + 1];
+
+ strlcpy(host_name, name, HOSTLEN);
+ add_local_domain(host_name, HOSTLEN);
+
+ if (request == NULL)
+ {
+ request = make_request(query);
+ request->name = (char *)MyMalloc(strlen(host_name) + 1);
+ strcpy(request->name, host_name);
+ request->state = REQ_A;
+ }
+
+ strlcpy(request->queryname, host_name, sizeof(request->queryname));
+ request->type = type;
+ query_name(request);
+}
+
+/*
+ * do_query_number - Use this to do reverse IP# lookups.
+ */
+static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *addr,
+ struct reslist *request)
+{
+ const unsigned char *cp;
+
+ if (request == NULL)
+ {
+ request = make_request(query);
+ memcpy(&request->addr, addr, sizeof(struct irc_sockaddr_storage));
+ request->name = (char *)MyMalloc(HOSTLEN + 1);
+ }
+
+ if (addr->ss_family == AF_INET)
+ {
+ struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
+ cp = (const unsigned char *)&v4->sin_addr.s_addr;
+
+ ircsprintf(request->queryname, "%u.%u.%u.%u.in-addr.arpa", (unsigned int)(cp[3]),
+ (unsigned int)(cp[2]), (unsigned int)(cp[1]), (unsigned int)(cp[0]));
+ }
+#ifdef IPV6
+ else if (addr->ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
+ cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
+
+ (void)sprintf(request->queryname, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
+ "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
+ (unsigned int)(cp[15] & 0xf), (unsigned int)(cp[15] >> 4),
+ (unsigned int)(cp[14] & 0xf), (unsigned int)(cp[14] >> 4),
+ (unsigned int)(cp[13] & 0xf), (unsigned int)(cp[13] >> 4),
+ (unsigned int)(cp[12] & 0xf), (unsigned int)(cp[12] >> 4),
+ (unsigned int)(cp[11] & 0xf), (unsigned int)(cp[11] >> 4),
+ (unsigned int)(cp[10] & 0xf), (unsigned int)(cp[10] >> 4),
+ (unsigned int)(cp[9] & 0xf), (unsigned int)(cp[9] >> 4),
+ (unsigned int)(cp[8] & 0xf), (unsigned int)(cp[8] >> 4),
+ (unsigned int)(cp[7] & 0xf), (unsigned int)(cp[7] >> 4),
+ (unsigned int)(cp[6] & 0xf), (unsigned int)(cp[6] >> 4),
+ (unsigned int)(cp[5] & 0xf), (unsigned int)(cp[5] >> 4),
+ (unsigned int)(cp[4] & 0xf), (unsigned int)(cp[4] >> 4),
+ (unsigned int)(cp[3] & 0xf), (unsigned int)(cp[3] >> 4),
+ (unsigned int)(cp[2] & 0xf), (unsigned int)(cp[2] >> 4),
+ (unsigned int)(cp[1] & 0xf), (unsigned int)(cp[1] >> 4),
+ (unsigned int)(cp[0] & 0xf), (unsigned int)(cp[0] >> 4));
+ }
+#endif
+
+ request->type = T_PTR;
+ query_name(request);
+}
+
+/*
+ * query_name - generate a query based on class, type and name.
+ */
+static void query_name(struct reslist *request)
+{
+ char buf[MAXPACKET];
+ int request_len = 0;
+
+ memset(buf, 0, sizeof(buf));
+
+ if ((request_len =
+ irc_res_mkquery(request->queryname, C_IN, request->type, (unsigned char *)buf, sizeof(buf))) > 0)
+ {
+ HEADER *header = (HEADER *) buf;
+#ifndef HAVE_LRAND48
+ int k = 0;
+ struct timeval tv;
+#endif
+ /*
+ * generate an unique id
+ * NOTE: we don't have to worry about converting this to and from
+ * network byte order, the nameserver does not interpret this value
+ * and returns it unchanged
+ */
+#ifdef HAVE_LRAND48
+ do
+ {
+ header->id = (header->id + lrand48()) & 0xffff;
+ } while (find_id(header->id));
+#else
+ gettimeofday(&tv, NULL);
+ do
+ {
+ header->id = (header->id + k + tv.tv_usec) & 0xffff;
+ k++;
+ } while (find_id(header->id));
+#endif /* HAVE_LRAND48 */
+ request->id = header->id;
+ ++request->sends;
+
+ request->sent += send_res_msg(buf, request_len, request->sends);
+ }
+}
+
+static void resend_query(struct reslist *request)
+{
+ if (request->resend == 0)
+ return;
+
+ switch (request->type)
+ {
+ case T_PTR:
+ do_query_number(NULL, &request->addr, request);
+ break;
+ case T_A:
+#ifdef IPV6
+ case T_AAAA:
+#endif
+ do_query_name(NULL, request->name, request, request->type);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * check_question - check if the reply really belongs to the
+ * name we queried (to guard against late replies from previous
+ * queries with the same id).
+ */
+static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob)
+{
+ char hostbuf[128]; /* working buffer */
+ unsigned char *current; /* current position in buf */
+ int n; /* temp count */
+
+ current = (unsigned char *)buf + sizeof(HEADER);
+ if (header->qdcount != 1)
+ return 0;
+ n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
+ sizeof(hostbuf));
+ if (n <= 0)
+ return 0;
+ if (strcasecmp(hostbuf, request->queryname))
+ return 0;
+ return 1;
+}
+
+/*
+ * proc_answer - process name server reply
+ */
+static int proc_answer(struct reslist *request, HEADER * header, char *buf, char *eob)
+{
+ char hostbuf[HOSTLEN + 100]; /* working buffer */
+ unsigned char *current; /* current position in buf */
+ int query_class; /* answer class */
+ int type; /* answer type */
+ int n; /* temp count */
+ int rd_length;
+ struct sockaddr_in *v4; /* conversion */
+#ifdef IPV6
+ struct sockaddr_in6 *v6;
+#endif
+ current = (unsigned char *)buf + sizeof(HEADER);
+
+ for (; header->qdcount > 0; --header->qdcount)
+ {
+ if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0)
+ return 0;
+
+ current += (size_t) n + QFIXEDSZ;
+ }
+
+ /*
+ * process each answer sent to us blech.
+ */
+ while (header->ancount > 0 && (char *)current < eob)
+ {
+ header->ancount--;
+
+ n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
+ sizeof(hostbuf));
+
+ if (n < 0)
+ {
+ /*
+ * broken message
+ */
+ return (0);
+ }
+ else if (n == 0)
+ {
+ /*
+ * no more answers left
+ */
+ return (0);
+ }
+
+ hostbuf[HOSTLEN] = '\0';
+
+ /* With Address arithmetic you have to be very anal
+ * this code was not working on alpha due to that
+ * (spotted by rodder/jailbird/dianora)
+ */
+ current += (size_t) n;
+
+ if (!(((char *)current + ANSWER_FIXED_SIZE) < eob))
+ break;
+
+ type = irc_ns_get16(current);
+ current += TYPE_SIZE;
+
+ query_class = irc_ns_get16(current);
+ current += CLASS_SIZE;
+
+ request->ttl = irc_ns_get32(current);
+ current += TTL_SIZE;
+
+ rd_length = irc_ns_get16(current);
+ current += RDLENGTH_SIZE;
+
+ /*
+ * Wait to set request->type until we verify this structure
+ */
+ switch (type)
+ {
+ case T_A:
+ if (request->type != T_A)
+ return (0);
+
+ /*
+ * check for invalid rd_length or too many addresses
+ */
+ if (rd_length != sizeof(struct in_addr))
+ return (0);
+ v4 = (struct sockaddr_in *)&request->addr;
+ SET_SS_LEN(request->addr, sizeof(struct sockaddr_in));
+ v4->sin_family = AF_INET;
+ memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
+ return (1);
+ break;
+#ifdef IPV6
+ case T_AAAA:
+ if (request->type != T_AAAA)
+ return (0);
+ if (rd_length != sizeof(struct in6_addr))
+ return (0);
+ SET_SS_LEN(request->addr, sizeof(struct sockaddr_in6));
+ v6 = (struct sockaddr_in6 *)&request->addr;
+ v6->sin6_family = AF_INET6;
+ memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
+ return (1);
+ break;
+#endif
+ case T_PTR:
+ if (request->type != T_PTR)
+ return (0);
+ n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current,
+ hostbuf, sizeof(hostbuf));
+ if (n < 0)
+ return (0); /* broken message */
+ else if (n == 0)
+ return (0); /* no more answers left */
+
+ strlcpy(request->name, hostbuf, HOSTLEN);
+
+ return (1);
+ break;
+ case T_CNAME: /* first check we already havent started looking
+ into a cname */
+ if (request->type != T_PTR)
+ return (0);
+
+ if (request->state == REQ_CNAME)
+ {
+ n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob,
+ current, hostbuf, sizeof(hostbuf));
+
+ if (n < 0)
+ return (0);
+ return (1);
+ }
+
+ request->state = REQ_CNAME;
+ current += rd_length;
+ break;
+
+ default:
+ /* XXX I'd rather just throw away the entire bogus thing
+ * but its possible its just a broken nameserver with still
+ * valid answers. But lets do some rudimentary logging for now...
+ */
+ ilog(L_MAIN, "irc_res.c bogus type %d", type);
+ break;
+ }
+ }
+
+ return (1);
+}
+
+/*
+ * res_readreply - read a dns reply from the nameserver and process it.
+ */
+static void res_readreply(int fd, void *data)
+{
+ char buf[sizeof(HEADER) + MAXPACKET]
+ /* Sparc and alpha need 16bit-alignment for accessing header->id
+ * (which is uint16_t). Because of the header = (HEADER*) buf;
+ * lateron, this is neeeded. --FaUl
+ */
+#if defined(__sparc__) || defined(__alpha__)
+ __attribute__ ((aligned(16)))
+#endif
+ ;
+ HEADER *header;
+ struct reslist *request = NULL;
+ struct DNSReply *reply = NULL;
+ int rc;
+ int answer_count;
+ socklen_t len = sizeof(struct irc_sockaddr_storage);
+ struct irc_sockaddr_storage lsin;
+
+ rc = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len);
+
+ /* Re-schedule a read *after* recvfrom, or we'll be registering
+ * interest where it'll instantly be ready for read :-) -- adrian
+ */
+ comm_setselect(fd, FDLIST_NONE, COMM_SELECT_READ, res_readreply, NULL, 0);
+ /* Better to cast the sizeof instead of rc */
+ if (rc <= (int)(sizeof(HEADER)))
+ return;
+
+ /*
+ * convert DNS reply reader from Network byte order to CPU byte order.
+ */
+ header = (HEADER *) buf;
+ header->ancount = ntohs(header->ancount);
+ header->qdcount = ntohs(header->qdcount);
+ header->nscount = ntohs(header->nscount);
+ header->arcount = ntohs(header->arcount);
+
+ /*
+ * response for an id which we have already received an answer for
+ * just ignore this response.
+ */
+ if (0 == (request = find_id(header->id)))
+ return;
+
+ /*
+ * check against possibly fake replies
+ */
+ if (!res_ourserver(&lsin))
+ return;
+
+ if (!check_question(request, header, buf, buf + rc))
+ return;
+
+ if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
+ {
+ if (NXDOMAIN == header->rcode)
+ {
+ (*request->query->callback) (request->query->ptr, NULL);
+ rem_request(request);
+ }
+ else
+ {
+ /*
+ * If a bad error was returned, we stop here and dont send
+ * send any more (no retries granted).
+ */
+ (*request->query->callback) (request->query->ptr, NULL);
+ rem_request(request);
+ }
+ return;
+ }
+ /*
+ * If this fails there was an error decoding the received packet,
+ * give up. -- jilles
+ */
+ answer_count = proc_answer(request, header, buf, buf + rc);
+
+ if (answer_count)
+ {
+ if (request->type == T_PTR)
+ {
+ if (request->name == NULL)
+ {
+ /*
+ * got a PTR response with no name, something bogus is happening
+ * don't bother trying again, the client address doesn't resolve
+ */
+ (*request->query->callback) (request->query->ptr, reply);
+ rem_request(request);
+ return;
+ }
+
+ /*
+ * Lookup the 'authoritative' name that we were given for the
+ * ip#.
+ *
+ */
+#ifdef IPV6
+ if (request->addr.ss_family == AF_INET6)
+ gethost_byname_type(request->name, request->query, T_AAAA);
+ else
+#endif
+ gethost_byname_type(request->name, request->query, T_A);
+ rem_request(request);
+ }
+ else
+ {
+ /*
+ * got a name and address response, client resolved
+ */
+ reply = make_dnsreply(request);
+ (*request->query->callback) (request->query->ptr, reply);
+ MyFree(reply);
+ rem_request(request);
+ }
+ }
+ else
+ {
+ /* couldn't decode, give up -- jilles */
+ (*request->query->callback) (request->query->ptr, NULL);
+ rem_request(request);
+ }
+}
+
+static struct DNSReply *make_dnsreply(struct reslist *request)
+{
+ struct DNSReply *cp;
+ s_assert(request != 0);
+
+ cp = (struct DNSReply *)MyMalloc(sizeof(struct DNSReply));
+
+ cp->h_name = request->name;
+ memcpy(&cp->addr, &request->addr, sizeof(cp->addr));
+ return (cp);
+}
+
+void report_dns_servers(struct Client *source_p)
+{
+ int i;
+ char ipaddr[128];
+
+ for (i = 0; i < irc_nscount; i++)
+ {
+ if (!inetntop_sock((struct sockaddr *)&(irc_nsaddr_list[i]),
+ ipaddr, sizeof ipaddr))
+ strlcpy(ipaddr, "?", sizeof ipaddr);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "A %s", ipaddr);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/* Original copyright ISC as above.
+ * Code modified specifically for ircd use from the following orginal files
+ * in bind ...
+ *
+ * res_comp.c
+ * ns_name.c
+ * ns_netint.c
+ * res_init.c
+ *
+ * - Dianora
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "common.h"
+#include "ircd.h"
+#include "commio.h"
+#include "res.h"
+#include "reslib.h"
+#include "tools.h"
+#include "event.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+
+#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
+#define DNS_LABELTYPE_BITSTRING 0x41
+#define MAXLINE 128
+
+/* $Id: reslib.c 1695 2006-06-27 15:11:23Z jilles $ */
+/* from Hybrid Id: reslib.c 177 2005-10-22 09:05:05Z michael $ */
+
+struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
+int irc_nscount = 0;
+char irc_domain[HOSTLEN + 1];
+
+static const char digitvalue[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
+};
+
+static int parse_resvconf(void);
+static void add_nameserver(const char *);
+
+static const char digits[] = "0123456789";
+static int labellen(const unsigned char *lp);
+static int special(int ch);
+static int printable(int ch);
+static int irc_decode_bitstring(const char **cpp, char *dn, const char *eom);
+static int irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz,
+ const unsigned char **dnptrs, const unsigned char **lastdnptr);
+static int irc_dn_find(const unsigned char *, const unsigned char *, const unsigned char * const *,
+ const unsigned char * const *);
+static int irc_encode_bitsring(const char **, const char *, unsigned char **, unsigned char **,
+ const char *);
+static int irc_ns_name_uncompress(const unsigned char *, const unsigned char *,
+ const unsigned char *, char *, size_t);
+static int irc_ns_name_unpack(const unsigned char *, const unsigned char *,
+ const unsigned char *, unsigned char *,
+ size_t);
+static int irc_ns_name_ntop(const char *, char *, size_t);
+static int irc_ns_name_skip(const unsigned char **, const unsigned char *);
+static int mklower(int ch);
+
+int
+irc_res_init(void)
+{
+ irc_nscount = 0;
+ return parse_resvconf();
+}
+
+/* parse_resvconf()
+ *
+ * inputs - NONE
+ * output - -1 if failure 0 if success
+ * side effects - fills in irc_nsaddr_list
+ */
+static int
+parse_resvconf(void)
+{
+ char *p;
+ char *opt;
+ char *arg;
+ char input[MAXLINE];
+ FILE *file;
+
+ /* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps
+ * for cygwin support etc. this hardcodes it to unix for now -db
+ */
+ if ((file = fopen("/etc/resolv.conf", "r")) == NULL)
+ return -1;
+
+ while (fgets(input, sizeof(input), file) != NULL)
+ {
+ /* blow away any newline */
+ if ((p = strpbrk(input, "\r\n")) != NULL)
+ *p = '\0';
+
+ p = input;
+ /* skip until something thats not a space is seen */
+ while (IsSpace(*p))
+ p++;
+ /* if at this point, have a '\0' then continue */
+ if (*p == '\0')
+ continue;
+
+ /* Ignore comment lines immediately */
+ if (*p == '#' || *p == ';')
+ continue;
+
+ /* skip until a space is found */
+ opt = p;
+ while (!IsSpace(*p) && *p != '\0')
+ p++;
+ if (*p == '\0')
+ continue; /* no arguments?.. ignore this line */
+ /* blow away the space character */
+ *p++ = '\0';
+
+ /* skip these spaces that are before the argument */
+ while (IsSpace(*p))
+ p++;
+ /* Now arg should be right where p is pointing */
+ arg = p;
+ if ((p = strpbrk(arg, " \t")) != NULL)
+ *p = '\0'; /* take the first word */
+
+ if (irccmp(opt, "domain") == 0)
+ strlcpy(irc_domain, arg, sizeof(irc_domain));
+ else if (irccmp(opt, "nameserver") == 0)
+ add_nameserver(arg);
+ }
+
+ fclose(file);
+ return 0;
+}
+
+/* add_nameserver()
+ *
+ * input - either an IPV4 address in dotted quad
+ * or an IPV6 address in : format
+ * output - NONE
+ * side effects - entry in irc_nsaddr_list is filled in as needed
+ */
+static void
+add_nameserver(const char *arg)
+{
+ struct addrinfo hints, *res;
+
+ /* Done max number of nameservers? */
+ if (irc_nscount >= IRCD_MAXNS)
+ {
+ ilog (L_MAIN, "Too many nameservers, ignoring %s", arg);
+ return;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+
+ if (getaddrinfo(arg, "domain", &hints, &res))
+ return;
+
+ if (res == NULL)
+ return;
+
+ memcpy(&irc_nsaddr_list[irc_nscount], res->ai_addr, res->ai_addrlen);
+ SET_SS_LEN(irc_nsaddr_list[irc_nscount], res->ai_addrlen);
+ irc_nscount++;
+ freeaddrinfo(res);
+}
+
+/*
+ * Expand compressed domain name 'comp_dn' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eomorig' points to the first location after the message,
+ * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int
+irc_dn_expand(const unsigned char *msg, const unsigned char *eom,
+ const unsigned char *src, char *dst, int dstsiz)
+{
+ int n = irc_ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+
+ if (n > 0 && dst[0] == '.')
+ dst[0] = '\0';
+ return(n);
+}
+
+/*
+ * irc_ns_name_uncompress(msg, eom, src, dst, dstsiz)
+ * Expand compressed domain name to presentation format.
+ * return:
+ * Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ * Root domain returns as "." not "".
+ */
+static int
+irc_ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
+ const unsigned char *src, char *dst, size_t dstsiz)
+{
+ unsigned char tmp[NS_MAXCDNAME];
+ int n;
+
+ if ((n = irc_ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+ return(-1);
+ if (irc_ns_name_ntop((char*)tmp, dst, dstsiz) == -1)
+ return(-1);
+ return(n);
+}
+/*
+ * irc_ns_name_unpack(msg, eom, src, dst, dstsiz)
+ * Unpack a domain name from a message, source may be compressed.
+ * return:
+ * -1 if it fails, or consumed octets if it succeeds.
+ */
+static int
+irc_ns_name_unpack(const unsigned char *msg, const unsigned char *eom,
+ const unsigned char *src, unsigned char *dst,
+ size_t dstsiz)
+{
+ const unsigned char *srcp, *dstlim;
+ unsigned char *dstp;
+ int n, len, checked, l;
+
+ len = -1;
+ checked = 0;
+ dstp = dst;
+ srcp = src;
+ dstlim = dst + dstsiz;
+ if (srcp < msg || srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ /* Fetch next label in domain name. */
+ while ((n = *srcp++) != 0) {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS) {
+ case 0:
+ case NS_TYPE_ELT:
+ /* Limit checks. */
+ if ((l = labellen(srcp - 1)) < 0) {
+ errno = EMSGSIZE;
+ return(-1);
+ }
+ if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += l + 1;
+ *dstp++ = n;
+ memcpy(dstp, srcp, l);
+ dstp += l;
+ srcp += l;
+ break;
+
+ case NS_CMPRSFLGS:
+ if (srcp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (len < 0)
+ len = srcp - src + 1;
+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+ if (srcp < msg || srcp >= eom) { /* Out of range. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eom - msg) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ break;
+
+ default:
+ errno = EMSGSIZE;
+ return (-1); /* flag error */
+ }
+ }
+ *dstp = '\0';
+ if (len < 0)
+ len = srcp - src;
+ return (len);
+}
+
+/*
+ * irc_ns_name_ntop(src, dst, dstsiz)
+ * Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * The root is returned as "."
+ * All other domains are returned in non absolute form
+ */
+static int
+irc_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
+{
+ const char *cp;
+ char *dn, *eom;
+ unsigned char c;
+ unsigned int n;
+ int l;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (dn != dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if ((l = labellen((unsigned char*)(cp - 1))) < 0) {
+ errno = EMSGSIZE; /* XXX */
+ return(-1);
+ }
+ if (dn + l >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
+ int m;
+
+ if (n != DNS_LABELTYPE_BITSTRING) {
+ /* XXX: labellen should reject this case */
+ errno = EINVAL;
+ return(-1);
+ }
+ if ((m = irc_decode_bitstring(&cp, dn, eom)) < 0)
+ {
+ errno = EMSGSIZE;
+ return(-1);
+ }
+ dn += m;
+ continue;
+ }
+ for ((void)NULL; l > 0; l--) {
+ c = *cp++;
+ if (special(c)) {
+ if (dn + 1 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = (char)c;
+ } else if (!printable(c)) {
+ if (dn + 3 >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\\';
+ *dn++ = digits[c / 100];
+ *dn++ = digits[(c % 100) / 10];
+ *dn++ = digits[c % 10];
+ } else {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = (char)c;
+ }
+ }
+ }
+ if (dn == dst) {
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '.';
+ }
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+static int
+irc_dn_comp(const char *src, unsigned char *dst, int dstsiz,
+ unsigned char **dnptrs, unsigned char **lastdnptr)
+{
+ return(irc_ns_name_compress(src, dst, (size_t)dstsiz,
+ (const unsigned char **)dnptrs,
+ (const unsigned char **)lastdnptr));
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+irc_dn_skipname(const unsigned char *ptr, const unsigned char *eom) {
+ const unsigned char *saveptr = ptr;
+
+ if (irc_ns_name_skip(&ptr, eom) == -1)
+ return(-1);
+ return(ptr - saveptr);
+}
+
+/*
+ * ns_name_skip(ptrptr, eom)
+ * Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ * 0 on success, -1 (with errno set) on failure.
+ */
+static int
+irc_ns_name_skip(const unsigned char **ptrptr, const unsigned char *eom)
+{
+ const unsigned char *cp;
+ unsigned int n;
+ int l;
+
+ cp = *ptrptr;
+
+ while (cp < eom && (n = *cp++) != 0)
+ {
+ /* Check for indirection. */
+ switch (n & NS_CMPRSFLGS)
+ {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case NS_TYPE_ELT: /* EDNS0 extended label */
+ if ((l = labellen(cp - 1)) < 0)
+ {
+ errno = EMSGSIZE; /* XXX */
+ return(-1);
+ }
+
+ cp += l;
+ continue;
+ case NS_CMPRSFLGS: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return(-1);
+ }
+
+ break;
+ }
+
+ if (cp > eom)
+ {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+
+ *ptrptr = cp;
+ return(0);
+}
+
+unsigned int
+irc_ns_get16(const unsigned char *src)
+{
+ unsigned int dst;
+
+ IRC_NS_GET16(dst, src);
+ return(dst);
+}
+
+unsigned long
+irc_ns_get32(const unsigned char *src)
+{
+ unsigned long dst;
+
+ IRC_NS_GET32(dst, src);
+ return(dst);
+}
+
+void
+irc_ns_put16(unsigned int src, unsigned char *dst)
+{
+ IRC_NS_PUT16(src, dst);
+}
+
+void
+irc_ns_put32(unsigned long src, unsigned char *dst)
+{
+ IRC_NS_PUT32(src, dst);
+}
+
+/* From ns_name.c */
+
+/*
+ * special(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this characted special ("in need of quoting") ?
+ * return:
+ * boolean.
+ */
+static int
+special(int ch)
+{
+ switch (ch)
+ {
+ case 0x22: /* '"' */
+ case 0x2E: /* '.' */
+ case 0x3B: /* ';' */
+ case 0x5C: /* '\\' */
+ case 0x28: /* '(' */
+ case 0x29: /* ')' */
+ /* Special modifiers in zone files. */
+ case 0x40: /* '@' */
+ case 0x24: /* '$' */
+ return(1);
+ default:
+ return(0);
+ }
+}
+
+static int
+labellen(const unsigned char *lp)
+{
+ int bitlen;
+ unsigned char l = *lp;
+
+ if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS)
+ {
+ /* should be avoided by the caller */
+ return(-1);
+ }
+
+ if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT)
+ {
+ if (l == DNS_LABELTYPE_BITSTRING)
+ {
+ if ((bitlen = *(lp + 1)) == 0)
+ bitlen = 256;
+ return((bitlen + 7 ) / 8 + 1);
+ }
+
+ return(-1); /* unknwon ELT */
+ }
+
+ return(l);
+}
+
+
+/*
+ * printable(ch)
+ * Thinking in noninternationalized USASCII (per the DNS spec),
+ * is this character visible and not a space when printed ?
+ * return:
+ * boolean.
+ */
+static int
+printable(int ch)
+{
+ return(ch > 0x20 && ch < 0x7f);
+}
+
+static int
+irc_decode_bitstring(const char **cpp, char *dn, const char *eom)
+{
+ const char *cp = *cpp;
+ char *beg = dn, tc;
+ int b, blen, plen;
+
+ if ((blen = (*cp & 0xff)) == 0)
+ blen = 256;
+ plen = (blen + 3) / 4;
+ plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
+ if (dn + plen >= eom)
+ return(-1);
+
+ cp++;
+ dn += sprintf(dn, "\\[x");
+ for (b = blen; b > 7; b -= 8, cp++)
+ dn += sprintf(dn, "%02x", *cp & 0xff);
+ if (b > 4) {
+ tc = *cp++;
+ dn += sprintf(dn, "%02x", tc & (0xff << (8 - b)));
+ } else if (b > 0) {
+ tc = *cp++;
+ dn += sprintf(dn, "%1x",
+ ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
+ }
+ dn += sprintf(dn, "/%d]", blen);
+
+ *cpp = cp;
+ return(dn - beg);
+}
+
+/*
+ * irc_ns_name_pton(src, dst, dstsiz)
+ * Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ * -1 if it fails
+ * 1 if string was fully qualified
+ * 0 is string was not fully qualified
+ * notes:
+ * Enforces label and domain length limits.
+ */
+static int
+irc_ns_name_pton(const char *src, unsigned char *dst, size_t dstsiz)
+{
+ unsigned char *label, *bp, *eom;
+ char *cp;
+ int c, n, escaped, e = 0;
+
+ escaped = 0;
+ bp = dst;
+ eom = dst + dstsiz;
+ label = bp++;
+
+
+ while ((c = *src++) != 0) {
+ if (escaped) {
+ if (c == '[') { /* start a bit string label */
+ if ((cp = strchr(src, ']')) == NULL) {
+ errno = EINVAL; /* ??? */
+ return(-1);
+ }
+ if ((e = irc_encode_bitsring(&src,
+ cp + 2,
+ &label,
+ &bp,
+ (const char *)eom))
+ != 0) {
+ errno = e;
+ return(-1);
+ }
+ escaped = 0;
+ label = bp++;
+ if ((c = *src++) == 0)
+ goto done;
+ else if (c != '.') {
+ errno = EINVAL;
+ return(-1);
+ }
+ continue;
+ }
+ else if ((cp = strchr(digits, c)) != NULL) {
+ n = (cp - digits) * 100;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits) * 10;
+ if ((c = *src++) == 0 ||
+ (cp = strchr(digits, c)) == NULL) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ n += (cp - digits);
+ if (n > 255) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ c = n;
+ }
+ escaped = 0;
+ } else if (c == '\\') {
+ escaped = 1;
+ continue;
+ } else if (c == '.') {
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ /* Fully qualified ? */
+ if (*src == '\0') {
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = '\0';
+ }
+ if ((bp - dst) > NS_MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return (1);
+ }
+ if (c == 0 || *src == '.') {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ label = bp++;
+ continue;
+ }
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = (unsigned char)c;
+ }
+ c = (bp - label - 1);
+ if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ done:
+ if (label >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *label = c;
+ if (c != 0) {
+ if (bp >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *bp++ = 0;
+ }
+
+ if ((bp - dst) > NS_MAXCDNAME)
+ { /* src too big */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * irc_ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ * Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ * Size of the compressed name, or -1.
+ * notes:
+ * 'dnptrs' is an array of pointers to previous compressed names.
+ * dnptrs[0] is a pointer to the beginning of the message. The array
+ * ends with NULL.
+ * 'lastdnptr' is a pointer to the end of the array pointed to
+ * by 'dnptrs'.
+ * Side effects:
+ * The list of pointers in dnptrs is updated for labels inserted into
+ * the message as we compress the name. If 'dnptr' is NULL, we don't
+ * try to compress names. If 'lastdnptr' is NULL, we don't update the
+ * list.
+ */
+static int
+irc_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz,
+ const unsigned char **dnptrs, const unsigned char **lastdnptr)
+{
+ unsigned char *dstp;
+ const unsigned char **cpp, **lpp, *eob, *msg;
+ const unsigned char *srcp;
+ int n, l, first = 1;
+
+ srcp = src;
+ dstp = dst;
+ eob = dstp + dstsiz;
+ lpp = cpp = NULL;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ (void)NULL;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+
+ /* make sure the domain we are about to add is legal */
+ l = 0;
+ do {
+ int l0;
+
+ n = *srcp;
+ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ if ((l0 = labellen(srcp)) < 0) {
+ errno = EINVAL;
+ return(-1);
+ }
+ l += l0 + 1;
+ if (l > NS_MAXCDNAME) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ srcp += l0 + 1;
+ } while (n != 0);
+
+ /* from here on we need to reset compression pointer array on error */
+ srcp = src;
+ do {
+ /* Look to see if we can use pointers. */
+ n = *srcp;
+ if (n != 0 && msg != NULL) {
+ l = irc_dn_find(srcp, msg, (const unsigned char * const *)dnptrs,
+ (const unsigned char * const *)lpp);
+ if (l >= 0) {
+ if (dstp + 1 >= eob) {
+ goto cleanup;
+ }
+ *dstp++ = (l >> 8) | NS_CMPRSFLGS;
+ *dstp++ = l % 256;
+ return (dstp - dst);
+ }
+ /* Not found, save it. */
+ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+ (dstp - msg) < 0x4000 && first) {
+ *cpp++ = dstp;
+ *cpp = NULL;
+ first = 0;
+ }
+ }
+ /* copy label to buffer */
+ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+ /* Should not happen. */
+ goto cleanup;
+ }
+ n = labellen(srcp);
+ if (dstp + 1 + n >= eob) {
+ goto cleanup;
+ }
+ memcpy(dstp, srcp, n + 1);
+ srcp += n + 1;
+ dstp += n + 1;
+ } while (n != 0);
+
+ if (dstp > eob) {
+cleanup:
+ if (msg != NULL)
+ *lpp = NULL;
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ return(dstp - dst);
+}
+
+static int
+irc_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz,
+ const unsigned char **dnptrs, const unsigned char **lastdnptr)
+{
+ unsigned char tmp[NS_MAXCDNAME];
+
+ if (irc_ns_name_pton(src, tmp, sizeof tmp) == -1)
+ return(-1);
+ return(irc_ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+static int
+irc_encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
+ unsigned char **dst, const char *eom)
+{
+ int afterslash = 0;
+ const char *cp = *bp;
+ char *tp, c;
+ const char *beg_blen;
+ char *end_blen = NULL;
+ int value = 0, count = 0, tbcount = 0, blen = 0;
+
+ beg_blen = end_blen = NULL;
+
+ /* a bitstring must contain at least 2 characters */
+ if (end - cp < 2)
+ return(EINVAL);
+
+ /* XXX: currently, only hex strings are supported */
+ if (*cp++ != 'x')
+ return(EINVAL);
+ if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */
+ return(EINVAL);
+
+ for (tp = (char*)(dst + 1); cp < end && tp < eom; cp++) {
+ switch((c = *cp)) {
+ case ']': /* end of the bitstring */
+ if (afterslash) {
+ if (beg_blen == NULL)
+ return(EINVAL);
+ blen = (int)strtol(beg_blen, &end_blen, 10);
+ if (*end_blen != ']')
+ return(EINVAL);
+ }
+ if (count)
+ *tp++ = ((value << 4) & 0xff);
+ cp++; /* skip ']' */
+ goto done;
+ case '/':
+ afterslash = 1;
+ break;
+ default:
+ if (afterslash) {
+ if (!isdigit(c&0xff))
+ return(EINVAL);
+ if (beg_blen == NULL) {
+
+ if (c == '0') {
+ /* blen never begings with 0 */
+ return(EINVAL);
+ }
+ beg_blen = cp;
+ }
+ } else {
+ if (!isxdigit(c&0xff))
+ return(EINVAL);
+ value <<= 4;
+ value += digitvalue[(int)c];
+ count += 4;
+ tbcount += 4;
+ if (tbcount > 256)
+ return(EINVAL);
+ if (count == 8) {
+ *tp++ = value;
+ count = 0;
+ }
+ }
+ break;
+ }
+ }
+ done:
+ if (cp >= end || tp >= eom)
+ return(EMSGSIZE);
+
+ /*
+ * bit length validation:
+ * If a <length> is present, the number of digits in the <bit-data>
+ * MUST be just sufficient to contain the number of bits specified
+ * by the <length>. If there are insignificant bits in a final
+ * hexadecimal or octal digit, they MUST be zero.
+ * RFC 2673, Section 3.2.
+ */
+ if (blen > 0) {
+ int traillen;
+
+ if (((blen + 3) & ~3) != tbcount)
+ return(EINVAL);
+ traillen = tbcount - blen; /* between 0 and 3 */
+ if (((value << (8 - traillen)) & 0xff) != 0)
+ return(EINVAL);
+ }
+ else
+ blen = tbcount;
+ if (blen == 256)
+ blen = 0;
+
+ /* encode the type and the significant bit fields */
+ **labelp = DNS_LABELTYPE_BITSTRING;
+ **dst = blen;
+
+ *bp = cp;
+ *dst = (unsigned char*)tp;
+
+ return(0);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ * Search for the counted-label name in an array of compressed names.
+ * return:
+ * offset from msg if found, or -1.
+ * notes:
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static int
+irc_dn_find(const unsigned char *domain, const unsigned char *msg,
+ const unsigned char * const *dnptrs,
+ const unsigned char * const *lastdnptr)
+{
+ const unsigned char *dn, *cp, *sp;
+ const unsigned char * const *cpp;
+ unsigned int n;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++)
+ {
+ sp = *cpp;
+ /*
+ * terminate search on:
+ * root label
+ * compression pointer
+ * unusable offset
+ */
+ while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
+ (sp - msg) < 0x4000) {
+ dn = domain;
+ cp = sp;
+ while ((n = *cp++) != 0) {
+ /*
+ * check for indirection
+ */
+ switch (n & NS_CMPRSFLGS) {
+ case 0: /* normal case, n == len */
+ n = labellen(cp - 1); /* XXX */
+
+ if (n != *dn++)
+ goto next;
+
+ for ((void)NULL; n > 0; n--)
+ if (mklower(*dn++) !=
+ mklower(*cp++))
+ goto next;
+ /* Is next root for both ? */
+ if (*dn == '\0' && *cp == '\0')
+ return (sp - msg);
+ if (*dn)
+ continue;
+ goto next;
+ case NS_CMPRSFLGS: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ }
+ next: ;
+ sp += *sp + 1;
+ }
+ }
+ errno = ENOENT;
+ return (-1);
+}
+
+/*
+ * * Thinking in noninternationalized USASCII (per the DNS spec),
+ * * convert this character to lower case if it's upper case.
+ * */
+static int
+mklower(int ch)
+{
+ if (ch >= 0x41 && ch <= 0x5A)
+ return(ch + 0x20);
+
+ return(ch);
+}
+
+/* From resolv/mkquery.c */
+
+/*
+ * Form all types of queries.
+ * Returns the size of the result or -1.
+ */
+int
+irc_res_mkquery(
+ const char *dname, /* domain name */
+ int class, int type, /* class and type of query */
+ unsigned char *buf, /* buffer to put query */
+ int buflen) /* size of buffer */
+{
+ HEADER *hp;
+ unsigned char *cp;
+ int n;
+ unsigned char *dnptrs[20], **dpp, **lastdnptr;
+
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ memset(buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+
+ hp->id = 0;
+ hp->opcode = QUERY;
+ hp->rd = 1; /* recurse */
+ hp->rcode = NO_ERRORS;
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+
+ if ((buflen -= QFIXEDSZ) < 0)
+ return (-1);
+ if ((n = irc_dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+
+ cp += n;
+ buflen -= n;
+ IRC_NS_PUT16(type, cp);
+ IRC_NS_PUT16(class, cp);
+ hp->qdcount = htons(1);
+
+ return (cp - buf);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * restart.c: Functions to allow the ircd to restart.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: restart.c 486 2006-01-15 10:36:32Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "restart.h"
+#include "common.h"
+#include "ircd.h"
+#include "send.h"
+#include "s_log.h"
+#include "client.h" /* for FLAGS_ALL */
+#include "memory.h"
+
+/* external var */
+extern char **myargv;
+
+void
+restart(const char *mesg)
+{
+ static int was_here = NO; /* redundant due to restarting flag below */
+
+ if(was_here)
+ abort();
+ was_here = YES;
+
+ ilog(L_MAIN, "Restarting Server because: %s, memory data limit: %ld", mesg, get_maxrss());
+
+ server_reboot();
+}
+
+void
+server_reboot(void)
+{
+ int i;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Restarting server...");
+
+ ilog(L_MAIN, "Restarting server...");
+ /*
+ * XXX we used to call flush_connections() here. But since this routine
+ * doesn't exist anymore, we won't be flushing. This is ok, since
+ * when close handlers come into existance, comm_close() will be called
+ * below, and the data flushing will be implicit.
+ * -- adrian
+ *
+ * bah, for now, the program ain't coming back to here, so forcibly
+ * close everything the "wrong" way for now, and just LEAVE...
+ */
+ for (i = 0; i < MAXCONNECTIONS; ++i)
+ close(i);
+
+ unlink(pidFileName);
+ execv(SPATH, myargv);
+
+ exit(-1);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_auth.c: Functions for querying a users ident.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_auth.c 1683 2006-06-20 14:26:16Z jilles $ */
+
+/*
+ * Changes:
+ * July 6, 1999 - Rewrote most of the code here. When a client connects
+ * to the server and passes initial socket validation checks, it
+ * is owned by this module (auth) which returns it to the rest of the
+ * server when dns and auth queries are finished. Until the client is
+ * released, the server does not know it exists and does not process
+ * any messages from it.
+ * --Bleep Thomas Helvey <tomh@inxpress.net>
+ */
+#include "stdinc.h"
+#include "config.h"
+#include "tools.h"
+#include "s_auth.h"
+#include "s_conf.h"
+#include "client.h"
+#include "common.h"
+#include "event.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "packet.h"
+#include "res.h"
+#include "commio.h"
+#include "s_log.h"
+#include "s_stats.h"
+#include "send.h"
+#include "memory.h"
+#include "hook.h"
+#include "blacklist.h"
+
+/*
+ * a bit different approach
+ * this replaces the original sendheader macros
+ */
+
+static const char *HeaderMessages[] =
+{
+ "NOTICE AUTH :*** Looking up your hostname...",
+ "NOTICE AUTH :*** Found your hostname",
+ "NOTICE AUTH :*** Couldn't look up your hostname",
+ "NOTICE AUTH :*** Checking Ident",
+ "NOTICE AUTH :*** Got Ident response",
+ "NOTICE AUTH :*** No Ident response",
+ "NOTICE AUTH :*** Your hostname is too long, ignoring hostname",
+ "NOTICE AUTH :*** Your forward and reverse DNS do not match, ignoring hostname",
+ "NOTICE AUTH :*** Cannot verify hostname validity, ignoring hostname",
+};
+
+typedef enum
+{
+ REPORT_DO_DNS,
+ REPORT_FIN_DNS,
+ REPORT_FAIL_DNS,
+ REPORT_DO_ID,
+ REPORT_FIN_ID,
+ REPORT_FAIL_ID,
+ REPORT_HOST_TOOLONG,
+ REPORT_HOST_MISMATCH,
+ REPORT_HOST_UNKNOWN
+}
+ReportType;
+
+#define sendheader(c, r) sendto_one(c, HeaderMessages[(r)])
+
+static dlink_list auth_poll_list;
+static BlockHeap *auth_heap;
+static EVH timeout_auth_queries_event;
+
+static PF read_auth_reply;
+static CNCB auth_connect_callback;
+
+/*
+ * init_auth()
+ *
+ * Initialise the auth code
+ */
+void
+init_auth(void)
+{
+ /* This hook takes a struct Client for its argument */
+ memset(&auth_poll_list, 0, sizeof(auth_poll_list));
+ eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
+ auth_heap = BlockHeapCreate(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE);
+}
+
+/*
+ * make_auth_request - allocate a new auth request
+ */
+static struct AuthRequest *
+make_auth_request(struct Client *client)
+{
+ struct AuthRequest *request = BlockHeapAlloc(auth_heap);
+ client->localClient->auth_request = request;
+ request->fd = -1;
+ request->client = client;
+ request->timeout = CurrentTime + ConfigFileEntry.connect_timeout;
+ return request;
+}
+
+/*
+ * free_auth_request - cleanup auth request allocations
+ */
+static void
+free_auth_request(struct AuthRequest *request)
+{
+ BlockHeapFree(auth_heap, request);
+}
+
+/*
+ * release_auth_client - release auth client from auth system
+ * this adds the client into the local client lists so it can be read by
+ * the main io processing loop
+ */
+static void
+release_auth_client(struct AuthRequest *auth)
+{
+ struct Client *client = auth->client;
+
+ if(IsDNSPending(auth) || IsDoingAuth(auth))
+ return;
+
+ client->localClient->auth_request = NULL;
+ dlinkDelete(&auth->node, &auth_poll_list);
+ free_auth_request(auth);
+ if(client->localClient->fd > highest_fd)
+ highest_fd = client->localClient->fd;
+
+ /*
+ * When a client has auth'ed, we want to start reading what it sends
+ * us. This is what read_packet() does.
+ * -- adrian
+ */
+ client->localClient->allow_read = MAX_FLOOD;
+ comm_setflush(client->localClient->fd, 1000, flood_recalc, client);
+ dlinkAddTail(client, &client->node, &global_client_list);
+ read_packet(client->localClient->fd, client);
+}
+
+/*
+ * auth_dns_callback - called when resolver query finishes
+ * if the query resulted in a successful search, hp will contain
+ * a non-null pointer, otherwise hp will be null.
+ * set the client on it's way to a connection completion, regardless
+ * of success of failure
+ */
+static void
+auth_dns_callback(void *vptr, struct DNSReply *reply)
+{
+ struct AuthRequest *auth = (struct AuthRequest *) vptr;
+ ClearDNSPending(auth);
+
+ /* XXX: this shouldn't happen, but it does. -nenolod */
+ if(auth->client->localClient == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "auth_dns_callback(): auth->client->localClient (%s) is NULL", get_client_name(auth->client, HIDE_IP));
+
+ dlinkDelete(&auth->node, &auth_poll_list);
+ free_auth_request(auth);
+
+ /* and they will silently drop through and all will hopefully be ok... -nenolod */
+ return;
+ }
+
+ if(reply)
+ {
+ int good = 1;
+
+ if(auth->client->localClient->ip.ss_family == AF_INET)
+ {
+ struct sockaddr_in *ip, *ip_fwd;
+
+ ip = (struct sockaddr_in *) &auth->client->localClient->ip;
+ ip_fwd = (struct sockaddr_in *) &reply->addr;
+
+ if(ip->sin_addr.s_addr != ip_fwd->sin_addr.s_addr)
+ {
+ sendheader(auth->client, REPORT_HOST_MISMATCH);
+ good = 0;
+ }
+ }
+#ifdef IPV6
+ else if(auth->client->localClient->ip.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *ip, *ip_fwd;
+
+ ip = (struct sockaddr_in6 *) &auth->client->localClient->ip;
+ ip_fwd = (struct sockaddr_in6 *) &reply->addr;
+
+ if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) != 0)
+ {
+ sendheader(auth->client, REPORT_HOST_MISMATCH);
+ good = 0;
+ }
+ }
+#endif
+ else /* can't verify it, don't know how. reject it. */
+ {
+ sendheader(auth->client, REPORT_HOST_UNKNOWN);
+ good = 0;
+ }
+
+ if(good && strlen(reply->h_name) <= HOSTLEN)
+ {
+ strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host));
+ sendheader(auth->client, REPORT_FIN_DNS);
+ }
+ else if (strlen(reply->h_name) > HOSTLEN)
+ sendheader(auth->client, REPORT_HOST_TOOLONG);
+ }
+ else
+ sendheader(auth->client, REPORT_FAIL_DNS);
+
+ release_auth_client(auth);
+}
+
+/*
+ * authsenderr - handle auth send errors
+ */
+static void
+auth_error(struct AuthRequest *auth)
+{
+ ++ServerStats->is_abad;
+
+ comm_close(auth->fd);
+ auth->fd = -1;
+
+ ClearAuth(auth);
+ sendheader(auth->client, REPORT_FAIL_ID);
+
+ release_auth_client(auth);
+}
+
+/*
+ * start_auth_query - Flag the client to show that an attempt to
+ * contact the ident server on
+ * the client's host. The connect and subsequently the socket are all put
+ * into 'non-blocking' mode. Should the connect or any later phase of the
+ * identifing process fail, it is aborted and the user is given a username
+ * of "unknown".
+ */
+static int
+start_auth_query(struct AuthRequest *auth)
+{
+ struct irc_sockaddr_storage localaddr;
+ socklen_t locallen = sizeof(struct irc_sockaddr_storage);
+ int fd;
+ int family;
+
+ if(IsAnyDead(auth->client))
+ return 0;
+
+ family = auth->client->localClient->ip.ss_family;
+ if((fd = comm_socket(family, SOCK_STREAM, 0, "ident")) == -1)
+ {
+ report_error("creating auth stream socket %s:%s",
+ get_client_name(auth->client, SHOW_IP),
+ log_client_name(auth->client, SHOW_IP), errno);
+ ++ServerStats->is_abad;
+ return 0;
+ }
+ if((MAXCONNECTIONS - 10) < fd)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Can't allocate fd for auth on %s",
+ get_client_name(auth->client, SHOW_IP));
+ comm_close(fd);
+ return 0;
+ }
+
+ sendheader(auth->client, REPORT_DO_ID);
+
+ /*
+ * get the local address of the client and bind to that to
+ * make the auth request. This used to be done only for
+ * ifdef VIRTUAL_HOST, but needs to be done for all clients
+ * since the ident request must originate from that same address--
+ * and machines with multiple IP addresses are common now
+ */
+ memset(&localaddr, 0, locallen);
+ getsockname(auth->client->localClient->fd,
+ (struct sockaddr *) &localaddr, &locallen);
+
+ mangle_mapped_sockaddr((struct sockaddr *)&localaddr);
+#ifdef IPV6
+ if(localaddr.ss_family == AF_INET6)
+ {
+ ((struct sockaddr_in6 *)&localaddr)->sin6_port = 0;
+ } else
+#endif
+ ((struct sockaddr_in *)&localaddr)->sin_port = 0;
+
+ auth->fd = fd;
+ SetAuthConnect(auth);
+
+ comm_connect_tcp(fd, auth->client->sockhost, 113,
+ (struct sockaddr *) &localaddr, GET_SS_LEN(localaddr),
+ auth_connect_callback, auth,
+ localaddr.ss_family, GlobalSetOptions.ident_timeout);
+ return 1; /* We suceed here for now */
+}
+
+/*
+ * GetValidIdent - parse ident query reply from identd server
+ *
+ * Inputs - pointer to ident buf
+ * Output - NULL if no valid ident found, otherwise pointer to name
+ * Side effects -
+ */
+static char *
+GetValidIdent(char *buf)
+{
+ int remp = 0;
+ int locp = 0;
+ char *colon1Ptr;
+ char *colon2Ptr;
+ char *colon3Ptr;
+ char *commaPtr;
+ char *remotePortString;
+
+ /* All this to get rid of a sscanf() fun. */
+ remotePortString = buf;
+
+ colon1Ptr = strchr(remotePortString, ':');
+ if(!colon1Ptr)
+ return 0;
+
+ *colon1Ptr = '\0';
+ colon1Ptr++;
+ colon2Ptr = strchr(colon1Ptr, ':');
+ if(!colon2Ptr)
+ return 0;
+
+ *colon2Ptr = '\0';
+ colon2Ptr++;
+ commaPtr = strchr(remotePortString, ',');
+
+ if(!commaPtr)
+ return 0;
+
+ *commaPtr = '\0';
+ commaPtr++;
+
+ remp = atoi(remotePortString);
+ if(!remp)
+ return 0;
+
+ locp = atoi(commaPtr);
+ if(!locp)
+ return 0;
+
+ /* look for USERID bordered by first pair of colons */
+ if(!strstr(colon1Ptr, "USERID"))
+ return 0;
+
+ colon3Ptr = strchr(colon2Ptr, ':');
+ if(!colon3Ptr)
+ return 0;
+
+ *colon3Ptr = '\0';
+ colon3Ptr++;
+ return (colon3Ptr);
+}
+
+/*
+ * start_auth - starts auth (identd) and dns queries for a client
+ */
+void
+start_auth(struct Client *client)
+{
+ struct AuthRequest *auth = 0;
+ s_assert(0 != client);
+ if(client == NULL)
+ return;
+
+ /* to aid bopm which needs something unique to match against */
+ sendto_one(client, "NOTICE AUTH :*** Processing connection to %s",
+ me.name);
+
+ auth = make_auth_request(client);
+
+ auth->dns_query.ptr = auth;
+ auth->dns_query.callback = auth_dns_callback;
+
+ sendheader(client, REPORT_DO_DNS);
+
+ /* No DNS cache now, remember? -- adrian */
+ gethost_byaddr(&client->localClient->ip, &auth->dns_query);
+
+ SetDNSPending(auth);
+
+ if(ConfigFileEntry.disable_auth == 0)
+ start_auth_query(auth);
+
+ dlinkAdd(auth, &auth->node, &auth_poll_list);
+}
+
+/*
+ * timeout_auth_queries - timeout resolver and identd requests
+ * allow clients through if requests failed
+ */
+static void
+timeout_auth_queries_event(void *notused)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct AuthRequest *auth;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head)
+ {
+ auth = ptr->data;
+
+ if(auth->timeout < CurrentTime)
+ {
+ if(auth->fd >= 0)
+ comm_close(auth->fd);
+
+ if(IsDoingAuth(auth))
+ {
+ ClearAuth(auth);
+ ++ServerStats->is_abad;
+ sendheader(auth->client, REPORT_FAIL_ID);
+ auth->client->localClient->auth_request = NULL;
+ }
+ if(IsDNSPending(auth))
+ {
+ ClearDNSPending(auth);
+ delete_resolver_queries(&auth->dns_query);
+ sendheader(auth->client, REPORT_FAIL_DNS);
+ }
+
+ auth->client->localClient->lasttime = CurrentTime;
+ release_auth_client(auth);
+ }
+ }
+}
+
+/*
+ * auth_connect_callback() - deal with the result of comm_connect_tcp()
+ *
+ * If the connection failed, we simply close the auth fd and report
+ * a failure. If the connection suceeded send the ident server a query
+ * giving "theirport , ourport". The write is only attempted *once* so
+ * it is deemed to be a fail if the entire write doesn't write all the
+ * data given. This shouldnt be a problem since the socket should have
+ * a write buffer far greater than this message to store it in should
+ * problems arise. -avalon
+ */
+static void
+auth_connect_callback(int fd, int error, void *data)
+{
+ struct AuthRequest *auth = data;
+ struct sockaddr_in us;
+ struct sockaddr_in them;
+ char authbuf[32];
+ socklen_t ulen = sizeof(struct sockaddr_in);
+ socklen_t tlen = sizeof(struct sockaddr_in);
+
+ /* Check the error */
+ if(error != COMM_OK)
+ {
+ /* We had an error during connection :( */
+ auth_error(auth);
+ return;
+ }
+
+ if(getsockname
+ (auth->client->localClient->fd, (struct sockaddr *) &us,
+ (socklen_t *) & ulen)
+ || getpeername(auth->client->localClient->fd,
+ (struct sockaddr *) &them, (socklen_t *) & tlen))
+ {
+ ilog(L_IOERROR, "auth get{sock,peer}name error for %s:%m",
+ log_client_name(auth->client, SHOW_IP));
+ auth_error(auth);
+ return;
+ }
+ ircsnprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
+ (unsigned int) ntohs(them.sin_port), (unsigned int) ntohs(us.sin_port));
+
+ if(write(auth->fd, authbuf, strlen(authbuf)) == -1)
+ {
+ auth_error(auth);
+ return;
+ }
+ ClearAuthConnect(auth);
+ SetAuthPending(auth);
+ read_auth_reply(auth->fd, auth);
+}
+
+
+/*
+ * read_auth_reply - read the reply (if any) from the ident server
+ * we connected to.
+ * We only give it one shot, if the reply isn't good the first time
+ * fail the authentication entirely. --Bleep
+ */
+#define AUTH_BUFSIZ 128
+
+static void
+read_auth_reply(int fd, void *data)
+{
+ struct AuthRequest *auth = data;
+ char *s = NULL;
+ char *t = NULL;
+ int len;
+ int count;
+ char buf[AUTH_BUFSIZ + 1]; /* buffer to read auth reply into */
+
+ len = read(auth->fd, buf, AUTH_BUFSIZ);
+
+ if(len < 0 && ignoreErrno(errno))
+ {
+ comm_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_READ, read_auth_reply, auth, 0);
+ return;
+ }
+
+ if(len > 0)
+ {
+ buf[len] = '\0';
+
+ if((s = GetValidIdent(buf)))
+ {
+ t = auth->client->username;
+
+ while (*s == '~' || *s == '^')
+ s++;
+
+ for (count = USERLEN; *s && count; s++)
+ {
+ if(*s == '@')
+ {
+ break;
+ }
+ if(!IsSpace(*s) && *s != ':' && *s != '[')
+ {
+ *t++ = *s;
+ count--;
+ }
+ }
+ *t = '\0';
+ }
+ }
+
+ comm_close(auth->fd);
+ auth->fd = -1;
+ ClearAuth(auth);
+
+ if(s == NULL)
+ {
+ ++ServerStats->is_abad;
+ strcpy(auth->client->username, "unknown");
+ sendheader(auth->client, REPORT_FAIL_ID);
+ }
+ else
+ {
+ sendheader(auth->client, REPORT_FIN_ID);
+ ++ServerStats->is_asuc;
+ SetGotId(auth->client);
+ }
+
+ release_auth_client(auth);
+}
+
+
+
+/*
+ * delete_auth_queries()
+ *
+ */
+void
+delete_auth_queries(struct Client *target_p)
+{
+ struct AuthRequest *auth;
+
+ if(target_p == NULL || target_p->localClient == NULL ||
+ target_p->localClient->auth_request == NULL)
+ return;
+
+ auth = target_p->localClient->auth_request;
+ target_p->localClient->auth_request = NULL;
+
+ if(IsDNSPending(auth))
+ delete_resolver_queries(&auth->dns_query);
+
+ if(auth->fd >= 0)
+ comm_close(auth->fd);
+
+ dlinkDelete(&auth->node, &auth_poll_list);
+ free_auth_request(auth);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_conf.c: Configuration file functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_conf.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "tools.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_serv.h"
+#include "s_stats.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "event.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "listener.h"
+#include "hostmask.h"
+#include "modules.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_log.h"
+#include "send.h"
+#include "s_gline.h"
+#include "memory.h"
+#include "balloc.h"
+#include "patricia.h"
+#include "reject.h"
+#include "cache.h"
+#include "blacklist.h"
+
+struct config_server_hide ConfigServerHide;
+
+extern int yyparse(); /* defined in y.tab.c */
+extern char linebuf[];
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+static BlockHeap *confitem_heap = NULL;
+
+dlink_list temp_klines[LAST_TEMP_TYPE];
+dlink_list temp_dlines[LAST_TEMP_TYPE];
+dlink_list service_list;
+
+/* internally defined functions */
+static void set_default_conf(void);
+static void validate_conf(void);
+static void read_conf(FILE *);
+static void clear_out_old_conf(void);
+
+static void expire_temp_kd(void *list);
+static void reorganise_temp_kd(void *list);
+
+FILE *conf_fbfile_in;
+extern char yytext[];
+
+static int verify_access(struct Client *client_p, const char *username);
+static int attach_iline(struct Client *, struct ConfItem *);
+
+void
+init_s_conf(void)
+{
+ confitem_heap = BlockHeapCreate(sizeof(struct ConfItem), CONFITEM_HEAP_SIZE);
+
+ eventAddIsh("expire_temp_klines", expire_temp_kd, &temp_klines[TEMP_MIN], 60);
+ eventAddIsh("expire_temp_dlines", expire_temp_kd, &temp_dlines[TEMP_MIN], 60);
+
+ eventAddIsh("expire_temp_klines_hour", reorganise_temp_kd,
+ &temp_klines[TEMP_HOUR], 3600);
+ eventAddIsh("expire_temp_dlines_hour", reorganise_temp_kd,
+ &temp_dlines[TEMP_HOUR], 3600);
+ eventAddIsh("expire_temp_klines_day", reorganise_temp_kd,
+ &temp_klines[TEMP_DAY], 86400);
+ eventAddIsh("expire_temp_dlines_day", reorganise_temp_kd,
+ &temp_dlines[TEMP_DAY], 86400);
+ eventAddIsh("expire_temp_klines_week", reorganise_temp_kd,
+ &temp_klines[TEMP_WEEK], 604800);
+ eventAddIsh("expire_temp_dlines_week", reorganise_temp_kd,
+ &temp_dlines[TEMP_WEEK], 604800);
+}
+
+/*
+ * make_conf
+ *
+ * inputs - none
+ * output - pointer to new conf entry
+ * side effects - none
+ */
+struct ConfItem *
+make_conf()
+{
+ struct ConfItem *aconf;
+
+ aconf = BlockHeapAlloc(confitem_heap);
+ aconf->status = CONF_ILLEGAL;
+ return (aconf);
+}
+
+/*
+ * free_conf
+ *
+ * inputs - pointer to conf to free
+ * output - none
+ * side effects - crucial password fields are zeroed, conf is freed
+ */
+void
+free_conf(struct ConfItem *aconf)
+{
+ s_assert(aconf != NULL);
+ if(aconf == NULL)
+ return;
+
+ /* security.. */
+ if(aconf->passwd)
+ memset(aconf->passwd, 0, strlen(aconf->passwd));
+ if(aconf->spasswd)
+ memset(aconf->spasswd, 0, strlen(aconf->spasswd));
+
+ MyFree(aconf->passwd);
+ MyFree(aconf->spasswd);
+ MyFree(aconf->name);
+ MyFree(aconf->className);
+ MyFree(aconf->user);
+ MyFree(aconf->host);
+
+ BlockHeapFree(confitem_heap, aconf);
+}
+
+/*
+ * check_client
+ *
+ * inputs - pointer to client
+ * output - 0 = Success
+ * NOT_AUTHORISED (-1) = Access denied (no I line match)
+ * SOCKET_ERROR (-2) = Bad socket.
+ * I_LINE_FULL (-3) = I-line is full
+ * TOO_MANY (-4) = Too many connections from hostname
+ * BANNED_CLIENT (-5) = K-lined
+ * side effects - Ordinary client access check.
+ * Look for conf lines which have the same
+ * status as the flags passed.
+ */
+int
+check_client(struct Client *client_p, struct Client *source_p, const char *username)
+{
+ int i;
+
+ ClearAccess(source_p);
+
+ if((i = verify_access(source_p, username)))
+ {
+ ilog(L_FUSER, "Access denied: %s[%s]",
+ source_p->name, source_p->sockhost);
+ }
+
+ switch (i)
+ {
+ case SOCKET_ERROR:
+ exit_client(client_p, source_p, &me, "Socket Error");
+ break;
+
+ case TOO_MANY_LOCAL:
+ sendto_realops_snomask(SNO_FULL, L_NETWIDE,
+ "Too many local connections for %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+
+ ilog(L_FUSER, "Too many local connections from %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+
+ ServerStats->is_ref++;
+ exit_client(client_p, source_p, &me, "Too many host connections (local)");
+ break;
+
+ case TOO_MANY_GLOBAL:
+ sendto_realops_snomask(SNO_FULL, L_NETWIDE,
+ "Too many global connections for %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+ ilog(L_FUSER, "Too many global connections from %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+
+ ServerStats->is_ref++;
+ exit_client(client_p, source_p, &me, "Too many host connections (global)");
+ break;
+
+ case TOO_MANY_IDENT:
+ sendto_realops_snomask(SNO_FULL, L_NETWIDE,
+ "Too many user connections for %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+ ilog(L_FUSER, "Too many user connections from %s!%s%s@%s",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+
+ ServerStats->is_ref++;
+ exit_client(client_p, source_p, &me, "Too many user connections (global)");
+ break;
+
+ case I_LINE_FULL:
+ sendto_realops_snomask(SNO_FULL, L_NETWIDE,
+ "I-line is full for %s!%s%s@%s (%s).",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->host,
+ source_p->sockhost);
+
+ ilog(L_FUSER, "Too many connections from %s!%s%s@%s.",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost);
+
+ ServerStats->is_ref++;
+ exit_client(client_p, source_p, &me,
+ "No more connections allowed in your connection class");
+ break;
+
+ case NOT_AUTHORISED:
+ {
+ int port = -1;
+#ifdef IPV6
+ if(source_p->localClient->ip.ss_family == AF_INET6)
+ port = ntohs(((struct sockaddr_in6 *)&source_p->localClient->listener->addr)->sin6_port);
+ else
+#endif
+ port = ntohs(((struct sockaddr_in *)&source_p->localClient->listener->addr)->sin_port);
+
+ ServerStats->is_ref++;
+ /* jdc - lists server name & port connections are on */
+ /* a purely cosmetical change */
+ /* why ipaddr, and not just source_p->sockhost? --fl */
+#if 0
+ static char ipaddr[HOSTIPLEN];
+ inetntop_sock(&source_p->localClient->ip, ipaddr, sizeof(ipaddr));
+#endif
+ sendto_realops_snomask(SNO_UNAUTH, L_ALL,
+ "Unauthorised client connection from "
+ "%s!%s%s@%s [%s] on [%s/%u].",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->host,
+ source_p->sockhost,
+ source_p->localClient->listener->name, port);
+
+ ilog(L_FUSER,
+ "Unauthorised client connection from %s!%s%s@%s on [%s/%u].",
+ source_p->name, IsGotId(source_p) ? "" : "~",
+ source_p->username, source_p->sockhost,
+ source_p->localClient->listener->name, port);
+ add_reject(client_p);
+ exit_client(client_p, source_p, &me,
+ "You are not authorised to use this server");
+ break;
+ }
+ case BANNED_CLIENT:
+ add_reject(client_p);
+ exit_client(client_p, client_p, &me, "*** Banned ");
+ ServerStats->is_ref++;
+ break;
+
+ case 0:
+ default:
+ break;
+ }
+ return (i);
+}
+
+/*
+ * verify_access
+ *
+ * inputs - pointer to client to verify
+ * - pointer to proposed username
+ * output - 0 if success -'ve if not
+ * side effect - find the first (best) I line to attach.
+ */
+static int
+verify_access(struct Client *client_p, const char *username)
+{
+ struct ConfItem *aconf;
+ char non_ident[USERLEN + 1];
+
+ if(IsGotId(client_p))
+ {
+ aconf = find_address_conf(client_p->host, client_p->sockhost,
+ client_p->username, client_p->username,
+ (struct sockaddr *) &client_p->localClient->ip,
+ client_p->localClient->ip.ss_family);
+ }
+ else
+ {
+ strlcpy(non_ident, "~", sizeof(non_ident));
+ strlcat(non_ident, username, sizeof(non_ident));
+ aconf = find_address_conf(client_p->host, client_p->sockhost,
+ non_ident, client_p->username,
+ (struct sockaddr *) &client_p->localClient->ip,
+ client_p->localClient->ip.ss_family);
+ }
+
+ if(aconf == NULL)
+ return NOT_AUTHORISED;
+
+ if(aconf->status & CONF_CLIENT)
+ {
+ if(aconf->flags & CONF_FLAGS_REDIR)
+ {
+ sendto_one(client_p, form_str(RPL_REDIR),
+ me.name, client_p->name,
+ aconf->name ? aconf->name : "", aconf->port);
+ return (NOT_AUTHORISED);
+ }
+
+
+ if(IsConfDoIdentd(aconf))
+ SetNeedId(client_p);
+
+ /* Thanks for spoof idea amm */
+ if(IsConfDoSpoofIp(aconf))
+ {
+ char *p;
+
+ /* show_ip() depends on this --fl */
+ SetIPSpoof(client_p);
+
+ if(IsConfSpoofNotice(aconf))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s spoofing: %s as %s",
+ client_p->name,
+ show_ip(NULL, client_p) ? client_p->host : aconf->name,
+ aconf->name);
+ }
+
+ /* user@host spoof */
+ if((p = strchr(aconf->name, '@')) != NULL)
+ {
+ char *host = p+1;
+ *p = '\0';
+
+ strlcpy(client_p->username, aconf->name,
+ sizeof(client_p->username));
+ strlcpy(client_p->host, host,
+ sizeof(client_p->host));
+ *p = '@';
+ }
+ else
+ strlcpy(client_p->host, aconf->name, sizeof(client_p->host));
+ }
+ return (attach_iline(client_p, aconf));
+ }
+ else if(aconf->status & CONF_KILL)
+ {
+ if(ConfigFileEntry.kline_with_reason)
+ {
+ sendto_one(client_p,
+ ":%s NOTICE %s :*** Banned %s",
+ me.name, client_p->name, aconf->passwd);
+ }
+ return (BANNED_CLIENT);
+ }
+ else if(aconf->status & CONF_GLINE)
+ {
+ sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name, client_p->name);
+
+ if(ConfigFileEntry.kline_with_reason)
+ sendto_one(client_p,
+ ":%s NOTICE %s :*** Banned %s",
+ me.name, client_p->name, aconf->passwd);
+
+ return (BANNED_CLIENT);
+ }
+
+ return NOT_AUTHORISED;
+}
+
+
+/*
+ * add_ip_limit
+ *
+ * Returns 1 if successful 0 if not
+ *
+ * This checks if the user has exceed the limits for their class
+ * unless of course they are exempt..
+ */
+
+static int
+add_ip_limit(struct Client *client_p, struct ConfItem *aconf)
+{
+ patricia_node_t *pnode;
+
+ /* If the limits are 0 don't do anything.. */
+ if(ConfCidrAmount(aconf) == 0 || ConfCidrBitlen(aconf) == 0)
+ return -1;
+
+ pnode = match_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip);
+
+ if(pnode == NULL)
+ pnode = make_and_lookup_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip, ConfCidrBitlen(aconf));
+
+ s_assert(pnode != NULL);
+
+ if(pnode != NULL)
+ {
+ if(((long) pnode->data) >= ConfCidrAmount(aconf)
+ && !IsConfExemptLimits(aconf))
+ {
+ /* This should only happen if the limits are set to 0 */
+ if((unsigned long) pnode->data == 0)
+ {
+ patricia_remove(ConfIpLimits(aconf), pnode);
+ }
+ return (0);
+ }
+
+ pnode->data++;
+ }
+ return 1;
+}
+
+static void
+remove_ip_limit(struct Client *client_p, struct ConfItem *aconf)
+{
+ patricia_node_t *pnode;
+
+ /* If the limits are 0 don't do anything.. */
+ if(ConfCidrAmount(aconf) == 0 || ConfCidrBitlen(aconf) == 0)
+ return;
+
+ pnode = match_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip);
+ if(pnode == NULL)
+ return;
+
+ pnode->data--;
+ if(((unsigned long) pnode->data) == 0)
+ {
+ patricia_remove(ConfIpLimits(aconf), pnode);
+ }
+
+}
+
+/*
+ * attach_iline
+ *
+ * inputs - client pointer
+ * - conf pointer
+ * output -
+ * side effects - do actual attach
+ */
+static int
+attach_iline(struct Client *client_p, struct ConfItem *aconf)
+{
+ struct Client *target_p;
+ dlink_node *ptr;
+ int local_count = 0;
+ int global_count = 0;
+ int ident_count = 0;
+ int unidented = 0;
+
+ if(IsConfExemptLimits(aconf))
+ return (attach_conf(client_p, aconf));
+
+ if(*client_p->username == '~')
+ unidented = 1;
+
+
+ /* find_hostname() returns the head of the list to search */
+ DLINK_FOREACH(ptr, find_hostname(client_p->host))
+ {
+ target_p = ptr->data;
+
+ if(irccmp(client_p->host, target_p->orighost) != 0)
+ continue;
+
+ if(MyConnect(target_p))
+ local_count++;
+
+ global_count++;
+
+ if(unidented)
+ {
+ if(*target_p->username == '~')
+ ident_count++;
+ }
+ else if(irccmp(target_p->username, client_p->username) == 0)
+ ident_count++;
+
+ if(ConfMaxLocal(aconf) && local_count >= ConfMaxLocal(aconf))
+ return (TOO_MANY_LOCAL);
+ else if(ConfMaxGlobal(aconf) && global_count >= ConfMaxGlobal(aconf))
+ return (TOO_MANY_GLOBAL);
+ else if(ConfMaxIdent(aconf) && ident_count >= ConfMaxIdent(aconf))
+ return (TOO_MANY_IDENT);
+ }
+
+
+ return (attach_conf(client_p, aconf));
+}
+
+/*
+ * detach_conf
+ *
+ * inputs - pointer to client to detach
+ * output - 0 for success, -1 for failure
+ * side effects - Disassociate configuration from the client.
+ * Also removes a class from the list if marked for deleting.
+ */
+int
+detach_conf(struct Client *client_p)
+{
+ struct ConfItem *aconf;
+
+ aconf = client_p->localClient->att_conf;
+
+ if(aconf != NULL)
+ {
+ if(ClassPtr(aconf))
+ {
+ remove_ip_limit(client_p, aconf);
+
+ if(ConfCurrUsers(aconf) > 0)
+ --ConfCurrUsers(aconf);
+
+ if(ConfMaxUsers(aconf) == -1 && ConfCurrUsers(aconf) == 0)
+ {
+ free_class(ClassPtr(aconf));
+ ClassPtr(aconf) = NULL;
+ }
+
+ }
+
+ aconf->clients--;
+ if(!aconf->clients && IsIllegal(aconf))
+ free_conf(aconf);
+
+ client_p->localClient->att_conf = NULL;
+ return 0;
+ }
+
+ return -1;
+}
+
+/*
+ * attach_conf
+ *
+ * inputs - client pointer
+ * - conf pointer
+ * output -
+ * side effects - Associate a specific configuration entry to a *local*
+ * client (this is the one which used in accepting the
+ * connection). Note, that this automatically changes the
+ * attachment if there was an old one...
+ */
+int
+attach_conf(struct Client *client_p, struct ConfItem *aconf)
+{
+ if(IsIllegal(aconf))
+ return (NOT_AUTHORISED);
+
+ if(ClassPtr(aconf))
+ {
+ if(!add_ip_limit(client_p, aconf))
+ return (TOO_MANY_LOCAL);
+ }
+
+ if((aconf->status & CONF_CLIENT) &&
+ ConfCurrUsers(aconf) >= ConfMaxUsers(aconf) && ConfMaxUsers(aconf) > 0)
+ {
+ if(!IsConfExemptLimits(aconf))
+ {
+ return (I_LINE_FULL);
+ }
+ else
+ {
+ sendto_one(client_p, ":%s NOTICE %s :*** I: line is full, but you have an >I: line!",
+ me.name, client_p->name);
+ SetExemptLimits(client_p);
+ }
+
+ }
+
+ if(client_p->localClient->att_conf != NULL)
+ detach_conf(client_p);
+
+ client_p->localClient->att_conf = aconf;
+
+ aconf->clients++;
+ ConfCurrUsers(aconf)++;
+ return (0);
+}
+
+/*
+ * rehash
+ *
+ * Actual REHASH service routine. Called with sig == 0 if it has been called
+ * as a result of an operator issuing this command, else assume it has been
+ * called as a result of the server receiving a HUP signal.
+ */
+int
+rehash(int sig)
+{
+ if(sig != 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Got signal SIGHUP, reloading ircd conf. file");
+ }
+
+ restart_resolver();
+ /* don't close listeners until we know we can go ahead with the rehash */
+ read_conf_files(NO);
+
+ if(ServerInfo.description != NULL)
+ strlcpy(me.info, ServerInfo.description, sizeof(me.info));
+ else
+ strlcpy(me.info, "unknown", sizeof(me.info));
+
+ open_logfiles();
+ return (0);
+}
+
+static struct banconf_entry
+{
+ const char **filename;
+ void (*func) (FILE *);
+ int perm;
+} banconfs[] = {
+ { &ConfigFileEntry.klinefile, parse_k_file, 0 },
+ { &ConfigFileEntry.klinefile, parse_k_file, 1 },
+ { &ConfigFileEntry.dlinefile, parse_d_file, 0 },
+ { &ConfigFileEntry.dlinefile, parse_d_file, 1 },
+ { &ConfigFileEntry.xlinefile, parse_x_file, 0 },
+ { &ConfigFileEntry.xlinefile, parse_x_file, 1 },
+ { &ConfigFileEntry.resvfile, parse_resv_file,0 },
+ { &ConfigFileEntry.resvfile, parse_resv_file,1 },
+ { NULL, NULL, 0 }
+};
+
+void
+rehash_bans(int sig)
+{
+ FILE *file;
+ char buf[MAXPATHLEN];
+ int i;
+
+ if(sig != 0)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Got signal SIGUSR2, reloading ban confs");
+
+ clear_out_address_conf_bans();
+ clear_s_newconf_bans();
+
+ for(i = 0; banconfs[i].filename; i++)
+ {
+ if(banconfs[i].perm)
+ snprintf(buf, sizeof(buf), "%s.perm", *banconfs[i].filename);
+ else
+ snprintf(buf, sizeof(buf), "%s", *banconfs[i].filename);
+
+ if((file = fopen(buf, "r")) == NULL)
+ {
+ if(banconfs[i].perm)
+ continue;
+
+ ilog(L_MAIN, "Failed reading ban file %s",
+ *banconfs[i].filename);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Can't open %s file bans could be missing!",
+ *banconfs[i].filename);
+ }
+ else
+ {
+ (banconfs[i].func)(file);
+ fclose(file);
+ }
+ }
+
+ check_banned_lines();
+}
+
+/*
+ * set_default_conf()
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects - Set default values here.
+ * This is called **PRIOR** to parsing the
+ * configuration file. If you want to do some validation
+ * of values later, put them in validate_conf().
+ */
+
+#define YES 1
+#define NO 0
+#define UNSET -1
+
+static void
+set_default_conf(void)
+{
+ /* ServerInfo.name is not rehashable */
+ /* ServerInfo.name = ServerInfo.name; */
+ ServerInfo.description = NULL;
+ DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
+ DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
+
+ memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
+ ServerInfo.specific_ipv4_vhost = 0;
+#ifdef IPV6
+ memset(&ServerInfo.ip6, 0, sizeof(ServerInfo.ip6));
+ ServerInfo.specific_ipv6_vhost = 0;
+#endif
+ ServerInfo.use_ts6 = YES;
+
+ /* Don't reset hub, as that will break lazylinks */
+ /* ServerInfo.hub = NO; */
+ AdminInfo.name = NULL;
+ AdminInfo.email = NULL;
+ AdminInfo.description = NULL;
+
+ DupString(ConfigFileEntry.default_operstring, "is an IRC operator");
+ DupString(ConfigFileEntry.default_adminstring, "is a Server Administrator");
+ DupString(ConfigFileEntry.servicestring, "is a Network Service");
+
+ ConfigFileEntry.default_umodes = UMODE_INVISIBLE;
+ ConfigFileEntry.failed_oper_notice = YES;
+ ConfigFileEntry.anti_nick_flood = NO;
+ ConfigFileEntry.disable_fake_channels = NO;
+ ConfigFileEntry.max_nick_time = 20;
+ ConfigFileEntry.max_nick_changes = 5;
+ ConfigFileEntry.max_accept = 20;
+ ConfigFileEntry.max_monitor = 60;
+ ConfigFileEntry.nick_delay = 900; /* 15 minutes */
+ ConfigFileEntry.target_change = YES;
+ ConfigFileEntry.anti_spam_exit_message_time = 0;
+ ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
+ ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
+ ConfigFileEntry.client_exit = YES;
+ ConfigFileEntry.dline_with_reason = YES;
+ ConfigFileEntry.kline_with_reason = YES;
+ ConfigFileEntry.kline_delay = 0;
+ ConfigFileEntry.warn_no_nline = YES;
+ ConfigFileEntry.non_redundant_klines = YES;
+ ConfigFileEntry.stats_e_disabled = NO;
+ ConfigFileEntry.stats_o_oper_only = NO;
+ ConfigFileEntry.stats_k_oper_only = 1; /* masked */
+ ConfigFileEntry.stats_i_oper_only = 1; /* masked */
+ ConfigFileEntry.stats_P_oper_only = NO;
+ ConfigFileEntry.stats_c_oper_only = NO;
+ ConfigFileEntry.stats_y_oper_only = NO;
+ ConfigFileEntry.stats_h_oper_only = NO;
+ ConfigFileEntry.map_oper_only = YES;
+ ConfigFileEntry.operspy_admin_only = NO;
+ ConfigFileEntry.pace_wait = 10;
+ ConfigFileEntry.caller_id_wait = 60;
+ ConfigFileEntry.pace_wait_simple = 1;
+ ConfigFileEntry.short_motd = NO;
+ ConfigFileEntry.no_oper_flood = NO;
+ ConfigFileEntry.fname_userlog = NULL;
+ ConfigFileEntry.fname_fuserlog = NULL;
+ ConfigFileEntry.fname_operlog = NULL;
+ ConfigFileEntry.fname_foperlog = NULL;
+ ConfigFileEntry.fname_serverlog = NULL;
+ ConfigFileEntry.fname_glinelog = NULL;
+ ConfigFileEntry.fname_klinelog = NULL;
+ ConfigFileEntry.fname_operspylog = NULL;
+ ConfigFileEntry.fname_ioerrorlog = NULL;
+ ConfigFileEntry.glines = NO;
+ ConfigFileEntry.use_egd = NO;
+ ConfigFileEntry.gline_time = 12 * 3600;
+ ConfigFileEntry.gline_min_cidr = 16;
+ ConfigFileEntry.gline_min_cidr6 = 48;
+ ConfigFileEntry.hide_spoof_ips = YES;
+ ConfigFileEntry.hide_error_messages = 1;
+ ConfigFileEntry.idletime = 0;
+ ConfigFileEntry.dots_in_ident = 0;
+ ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
+ DupString(ConfigFileEntry.servlink_path, SLPATH);
+ ConfigFileEntry.egdpool_path = NULL;
+ ConfigFileEntry.use_whois_actually = YES;
+ ConfigFileEntry.burst_away = NO;
+ ConfigFileEntry.collision_fnc = YES;
+ ConfigFileEntry.global_snotices = YES;
+ ConfigFileEntry.operspy_dont_care_user_info = NO;
+
+#ifdef HAVE_LIBZ
+ ConfigFileEntry.compression_level = 4;
+#endif
+
+ ConfigFileEntry.oper_umodes = UMODE_LOCOPS | UMODE_SERVNOTICE |
+ UMODE_OPERWALL | UMODE_WALLOP;
+ ConfigFileEntry.oper_only_umodes = UMODE_SERVNOTICE;
+ ConfigFileEntry.oper_snomask = SNO_GENERAL;
+
+ ConfigChannel.use_except = YES;
+ ConfigChannel.use_invex = YES;
+ ConfigChannel.use_knock = YES;
+ ConfigChannel.use_forward = YES;
+ ConfigChannel.knock_delay = 300;
+ ConfigChannel.knock_delay_channel = 60;
+ ConfigChannel.max_chans_per_user = 15;
+ ConfigChannel.max_bans = 25;
+ ConfigChannel.max_bans_large = 500;
+ ConfigChannel.burst_topicwho = NO;
+ ConfigChannel.invite_ops_only = YES;
+ ConfigChannel.kick_on_split_riding = NO;
+
+ ConfigChannel.default_split_user_count = 15000;
+ ConfigChannel.default_split_server_count = 10;
+ ConfigChannel.no_join_on_split = NO;
+ ConfigChannel.no_create_on_split = YES;
+
+ ConfigServerHide.flatten_links = 0;
+ ConfigServerHide.links_delay = 300;
+ ConfigServerHide.hidden = 0;
+ ConfigServerHide.disable_hidden = 0;
+
+ ConfigFileEntry.min_nonwildcard = 4;
+ ConfigFileEntry.min_nonwildcard_simple = 3;
+ ConfigFileEntry.default_floodcount = 8;
+ ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
+ ConfigFileEntry.tkline_expire_notices = 0;
+
+ ConfigFileEntry.reject_after_count = 5;
+ ConfigFileEntry.reject_ban_time = 300;
+ ConfigFileEntry.reject_duration = 120;
+
+}
+
+#undef YES
+#undef NO
+
+/*
+ * read_conf()
+ *
+ *
+ * inputs - file descriptor pointing to config file to use
+ * output - None
+ * side effects - Read configuration file.
+ */
+static void
+read_conf(FILE * file)
+{
+ lineno = 0;
+
+ set_default_conf(); /* Set default values prior to conf parsing */
+ yyparse(); /* Load the values from the conf */
+ validate_conf(); /* Check to make sure some values are still okay. */
+ /* Some global values are also loaded here. */
+ check_class(); /* Make sure classes are valid */
+}
+
+static void
+validate_conf(void)
+{
+ if(ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
+ ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
+
+ if(ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
+ ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
+
+ if(ConfigFileEntry.servlink_path == NULL)
+ DupString(ConfigFileEntry.servlink_path, SLPATH);
+
+ if(ServerInfo.network_name == NULL)
+ DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
+
+ if(ServerInfo.network_desc == NULL)
+ DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
+
+ if((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
+ (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
+ ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
+
+ GlobalSetOptions.idletime = (ConfigFileEntry.idletime * 60);
+
+ if(!split_users || !split_servers ||
+ (!ConfigChannel.no_create_on_split && !ConfigChannel.no_join_on_split))
+ {
+ eventDelete(check_splitmode, NULL);
+ splitmode = 0;
+ splitchecking = 0;
+ }
+}
+
+/*
+ * lookup_confhost - start DNS lookups of all hostnames in the conf
+ * line and convert an IP addresses in a.b.c.d number for to IP#s.
+ *
+ */
+
+/*
+ * conf_connect_allowed
+ *
+ * inputs - pointer to inaddr
+ * - int type ipv4 or ipv6
+ * output - ban info or NULL
+ * side effects - none
+ */
+struct ConfItem *
+conf_connect_allowed(struct sockaddr *addr, int aftype)
+{
+ struct ConfItem *aconf = find_dline(addr, aftype);
+
+ /* DLINE exempt also gets you out of static limits/pacing... */
+ if(aconf && (aconf->status & CONF_EXEMPTDLINE))
+ return NULL;
+
+ if(aconf != NULL)
+ return aconf;
+
+ return NULL;
+}
+
+/* add_temp_kline()
+ *
+ * inputs - pointer to struct ConfItem
+ * output - none
+ * Side effects - links in given struct ConfItem into
+ * temporary kline link list
+ */
+void
+add_temp_kline(struct ConfItem *aconf)
+{
+ if(aconf->hold >= CurrentTime + (10080 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_klines[TEMP_WEEK]);
+ aconf->port = TEMP_WEEK;
+ }
+ else if(aconf->hold >= CurrentTime + (1440 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_klines[TEMP_DAY]);
+ aconf->port = TEMP_DAY;
+ }
+ else if(aconf->hold >= CurrentTime + (60 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_klines[TEMP_HOUR]);
+ aconf->port = TEMP_HOUR;
+ }
+ else
+ {
+ dlinkAddAlloc(aconf, &temp_klines[TEMP_MIN]);
+ aconf->port = TEMP_MIN;
+ }
+
+ aconf->flags |= CONF_FLAGS_TEMPORARY;
+ add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf);
+}
+
+/* add_temp_dline()
+ *
+ * input - pointer to struct ConfItem
+ * output - none
+ * side effects - added to tdline link list and address hash
+ */
+void
+add_temp_dline(struct ConfItem *aconf)
+{
+ if(aconf->hold >= CurrentTime + (10080 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_dlines[TEMP_WEEK]);
+ aconf->port = TEMP_WEEK;
+ }
+ else if(aconf->hold >= CurrentTime + (1440 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_dlines[TEMP_DAY]);
+ aconf->port = TEMP_DAY;
+ }
+ else if(aconf->hold >= CurrentTime + (60 * 60))
+ {
+ dlinkAddAlloc(aconf, &temp_dlines[TEMP_HOUR]);
+ aconf->port = TEMP_HOUR;
+ }
+ else
+ {
+ dlinkAddAlloc(aconf, &temp_dlines[TEMP_MIN]);
+ aconf->port = TEMP_MIN;
+ }
+
+ aconf->flags |= CONF_FLAGS_TEMPORARY;
+ add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, aconf);
+}
+
+/* expire_tkline()
+ *
+ * inputs - list pointer
+ * - type
+ * output - NONE
+ * side effects - expire tklines and moves them between lists
+ */
+static void
+expire_temp_kd(void *list)
+{
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ struct ConfItem *aconf;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, ((dlink_list *) list)->head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold <= CurrentTime)
+ {
+ /* Alert opers that a TKline expired - Hwy */
+ if(ConfigFileEntry.tkline_expire_notices)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Temporary K-line for [%s@%s] expired",
+ (aconf->user) ? aconf->
+ user : "*", (aconf->host) ? aconf->host : "*");
+
+ delete_one_address_conf(aconf->host, aconf);
+ dlinkDestroy(ptr, list);
+ }
+ }
+}
+
+static void
+reorganise_temp_kd(void *list)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, ((dlink_list *) list)->head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold < (CurrentTime + (60 * 60)))
+ {
+ dlinkMoveNode(ptr, list, (aconf->status == CONF_KILL) ?
+ &temp_klines[TEMP_MIN] : &temp_dlines[TEMP_MIN]);
+ aconf->port = TEMP_MIN;
+ }
+ else if(aconf->port > TEMP_HOUR)
+ {
+ if(aconf->hold < (CurrentTime + (1440 * 60)))
+ {
+ dlinkMoveNode(ptr, list, (aconf->status == CONF_KILL) ?
+ &temp_klines[TEMP_HOUR] : &temp_dlines[TEMP_HOUR]);
+ aconf->port = TEMP_HOUR;
+ }
+ else if(aconf->port > TEMP_DAY &&
+ (aconf->hold < (CurrentTime + (10080 * 60))))
+ {
+ dlinkMoveNode(ptr, list, (aconf->status == CONF_KILL) ?
+ &temp_klines[TEMP_DAY] : &temp_dlines[TEMP_DAY]);
+ aconf->port = TEMP_DAY;
+ }
+ }
+ }
+}
+
+
+/* const char* get_oper_name(struct Client *client_p)
+ * Input: A client to find the active oper{} name for.
+ * Output: The nick!user@host{oper} of the oper.
+ * "oper" is server name for remote opers
+ * Side effects: None.
+ */
+char *
+get_oper_name(struct Client *client_p)
+{
+ /* +5 for !,@,{,} and null */
+ static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
+
+ if(MyOper(client_p))
+ {
+ ircsnprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}",
+ client_p->name, client_p->username,
+ client_p->host, client_p->localClient->opername);
+ return buffer;
+ }
+
+ ircsnprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}",
+ client_p->name, client_p->username,
+ client_p->host, client_p->servptr->name);
+ return buffer;
+}
+
+/*
+ * get_printable_conf
+ *
+ * inputs - struct ConfItem
+ *
+ * output - name
+ * - host
+ * - pass
+ * - user
+ * - port
+ *
+ * side effects -
+ * Examine the struct struct ConfItem, setting the values
+ * of name, host, pass, user to values either
+ * in aconf, or "<NULL>" port is set to aconf->port in all cases.
+ */
+void
+get_printable_conf(struct ConfItem *aconf, char **name, char **host,
+ char **pass, char **user, int *port, char **classname)
+{
+ static char null[] = "<NULL>";
+ static char zero[] = "default";
+
+ *name = EmptyString(aconf->name) ? null : aconf->name;
+ *host = EmptyString(aconf->host) ? null : aconf->host;
+ *pass = EmptyString(aconf->passwd) ? null : aconf->passwd;
+ *user = EmptyString(aconf->user) ? null : aconf->user;
+ *classname = EmptyString(aconf->className) ? zero : aconf->className;
+ *port = (int) aconf->port;
+}
+
+void
+get_printable_kline(struct Client *source_p, struct ConfItem *aconf,
+ char **host, char **reason,
+ char **user, char **oper_reason)
+{
+ static char null[] = "<NULL>";
+
+ *host = EmptyString(aconf->host) ? null : aconf->host;
+ *reason = EmptyString(aconf->passwd) ? null : aconf->passwd;
+ *user = EmptyString(aconf->user) ? null : aconf->user;
+
+ if(EmptyString(aconf->spasswd) || !IsOper(source_p))
+ *oper_reason = NULL;
+ else
+ *oper_reason = aconf->spasswd;
+}
+
+/*
+ * read_conf_files
+ *
+ * inputs - cold start YES or NO
+ * output - none
+ * side effects - read all conf files needed, ircd.conf kline.conf etc.
+ */
+void
+read_conf_files(int cold)
+{
+ const char *filename;
+
+ conf_fbfile_in = NULL;
+
+ filename = get_conf_name(CONF_TYPE);
+
+ /* We need to know the initial filename for the yyerror() to report
+ FIXME: The full path is in conffilenamebuf first time since we
+ dont know anything else
+
+ - Gozem 2002-07-21
+ */
+ strlcpy(conffilebuf, filename, sizeof(conffilebuf));
+
+ if((conf_fbfile_in = fopen(filename, "r")) == NULL)
+ {
+ if(cold)
+ {
+ ilog(L_MAIN, "Failed in reading configuration file %s", filename);
+ exit(-1);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Can't open file '%s' - aborting rehash!", filename);
+ return;
+ }
+ }
+
+ if(!cold)
+ {
+ clear_out_old_conf();
+ }
+
+ read_conf(conf_fbfile_in);
+ fclose(conf_fbfile_in);
+}
+
+/*
+ * clear_out_old_conf
+ *
+ * inputs - none
+ * output - none
+ * side effects - Clear out the old configuration
+ */
+static void
+clear_out_old_conf(void)
+{
+ struct Class *cltmp;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ int i;
+
+ /*
+ * don't delete the class table, rather mark all entries
+ * for deletion. The table is cleaned up by check_class. - avalon
+ */
+ DLINK_FOREACH(ptr, class_list.head)
+ {
+ cltmp = ptr->data;
+ MaxUsers(cltmp) = -1;
+ }
+
+ clear_out_address_conf();
+ clear_s_newconf();
+
+ /* clean out module paths */
+#ifndef STATIC_MODULES
+ mod_clear_paths();
+ mod_add_path(MODULE_DIR);
+ mod_add_path(MODULE_DIR "/autoload");
+#endif
+
+ /* clean out ServerInfo */
+ MyFree(ServerInfo.description);
+ ServerInfo.description = NULL;
+ MyFree(ServerInfo.network_name);
+ ServerInfo.network_name = NULL;
+ MyFree(ServerInfo.network_desc);
+ ServerInfo.network_desc = NULL;
+
+ /* clean out AdminInfo */
+ MyFree(AdminInfo.name);
+ AdminInfo.name = NULL;
+ MyFree(AdminInfo.email);
+ AdminInfo.email = NULL;
+ MyFree(AdminInfo.description);
+ AdminInfo.description = NULL;
+
+ /* operator{} and class{} blocks are freed above */
+ /* clean out listeners */
+ close_listeners();
+
+ /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{}, exempt{}
+ * and gecos{} blocks are freed above too
+ */
+
+ /* clean out general */
+ MyFree(ConfigFileEntry.servlink_path);
+ ConfigFileEntry.servlink_path = NULL;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, service_list.head)
+ {
+ MyFree(ptr->data);
+ dlinkDestroy(ptr, &service_list);
+ }
+
+ /* remove any aliases... -- nenolod */
+ for (i = 0; i < MAX_MSG_HASH; i++)
+ {
+ DLINK_FOREACH_SAFE(ptr, next_ptr, alias_hash_table[i].head)
+ {
+ struct alias_entry *aptr = ptr->data;
+
+ MyFree(aptr->name);
+ MyFree(aptr->target);
+ MyFree(aptr);
+
+ dlinkDestroy(ptr, &alias_hash_table[i]);
+ }
+ }
+
+ destroy_blacklists();
+
+ /* OK, that should be everything... */
+}
+
+
+/* write_confitem()
+ *
+ * inputs - kline, dline or resv type flag
+ * - client pointer to report to
+ * - user name of target
+ * - host name of target
+ * - reason for target
+ * - time string
+ * - type of xline
+ * output - NONE
+ * side effects - This function takes care of finding the right conf
+ * file and adding the line to it, as well as notifying
+ * opers and the user.
+ */
+void
+write_confitem(KlineType type, struct Client *source_p, char *user,
+ char *host, const char *reason, const char *oper_reason,
+ const char *current_date, int xtype)
+{
+ char buffer[1024];
+ FILE *out;
+ const char *filename; /* filename to use for kline */
+
+ filename = get_conf_name(type);
+
+ if(type == KLINE_TYPE)
+ {
+ if(EmptyString(oper_reason))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added K-Line for [%s@%s] [%s]",
+ get_oper_name(source_p), user,
+ host, reason);
+ ilog(L_KLINE, "K %s 0 %s %s %s",
+ get_oper_name(source_p), user, host, reason);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added K-Line for [%s@%s] [%s|%s]",
+ get_oper_name(source_p), user,
+ host, reason, oper_reason);
+ ilog(L_KLINE, "K %s 0 %s %s %s|%s",
+ get_oper_name(source_p), user, host,
+ reason, oper_reason);
+ }
+
+ sendto_one_notice(source_p, ":Added K-Line [%s@%s]",
+ user, host);
+ }
+ else if(type == DLINE_TYPE)
+ {
+ if(EmptyString(oper_reason))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added D-Line for [%s] [%s]",
+ get_oper_name(source_p), host, reason);
+ ilog(L_KLINE, "D %s 0 %s %s",
+ get_oper_name(source_p), host, reason);
+ }
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added D-Line for [%s] [%s|%s]",
+ get_oper_name(source_p), host,
+ reason, oper_reason);
+ ilog(L_KLINE, "D %s 0 %s %s|%s",
+ get_oper_name(source_p), host,
+ reason, oper_reason);
+ }
+
+ sendto_one(source_p,
+ ":%s NOTICE %s :Added D-Line [%s] to %s", me.name,
+ source_p->name, host, filename);
+
+ }
+ else if(type == RESV_TYPE)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s added RESV for [%s] [%s]",
+ get_oper_name(source_p), host, reason);
+ ilog(L_KLINE, "R %s 0 %s %s",
+ get_oper_name(source_p), host, reason);
+
+ sendto_one_notice(source_p, ":Added RESV for [%s] [%s]",
+ host, reason);
+ }
+
+ if((out = fopen(filename, "a")) == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem opening %s ", filename);
+ sendto_one_notice(source_p, ":*** Problem opening file, added temporarily only");
+ return;
+ }
+
+ if(oper_reason == NULL)
+ oper_reason = "";
+
+ if(type == KLINE_TYPE)
+ {
+ ircsnprintf(buffer, sizeof(buffer),
+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%ld\n",
+ user, host, reason, oper_reason, current_date,
+ get_oper_name(source_p), CurrentTime);
+ }
+ else if(type == DLINE_TYPE)
+ {
+ ircsnprintf(buffer, sizeof(buffer),
+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%ld\n", host,
+ reason, oper_reason, current_date, get_oper_name(source_p), CurrentTime);
+ }
+ else if(type == RESV_TYPE)
+ {
+ ircsnprintf(buffer, sizeof(buffer), "\"%s\",\"%s\",\"%s\",%ld\n",
+ host, reason, get_oper_name(source_p), CurrentTime);
+ }
+
+ if(fputs(buffer, out) == -1)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem writing to %s", filename);
+ sendto_one_notice(source_p, ":*** Problem writing to file, added temporarily only");
+ fclose(out);
+ return;
+ }
+
+ if (fclose(out))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "*** Problem writing to %s", filename);
+ sendto_one_notice(source_p, ":*** Problem writing to file, added temporarily only");
+ return;
+ }
+}
+
+/* get_conf_name
+ *
+ * inputs - type of conf file to return name of file for
+ * output - pointer to filename for type of conf
+ * side effects - none
+ */
+const char *
+get_conf_name(KlineType type)
+{
+ if(type == CONF_TYPE)
+ {
+ return (ConfigFileEntry.configfile);
+ }
+ else if(type == DLINE_TYPE)
+ {
+ return (ConfigFileEntry.dlinefile);
+ }
+ else if(type == RESV_TYPE)
+ {
+ return (ConfigFileEntry.resvfile);
+ }
+
+ return ConfigFileEntry.klinefile;
+}
+
+/*
+ * conf_add_class_to_conf
+ * inputs - pointer to config item
+ * output - NONE
+ * side effects - Add a class pointer to a conf
+ */
+
+void
+conf_add_class_to_conf(struct ConfItem *aconf)
+{
+ if(aconf->className == NULL)
+ {
+ DupString(aconf->className, "default");
+ ClassPtr(aconf) = default_class;
+ return;
+ }
+
+ ClassPtr(aconf) = find_class(aconf->className);
+
+ if(ClassPtr(aconf) == default_class)
+ {
+ if(aconf->status == CONF_CLIENT)
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Warning -- Using default class for missing class \"%s\" in auth{} for %s@%s",
+ aconf->className, aconf->user, aconf->host);
+ }
+
+ MyFree(aconf->className);
+ DupString(aconf->className, "default");
+ return;
+ }
+
+ if(ConfMaxUsers(aconf) < 0)
+ {
+ ClassPtr(aconf) = default_class;
+ MyFree(aconf->className);
+ DupString(aconf->className, "default");
+ return;
+ }
+}
+
+/*
+ * conf_add_d_conf
+ * inputs - pointer to config item
+ * output - NONE
+ * side effects - Add a d/D line
+ */
+void
+conf_add_d_conf(struct ConfItem *aconf)
+{
+ if(aconf->host == NULL)
+ return;
+
+ aconf->user = NULL;
+
+ /* XXX - Should 'd' ever be in the old conf? For new conf we don't
+ * need this anyway, so I will disable it for now... -A1kmm
+ */
+
+ if(parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
+ {
+ ilog(L_MAIN, "Invalid Dline %s ignored", aconf->host);
+ free_conf(aconf);
+ }
+ else
+ {
+ add_conf_by_address(aconf->host, CONF_DLINE, NULL, aconf);
+ }
+}
+
+
+/*
+ * yyerror
+ *
+ * inputs - message from parser
+ * output - none
+ * side effects - message to opers and log file entry is made
+ */
+void
+yyerror(const char *msg)
+{
+ char newlinebuf[BUFSIZE];
+
+ strip_tabs(newlinebuf, (const unsigned char *) linebuf, strlen(linebuf));
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "\"%s\", line %d: %s at '%s'",
+ conffilebuf, lineno + 1, msg, newlinebuf);
+
+ ilog(L_MAIN, "\"%s\", line %d: %s at '%s'", conffilebuf, lineno + 1, msg, newlinebuf);
+}
+
+int
+conf_fgets(char *lbuf, int max_size, FILE * fb)
+{
+ char *buff;
+
+ if((buff = fgets(lbuf, max_size, fb)) == NULL)
+ return (0);
+
+ return (strlen(lbuf));
+}
+
+int
+conf_yy_fatal_error(const char *msg)
+{
+ return (0);
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_gline.c: GLine global ban functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_gline.c 254 2005-09-21 23:35:12Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "common.h"
+#include "config.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "scache.h"
+#include "send.h"
+#include "msg.h"
+#include "s_serv.h"
+#include "s_gline.h"
+#include "hash.h"
+#include "event.h"
+#include "memory.h"
+
+dlink_list glines;
+
+static void expire_glines(void);
+static void expire_pending_glines(void);
+
+/* add_gline
+ *
+ * inputs - pointer to struct ConfItem
+ * output - none
+ * Side effects - links in given struct ConfItem into gline link list
+ */
+void
+add_gline(struct ConfItem *aconf)
+{
+ dlinkAddTailAlloc(aconf, &glines);
+ add_conf_by_address(aconf->host, CONF_GLINE, aconf->user, aconf);
+}
+
+/*
+ * find_is_glined
+ * inputs - hostname
+ * - username
+ * output - pointer to struct ConfItem if user@host glined
+ * side effects -
+ */
+struct ConfItem *
+find_is_glined(const char *host, const char *user)
+{
+ dlink_node *gline_node;
+ struct ConfItem *kill_ptr;
+
+ DLINK_FOREACH(gline_node, glines.head)
+ {
+ kill_ptr = gline_node->data;
+ if((kill_ptr->user && (!user || match(kill_ptr->user, user)))
+ && (kill_ptr->host && (!host || match(kill_ptr->host, host))))
+ {
+ return (kill_ptr);
+ }
+ }
+
+ return (NULL);
+}
+
+/*
+ * cleanup_glines
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects - expire gline lists
+ * This is an event started off in ircd.c
+ */
+void
+cleanup_glines(void *unused)
+{
+ expire_glines();
+ expire_pending_glines();
+}
+
+/*
+ * expire_glines
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects -
+ *
+ * Go through the gline list, expire any needed.
+ */
+static void
+expire_glines()
+{
+ dlink_node *gline_node;
+ dlink_node *next_node;
+ struct ConfItem *kill_ptr;
+
+ DLINK_FOREACH_SAFE(gline_node, next_node, glines.head)
+ {
+ kill_ptr = gline_node->data;
+
+ /* these are in chronological order */
+ if(kill_ptr->hold > CurrentTime)
+ break;
+
+ dlinkDestroy(gline_node, &glines);
+ delete_one_address_conf(kill_ptr->host, kill_ptr);
+ }
+}
+
+/*
+ * expire_pending_glines
+ *
+ * inputs - NONE
+ * output - NONE
+ * side effects -
+ *
+ * Go through the pending gline list, expire any that haven't had
+ * enough "votes" in the time period allowed
+ */
+static void
+expire_pending_glines()
+{
+ dlink_node *pending_node;
+ dlink_node *next_node;
+ struct gline_pending *glp_ptr;
+
+ DLINK_FOREACH_SAFE(pending_node, next_node, pending_glines.head)
+ {
+ glp_ptr = pending_node->data;
+
+ if(((glp_ptr->last_gline_time + GLINE_PENDING_EXPIRE) <=
+ CurrentTime) || find_is_glined(glp_ptr->host, glp_ptr->user))
+
+ {
+ MyFree(glp_ptr->reason1);
+ MyFree(glp_ptr->reason2);
+ MyFree(glp_ptr);
+ dlinkDestroy(pending_node, &pending_glines);
+ }
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ *
+ * Copyright (C) 2003 Lee H <lee@leeh.co.uk>
+ * Copyright (C) 2003-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: s_log.c 1563 2006-06-02 00:43:35Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "sprintf_irc.h"
+#include "send.h"
+#include "client.h"
+#include "s_serv.h"
+
+static FILE *log_main;
+static FILE *log_user;
+static FILE *log_fuser;
+static FILE *log_oper;
+static FILE *log_foper;
+static FILE *log_server;
+static FILE *log_kill;
+static FILE *log_gline;
+static FILE *log_kline;
+static FILE *log_operspy;
+static FILE *log_ioerror;
+
+struct log_struct
+{
+ char **name;
+ FILE **logfile;
+};
+
+static struct log_struct log_table[LAST_LOGFILE] =
+{
+ { NULL, &log_main },
+ { &ConfigFileEntry.fname_userlog, &log_user },
+ { &ConfigFileEntry.fname_fuserlog, &log_fuser },
+ { &ConfigFileEntry.fname_operlog, &log_oper },
+ { &ConfigFileEntry.fname_foperlog, &log_foper },
+ { &ConfigFileEntry.fname_serverlog, &log_server },
+ { &ConfigFileEntry.fname_killlog, &log_kill },
+ { &ConfigFileEntry.fname_klinelog, &log_kline },
+ { &ConfigFileEntry.fname_glinelog, &log_gline },
+ { &ConfigFileEntry.fname_operspylog, &log_operspy },
+ { &ConfigFileEntry.fname_ioerrorlog, &log_ioerror }
+};
+
+void
+init_main_logfile(void)
+{
+ if(log_main == NULL)
+ log_main = fopen(LPATH, "a");
+}
+
+void
+open_logfiles(void)
+{
+ int i;
+
+ if(log_main != NULL)
+ fclose(log_main);
+
+ log_main = fopen(LPATH, "a");
+
+ /* log_main is handled above, so just do the rest */
+ for(i = 1; i < LAST_LOGFILE; i++)
+ {
+ /* close open logfiles */
+ if(*log_table[i].logfile != NULL)
+ {
+ fclose(*log_table[i].logfile);
+ *log_table[i].logfile = NULL;
+ }
+
+ /* reopen those with paths */
+ if(!EmptyString(*log_table[i].name))
+ *log_table[i].logfile = fopen(*log_table[i].name, "a");
+ }
+}
+
+void
+ilog(ilogfile dest, const char *format, ...)
+{
+ FILE *logfile = *log_table[dest].logfile;
+ char buf[BUFSIZE];
+ char buf2[BUFSIZE];
+ va_list args;
+
+ if(logfile == NULL)
+ return;
+
+ va_start(args, format);
+ ircvsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ ircsnprintf(buf2, sizeof(buf2), "%s %s\n", smalldate(), buf);
+
+ if(fputs(buf2, logfile) < 0)
+ {
+ fclose(logfile);
+ *log_table[dest].logfile = NULL;
+ }
+
+ fflush(logfile);
+}
+
+static void
+_iprint(const char *domain, char *buf)
+{
+ if (domain == NULL || buf == NULL)
+ return;
+
+ fprintf(stderr, "%8s: %s\n", domain, buf);
+}
+
+void
+inotice(const char *format, ...)
+{
+ char buf[BUFSIZE];
+ va_list args;
+
+ va_start(args, format);
+ ircvsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ _iprint("notice", buf);
+
+ ilog(L_MAIN, "%s", buf);
+}
+
+void
+iwarn(const char *format, ...)
+{
+ char buf[BUFSIZE];
+ va_list args;
+
+ va_start(args, format);
+ ircvsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ _iprint("warning", buf);
+
+ ilog(L_MAIN, "%s", buf);
+}
+
+void
+ierror(const char *format, ...)
+{
+ char buf[BUFSIZE];
+ va_list args;
+
+ va_start(args, format);
+ ircvsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ _iprint("error", buf);
+
+ ilog(L_MAIN, "%s", buf);
+}
+
+void
+report_operspy(struct Client *source_p, const char *token, const char *arg)
+{
+ /* if its not my client its already propagated */
+ if(MyClient(source_p))
+ sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS,
+ "ENCAP * OPERSPY %s %s",
+ token, arg ? arg : "");
+
+ sendto_realops_snomask(SNO_OPERSPY,
+ ConfigFileEntry.operspy_admin_only ? L_ADMIN : L_ALL,
+ "OPERSPY %s %s %s",
+ get_oper_name(source_p), token,
+ arg ? arg : "");
+
+ ilog(L_OPERSPY, "OPERSPY %s %s %s",
+ get_oper_name(source_p), token, arg ? arg : "");
+}
+
+const char *
+smalldate(void)
+{
+ static char buf[MAX_DATE_STRING];
+ struct tm *lt;
+ time_t ltime = CurrentTime;
+
+ lt = localtime(<ime);
+
+ ircsnprintf(buf, sizeof(buf), "%d/%d/%d %02d.%02d",
+ lt->tm_year + 1900, lt->tm_mon + 1,
+ lt->tm_mday, lt->tm_hour, lt->tm_min);
+
+ return buf;
+}
+
+/*
+ * report_error - report an error from an errno.
+ * Record error to log and also send a copy to all *LOCAL* opers online.
+ *
+ * text is a *format* string for outputing error. It must
+ * contain only two '%s', the first will be replaced
+ * by the sockhost from the client_p, and the latter will
+ * be taken from sys_errlist[errno].
+ *
+ * client_p if not NULL, is the *LOCAL* client associated with
+ * the error.
+ *
+ * Cannot use perror() within daemon. stderr is closed in
+ * ircd and cannot be used. And, worse yet, it might have
+ * been reassigned to a normal connection...
+ *
+ * Actually stderr is still there IFF ircd was run with -s --Rodder
+ */
+
+void
+report_error(const char *text, const char *who, const char *wholog, int error)
+{
+ who = (who) ? who : "";
+ wholog = (wholog) ? wholog : "";
+
+ sendto_realops_snomask(SNO_DEBUG, L_ALL, text, who, strerror(error));
+
+ ilog(L_IOERROR, text, wholog, strerror(error));
+}
--- /dev/null
+/*
+ * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ * s_newconf.c - code for dealing with conf stuff
+ *
+ * Copyright (C) 2004 Lee Hardy <lee@leeh.co.uk>
+ * Copyright (C) 2004-2005 ircd-ratbox development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: s_newconf.c 1747 2006-07-25 21:22:45Z jilles $
+ */
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "common.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "tools.h"
+#include "client.h"
+#include "memory.h"
+#include "s_serv.h"
+#include "send.h"
+#include "hostmask.h"
+#include "newconf.h"
+#include "hash.h"
+#include "balloc.h"
+#include "event.h"
+#include "sprintf_irc.h"
+
+dlink_list shared_conf_list;
+dlink_list cluster_conf_list;
+dlink_list oper_conf_list;
+dlink_list hubleaf_conf_list;
+dlink_list server_conf_list;
+dlink_list xline_conf_list;
+dlink_list resv_conf_list; /* nicks only! */
+dlink_list nd_list; /* nick delay */
+dlink_list tgchange_list;
+
+patricia_tree_t *tgchange_tree;
+
+static BlockHeap *nd_heap = NULL;
+
+static void expire_temp_rxlines(void *unused);
+static void expire_nd_entries(void *unused);
+
+void
+init_s_newconf(void)
+{
+ tgchange_tree = New_Patricia(PATRICIA_BITS);
+ nd_heap = BlockHeapCreate(sizeof(struct nd_entry), ND_HEAP_SIZE);
+ eventAddIsh("expire_nd_entries", expire_nd_entries, NULL, 30);
+ eventAddIsh("expire_temp_rxlines", expire_temp_rxlines, NULL, 60);
+}
+
+void
+clear_s_newconf(void)
+{
+ struct server_conf *server_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, shared_conf_list.head)
+ {
+ /* ptr here is ptr->data->node */
+ dlinkDelete(ptr, &shared_conf_list);
+ free_remote_conf(ptr->data);
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, cluster_conf_list.head)
+ {
+ dlinkDelete(ptr, &cluster_conf_list);
+ free_remote_conf(ptr->data);
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, hubleaf_conf_list.head)
+ {
+ dlinkDelete(ptr, &hubleaf_conf_list);
+ free_remote_conf(ptr->data);
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, oper_conf_list.head)
+ {
+ free_oper_conf(ptr->data);
+ dlinkDestroy(ptr, &oper_conf_list);
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, server_conf_list.head)
+ {
+ server_p = ptr->data;
+
+ if(!server_p->servers)
+ {
+ dlinkDelete(ptr, &server_conf_list);
+ free_server_conf(ptr->data);
+ }
+ else
+ server_p->flags |= SERVER_ILLEGAL;
+ }
+}
+
+void
+clear_s_newconf_bans(void)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr, *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold)
+ continue;
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &xline_conf_list);
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ /* temporary resv */
+ if(aconf->hold)
+ continue;
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &resv_conf_list);
+ }
+
+ clear_resv_hash();
+}
+
+struct remote_conf *
+make_remote_conf(void)
+{
+ struct remote_conf *remote_p = MyMalloc(sizeof(struct remote_conf));
+ return remote_p;
+}
+
+void
+free_remote_conf(struct remote_conf *remote_p)
+{
+ s_assert(remote_p != NULL);
+ if(remote_p == NULL)
+ return;
+
+ MyFree(remote_p->username);
+ MyFree(remote_p->host);
+ MyFree(remote_p->server);
+ MyFree(remote_p);
+}
+
+int
+find_shared_conf(const char *username, const char *host,
+ const char *server, int flags)
+{
+ struct remote_conf *shared_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, shared_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ if(match(shared_p->username, username) &&
+ match(shared_p->host, host) &&
+ match(shared_p->server, server))
+ {
+ if(shared_p->flags & flags)
+ return YES;
+ else
+ return NO;
+ }
+ }
+
+ return NO;
+}
+
+void
+propagate_generic(struct Client *source_p, const char *command,
+ const char *target, int cap, const char *format, ...)
+{
+ char buffer[BUFSIZE];
+ va_list args;
+
+ va_start(args, format);
+ ircvsnprintf(buffer, sizeof(buffer), format, args);
+ va_end(args);
+
+ sendto_match_servs(source_p, target, cap, NOCAPS,
+ "%s %s %s",
+ command, target, buffer);
+ sendto_match_servs(source_p, target, CAP_ENCAP, cap,
+ "ENCAP %s %s %s",
+ target, command, buffer);
+}
+
+void
+cluster_generic(struct Client *source_p, const char *command,
+ int cltype, int cap, const char *format, ...)
+{
+ char buffer[BUFSIZE];
+ struct remote_conf *shared_p;
+ va_list args;
+ dlink_node *ptr;
+
+ va_start(args, format);
+ ircvsnprintf(buffer, sizeof(buffer), format, args);
+ va_end(args);
+
+ DLINK_FOREACH(ptr, cluster_conf_list.head)
+ {
+ shared_p = ptr->data;
+
+ if(!(shared_p->flags & cltype))
+ continue;
+
+ sendto_match_servs(source_p, shared_p->server, cap, NOCAPS,
+ "%s %s %s",
+ command, shared_p->server, buffer);
+ sendto_match_servs(source_p, shared_p->server, CAP_ENCAP, cap,
+ "ENCAP %s %s %s",
+ shared_p->server, command, buffer);
+ }
+}
+
+struct oper_conf *
+make_oper_conf(void)
+{
+ struct oper_conf *oper_p = MyMalloc(sizeof(struct oper_conf));
+ return oper_p;
+}
+
+void
+free_oper_conf(struct oper_conf *oper_p)
+{
+ s_assert(oper_p != NULL);
+ if(oper_p == NULL)
+ return;
+
+ MyFree(oper_p->username);
+ MyFree(oper_p->host);
+ MyFree(oper_p->name);
+
+ if(oper_p->passwd)
+ {
+ memset(oper_p->passwd, 0, strlen(oper_p->passwd));
+ MyFree(oper_p->passwd);
+ }
+
+#ifdef HAVE_LIBCRYPTO
+ MyFree(oper_p->rsa_pubkey_file);
+
+ if(oper_p->rsa_pubkey)
+ RSA_free(oper_p->rsa_pubkey);
+#endif
+
+ MyFree(oper_p);
+}
+
+struct oper_conf *
+find_oper_conf(const char *username, const char *host, const char *locip, const char *name)
+{
+ struct oper_conf *oper_p;
+ struct irc_sockaddr_storage ip, cip;
+ char addr[HOSTLEN+1];
+ int bits, cbits;
+ dlink_node *ptr;
+
+ parse_netmask(locip, (struct sockaddr *)&cip, &cbits);
+
+ DLINK_FOREACH(ptr, oper_conf_list.head)
+ {
+ oper_p = ptr->data;
+
+ /* name/username doesnt match.. */
+ if(irccmp(oper_p->name, name) || !match(oper_p->username, username))
+ continue;
+
+ strlcpy(addr, oper_p->host, sizeof(addr));
+
+ if(parse_netmask(addr, (struct sockaddr *)&ip, &bits) != HM_HOST)
+ {
+ if(ip.ss_family == cip.ss_family &&
+ comp_with_mask_sock((struct sockaddr *)&ip, (struct sockaddr *)&cip, bits))
+ return oper_p;
+ }
+
+ /* we have to compare against the host as well, because its
+ * valid to set a spoof to an IP, which if we only compare
+ * in ip form to sockhost will not necessarily match --anfl
+ */
+ if(match(oper_p->host, host))
+ return oper_p;
+ }
+
+ return NULL;
+}
+
+struct oper_flags
+{
+ int flag;
+ char has;
+ char hasnt;
+};
+static struct oper_flags oper_flagtable[] =
+{
+ { OPER_GLINE, 'G', 'g' },
+ { OPER_KLINE, 'K', 'k' },
+ { OPER_XLINE, 'X', 'x' },
+ { OPER_GLOBKILL, 'O', 'o' },
+ { OPER_LOCKILL, 'C', 'c' },
+ { OPER_REMOTE, 'R', 'r' },
+ { OPER_UNKLINE, 'U', 'u' },
+ { OPER_REHASH, 'H', 'h' },
+ { OPER_DIE, 'D', 'd' },
+ { OPER_ADMIN, 'A', 'a' },
+ { OPER_NICKS, 'N', 'n' },
+ { OPER_OPERWALL, 'L', 'l' },
+ { OPER_SPY, 'S', 's' },
+ { OPER_INVIS, 'P', 'p' },
+ { OPER_REMOTEBAN, 'B', 'b' },
+ { 0, '\0', '\0' }
+};
+
+const char *
+get_oper_privs(int flags)
+{
+ static char buf[20];
+ char *p;
+ int i;
+
+ p = buf;
+
+ for(i = 0; oper_flagtable[i].flag; i++)
+ {
+ if(flags & oper_flagtable[i].flag)
+ *p++ = oper_flagtable[i].has;
+ else
+ *p++ = oper_flagtable[i].hasnt;
+ }
+
+ *p = '\0';
+
+ return buf;
+}
+
+struct server_conf *
+make_server_conf(void)
+{
+ struct server_conf *server_p = MyMalloc(sizeof(struct server_conf));
+ server_p->aftype = AF_INET;
+ return server_p;
+}
+
+void
+free_server_conf(struct server_conf *server_p)
+{
+ s_assert(server_p != NULL);
+ if(server_p == NULL)
+ return;
+
+ if(!EmptyString(server_p->passwd))
+ {
+ memset(server_p->passwd, 0, strlen(server_p->passwd));
+ MyFree(server_p->passwd);
+ }
+
+ if(!EmptyString(server_p->spasswd))
+ {
+ memset(server_p->spasswd, 0, strlen(server_p->spasswd));
+ MyFree(server_p->spasswd);
+ }
+
+ MyFree(server_p->name);
+ MyFree(server_p->host);
+ MyFree(server_p->class_name);
+ MyFree(server_p);
+}
+
+void
+add_server_conf(struct server_conf *server_p)
+{
+ if(EmptyString(server_p->class_name))
+ {
+ DupString(server_p->class_name, "default");
+ server_p->class = default_class;
+ return;
+ }
+
+ server_p->class = find_class(server_p->class_name);
+
+ if(server_p->class == default_class)
+ {
+ conf_report_error("Warning connect::class invalid for %s",
+ server_p->name);
+
+ MyFree(server_p->class_name);
+ DupString(server_p->class_name, "default");
+ }
+
+ if(strchr(server_p->host, '*') || strchr(server_p->host, '?'))
+ return;
+}
+
+struct server_conf *
+find_server_conf(const char *name)
+{
+ struct server_conf *server_p;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, server_conf_list.head)
+ {
+ server_p = ptr->data;
+
+ if(ServerConfIllegal(server_p))
+ continue;
+
+ if(match(name, server_p->name))
+ return server_p;
+ }
+
+ return NULL;
+}
+
+void
+attach_server_conf(struct Client *client_p, struct server_conf *server_p)
+{
+ /* already have an attached conf */
+ if(client_p->localClient->att_sconf)
+ {
+ /* short circuit this special case :) */
+ if(client_p->localClient->att_sconf == server_p)
+ return;
+
+ detach_server_conf(client_p);
+ }
+
+ CurrUsers(server_p->class)++;
+
+ client_p->localClient->att_sconf = server_p;
+ server_p->servers++;
+}
+
+void
+detach_server_conf(struct Client *client_p)
+{
+ struct server_conf *server_p = client_p->localClient->att_sconf;
+
+ if(server_p == NULL)
+ return;
+
+ client_p->localClient->att_sconf = NULL;
+ server_p->servers--;
+ CurrUsers(server_p->class)--;
+
+ if(ServerConfIllegal(server_p) && !server_p->servers)
+ {
+ /* the class this one is using may need destroying too */
+ if(MaxUsers(server_p->class) < 0 && CurrUsers(server_p->class) <= 0)
+ free_class(server_p->class);
+
+ dlinkDelete(&server_p->node, &server_conf_list);
+ free_server_conf(server_p);
+ }
+}
+
+void
+set_server_conf_autoconn(struct Client *source_p, char *name, int newval)
+{
+ struct server_conf *server_p;
+
+ if((server_p = find_server_conf(name)) != NULL)
+ {
+ if(newval)
+ server_p->flags |= SERVER_AUTOCONN;
+ else
+ server_p->flags &= ~SERVER_AUTOCONN;
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s has changed AUTOCONN for %s to %i",
+ get_oper_name(source_p), name, newval);
+ }
+ else
+ sendto_one(source_p, ":%s NOTICE %s :Can't find %s",
+ me.name, source_p->name, name);
+}
+
+struct ConfItem *
+find_xline(const char *gecos, int counter)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(match_esc(aconf->name, gecos))
+ {
+ if(counter)
+ aconf->port++;
+ return aconf;
+ }
+ }
+
+ return NULL;
+}
+
+struct ConfItem *
+find_nick_resv(const char *name)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+
+ DLINK_FOREACH(ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(match_esc(aconf->name, name))
+ {
+ aconf->port++;
+ return aconf;
+ }
+ }
+
+ return NULL;
+}
+
+/* clean_resv_nick()
+ *
+ * inputs - nick
+ * outputs - 1 if nick is vaild resv, 0 otherwise
+ * side effects -
+ */
+int
+clean_resv_nick(const char *nick)
+{
+ char tmpch;
+ int as = 0;
+ int q = 0;
+ int ch = 0;
+
+ if(*nick == '-' || IsDigit(*nick))
+ return 0;
+
+ while ((tmpch = *nick++))
+ {
+ if(tmpch == '?' || tmpch == '@' || tmpch == '#')
+ q++;
+ else if(tmpch == '*')
+ as++;
+ else if(IsNickChar(tmpch))
+ ch++;
+ else
+ return 0;
+ }
+
+ if(!ch && as)
+ return 0;
+
+ return 1;
+}
+
+/* valid_wild_card_simple()
+ *
+ * inputs - "thing" to test
+ * outputs - 1 if enough wildcards, else 0
+ * side effects -
+ */
+int
+valid_wild_card_simple(const char *data)
+{
+ const char *p;
+ char tmpch;
+ int nonwild = 0;
+
+ /* check the string for minimum number of nonwildcard chars */
+ p = data;
+
+ while((tmpch = *p++))
+ {
+ /* found an escape, p points to the char after it, so skip
+ * that and move on.
+ */
+ if(tmpch == '\\')
+ {
+ p++;
+ }
+ else if(!IsMWildChar(tmpch))
+ {
+ /* if we have enough nonwildchars, return */
+ if(++nonwild >= ConfigFileEntry.min_nonwildcard_simple)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+time_t
+valid_temp_time(const char *p)
+{
+ time_t result = 0;
+
+ while(*p)
+ {
+ if(IsDigit(*p))
+ {
+ result *= 10;
+ result += ((*p) & 0xF);
+ p++;
+ }
+ else
+ return -1;
+ }
+
+ if(result > (60 * 24 * 7 * 52))
+ result = (60 * 24 * 7 * 52);
+
+ return(result * 60);
+}
+
+static void
+expire_temp_rxlines(void *unused)
+{
+ struct ConfItem *aconf;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ int i;
+
+ HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold && aconf->hold <= CurrentTime)
+ {
+ if(ConfigFileEntry.tkline_expire_notices)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Temporary RESV for [%s] expired",
+ aconf->name);
+
+ free_conf(aconf);
+ dlinkDestroy(ptr, &resvTable[i]);
+ }
+ }
+ HASH_WALK_END
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold && aconf->hold <= CurrentTime)
+ {
+ if(ConfigFileEntry.tkline_expire_notices)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Temporary RESV for [%s] expired",
+ aconf->name);
+ free_conf(aconf);
+ dlinkDestroy(ptr, &resv_conf_list);
+ }
+ }
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, xline_conf_list.head)
+ {
+ aconf = ptr->data;
+
+ if(aconf->hold && aconf->hold <= CurrentTime)
+ {
+ if(ConfigFileEntry.tkline_expire_notices)
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Temporary X-line for [%s] expired",
+ aconf->name);
+ free_conf(aconf);
+ dlinkDestroy(ptr, &xline_conf_list);
+ }
+ }
+}
+
+unsigned long
+get_nd_count(void)
+{
+ return(dlink_list_length(&nd_list));
+}
+
+
+void
+add_nd_entry(const char *name)
+{
+ struct nd_entry *nd;
+
+ if(hash_find_nd(name) != NULL)
+ return;
+
+ nd = BlockHeapAlloc(nd_heap);
+
+ strlcpy(nd->name, name, sizeof(nd->name));
+ nd->expire = CurrentTime + ConfigFileEntry.nick_delay;
+
+ /* this list is ordered */
+ dlinkAddTail(nd, &nd->lnode, &nd_list);
+ add_to_nd_hash(name, nd);
+}
+
+void
+free_nd_entry(struct nd_entry *nd)
+{
+ dlinkDelete(&nd->lnode, &nd_list);
+ dlinkDelete(&nd->hnode, &ndTable[nd->hashv]);
+ BlockHeapFree(nd_heap, nd);
+}
+
+void
+expire_nd_entries(void *unused)
+{
+ struct nd_entry *nd;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, nd_list.head)
+ {
+ nd = ptr->data;
+
+ /* this list is ordered - we can stop when we hit the first
+ * entry that doesnt expire..
+ */
+ if(nd->expire > CurrentTime)
+ return;
+
+ free_nd_entry(nd);
+ }
+}
+
+void
+add_tgchange(const char *host)
+{
+ tgchange *target;
+ patricia_node_t *pnode;
+
+ if(find_tgchange(host))
+ return;
+
+ target = MyMalloc(sizeof(tgchange));
+ pnode = make_and_lookup(tgchange_tree, host);
+
+ pnode->data = target;
+ target->pnode = pnode;
+
+ DupString(target->ip, host);
+ target->expiry = CurrentTime + (60*60*12);
+
+ dlinkAdd(target, &target->node, &tgchange_list);
+}
+
+tgchange *
+find_tgchange(const char *host)
+{
+ patricia_node_t *pnode;
+
+ if((pnode = match_exact_string(tgchange_tree, host)))
+ return pnode->data;
+
+ return NULL;
+}
+
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_serv.c: Server related functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_serv.c 2723 2006-11-09 23:35:48Z jilles $
+ */
+
+#include "stdinc.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/rsa.h>
+#endif
+
+#include "tools.h"
+#include "s_serv.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "event.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "ircd_defs.h"
+#include "numeric.h"
+#include "packet.h"
+#include "res.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "s_stats.h"
+#include "s_user.h"
+#include "scache.h"
+#include "send.h"
+#include "client.h"
+#include "memory.h"
+#include "channel.h" /* chcap_usage_counts stuff... */
+#include "hook.h"
+#include "msg.h"
+
+extern char *crypt();
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+#ifndef HAVE_SOCKETPAIR
+static int inet_socketpair(int d, int type, int protocol, int sv[2]);
+#endif
+
+int MaxConnectionCount = 1;
+int MaxClientCount = 1;
+int refresh_user_links = 0;
+
+static char buf[BUFSIZE];
+
+static void start_io(struct Client *server);
+
+static SlinkRplHnd slink_error;
+static SlinkRplHnd slink_zipstats;
+/*
+ * list of recognized server capabilities. "TS" is not on the list
+ * because all servers that we talk to already do TS, and the kludged
+ * extra argument to "PASS" takes care of checking that. -orabidoo
+ */
+struct Capability captab[] = {
+/* name cap */
+ { "QS", CAP_QS },
+ { "EX", CAP_EX },
+ { "CHW", CAP_CHW},
+ { "IE", CAP_IE},
+ { "KLN", CAP_KLN},
+ { "GLN", CAP_GLN},
+ { "KNOCK", CAP_KNOCK},
+ { "ZIP", CAP_ZIP},
+ { "TB", CAP_TB},
+ { "UNKLN", CAP_UNKLN},
+ { "CLUSTER", CAP_CLUSTER},
+ { "ENCAP", CAP_ENCAP },
+ { "SERVICES", CAP_SERVICE },
+ { "RSFNC", CAP_RSFNC },
+ { "SAVE", CAP_SAVE },
+ { "EUID", CAP_EUID },
+ {0, 0}
+};
+
+struct SlinkRplDef slinkrpltab[] = {
+ {SLINKRPL_ERROR, slink_error, SLINKRPL_FLAG_DATA},
+ {SLINKRPL_ZIPSTATS, slink_zipstats, SLINKRPL_FLAG_DATA},
+ {0, 0, 0},
+};
+
+static int fork_server(struct Client *client_p);
+
+static CNCB serv_connect_callback;
+
+void
+slink_error(unsigned int rpl, unsigned int len, unsigned char *data, struct Client *server_p)
+{
+ char squitreason[256];
+
+ s_assert(rpl == SLINKRPL_ERROR);
+
+ s_assert(len < 256);
+ data[len - 1] = '\0';
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "SlinkError for %s: %s", server_p->name, data);
+ snprintf(squitreason, sizeof squitreason, "servlink error: %s", data);
+ exit_client(server_p, server_p, &me, squitreason);
+}
+
+void
+slink_zipstats(unsigned int rpl, unsigned int len, unsigned char *data, struct Client *server_p)
+{
+ struct ZipStats zipstats;
+ u_int32_t in = 0, in_wire = 0, out = 0, out_wire = 0;
+ int i = 0;
+
+ s_assert(rpl == SLINKRPL_ZIPSTATS);
+ s_assert(len == 16);
+ s_assert(IsCapable(server_p, CAP_ZIP));
+
+ /* Yes, it needs to be done this way, no we cannot let the compiler
+ * work with the pointer to the structure. This works around a GCC
+ * bug on SPARC that affects all versions at the time of this writing.
+ * I will feed you to the creatures living in RMS's beard if you do
+ * not leave this as is, without being sure that you are not causing
+ * regression for most of our installed SPARC base.
+ * -jmallett, 04/27/2002
+ */
+ memcpy(&zipstats, &server_p->localClient->zipstats, sizeof(struct ZipStats));
+
+ in |= (data[i++] << 24);
+ in |= (data[i++] << 16);
+ in |= (data[i++] << 8);
+ in |= (data[i++]);
+
+ in_wire |= (data[i++] << 24);
+ in_wire |= (data[i++] << 16);
+ in_wire |= (data[i++] << 8);
+ in_wire |= (data[i++]);
+
+ out |= (data[i++] << 24);
+ out |= (data[i++] << 16);
+ out |= (data[i++] << 8);
+ out |= (data[i++]);
+
+ out_wire |= (data[i++] << 24);
+ out_wire |= (data[i++] << 16);
+ out_wire |= (data[i++] << 8);
+ out_wire |= (data[i++]);
+
+ zipstats.in += in;
+ zipstats.inK += zipstats.in >> 10;
+ zipstats.in &= 0x03ff;
+
+ zipstats.in_wire += in_wire;
+ zipstats.inK_wire += zipstats.in_wire >> 10;
+ zipstats.in_wire &= 0x03ff;
+
+ zipstats.out += out;
+ zipstats.outK += zipstats.out >> 10;
+ zipstats.out &= 0x03ff;
+
+ zipstats.out_wire += out_wire;
+ zipstats.outK_wire += zipstats.out_wire >> 10;
+ zipstats.out_wire &= 0x03ff;
+
+ if(zipstats.inK > 0)
+ zipstats.in_ratio =
+ (((double) (zipstats.inK - zipstats.inK_wire) /
+ (double) zipstats.inK) * 100.00);
+ else
+ zipstats.in_ratio = 0;
+
+ if(zipstats.outK > 0)
+ zipstats.out_ratio =
+ (((double) (zipstats.outK - zipstats.outK_wire) /
+ (double) zipstats.outK) * 100.00);
+ else
+ zipstats.out_ratio = 0;
+
+ memcpy(&server_p->localClient->zipstats, &zipstats, sizeof(struct ZipStats));
+}
+
+void
+collect_zipstats(void *unused)
+{
+ dlink_node *ptr;
+ struct Client *target_p;
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+ if(IsCapable(target_p, CAP_ZIP))
+ {
+ /* only bother if we haven't already got something queued... */
+ if(!target_p->localClient->slinkq)
+ {
+ target_p->localClient->slinkq = MyMalloc(1); /* sigh.. */
+ target_p->localClient->slinkq[0] = SLINKCMD_ZIPSTATS;
+ target_p->localClient->slinkq_ofs = 0;
+ target_p->localClient->slinkq_len = 1;
+ send_queued_slink_write(target_p->localClient->ctrlfd, target_p);
+ }
+ }
+ }
+}
+
+/*
+ * hunt_server - Do the basic thing in delivering the message (command)
+ * across the relays to the specific server (server) for
+ * actions.
+ *
+ * Note: The command is a format string and *MUST* be
+ * of prefixed style (e.g. ":%s COMMAND %s ...").
+ * Command can have only max 8 parameters.
+ *
+ * server parv[server] is the parameter identifying the
+ * target server.
+ *
+ * *WARNING*
+ * parv[server] is replaced with the pointer to the
+ * real servername from the matched client (I'm lazy
+ * now --msa).
+ *
+ * returns: (see #defines)
+ */
+int
+hunt_server(struct Client *client_p, struct Client *source_p,
+ const char *command, int server, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ int wilds;
+ dlink_node *ptr;
+ const char *old;
+ char *new;
+
+ /*
+ * Assume it's me, if no server
+ */
+ if(parc <= server || EmptyString(parv[server]) ||
+ match(me.name, parv[server]) || match(parv[server], me.name) ||
+ (strcmp(parv[server], me.id) == 0))
+ return (HUNTED_ISME);
+
+ new = LOCAL_COPY(parv[server]);
+
+ /*
+ * These are to pickup matches that would cause the following
+ * message to go in the wrong direction while doing quick fast
+ * non-matching lookups.
+ */
+ if(MyClient(source_p))
+ target_p = find_named_client(new);
+ else
+ target_p = find_client(new);
+
+ if(target_p)
+ if(target_p->from == source_p->from && !MyConnect(target_p))
+ target_p = NULL;
+
+ if(target_p == NULL && (target_p = find_server(source_p, new)))
+ if(target_p->from == source_p->from && !MyConnect(target_p))
+ target_p = NULL;
+
+ collapse(new);
+ wilds = (strchr(new, '?') || strchr(new, '*'));
+
+ /*
+ * Again, if there are no wild cards involved in the server
+ * name, use the hash lookup
+ */
+ if(!target_p)
+ {
+ if(!wilds)
+ {
+ if(MyClient(source_p) || !IsDigit(parv[server][0]))
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ parv[server]);
+ return (HUNTED_NOSUCH);
+ }
+ else
+ {
+ target_p = NULL;
+
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ if(match(new, ((struct Client *) (ptr->data))->name))
+ {
+ target_p = ptr->data;
+ break;
+ }
+ }
+ }
+ }
+
+ if(target_p)
+ {
+ if(!IsRegistered(target_p))
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER),
+ parv[server]);
+ return HUNTED_NOSUCH;
+ }
+
+ if(IsMe(target_p) || MyClient(target_p))
+ return HUNTED_ISME;
+
+ old = parv[server];
+ parv[server] = get_id(target_p, target_p);
+
+ sendto_one(target_p, command, get_id(source_p, target_p),
+ parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
+ parv[server] = old;
+ return (HUNTED_PASS);
+ }
+
+ if(!IsDigit(parv[server][0]))
+ sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
+ form_str(ERR_NOSUCHSERVER), parv[server]);
+ return (HUNTED_NOSUCH);
+}
+
+/*
+ * try_connections - scan through configuration and try new connections.
+ * Returns the calendar time when the next call to this
+ * function should be made latest. (No harm done if this
+ * is called earlier or later...)
+ */
+void
+try_connections(void *unused)
+{
+ struct Client *client_p;
+ struct server_conf *server_p = NULL;
+ struct server_conf *tmp_p;
+ struct Class *cltmp;
+ dlink_node *ptr;
+ int connecting = FALSE;
+ int confrq = 0;
+ time_t next = 0;
+
+ DLINK_FOREACH(ptr, server_conf_list.head)
+ {
+ tmp_p = ptr->data;
+
+ if(ServerConfIllegal(tmp_p) || !ServerConfAutoconn(tmp_p))
+ continue;
+
+ cltmp = tmp_p->class;
+
+ /*
+ * Skip this entry if the use of it is still on hold until
+ * future. Otherwise handle this entry (and set it on hold
+ * until next time). Will reset only hold times, if already
+ * made one successfull connection... [this algorithm is
+ * a bit fuzzy... -- msa >;) ]
+ */
+ if(tmp_p->hold > CurrentTime)
+ {
+ if(next > tmp_p->hold || next == 0)
+ next = tmp_p->hold;
+ continue;
+ }
+
+ confrq = get_con_freq(cltmp);
+ tmp_p->hold = CurrentTime + confrq;
+
+ /*
+ * Found a CONNECT config with port specified, scan clients
+ * and see if this server is already connected?
+ */
+ client_p = find_server(NULL, tmp_p->name);
+
+ if(!client_p && (CurrUsers(cltmp) < MaxUsers(cltmp)) && !connecting)
+ {
+ server_p = tmp_p;
+
+ /* We connect only one at time... */
+ connecting = TRUE;
+ }
+
+ if((next > tmp_p->hold) || (next == 0))
+ next = tmp_p->hold;
+ }
+
+ /* TODO: change this to set active flag to 0 when added to event! --Habeeb */
+ if(GlobalSetOptions.autoconn == 0)
+ return;
+
+ if(!connecting)
+ return;
+
+ /* move this connect entry to end.. */
+ dlinkDelete(&server_p->node, &server_conf_list);
+ dlinkAddTail(server_p, &server_p->node, &server_conf_list);
+
+ /*
+ * We used to only print this if serv_connect() actually
+ * suceeded, but since comm_tcp_connect() can call the callback
+ * immediately if there is an error, we were getting error messages
+ * in the wrong order. SO, we just print out the activated line,
+ * and let serv_connect() / serv_connect_callback() print an
+ * error afterwards if it fails.
+ * -- adrian
+ */
+#ifndef HIDE_SERVERS_IPS
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Connection to %s[%s] activated.",
+ server_p->name, server_p->host);
+#else
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Connection to %s activated",
+ server_p->name);
+#endif
+
+ serv_connect(server_p, 0);
+}
+
+int
+check_server(const char *name, struct Client *client_p)
+{
+ struct server_conf *server_p = NULL;
+ struct server_conf *tmp_p;
+ dlink_node *ptr;
+ int error = -1;
+
+ s_assert(NULL != client_p);
+ if(client_p == NULL)
+ return error;
+
+ if(!(client_p->localClient->passwd))
+ return -2;
+
+ if(strlen(name) > HOSTLEN)
+ return -4;
+
+ DLINK_FOREACH(ptr, server_conf_list.head)
+ {
+ tmp_p = ptr->data;
+
+ if(ServerConfIllegal(tmp_p))
+ continue;
+
+ if(!match(tmp_p->name, name))
+ continue;
+
+ error = -3;
+
+ /* XXX: Fix me for IPv6 */
+ /* XXX sockhost is the IPv4 ip as a string */
+ if(match(tmp_p->host, client_p->host) ||
+ match(tmp_p->host, client_p->sockhost))
+ {
+ error = -2;
+
+ if(ServerConfEncrypted(tmp_p))
+ {
+ if(!strcmp(tmp_p->passwd, crypt(client_p->localClient->passwd,
+ tmp_p->passwd)))
+ {
+ server_p = tmp_p;
+ break;
+ }
+ }
+ else if(!strcmp(tmp_p->passwd, client_p->localClient->passwd))
+ {
+ server_p = tmp_p;
+ break;
+ }
+ }
+ }
+
+ if(server_p == NULL)
+ return error;
+
+ attach_server_conf(client_p, server_p);
+
+ /* clear ZIP/TB if they support but we dont want them */
+#ifdef HAVE_LIBZ
+ if(!ServerConfCompressed(server_p))
+#endif
+ ClearCap(client_p, CAP_ZIP);
+
+ if(!ServerConfTb(server_p))
+ ClearCap(client_p, CAP_TB);
+
+ return 0;
+}
+
+/*
+ * send_capabilities
+ *
+ * inputs - Client pointer to send to
+ * - int flag of capabilities that this server has
+ * output - NONE
+ * side effects - send the CAPAB line to a server -orabidoo
+ *
+ */
+void
+send_capabilities(struct Client *client_p, int cap_can_send)
+{
+ struct Capability *cap;
+ char msgbuf[BUFSIZE];
+ char *t;
+ int tl;
+
+ t = msgbuf;
+
+ for (cap = captab; cap->name; ++cap)
+ {
+ if(cap->cap & cap_can_send)
+ {
+ tl = ircsprintf(t, "%s ", cap->name);
+ t += tl;
+ }
+ }
+
+ t--;
+ *t = '\0';
+
+ sendto_one(client_p, "CAPAB :%s", msgbuf);
+}
+
+/* burst_modes_TS5()
+ *
+ * input - client to burst to, channel name, list to burst, mode flag
+ * output -
+ * side effects - client is sent a list of +b, or +e, or +I modes
+ */
+static void
+burst_modes_TS5(struct Client *client_p, char *chname, dlink_list *list, char flag)
+{
+ dlink_node *ptr;
+ struct Ban *banptr;
+ char mbuf[MODEBUFLEN];
+ char pbuf[BUFSIZE];
+ int tlen;
+ int mlen;
+ int cur_len;
+ char *mp;
+ char *pp;
+ int count = 0;
+
+ mlen = ircsprintf(buf, ":%s MODE %s +", me.name, chname);
+ cur_len = mlen;
+
+ mp = mbuf;
+ pp = pbuf;
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ banptr = ptr->data;
+ tlen = strlen(banptr->banstr) + 3;
+
+ /* uh oh */
+ if(tlen > MODEBUFLEN)
+ continue;
+
+ if((count >= MAXMODEPARAMS) || ((cur_len + tlen + 2) > (BUFSIZE - 3)))
+ {
+ sendto_one(client_p, "%s%s %s", buf, mbuf, pbuf);
+
+ mp = mbuf;
+ pp = pbuf;
+ cur_len = mlen;
+ count = 0;
+ }
+
+ *mp++ = flag;
+ *mp = '\0';
+ pp += ircsprintf(pp, "%s ", banptr->banstr);
+ cur_len += tlen;
+ count++;
+ }
+
+ if(count != 0)
+ sendto_one(client_p, "%s%s %s", buf, mbuf, pbuf);
+}
+
+/* burst_modes_TS6()
+ *
+ * input - client to burst to, channel name, list to burst, mode flag
+ * output -
+ * side effects - client is sent a list of +b, +e, or +I modes
+ */
+static void
+burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
+ dlink_list *list, char flag)
+{
+ dlink_node *ptr;
+ struct Ban *banptr;
+ char *t;
+ int tlen;
+ int mlen;
+ int cur_len;
+
+ cur_len = mlen = ircsprintf(buf, ":%s BMASK %ld %s %c :",
+ me.id, (long) chptr->channelts, chptr->chname, flag);
+ t = buf + mlen;
+
+ DLINK_FOREACH(ptr, list->head)
+ {
+ banptr = ptr->data;
+
+ tlen = strlen(banptr->banstr) + 1;
+
+ /* uh oh */
+ if(cur_len + tlen > BUFSIZE - 3)
+ {
+ /* the one we're trying to send doesnt fit at all! */
+ if(cur_len == mlen)
+ {
+ s_assert(0);
+ continue;
+ }
+
+ /* chop off trailing space and send.. */
+ *(t-1) = '\0';
+ sendto_one(client_p, "%s", buf);
+ cur_len = mlen;
+ t = buf + mlen;
+ }
+
+ ircsprintf(t, "%s ", banptr->banstr);
+ t += tlen;
+ cur_len += tlen;
+ }
+
+ /* cant ever exit the loop above without having modified buf,
+ * chop off trailing space and send.
+ */
+ *(t-1) = '\0';
+ sendto_one(client_p, "%s", buf);
+}
+
+/*
+ * burst_TS5
+ *
+ * inputs - client (server) to send nick towards
+ * - client to send nick for
+ * output - NONE
+ * side effects - NICK message is sent towards given client_p
+ */
+static void
+burst_TS5(struct Client *client_p)
+{
+ static char ubuf[12];
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+ hook_data_client hclientinfo;
+ hook_data_channel hchaninfo;
+ dlink_node *ptr;
+ dlink_node *uptr;
+ char *t;
+ int tlen, mlen;
+ int cur_len = 0;
+
+ hclientinfo.client = hchaninfo.client = client_p;
+
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!IsPerson(target_p))
+ continue;
+
+ send_umode(NULL, target_p, 0, 0, ubuf);
+ if(!*ubuf)
+ {
+ ubuf[0] = '+';
+ ubuf[1] = '\0';
+ }
+
+ sendto_one(client_p, "NICK %s %d %ld %s %s %s %s :%s",
+ target_p->name, target_p->hopcount + 1,
+ (long) target_p->tsinfo, ubuf,
+ target_p->username, target_p->host,
+ target_p->user->server, target_p->info);
+
+ if(IsDynSpoof(target_p))
+ sendto_one(client_p, ":%s ENCAP * REALHOST %s",
+ target_p->name, target_p->orighost);
+ if(!EmptyString(target_p->user->suser))
+ sendto_one(client_p, ":%s ENCAP * LOGIN %s",
+ target_p->name, target_p->user->suser);
+
+ if(ConfigFileEntry.burst_away && !EmptyString(target_p->user->away))
+ sendto_one(client_p, ":%s AWAY :%s",
+ target_p->name, target_p->user->away);
+
+ hclientinfo.target = target_p;
+ call_hook(h_burst_client, &hclientinfo);
+ }
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+
+ if(*chptr->chname != '#')
+ continue;
+
+ cur_len = mlen = ircsprintf(buf, ":%s SJOIN %ld %s %s :", me.name,
+ (long) chptr->channelts, chptr->chname,
+ channel_modes(chptr, client_p));
+
+ t = buf + mlen;
+
+ DLINK_FOREACH(uptr, chptr->members.head)
+ {
+ msptr = uptr->data;
+
+ tlen = strlen(msptr->client_p->name) + 1;
+ if(is_chanop(msptr))
+ tlen++;
+ if(is_voiced(msptr))
+ tlen++;
+
+ if(cur_len + tlen >= BUFSIZE - 3)
+ {
+ t--;
+ *t = '\0';
+ sendto_one(client_p, "%s", buf);
+ cur_len = mlen;
+ t = buf + mlen;
+ }
+
+ ircsprintf(t, "%s%s ", find_channel_status(msptr, 1),
+ msptr->client_p->name);
+
+ cur_len += tlen;
+ t += tlen;
+ }
+
+ if (dlink_list_length(&chptr->members) > 0)
+ {
+ /* remove trailing space */
+ t--;
+ *t = '\0';
+ }
+ sendto_one(client_p, "%s", buf);
+
+ burst_modes_TS5(client_p, chptr->chname, &chptr->banlist, 'b');
+
+ if(IsCapable(client_p, CAP_EX))
+ burst_modes_TS5(client_p, chptr->chname, &chptr->exceptlist, 'e');
+
+ if(IsCapable(client_p, CAP_IE))
+ burst_modes_TS5(client_p, chptr->chname, &chptr->invexlist, 'I');
+
+ burst_modes_TS5(client_p, chptr->chname, &chptr->quietlist, 'q');
+
+ if(IsCapable(client_p, CAP_TB) && chptr->topic != NULL)
+ sendto_one(client_p, ":%s TB %s %ld %s%s:%s",
+ me.name, chptr->chname, (long) chptr->topic_time,
+ ConfigChannel.burst_topicwho ? chptr->topic_info : "",
+ ConfigChannel.burst_topicwho ? " " : "",
+ chptr->topic);
+
+ hchaninfo.chptr = chptr;
+ call_hook(h_burst_channel, &hchaninfo);
+ }
+
+ hclientinfo.target = NULL;
+ call_hook(h_burst_finished, &hclientinfo);
+}
+
+/*
+ * burst_TS6
+ *
+ * inputs - client (server) to send nick towards
+ * - client to send nick for
+ * output - NONE
+ * side effects - NICK message is sent towards given client_p
+ */
+static void
+burst_TS6(struct Client *client_p)
+{
+ static char ubuf[12];
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+ hook_data_client hclientinfo;
+ hook_data_channel hchaninfo;
+ dlink_node *ptr;
+ dlink_node *uptr;
+ char *t;
+ int tlen, mlen;
+ int cur_len = 0;
+
+ hclientinfo.client = hchaninfo.client = client_p;
+
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+
+ if(!IsPerson(target_p))
+ continue;
+
+ send_umode(NULL, target_p, 0, 0, ubuf);
+ if(!*ubuf)
+ {
+ ubuf[0] = '+';
+ ubuf[1] = '\0';
+ }
+
+ if(has_id(target_p) && IsCapable(client_p, CAP_EUID))
+ sendto_one(client_p, ":%s EUID %s %d %ld %s %s %s %s %s %s %s :%s",
+ target_p->servptr->id, target_p->name,
+ target_p->hopcount + 1,
+ (long) target_p->tsinfo, ubuf,
+ target_p->username, target_p->host,
+ IsIPSpoof(target_p) ? "0" : target_p->sockhost,
+ target_p->id,
+ IsDynSpoof(target_p) ? target_p->orighost : "*",
+ EmptyString(target_p->user->suser) ? "*" : target_p->user->suser,
+ target_p->info);
+ else if(has_id(target_p))
+ sendto_one(client_p, ":%s UID %s %d %ld %s %s %s %s %s :%s",
+ target_p->servptr->id, target_p->name,
+ target_p->hopcount + 1,
+ (long) target_p->tsinfo, ubuf,
+ target_p->username, target_p->host,
+ IsIPSpoof(target_p) ? "0" : target_p->sockhost,
+ target_p->id, target_p->info);
+ else
+ sendto_one(client_p, "NICK %s %d %ld %s %s %s %s :%s",
+ target_p->name,
+ target_p->hopcount + 1,
+ (long) target_p->tsinfo,
+ ubuf,
+ target_p->username, target_p->host,
+ target_p->user->server, target_p->info);
+
+ if(!has_id(target_p) || !IsCapable(client_p, CAP_EUID))
+ {
+ if(IsDynSpoof(target_p))
+ sendto_one(client_p, ":%s ENCAP * REALHOST %s",
+ use_id(target_p), target_p->orighost);
+ if(!EmptyString(target_p->user->suser))
+ sendto_one(client_p, ":%s ENCAP * LOGIN %s",
+ use_id(target_p), target_p->user->suser);
+ }
+
+ if(ConfigFileEntry.burst_away && !EmptyString(target_p->user->away))
+ sendto_one(client_p, ":%s AWAY :%s",
+ use_id(target_p),
+ target_p->user->away);
+
+ hclientinfo.target = target_p;
+ call_hook(h_burst_client, &hclientinfo);
+ }
+
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+
+ if(*chptr->chname != '#')
+ continue;
+
+ cur_len = mlen = ircsprintf(buf, ":%s SJOIN %ld %s %s :", me.id,
+ (long) chptr->channelts, chptr->chname,
+ channel_modes(chptr, client_p));
+
+ t = buf + mlen;
+
+ DLINK_FOREACH(uptr, chptr->members.head)
+ {
+ msptr = uptr->data;
+
+ tlen = strlen(use_id(msptr->client_p)) + 1;
+ if(is_chanop(msptr))
+ tlen++;
+ if(is_voiced(msptr))
+ tlen++;
+
+ if(cur_len + tlen >= BUFSIZE - 3)
+ {
+ *(t-1) = '\0';
+ sendto_one(client_p, "%s", buf);
+ cur_len = mlen;
+ t = buf + mlen;
+ }
+
+ ircsprintf(t, "%s%s ", find_channel_status(msptr, 1),
+ use_id(msptr->client_p));
+
+ cur_len += tlen;
+ t += tlen;
+ }
+
+ if (dlink_list_length(&chptr->members) > 0)
+ {
+ /* remove trailing space */
+ *(t-1) = '\0';
+ }
+ sendto_one(client_p, "%s", buf);
+
+ if(dlink_list_length(&chptr->banlist) > 0)
+ burst_modes_TS6(client_p, chptr, &chptr->banlist, 'b');
+
+ if(IsCapable(client_p, CAP_EX) &&
+ dlink_list_length(&chptr->exceptlist) > 0)
+ burst_modes_TS6(client_p, chptr, &chptr->exceptlist, 'e');
+
+ if(IsCapable(client_p, CAP_IE) &&
+ dlink_list_length(&chptr->invexlist) > 0)
+ burst_modes_TS6(client_p, chptr, &chptr->invexlist, 'I');
+
+ if(dlink_list_length(&chptr->quietlist) > 0)
+ burst_modes_TS6(client_p, chptr, &chptr->quietlist, 'q');
+
+ if(IsCapable(client_p, CAP_TB) && chptr->topic != NULL)
+ sendto_one(client_p, ":%s TB %s %ld %s%s:%s",
+ me.id, chptr->chname, (long) chptr->topic_time,
+ ConfigChannel.burst_topicwho ? chptr->topic_info : "",
+ ConfigChannel.burst_topicwho ? " " : "",
+ chptr->topic);
+
+ hchaninfo.chptr = chptr;
+ call_hook(h_burst_channel, &hchaninfo);
+ }
+
+ hclientinfo.target = NULL;
+ call_hook(h_burst_finished, &hclientinfo);
+}
+
+/*
+ * show_capabilities - show current server capabilities
+ *
+ * inputs - pointer to an struct Client
+ * output - pointer to static string
+ * side effects - build up string representing capabilities of server listed
+ */
+const char *
+show_capabilities(struct Client *target_p)
+{
+ static char msgbuf[BUFSIZE];
+ struct Capability *cap;
+ char *t;
+ int tl;
+
+ t = msgbuf;
+ tl = ircsprintf(msgbuf, "TS ");
+ t += tl;
+
+ if(!IsServer(target_p) || !target_p->serv->caps) /* short circuit if no caps */
+ {
+ msgbuf[2] = '\0';
+ return msgbuf;
+ }
+
+ for (cap = captab; cap->cap; ++cap)
+ {
+ if(cap->cap & target_p->serv->caps)
+ {
+ tl = ircsprintf(t, "%s ", cap->name);
+ t += tl;
+ }
+ }
+
+ t--;
+ *t = '\0';
+
+ return msgbuf;
+}
+
+/*
+ * server_estab
+ *
+ * inputs - pointer to a struct Client
+ * output -
+ * side effects -
+ */
+int
+server_estab(struct Client *client_p)
+{
+ struct Client *target_p;
+ struct server_conf *server_p;
+ hook_data_client hdata;
+ char *host;
+ dlink_node *ptr;
+
+ s_assert(NULL != client_p);
+ if(client_p == NULL)
+ return -1;
+ ClearAccess(client_p);
+
+ host = client_p->name;
+
+ if((server_p = client_p->localClient->att_sconf) == NULL)
+ {
+ /* This shouldn't happen, better tell the ops... -A1kmm */
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
+ "Warning: Lost connect{} block for server %s!", host);
+ return exit_client(client_p, client_p, client_p, "Lost connect{} block!");
+ }
+
+ /* We shouldn't have to check this, it should already done before
+ * server_estab is called. -A1kmm
+ */
+ if(client_p->localClient->passwd)
+ {
+ memset(client_p->localClient->passwd, 0, strlen(client_p->localClient->passwd));
+ MyFree(client_p->localClient->passwd);
+ client_p->localClient->passwd = NULL;
+ }
+
+ /* Its got identd , since its a server */
+ SetGotId(client_p);
+
+ /* If there is something in the serv_list, it might be this
+ * connecting server..
+ */
+ if(!ServerInfo.hub && serv_list.head)
+ {
+ if(client_p != serv_list.head->data || serv_list.head->next)
+ {
+ ServerStats->is_ref++;
+ sendto_one(client_p, "ERROR :I'm a leaf not a hub");
+ return exit_client(client_p, client_p, client_p, "I'm a leaf");
+ }
+ }
+
+ if(IsUnknown(client_p))
+ {
+ /*
+ * jdc -- 1. Use EmptyString(), not [0] index reference.
+ * 2. Check ->spasswd, not ->passwd.
+ */
+ if(!EmptyString(server_p->spasswd))
+ {
+ /* kludge, if we're not using TS6, dont ever send
+ * ourselves as being TS6 capable.
+ */
+ if(ServerInfo.use_ts6)
+ sendto_one(client_p, "PASS %s TS %d :%s",
+ server_p->spasswd, TS_CURRENT, me.id);
+ else
+ sendto_one(client_p, "PASS %s :TS",
+ server_p->spasswd);
+ }
+
+ /* pass info to new server */
+ send_capabilities(client_p, default_server_capabs
+ | (ServerConfCompressed(server_p) ? CAP_ZIP_SUPPORTED : 0)
+ | (ServerConfTb(server_p) ? CAP_TB : 0));
+
+ sendto_one(client_p, "SERVER %s 1 :%s%s",
+ me.name,
+ ConfigServerHide.hidden ? "(H) " : "",
+ (me.info[0]) ? (me.info) : "IRCers United");
+ }
+
+ if(!comm_set_buffers(client_p->localClient->fd, READBUF_SIZE))
+ report_error(SETBUF_ERROR_MSG,
+ get_server_name(client_p, SHOW_IP),
+ log_client_name(client_p, SHOW_IP), errno);
+
+ /* Hand the server off to servlink now */
+ if(IsCapable(client_p, CAP_ZIP))
+ {
+ if(fork_server(client_p) < 0)
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
+ "Warning: fork failed for server %s -- check servlink_path (%s)",
+ get_server_name(client_p, HIDE_IP),
+ ConfigFileEntry.servlink_path);
+ return exit_client(client_p, client_p, client_p, "Fork failed");
+ }
+ start_io(client_p);
+ SetServlink(client_p);
+ }
+
+ sendto_one(client_p, "SVINFO %d %d 0 :%ld", TS_CURRENT, TS_MIN, CurrentTime);
+
+ client_p->servptr = &me;
+
+ if(IsAnyDead(client_p))
+ return CLIENT_EXITED;
+
+ SetServer(client_p);
+
+ /* Update the capability combination usage counts */
+ set_chcap_usage_counts(client_p);
+
+ dlinkAdd(client_p, &client_p->lnode, &me.serv->servers);
+ dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &serv_list);
+ dlinkAddTailAlloc(client_p, &global_serv_list);
+
+ if(has_id(client_p))
+ add_to_id_hash(client_p->id, client_p);
+
+ add_to_client_hash(client_p->name, client_p);
+ /* doesnt duplicate client_p->serv if allocated this struct already */
+ make_server(client_p);
+ client_p->serv->up = me.name;
+ client_p->serv->upid = me.id;
+
+ client_p->serv->caps = client_p->localClient->caps;
+
+ if(client_p->localClient->fullcaps)
+ {
+ DupString(client_p->serv->fullcaps, client_p->localClient->fullcaps);
+ MyFree(client_p->localClient->fullcaps);
+ client_p->localClient->fullcaps = NULL;
+ }
+
+ /* add it to scache */
+ find_or_add(client_p->name);
+ client_p->localClient->firsttime = CurrentTime;
+ /* fixing eob timings.. -gnp */
+
+ /* Show the real host/IP to admins */
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Link with %s established: (%s) link",
+ get_server_name(client_p, SHOW_IP),
+ show_capabilities(client_p));
+
+ ilog(L_SERVER, "Link with %s established: (%s) link",
+ log_client_name(client_p, SHOW_IP), show_capabilities(client_p));
+
+ hdata.client = &me;
+ hdata.target = client_p;
+ call_hook(h_server_introduced, &hdata);
+
+ if(HasServlink(client_p))
+ {
+ /* we won't overflow FD_DESC_SZ here, as it can hold
+ * client_p->name + 64
+ */
+ comm_note(client_p->localClient->fd, "slink data: %s", client_p->name);
+ comm_note(client_p->localClient->ctrlfd, "slink ctrl: %s", client_p->name);
+ }
+ else
+ comm_note(client_p->localClient->fd, "Server: %s", client_p->name);
+
+ /*
+ ** Old sendto_serv_but_one() call removed because we now
+ ** need to send different names to different servers
+ ** (domain name matching) Send new server to other servers.
+ */
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(target_p == client_p)
+ continue;
+
+ if(has_id(target_p) && has_id(client_p))
+ {
+ sendto_one(target_p, ":%s SID %s 2 %s :%s%s",
+ me.id, client_p->name, client_p->id,
+ IsHidden(client_p) ? "(H) " : "", client_p->info);
+
+ if(IsCapable(target_p, CAP_ENCAP) &&
+ !EmptyString(client_p->serv->fullcaps))
+ sendto_one(target_p, ":%s ENCAP * GCAP :%s",
+ client_p->id, client_p->serv->fullcaps);
+ }
+ else
+ {
+ sendto_one(target_p, ":%s SERVER %s 2 :%s%s",
+ me.name, client_p->name,
+ IsHidden(client_p) ? "(H) " : "", client_p->info);
+
+ if(IsCapable(target_p, CAP_ENCAP) &&
+ !EmptyString(client_p->serv->fullcaps))
+ sendto_one(target_p, ":%s ENCAP * GCAP :%s",
+ client_p->name, client_p->serv->fullcaps);
+ }
+ }
+
+ /*
+ ** Pass on my client information to the new server
+ **
+ ** First, pass only servers (idea is that if the link gets
+ ** cancelled beacause the server was already there,
+ ** there are no NICK's to be cancelled...). Of course,
+ ** if cancellation occurs, all this info is sent anyway,
+ ** and I guess the link dies when a read is attempted...? --msa
+ **
+ ** Note: Link cancellation to occur at this point means
+ ** that at least two servers from my fragment are building
+ ** up connection this other fragment at the same time, it's
+ ** a race condition, not the normal way of operation...
+ **
+ ** ALSO NOTE: using the get_client_name for server names--
+ ** see previous *WARNING*!!! (Also, original inpath
+ ** is destroyed...)
+ */
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ /* target_p->from == target_p for target_p == client_p */
+ if(IsMe(target_p) || target_p->from == client_p)
+ continue;
+
+ /* presumption, if target has an id, so does its uplink */
+ if(has_id(client_p) && has_id(target_p))
+ sendto_one(client_p, ":%s SID %s %d %s :%s%s",
+ target_p->serv->upid, target_p->name,
+ target_p->hopcount + 1, target_p->id,
+ IsHidden(target_p) ? "(H) " : "", target_p->info);
+ else
+ sendto_one(client_p, ":%s SERVER %s %d :%s%s",
+ target_p->serv->up,
+ target_p->name, target_p->hopcount + 1,
+ IsHidden(target_p) ? "(H) " : "", target_p->info);
+
+ if(IsCapable(client_p, CAP_ENCAP) &&
+ !EmptyString(target_p->serv->fullcaps))
+ sendto_one(client_p, ":%s ENCAP * GCAP :%s",
+ get_id(target_p, client_p),
+ target_p->serv->fullcaps);
+ }
+
+ if(has_id(client_p))
+ burst_TS6(client_p);
+ else
+ burst_TS5(client_p);
+
+ /* Always send a PING after connect burst is done */
+ sendto_one(client_p, "PING :%s", get_id(&me, client_p));
+
+ free_pre_client(client_p);
+
+ return 0;
+}
+
+static void
+start_io(struct Client *server)
+{
+ unsigned char *iobuf;
+ int c = 0;
+ int linecount = 0;
+ int linelen;
+
+ iobuf = MyMalloc(256); /* XXX: This seems arbitrary. Perhaps make it IRCD_BUFSIZE? --nenolod */
+
+ if(IsCapable(server, CAP_ZIP))
+ {
+ /* ziplink */
+ iobuf[c++] = SLINKCMD_SET_ZIP_OUT_LEVEL;
+ iobuf[c++] = 0; /* | */
+ iobuf[c++] = 1; /* \ len is 1 */
+ iobuf[c++] = ConfigFileEntry.compression_level;
+ iobuf[c++] = SLINKCMD_START_ZIP_IN;
+ iobuf[c++] = SLINKCMD_START_ZIP_OUT;
+ }
+
+ while (MyConnect(server))
+ {
+ linecount++;
+
+ iobuf = MyRealloc(iobuf, (c + READBUF_SIZE + 64));
+
+ /* store data in c+3 to allow for SLINKCMD_INJECT_RECVQ and len u16 */
+ linelen = linebuf_get(&server->localClient->buf_recvq, (char *) (iobuf + c + 3), READBUF_SIZE, LINEBUF_PARTIAL, LINEBUF_RAW); /* include partial lines */
+
+ if(linelen)
+ {
+ iobuf[c++] = SLINKCMD_INJECT_RECVQ;
+ iobuf[c++] = (linelen >> 8);
+ iobuf[c++] = (linelen & 0xff);
+ c += linelen;
+ }
+ else
+ break;
+ }
+
+ while (MyConnect(server))
+ {
+ linecount++;
+
+ iobuf = MyRealloc(iobuf, (c + BUF_DATA_SIZE + 64));
+
+ /* store data in c+3 to allow for SLINKCMD_INJECT_RECVQ and len u16 */
+ linelen = linebuf_get(&server->localClient->buf_sendq,
+ (char *) (iobuf + c + 3), READBUF_SIZE,
+ LINEBUF_PARTIAL, LINEBUF_PARSED); /* include partial lines */
+
+ if(linelen)
+ {
+ iobuf[c++] = SLINKCMD_INJECT_SENDQ;
+ iobuf[c++] = (linelen >> 8);
+ iobuf[c++] = (linelen & 0xff);
+ c += linelen;
+ }
+ else
+ break;
+ }
+
+ /* start io */
+ iobuf[c++] = SLINKCMD_INIT;
+
+ server->localClient->slinkq = iobuf;
+ server->localClient->slinkq_ofs = 0;
+ server->localClient->slinkq_len = c;
+
+ /* schedule a write */
+ send_queued_slink_write(server->localClient->ctrlfd, server);
+}
+
+/*
+ * fork_server
+ *
+ * inputs - struct Client *server
+ * output - success: 0 / failure: -1
+ * side effect - fork, and exec SERVLINK to handle this connection
+ */
+static int
+fork_server(struct Client *server)
+{
+ int ret;
+ int i;
+ int ctrl_fds[2];
+ int data_fds[2];
+
+ char fd_str[4][6];
+ char *kid_argv[7];
+ char slink[] = "-slink";
+
+
+ /* ctrl */
+#ifdef HAVE_SOCKETPAIR
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, ctrl_fds) < 0)
+#else
+ if(inet_socketpair(AF_INET,SOCK_STREAM, 0, ctrl_fds) < 0)
+#endif
+ goto fork_error;
+
+
+
+ /* data */
+#ifdef HAVE_SOCKETPAIR
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, data_fds) < 0)
+#else
+ if(inet_socketpair(AF_INET,SOCK_STREAM, 0, data_fds) < 0)
+#endif
+ goto fork_error;
+
+
+#ifdef __CYGWIN__
+ if((ret = vfork()) < 0)
+#else
+ if((ret = fork()) < 0)
+#endif
+ goto fork_error;
+ else if(ret == 0)
+ {
+ /* set our fds as non blocking and close everything else */
+ for (i = 0; i < HARD_FDLIMIT; i++)
+ {
+
+
+ if((i == ctrl_fds[1]) || (i == data_fds[1]) || (i == server->localClient->fd))
+ {
+ comm_set_nb(i);
+ }
+ else
+ {
+#ifdef __CYGWIN__
+ if(i > 2) /* don't close std* */
+#endif
+ close(i);
+ }
+ }
+
+ ircsnprintf(fd_str[0], sizeof(fd_str[0]), "%d", ctrl_fds[1]);
+ ircsnprintf(fd_str[1], sizeof(fd_str[1]), "%d", data_fds[1]);
+ ircsnprintf(fd_str[2], sizeof(fd_str[2]), "%d", server->localClient->fd);
+ kid_argv[0] = slink;
+ kid_argv[1] = fd_str[0];
+ kid_argv[2] = fd_str[1];
+ kid_argv[3] = fd_str[2];
+ kid_argv[4] = NULL;
+
+ /* exec servlink program */
+ execv(ConfigFileEntry.servlink_path, kid_argv);
+
+ /* We're still here, abort. */
+ _exit(1);
+ }
+ else
+ {
+ comm_close(server->localClient->fd);
+
+ /* close the childs end of the pipes */
+ close(ctrl_fds[1]);
+ close(data_fds[1]);
+
+ s_assert(server->localClient);
+ server->localClient->ctrlfd = ctrl_fds[0];
+ server->localClient->fd = data_fds[0];
+
+ if(!comm_set_nb(server->localClient->fd))
+ {
+ report_error(NONB_ERROR_MSG,
+ get_server_name(server, SHOW_IP),
+ log_client_name(server, SHOW_IP),
+ errno);
+ }
+
+ if(!comm_set_nb(server->localClient->ctrlfd))
+ {
+ report_error(NONB_ERROR_MSG,
+ get_server_name(server, SHOW_IP),
+ log_client_name(server, SHOW_IP),
+ errno);
+ }
+
+ comm_open(server->localClient->ctrlfd, FD_SOCKET, NULL);
+ comm_open(server->localClient->fd, FD_SOCKET, NULL);
+
+ read_ctrl_packet(server->localClient->ctrlfd, server);
+ read_packet(server->localClient->fd, server);
+ }
+
+ return 0;
+
+ fork_error:
+ /* this is ugly, but nicer than repeating
+ * about 50 close() statements everywhre... */
+ close(data_fds[0]);
+ close(data_fds[1]);
+ close(ctrl_fds[0]);
+ close(ctrl_fds[1]);
+ return -1;
+}
+
+/*
+ * New server connection code
+ * Based upon the stuff floating about in s_bsd.c
+ * -- adrian
+ */
+
+/*
+ * serv_connect() - initiate a server connection
+ *
+ * inputs - pointer to conf
+ * - pointer to client doing the connet
+ * output -
+ * side effects -
+ *
+ * This code initiates a connection to a server. It first checks to make
+ * sure the given server exists. If this is the case, it creates a socket,
+ * creates a client, saves the socket information in the client, and
+ * initiates a connection to the server through comm_connect_tcp(). The
+ * completion of this goes through serv_completed_connection().
+ *
+ * We return 1 if the connection is attempted, since we don't know whether
+ * it suceeded or not, and 0 if it fails in here somewhere.
+ */
+int
+serv_connect(struct server_conf *server_p, struct Client *by)
+{
+ struct Client *client_p;
+ struct irc_sockaddr_storage myipnum;
+ int fd;
+
+ s_assert(server_p != NULL);
+ if(server_p == NULL)
+ return 0;
+
+ /*
+ * Make sure this server isn't already connected
+ */
+ if((client_p = find_server(NULL, server_p->name)))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Server %s already present from %s",
+ server_p->name, get_server_name(client_p, SHOW_IP));
+ if(by && IsPerson(by) && !MyClient(by))
+ sendto_one_notice(by, ":Server %s already present from %s",
+ server_p->name, get_server_name(client_p, SHOW_IP));
+ return 0;
+ }
+
+ /* create a socket for the server connection */
+ if((fd = comm_socket(server_p->aftype, SOCK_STREAM, 0, NULL)) < 0)
+ {
+ /* Eek, failure to create the socket */
+ report_error("opening stream socket to %s: %s",
+ server_p->name, server_p->name, errno);
+ return 0;
+ }
+
+ /* servernames are always guaranteed under HOSTLEN chars */
+ comm_note(fd, "Server: %s", server_p->name);
+
+ /* Create a local client */
+ client_p = make_client(NULL);
+
+ /* Copy in the server, hostname, fd
+ * The sockhost may be a hostname, this will be corrected later
+ * -- jilles
+ */
+ strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
+ strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
+ strlcpy(client_p->sockhost, server_p->host, sizeof(client_p->sockhost));
+ client_p->localClient->fd = fd;
+
+ /*
+ * Set up the initial server evilness, ripped straight from
+ * connect_server(), so don't blame me for it being evil.
+ * -- adrian
+ */
+
+ if(!comm_set_buffers(client_p->localClient->fd, READBUF_SIZE))
+ {
+ report_error(SETBUF_ERROR_MSG,
+ get_server_name(client_p, SHOW_IP),
+ log_client_name(client_p, SHOW_IP),
+ errno);
+ }
+
+ /*
+ * Attach config entries to client here rather than in
+ * serv_connect_callback(). This to avoid null pointer references.
+ */
+ attach_server_conf(client_p, server_p);
+
+ /*
+ * at this point we have a connection in progress and C/N lines
+ * attached to the client, the socket info should be saved in the
+ * client and it should either be resolved or have a valid address.
+ *
+ * The socket has been connected or connect is in progress.
+ */
+ make_server(client_p);
+ if(by && IsPerson(by))
+ {
+ strcpy(client_p->serv->by, by->name);
+ if(client_p->serv->user)
+ free_user(client_p->serv->user, NULL);
+ client_p->serv->user = by->user;
+ by->user->refcnt++;
+ }
+ else
+ {
+ strcpy(client_p->serv->by, "AutoConn.");
+ if(client_p->serv->user)
+ free_user(client_p->serv->user, NULL);
+ client_p->serv->user = NULL;
+ }
+ client_p->serv->up = me.name;
+ client_p->serv->upid = me.id;
+ SetConnecting(client_p);
+ dlinkAddTail(client_p, &client_p->node, &global_client_list);
+
+ /* log */
+ ilog(L_SERVER, "Connecting to %s[%s] port %d (%s)", server_p->name, server_p->host, server_p->port,
+#ifdef IPV6
+ server_p->aftype == AF_INET6 ? "IPv6" :
+#endif
+ (server_p->aftype == AF_INET ? "IPv4" : "?"));
+
+ if(ServerConfVhosted(server_p))
+ {
+ memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
+ ((struct sockaddr_in *)&myipnum)->sin_port = 0;
+ myipnum.ss_family = server_p->aftype;
+
+ }
+ else if(server_p->aftype == AF_INET && ServerInfo.specific_ipv4_vhost)
+ {
+ memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum));
+ ((struct sockaddr_in *)&myipnum)->sin_port = 0;
+ myipnum.ss_family = AF_INET;
+ SET_SS_LEN(myipnum, sizeof(struct sockaddr_in));
+ }
+
+#ifdef IPV6
+ else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost)
+ {
+ memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
+ ((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
+ myipnum.ss_family = AF_INET6;
+ SET_SS_LEN(myipnum, sizeof(struct sockaddr_in6));
+ }
+#endif
+ else
+ {
+ comm_connect_tcp(client_p->localClient->fd, server_p->host,
+ server_p->port, NULL, 0, serv_connect_callback,
+ client_p, server_p->aftype,
+ ConfigFileEntry.connect_timeout);
+ return 1;
+ }
+
+ comm_connect_tcp(client_p->localClient->fd, server_p->host,
+ server_p->port, (struct sockaddr *) &myipnum,
+ GET_SS_LEN(myipnum), serv_connect_callback, client_p,
+ myipnum.ss_family, ConfigFileEntry.connect_timeout);
+
+ return 1;
+}
+
+/*
+ * serv_connect_callback() - complete a server connection.
+ *
+ * This routine is called after the server connection attempt has
+ * completed. If unsucessful, an error is sent to ops and the client
+ * is closed. If sucessful, it goes through the initialisation/check
+ * procedures, the capabilities are sent, and the socket is then
+ * marked for reading.
+ */
+static void
+serv_connect_callback(int fd, int status, void *data)
+{
+ struct Client *client_p = data;
+ struct server_conf *server_p;
+ char *errstr;
+
+ /* First, make sure its a real client! */
+ s_assert(client_p != NULL);
+ s_assert(client_p->localClient->fd == fd);
+
+ if(client_p == NULL)
+ return;
+
+ /* while we were waiting for the callback, its possible this already
+ * linked in.. --fl
+ */
+ if(find_server(NULL, client_p->name) != NULL)
+ {
+ exit_client(client_p, client_p, &me, "Server Exists");
+ return;
+ }
+
+ /* Next, for backward purposes, record the ip of the server */
+ memcpy(&client_p->localClient->ip, &fd_table[fd].connect.hostaddr, sizeof client_p->localClient->ip);
+ /* Set sockhost properly now -- jilles */
+ inetntop_sock((struct sockaddr *)&fd_table[fd].connect.hostaddr,
+ client_p->sockhost, sizeof client_p->sockhost);
+
+ /* Check the status */
+ if(status != COMM_OK)
+ {
+ /* COMM_ERR_TIMEOUT wont have an errno associated with it,
+ * the others will.. --fl
+ */
+ if(status == COMM_ERR_TIMEOUT)
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
+ "Error connecting to %s[%s]: %s",
+ client_p->name,
+#ifdef HIDE_SERVERS_IPS
+ "255.255.255.255",
+#else
+ client_p->host,
+#endif
+ comm_errstr(status));
+ ilog(L_SERVER, "Error connecting to %s[%s]: %s",
+ client_p->name, client_p->sockhost,
+ comm_errstr(status));
+ }
+ else
+ {
+ errstr = strerror(comm_get_sockerr(fd));
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
+ "Error connecting to %s[%s]: %s (%s)",
+ client_p->name,
+#ifdef HIDE_SERVERS_IPS
+ "255.255.255.255",
+#else
+ client_p->host,
+#endif
+ comm_errstr(status), errstr);
+ ilog(L_SERVER, "Error connecting to %s[%s]: %s (%s)",
+ client_p->name, client_p->sockhost,
+ comm_errstr(status), errstr);
+ }
+
+ exit_client(client_p, client_p, &me, comm_errstr(status));
+ return;
+ }
+
+ /* COMM_OK, so continue the connection procedure */
+ /* Get the C/N lines */
+ if((server_p = client_p->localClient->att_sconf) == NULL)
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Lost connect{} block for %s",
+ get_server_name(client_p, HIDE_IP));
+ exit_client(client_p, client_p, &me, "Lost connect{} block");
+ return;
+ }
+
+ /* Next, send the initial handshake */
+ SetHandshake(client_p);
+
+ /* kludge, if we're not using TS6, dont ever send
+ * ourselves as being TS6 capable.
+ */
+ if(!EmptyString(server_p->spasswd))
+ {
+ if(ServerInfo.use_ts6)
+ sendto_one(client_p, "PASS %s TS %d :%s",
+ server_p->spasswd, TS_CURRENT, me.id);
+ else
+ sendto_one(client_p, "PASS %s :TS",
+ server_p->spasswd);
+ }
+
+ /* pass my info to the new server */
+ send_capabilities(client_p, default_server_capabs
+ | (ServerConfCompressed(server_p) ? CAP_ZIP_SUPPORTED : 0)
+ | (ServerConfTb(server_p) ? CAP_TB : 0));
+
+ sendto_one(client_p, "SERVER %s 1 :%s%s",
+ me.name,
+ ConfigServerHide.hidden ? "(H) " : "", me.info);
+
+ /*
+ * If we've been marked dead because a send failed, just exit
+ * here now and save everyone the trouble of us ever existing.
+ */
+ if(IsAnyDead(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
+ "%s went dead during handshake", client_p->name);
+ exit_client(client_p, client_p, &me, "Went dead during handshake");
+ return;
+ }
+
+ /* don't move to serv_list yet -- we haven't sent a burst! */
+
+ /* If we get here, we're ok, so lets start reading some data */
+ read_packet(fd, client_p);
+}
+
+#ifndef HAVE_SOCKETPAIR
+static int
+inet_socketpair(int d, int type, int protocol, int sv[2])
+{
+ struct sockaddr_in addr1, addr2, addr3;
+ int addr3_len = sizeof(addr3);
+ int fd, rc;
+ int port_no = 20000;
+
+ if(d != AF_INET || type != SOCK_STREAM || protocol)
+ {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ if(((sv[0] = socket(AF_INET, SOCK_STREAM, 0)) < 0) || ((sv[1] = socket(AF_INET, SOCK_STREAM, 0)) < 0))
+ return -1;
+
+ addr1.sin_port = htons(port_no);
+ addr1.sin_family = AF_INET;
+ addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ while ((rc = bind (sv[0], (struct sockaddr *) &addr1, sizeof (addr1))) < 0 && errno == EADDRINUSE)
+ addr1.sin_port = htons(++port_no);
+
+ if(rc < 0)
+ return -1;
+
+ if(listen(sv[0], 1) < 0)
+ {
+ close(sv[0]);
+ close(sv[1]);
+ return -1;
+ }
+
+ addr2.sin_port = htons(port_no);
+ addr2.sin_family = AF_INET;
+ addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ if(connect (sv[1], (struct sockaddr *) &addr2, sizeof (addr2)) < 0)
+ {
+ close(sv[0]);
+ close(sv[1]);
+ return -1;
+ }
+
+ if((fd = accept(sv[1], (struct sockaddr *) &addr3, &addr3_len)) < 0)
+ {
+ close(sv[0]);
+ close(sv[1]);
+ return -1;
+ }
+ close(sv[0]);
+ sv[0] = fd;
+
+ return(0);
+
+}
+#endif
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_stats.c: Statistics related functions
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_stats.c 1409 2006-05-21 14:46:17Z jilles $
+ */
+
+#include "stdinc.h"
+#include "s_stats.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "send.h"
+#include "memory.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "whowas.h"
+#include "hash.h"
+#include "scache.h"
+#include "reject.h"
+
+/*
+ * stats stuff
+ */
+static struct ServerStatistics ircst;
+struct ServerStatistics *ServerStats = &ircst;
+
+void
+init_stats()
+{
+ memset(&ircst, 0, sizeof(ircst));
+}
+
+/*
+ * tstats
+ *
+ * inputs - client to report to
+ * output - NONE
+ * side effects -
+ */
+void
+tstats(struct Client *source_p)
+{
+ struct Client *target_p;
+ struct ServerStatistics *sp;
+ struct ServerStatistics tmp;
+ dlink_node *ptr;
+
+ sp = &tmp;
+ memcpy(sp, ServerStats, sizeof(struct ServerStatistics));
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ sp->is_sbs += target_p->localClient->sendB;
+ sp->is_sbr += target_p->localClient->receiveB;
+ sp->is_sks += target_p->localClient->sendK;
+ sp->is_skr += target_p->localClient->receiveK;
+ sp->is_sti += CurrentTime - target_p->localClient->firsttime;
+ sp->is_sv++;
+ if(sp->is_sbs > 1023)
+ {
+ sp->is_sks += (sp->is_sbs >> 10);
+ sp->is_sbs &= 0x3ff;
+ }
+ if(sp->is_sbr > 1023)
+ {
+ sp->is_skr += (sp->is_sbr >> 10);
+ sp->is_sbr &= 0x3ff;
+ }
+ }
+
+ DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ sp->is_cbs += target_p->localClient->sendB;
+ sp->is_cbr += target_p->localClient->receiveB;
+ sp->is_cks += target_p->localClient->sendK;
+ sp->is_ckr += target_p->localClient->receiveK;
+ sp->is_cti += CurrentTime - target_p->localClient->firsttime;
+ sp->is_cl++;
+ if(sp->is_cbs > 1023)
+ {
+ sp->is_cks += (sp->is_cbs >> 10);
+ sp->is_cbs &= 0x3ff;
+ }
+ if(sp->is_cbr > 1023)
+ {
+ sp->is_ckr += (sp->is_cbr >> 10);
+ sp->is_cbr &= 0x3ff;
+ }
+
+ }
+
+ DLINK_FOREACH(ptr, unknown_list.head)
+ {
+ sp->is_ni++;
+ }
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :accepts %u refused %u", sp->is_ac, sp->is_ref);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :rejected %u delaying %lu",
+ sp->is_rej, dlink_list_length(&delay_exit));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :nicks being delayed %lu",
+ get_nd_count());
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :unknown commands %u prefixes %u",
+ sp->is_unco, sp->is_unpf);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :nick collisions %u saves %u unknown closes %u",
+ sp->is_kill, sp->is_save, sp->is_ni);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :wrong direction %u empty %u",
+ sp->is_wrdi, sp->is_empt);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :numerics seen %u", sp->is_num);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :auth successes %u fails %u",
+ sp->is_asuc, sp->is_abad);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :sasl successes %u fails %u",
+ sp->is_ssuc, sp->is_sbad);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :Client Server");
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :connected %u %u", sp->is_cl, sp->is_sv);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :bytes sent %d.%uK %d.%uK",
+ (int) sp->is_cks, sp->is_cbs,
+ (int) sp->is_sks, sp->is_sbs);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :bytes recv %d.%uK %d.%uK",
+ (int) sp->is_ckr, sp->is_cbr,
+ (int) sp->is_skr, sp->is_sbr);
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "T :time connected %d %d",
+ (int) sp->is_cti, (int) sp->is_sti);
+}
+
+void
+count_memory(struct Client *source_p)
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct Ban *actualBan;
+ dlink_node *dlink;
+ dlink_node *ptr;
+ int channel_count = 0;
+ int local_client_conf_count = 0; /* local client conf links */
+ int users_counted = 0; /* user structs */
+
+ int channel_users = 0;
+ int channel_invites = 0;
+ int channel_bans = 0;
+ int channel_except = 0;
+ int channel_invex = 0;
+ int channel_quiets = 0;
+
+ size_t wwu = 0; /* whowas users */
+ int class_count = 0; /* classes */
+ int conf_count = 0; /* conf lines */
+ int users_invited_count = 0; /* users invited */
+ int user_channels = 0; /* users in channels */
+ int aways_counted = 0;
+ size_t number_servers_cached; /* number of servers cached by scache */
+
+ size_t channel_memory = 0;
+ size_t channel_ban_memory = 0;
+ size_t channel_except_memory = 0;
+ size_t channel_invex_memory = 0;
+ size_t channel_quiet_memory = 0;
+
+ size_t away_memory = 0; /* memory used by aways */
+ size_t wwm = 0; /* whowas array memory used */
+ size_t conf_memory = 0; /* memory used by conf lines */
+ size_t mem_servers_cached; /* memory used by scache */
+
+ size_t linebuf_count = 0;
+ size_t linebuf_memory_used = 0;
+
+ size_t total_channel_memory = 0;
+ size_t totww = 0;
+
+ size_t local_client_count = 0;
+ size_t local_client_memory_used = 0;
+
+ size_t remote_client_count = 0;
+ size_t remote_client_memory_used = 0;
+
+ size_t total_memory = 0;
+
+ count_whowas_memory(&wwu, &wwm);
+
+ DLINK_FOREACH(ptr, global_client_list.head)
+ {
+ target_p = ptr->data;
+ if(MyConnect(target_p))
+ {
+ local_client_conf_count++;
+ }
+
+ if(target_p->user)
+ {
+ users_counted++;
+ users_invited_count += dlink_list_length(&target_p->user->invited);
+ user_channels += dlink_list_length(&target_p->user->channel);
+ if(target_p->user->away)
+ {
+ aways_counted++;
+ away_memory += (strlen(target_p->user->away) + 1);
+ }
+ }
+ }
+
+ /* Count up all channels, ban lists, except lists, Invex lists */
+ DLINK_FOREACH(ptr, global_channel_list.head)
+ {
+ chptr = ptr->data;
+ channel_count++;
+ channel_memory += (strlen(chptr->chname) + sizeof(struct Channel));
+
+ channel_users += dlink_list_length(&chptr->members);
+ channel_invites += dlink_list_length(&chptr->invites);
+
+ DLINK_FOREACH(dlink, chptr->banlist.head)
+ {
+ actualBan = dlink->data;
+ channel_bans++;
+
+ channel_ban_memory += sizeof(dlink_node) + sizeof(struct Ban);
+ }
+
+ DLINK_FOREACH(dlink, chptr->exceptlist.head)
+ {
+ actualBan = dlink->data;
+ channel_except++;
+
+ channel_except_memory += (sizeof(dlink_node) + sizeof(struct Ban));
+ }
+
+ DLINK_FOREACH(dlink, chptr->invexlist.head)
+ {
+ actualBan = dlink->data;
+ channel_invex++;
+
+ channel_invex_memory += (sizeof(dlink_node) + sizeof(struct Ban));
+ }
+
+ DLINK_FOREACH(dlink, chptr->quietlist.head)
+ {
+ actualBan = dlink->data;
+ channel_quiets++;
+
+ channel_quiet_memory += (sizeof(dlink_node) + sizeof(struct Ban));
+ }
+ }
+
+ /* count up all classes */
+
+ class_count = dlink_list_length(&class_list) + 1;
+
+ count_linebuf_memory(&linebuf_count, &linebuf_memory_used);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Users %u(%lu) Invites %u(%lu)",
+ users_counted,
+ (unsigned long) users_counted * sizeof(struct User),
+ users_invited_count,
+ (unsigned long) users_invited_count * sizeof(dlink_node));
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :User channels %u(%lu) Aways %u(%d)",
+ user_channels,
+ (unsigned long) user_channels * sizeof(dlink_node),
+ aways_counted, (int) away_memory);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Attached confs %u(%lu)",
+ local_client_conf_count,
+ (unsigned long) local_client_conf_count * sizeof(dlink_node));
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Conflines %u(%d)", conf_count, (int) conf_memory);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Classes %u(%lu)",
+ class_count,
+ (unsigned long) class_count * sizeof(struct Class));
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Channels %u(%d)",
+ channel_count, (int) channel_memory);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Bans %u(%d) Exceptions %u(%d) Invex %u(%d) Quiets %u(%d)",
+ channel_bans, (int) channel_ban_memory,
+ channel_except, (int) channel_except_memory,
+ channel_invex, (int) channel_invex_memory,
+ channel_quiets, (int) channel_quiet_memory);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Channel members %u(%lu) invite %u(%lu)",
+ channel_users,
+ (unsigned long) channel_users * sizeof(dlink_node),
+ channel_invites,
+ (unsigned long) channel_invites * sizeof(dlink_node));
+
+ total_channel_memory = channel_memory +
+ channel_ban_memory +
+ channel_users * sizeof(dlink_node) + channel_invites * sizeof(dlink_node);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Whowas users %ld(%ld)",
+ (long)wwu, (long) (wwu * sizeof(struct User)));
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Whowas array %u(%d)",
+ NICKNAMEHISTORYLENGTH, (int) wwm);
+
+ totww = wwu * sizeof(struct User) + wwm;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Hash: client %u(%ld) chan %u(%ld)",
+ U_MAX, (long)(U_MAX * sizeof(dlink_list)),
+ CH_MAX, (long)(CH_MAX * sizeof(dlink_list)));
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :linebuf %ld(%ld)",
+ (long)linebuf_count, (long)linebuf_memory_used);
+
+ count_scache(&number_servers_cached, &mem_servers_cached);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :scache %ld(%ld)",
+ (long)number_servers_cached, (long)mem_servers_cached);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :hostname hash %d(%ld)",
+ HOST_MAX, (long)HOST_MAX * sizeof(dlink_list));
+
+ total_memory = totww + total_channel_memory + conf_memory +
+ class_count * sizeof(struct Class);
+
+ total_memory += mem_servers_cached;
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Total: whowas %d channel %d conf %d",
+ (int) totww, (int) total_channel_memory,
+ (int) conf_memory);
+
+ count_local_client_memory(&local_client_count, &local_client_memory_used);
+ total_memory += local_client_memory_used;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Local client Memory in use: %ld(%ld)",
+ (long)local_client_count, (long)local_client_memory_used);
+
+
+ count_remote_client_memory(&remote_client_count, &remote_client_memory_used);
+ total_memory += remote_client_memory_used;
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :Remote client Memory in use: %ld(%ld)",
+ (long)remote_client_count,
+ (long)remote_client_memory_used);
+
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "z :TOTAL: %d Available: Current max RSS: %lu",
+ (int) total_memory, get_maxrss());
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * s_user.c: User related functions.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: s_user.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "s_user.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "listener.h"
+#include "msg.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_stats.h"
+#include "scache.h"
+#include "send.h"
+#include "supported.h"
+#include "whowas.h"
+#include "memory.h"
+#include "packet.h"
+#include "reject.h"
+#include "cache.h"
+#include "hook.h"
+#include "monitor.h"
+#include "snomask.h"
+#include "blacklist.h"
+
+static void report_and_set_user_flags(struct Client *, struct ConfItem *);
+void user_welcome(struct Client *source_p);
+
+extern char *crypt();
+
+char umodebuf[128];
+
+int user_modes[256] = {
+ /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */
+ /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */
+ /* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2F */
+ /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3F */
+ 0, /* @ */
+ 0, /* A */
+ 0, /* B */
+ 0, /* C */
+ UMODE_DEAF, /* D */
+ 0, /* E */
+ 0, /* F */
+ 0, /* G */
+ 0, /* H */
+ 0, /* I */
+ 0, /* J */
+ 0, /* K */
+ 0, /* L */
+ 0, /* M */
+ 0, /* N */
+ 0, /* O */
+ 0, /* P */
+ UMODE_NOFORWARD, /* Q */
+ UMODE_REGONLYMSG, /* R */
+ UMODE_SERVICE, /* S */
+ 0, /* T */
+ 0, /* U */
+ 0, /* V */
+ 0, /* W */
+ 0, /* X */
+ 0, /* Y */
+ 0, /* Z */
+ /* 0x5B */ 0, 0, 0, 0, 0, 0, /* 0x60 */
+ UMODE_ADMIN, /* a */
+ 0, /* b */
+ 0, /* c */
+ 0, /* d */
+ 0, /* e */
+ 0, /* f */
+ UMODE_CALLERID, /* g */
+ 0, /* h */
+ UMODE_INVISIBLE, /* i */
+ 0, /* j */
+ 0, /* k */
+ UMODE_LOCOPS, /* l */
+ 0, /* m */
+ 0, /* n */
+ UMODE_OPER, /* o */
+ 0, /* p */
+ 0, /* q */
+ 0, /* r */
+ UMODE_SERVNOTICE, /* s */
+ 0, /* t */
+ 0, /* u */
+ 0, /* v */
+ UMODE_WALLOP, /* w */
+ 0, /* x */
+ 0, /* y */
+ UMODE_OPERWALL, /* z */
+ /* 0x7B */ 0, 0, 0, 0, 0, /* 0x7F */
+ /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
+ /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
+ /* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xAF */
+ /* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xBF */
+ /* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCF */
+ /* 0xD0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xDF */
+ /* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xEF */
+ /* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xFF */
+};
+/* *INDENT-ON* */
+
+/*
+ * show_lusers -
+ *
+ * inputs - pointer to client
+ * output -
+ * side effects - display to client user counts etc.
+ */
+int
+show_lusers(struct Client *source_p)
+{
+ sendto_one_numeric(source_p, RPL_LUSERCLIENT, form_str(RPL_LUSERCLIENT),
+ (Count.total - Count.invisi),
+ Count.invisi, dlink_list_length(&global_serv_list));
+
+ if(dlink_list_length(&oper_list) > 0)
+ sendto_one_numeric(source_p, RPL_LUSEROP,
+ form_str(RPL_LUSEROP), dlink_list_length(&oper_list));
+
+ if(dlink_list_length(&unknown_list) > 0)
+ sendto_one_numeric(source_p, RPL_LUSERUNKNOWN,
+ form_str(RPL_LUSERUNKNOWN),
+ dlink_list_length(&unknown_list));
+
+ if(dlink_list_length(&global_channel_list) > 0)
+ sendto_one_numeric(source_p, RPL_LUSERCHANNELS,
+ form_str(RPL_LUSERCHANNELS),
+ dlink_list_length(&global_channel_list));
+
+ sendto_one_numeric(source_p, RPL_LUSERME, form_str(RPL_LUSERME),
+ dlink_list_length(&lclient_list),
+ dlink_list_length(&serv_list));
+
+ sendto_one_numeric(source_p, RPL_LOCALUSERS,
+ form_str(RPL_LOCALUSERS),
+ dlink_list_length(&lclient_list),
+ Count.max_loc,
+ dlink_list_length(&lclient_list),
+ Count.max_loc);
+
+ sendto_one_numeric(source_p, RPL_GLOBALUSERS, form_str(RPL_GLOBALUSERS),
+ Count.total, Count.max_tot,
+ Count.total, Count.max_tot);
+
+ sendto_one_numeric(source_p, RPL_STATSCONN,
+ form_str(RPL_STATSCONN),
+ MaxConnectionCount, MaxClientCount,
+ Count.totalrestartcount);
+
+ if(dlink_list_length(&lclient_list) > (unsigned long)MaxClientCount)
+ MaxClientCount = dlink_list_length(&lclient_list);
+
+ if((dlink_list_length(&lclient_list) + dlink_list_length(&serv_list)) >
+ (unsigned long)MaxConnectionCount)
+ MaxConnectionCount = dlink_list_length(&lclient_list) +
+ dlink_list_length(&serv_list);
+
+ return 0;
+}
+
+/*
+** register_local_user
+** This function is called when both NICK and USER messages
+** have been accepted for the client, in whatever order. Only
+** after this, is the USER message propagated.
+**
+** NICK's must be propagated at once when received, although
+** it would be better to delay them too until full info is
+** available. Doing it is not so simple though, would have
+** to implement the following:
+**
+** (actually it has been implemented already for a while) -orabidoo
+**
+** 1) user telnets in and gives only "NICK foobar" and waits
+** 2) another user far away logs in normally with the nick
+** "foobar" (quite legal, as this server didn't propagate
+** it).
+** 3) now this server gets nick "foobar" from outside, but
+** has alread the same defined locally. Current server
+** would just issue "KILL foobar" to clean out dups. But,
+** this is not fair. It should actually request another
+** nick from local user or kill him/her...
+*/
+
+int
+register_local_user(struct Client *client_p, struct Client *source_p, const char *username)
+{
+ struct ConfItem *aconf;
+ struct User *user = source_p->user;
+ char tmpstr2[IRCD_BUFSIZE];
+ char ipaddr[HOSTIPLEN];
+ char myusername[USERLEN+1];
+ int status;
+
+ s_assert(NULL != source_p);
+ s_assert(MyConnect(source_p));
+ s_assert(source_p->username != username);
+
+ if(source_p == NULL)
+ return -1;
+
+ if(IsAnyDead(source_p))
+ return -1;
+
+ if(ConfigFileEntry.ping_cookie)
+ {
+ if(!(source_p->flags & FLAGS_PINGSENT) && source_p->localClient->random_ping == 0)
+ {
+ source_p->localClient->random_ping = (unsigned long) (rand() * rand()) << 1;
+ sendto_one(source_p, "PING :%08lX",
+ (unsigned long) source_p->localClient->random_ping);
+ source_p->flags |= FLAGS_PINGSENT;
+ return -1;
+ }
+ if(!(source_p->flags2 & FLAGS2_PING_COOKIE))
+ {
+ return -1;
+ }
+ }
+
+ /* hasnt finished client cap negotiation */
+ if(source_p->flags2 & FLAGS2_CLICAP)
+ return -1;
+
+ /* still has DNSbls to validate against */
+ if(dlink_list_length(&source_p->preClient->dnsbl_queries) > 0)
+ return -1;
+
+ client_p->localClient->last = CurrentTime;
+ /* Straight up the maximum rate of flooding... */
+ source_p->localClient->allow_read = MAX_FLOOD_BURST;
+
+ /* XXX - fixme. we shouldnt have to build a users buffer twice.. */
+ if(!IsGotId(source_p) && (strchr(username, '[') != NULL))
+ {
+ const char *p;
+ int i = 0;
+
+ p = username;
+
+ while(*p && i < USERLEN)
+ {
+ if(*p != '[')
+ myusername[i++] = *p;
+ p++;
+ }
+
+ myusername[i] = '\0';
+ username = myusername;
+ }
+
+ if((status = check_client(client_p, source_p, username)) < 0)
+ return (CLIENT_EXITED);
+
+ /* Apply nick override */
+ if(*source_p->preClient->spoofnick)
+ {
+ del_from_client_hash(source_p->name, source_p);
+ strlcpy(source_p->name, source_p->preClient->spoofnick, NICKLEN + 1);
+ add_to_client_hash(source_p->name, source_p);
+ comm_note(source_p->localClient->fd, "Nick: %s", source_p->name);
+ }
+
+ if(!valid_hostname(source_p->host))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Notice -- You have an illegal character in your hostname",
+ me.name, source_p->name);
+
+ strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
+
+#ifdef IPV6
+ if(ConfigFileEntry.dot_in_ip6_addr == 1)
+ strlcat(source_p->host, ".", sizeof(source_p->host));
+#endif
+ }
+
+
+ aconf = source_p->localClient->att_conf;
+
+ if(aconf == NULL)
+ {
+ exit_client(client_p, source_p, &me, "*** Not Authorised");
+ return (CLIENT_EXITED);
+ }
+
+ if(!IsGotId(source_p))
+ {
+ const char *p;
+ int i = 0;
+
+ if(IsNeedIdentd(aconf))
+ {
+ ServerStats->is_ref++;
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Notice -- You need to install identd to use this server",
+ me.name, client_p->name);
+ exit_client(client_p, source_p, &me, "Install identd");
+ return (CLIENT_EXITED);
+ }
+
+ /* dont replace username if its supposed to be spoofed --fl */
+ if(!IsConfDoSpoofIp(aconf) || !strchr(aconf->name, '@'))
+ {
+ p = username;
+
+ if(!IsNoTilde(aconf))
+ source_p->username[i++] = '~';
+
+ while (*p && i < USERLEN)
+ {
+ if(*p != '[')
+ source_p->username[i++] = *p;
+ p++;
+ }
+
+ source_p->username[i] = '\0';
+ }
+ }
+
+ if(IsNeedSasl(aconf) && !*user->suser)
+ {
+ ServerStats->is_ref++;
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Notice -- You need to identify via SASL to use this server",
+ me.name, client_p->name);
+ exit_client(client_p, source_p, &me, "SASL access only");
+ return (CLIENT_EXITED);
+ }
+
+ /* password check */
+ if(!EmptyString(aconf->passwd))
+ {
+ const char *encr;
+
+ if(EmptyString(source_p->localClient->passwd))
+ encr = "";
+ else if(IsConfEncrypted(aconf))
+ encr = crypt(source_p->localClient->passwd, aconf->passwd);
+ else
+ encr = source_p->localClient->passwd;
+
+ if(strcmp(encr, aconf->passwd))
+ {
+ ServerStats->is_ref++;
+ sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
+ exit_client(client_p, source_p, &me, "Bad Password");
+ return (CLIENT_EXITED);
+ }
+
+ /* clear password only if used now, otherwise send it
+ * to services -- jilles */
+ if(source_p->localClient->passwd)
+ {
+ memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd));
+ MyFree(source_p->localClient->passwd);
+ source_p->localClient->passwd = NULL;
+ }
+ }
+
+ /* report if user has &^>= etc. and set flags as needed in source_p */
+ report_and_set_user_flags(source_p, aconf);
+
+ /* Limit clients */
+ /*
+ * We want to be able to have servers and F-line clients
+ * connect, so save room for "buffer" connections.
+ * Smaller servers may want to decrease this, and it should
+ * probably be just a percentage of the MAXCLIENTS...
+ * -Taner
+ */
+ /* Except "F:" clients */
+ if(((dlink_list_length(&lclient_list) + 1) >=
+ ((unsigned long)GlobalSetOptions.maxclients + MAX_BUFFER) ||
+ (dlink_list_length(&lclient_list) + 1) >=
+ ((unsigned long)GlobalSetOptions.maxclients - 5)) && !(IsExemptLimits(source_p)))
+ {
+ sendto_realops_snomask(SNO_FULL, L_ALL,
+ "Too many clients, rejecting %s[%s].", source_p->name, source_p->host);
+
+ ServerStats->is_ref++;
+ exit_client(client_p, source_p, &me, "Sorry, server is full - try later");
+ return (CLIENT_EXITED);
+ }
+
+ /* valid user name check */
+
+ if(!valid_username(source_p->username))
+ {
+ sendto_realops_snomask(SNO_REJ, L_ALL,
+ "Invalid username: %s (%s@%s)",
+ source_p->name, source_p->username, source_p->host);
+ ServerStats->is_ref++;
+ ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username);
+ exit_client(client_p, source_p, &me, tmpstr2);
+ return (CLIENT_EXITED);
+ }
+
+ /* end of valid user name check */
+
+ /* kline exemption extends to xline too */
+ if(!IsExemptKline(source_p) &&
+ find_xline(source_p->info, 1) != NULL)
+ {
+ ServerStats->is_ref++;
+ add_reject(source_p);
+ exit_client(client_p, source_p, &me, "Bad user info");
+ return CLIENT_EXITED;
+ }
+
+ /* dnsbl check */
+ if (source_p->preClient->dnsbl_listed != NULL)
+ {
+ if (IsExemptKline(source_p) || IsConfExemptDNSBL(aconf))
+ sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s, but you are exempt",
+ source_p->sockhost, source_p->preClient->dnsbl_listed->host);
+ else
+ {
+ ServerStats->is_ref++;
+ sendto_one(source_p, form_str(ERR_YOUREBANNEDCREEP),
+ me.name, source_p->name,
+ source_p->preClient->dnsbl_listed->reject_reason);
+ sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s",
+ source_p->sockhost, source_p->preClient->dnsbl_listed->host);
+ source_p->preClient->dnsbl_listed->hits++;
+ add_reject(source_p);
+ exit_client(client_p, source_p, &me, "*** Banned (DNS blacklist)");
+ return CLIENT_EXITED;
+ }
+ }
+
+ /* Store original hostname -- jilles */
+ strlcpy(source_p->orighost, source_p->host, HOSTLEN + 1);
+
+ /* Spoof user@host */
+ if(*source_p->preClient->spoofuser)
+ strlcpy(source_p->username, source_p->preClient->spoofuser, USERLEN + 1);
+ if(*source_p->preClient->spoofhost)
+ {
+ strlcpy(source_p->host, source_p->preClient->spoofhost, HOSTLEN + 1);
+ if (irccmp(source_p->host, source_p->orighost))
+ SetDynSpoof(source_p);
+ }
+
+ if(IsAnyDead(client_p))
+ return CLIENT_EXITED;
+
+ inetntop_sock((struct sockaddr *)&source_p->localClient->ip, ipaddr, sizeof(ipaddr));
+
+ sendto_realops_snomask(SNO_CCONN, L_ALL,
+ "Client connecting: %s (%s@%s) [%s] {%s} [%s]",
+ source_p->name, source_p->username, source_p->orighost,
+ show_ip(NULL, source_p) ? ipaddr : "255.255.255.255",
+ get_client_class(source_p), source_p->info);
+
+ sendto_realops_snomask(SNO_CCONNEXT, L_ALL,
+ "CLICONN %s %s %s %s %s %s 0 %s",
+ source_p->name, source_p->username, source_p->orighost,
+ show_ip(NULL, source_p) ? ipaddr : "255.255.255.255",
+ get_client_class(source_p),
+ /* mirc can sometimes send ips here */
+ show_ip(NULL, source_p) ? source_p->localClient->fullcaps : "<hidden> <hidden>",
+ source_p->info);
+
+ /* If they have died in send_* don't do anything. */
+ if(IsAnyDead(source_p))
+ return CLIENT_EXITED;
+
+ add_to_hostname_hash(source_p->orighost, source_p);
+
+ /* Allocate a UID if it was not previously allocated.
+ * If this already occured, it was probably during SASL auth...
+ */
+ if(!*source_p->id)
+ {
+ strcpy(source_p->id, generate_uid());
+ add_to_id_hash(source_p->id, source_p);
+ }
+
+ source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes;
+
+ if (source_p->umodes & UMODE_INVISIBLE)
+ Count.invisi++;
+
+ s_assert(!IsClient(source_p));
+ dlinkMoveNode(&source_p->localClient->tnode, &unknown_list, &lclient_list);
+ SetClient(source_p);
+
+ /* XXX source_p->servptr is &me, since local client */
+ source_p->servptr = find_server(NULL, user->server);
+ dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users);
+ /* Increment our total user count here */
+ if(++Count.total > Count.max_tot)
+ Count.max_tot = Count.total;
+ source_p->localClient->allow_read = MAX_FLOOD_BURST;
+
+ Count.totalrestartcount++;
+
+ s_assert(source_p->localClient != NULL);
+
+ if(dlink_list_length(&lclient_list) > (unsigned long)Count.max_loc)
+ {
+ Count.max_loc = dlink_list_length(&lclient_list);
+ if(!(Count.max_loc % 10))
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "New Max Local Clients: %d", Count.max_loc);
+ }
+
+ /* they get a reduced limit */
+ if(find_tgchange(source_p->sockhost))
+ USED_TARGETS(source_p) = 6;
+
+ call_hook(h_new_local_user, source_p);
+
+ monitor_signon(source_p);
+ user_welcome(source_p);
+
+ free_pre_client(source_p);
+
+ return (introduce_client(client_p, source_p, user, source_p->name, 1));
+}
+
+/*
+ * introduce_clients
+ *
+ * inputs -
+ * output -
+ * side effects - This common function introduces a client to the rest
+ * of the net, either from a local client connect or
+ * from a remote connect.
+ */
+int
+introduce_client(struct Client *client_p, struct Client *source_p, struct User *user, const char *nick, int use_euid)
+{
+ static char ubuf[12];
+ struct Client *identifyservice_p;
+ char *p;
+ hook_data_umode_changed hdata;
+ hook_data_client hdata2;
+
+ if(MyClient(source_p))
+ send_umode(source_p, source_p, 0, 0, ubuf);
+ else
+ send_umode(NULL, source_p, 0, 0, ubuf);
+
+ if(!*ubuf)
+ {
+ ubuf[0] = '+';
+ ubuf[1] = '\0';
+ }
+
+ /* if it has an ID, introduce it with its id to TS6 servers,
+ * otherwise introduce it normally to all.
+ */
+ if(has_id(source_p))
+ {
+ char sockhost[HOSTLEN];
+ if(source_p->sockhost[0] == ':')
+ {
+ sockhost[0] = '0';
+ sockhost[1] = '\0';
+ strlcat(sockhost, source_p->sockhost, sizeof(sockhost));
+ } else
+ strcpy(sockhost, source_p->sockhost);
+
+ if (use_euid)
+ sendto_server(client_p, NULL, CAP_EUID | CAP_TS6, NOCAPS,
+ ":%s EUID %s %d %ld %s %s %s %s %s %s %s :%s",
+ source_p->servptr->id, nick,
+ source_p->hopcount + 1,
+ (long) source_p->tsinfo, ubuf,
+ source_p->username, source_p->host,
+ IsIPSpoof(source_p) ? "0" : sockhost,
+ source_p->id,
+ IsDynSpoof(source_p) ? source_p->orighost : "*",
+ EmptyString(source_p->user->suser) ? "*" : source_p->user->suser,
+ source_p->info);
+
+ sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS,
+ ":%s UID %s %d %ld %s %s %s %s %s :%s",
+ source_p->servptr->id, nick,
+ source_p->hopcount + 1,
+ (long) source_p->tsinfo, ubuf,
+ source_p->username, source_p->host,
+ IsIPSpoof(source_p) ? "0" : sockhost,
+ source_p->id, source_p->info);
+
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
+ "NICK %s %d %ld %s %s %s %s :%s",
+ nick, source_p->hopcount + 1,
+ (long) source_p->tsinfo,
+ ubuf, source_p->username, source_p->host,
+ user->server, source_p->info);
+ }
+ else
+ sendto_server(client_p, NULL, NOCAPS, NOCAPS,
+ "NICK %s %d %ld %s %s %s %s :%s",
+ nick, source_p->hopcount + 1,
+ (long) source_p->tsinfo,
+ ubuf, source_p->username, source_p->host,
+ user->server, source_p->info);
+
+ if (IsDynSpoof(source_p))
+ {
+ sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS, ":%s ENCAP * REALHOST %s",
+ use_id(source_p), source_p->orighost);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * REALHOST %s",
+ source_p->name, source_p->orighost);
+ }
+ if (!EmptyString(source_p->user->suser))
+ {
+ sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS, ":%s ENCAP * LOGIN %s",
+ use_id(source_p), source_p->user->suser);
+ sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * LOGIN %s",
+ source_p->name, source_p->user->suser);
+ }
+
+ if(MyConnect(source_p) && source_p->localClient->passwd)
+ {
+ if (ConfigFileEntry.identifyservice[0] != '\0' &&
+ ConfigFileEntry.identifycommand[0] != '\0')
+ {
+ /* use user@server */
+ p = strchr(ConfigFileEntry.identifyservice, '@');
+ if (p != NULL)
+ identifyservice_p = find_named_client(p + 1);
+ else
+ identifyservice_p = NULL;
+ if (identifyservice_p != NULL)
+ sendto_one(identifyservice_p, ":%s PRIVMSG %s :%s %s",
+ get_id(source_p, identifyservice_p),
+ ConfigFileEntry.identifyservice,
+ ConfigFileEntry.identifycommand,
+ source_p->localClient->passwd);
+ }
+ memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd));
+ MyFree(source_p->localClient->passwd);
+ source_p->localClient->passwd = NULL;
+ }
+
+ /* let modules providing usermodes know that we've got a new user,
+ * why is this here? -- well, some modules need to be able to send out new
+ * information about a client, so this was the best place to do it
+ * --nenolod
+ */
+ hdata.client = source_p;
+ hdata.oldumodes = 0;
+ hdata.oldsnomask = 0;
+ call_hook(h_umode_changed, &hdata);
+
+ /* On the other hand, some modules need to know when a client is
+ * being introduced, period.
+ * --gxti
+ */
+ hdata2.client = client_p;
+ hdata2.target = source_p;
+ call_hook(h_introduce_client, &hdata2);
+
+ return 0;
+}
+
+/*
+ * valid_hostname - check hostname for validity
+ *
+ * Inputs - pointer to user
+ * Output - YES if valid, NO if not
+ * Side effects - NONE
+ *
+ * NOTE: this doesn't allow a hostname to begin with a dot and
+ * will not allow more dots than chars.
+ */
+int
+valid_hostname(const char *hostname)
+{
+ const char *p = hostname;
+ int found_sep = 0;
+
+ s_assert(NULL != p);
+
+ if(hostname == NULL)
+ return NO;
+
+ if('.' == *p || ':' == *p)
+ return NO;
+
+ while (*p)
+ {
+ if(!IsHostChar(*p))
+ return NO;
+ if(*p == '.' || *p == ':')
+ found_sep++;
+ p++;
+ }
+
+ if(found_sep == 0)
+ return(NO);
+
+ return (YES);
+}
+
+/*
+ * valid_username - check username for validity
+ *
+ * Inputs - pointer to user
+ * Output - YES if valid, NO if not
+ * Side effects - NONE
+ *
+ * Absolutely always reject any '*' '!' '?' '@' in an user name
+ * reject any odd control characters names.
+ * Allow '.' in username to allow for "first.last"
+ * style of username
+ */
+int
+valid_username(const char *username)
+{
+ int dots = 0;
+ const char *p = username;
+
+ s_assert(NULL != p);
+
+ if(username == NULL)
+ return NO;
+
+ if('~' == *p)
+ ++p;
+
+ /* reject usernames that don't start with an alphanum
+ * i.e. reject jokers who have '-@somehost' or '.@somehost'
+ * or "-hi-@somehost", "h-----@somehost" would still be accepted.
+ */
+ if(!IsAlNum(*p))
+ return NO;
+
+ while (*++p)
+ {
+ if((*p == '.') && ConfigFileEntry.dots_in_ident)
+ {
+ dots++;
+ if(dots > ConfigFileEntry.dots_in_ident)
+ return NO;
+ if(!IsUserChar(p[1]))
+ return NO;
+ }
+ else if(!IsUserChar(*p))
+ return NO;
+ }
+ return YES;
+}
+
+/* report_and_set_user_flags
+ *
+ * Inputs - pointer to source_p
+ * - pointer to aconf for this user
+ * Output - NONE
+ * Side effects -
+ * Report to user any special flags they are getting, and set them.
+ */
+
+static void
+report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf)
+{
+ /* If this user is being spoofed, tell them so */
+ if(IsConfDoSpoofIp(aconf))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** Spoofing your IP. congrats.",
+ me.name, source_p->name);
+ }
+
+ /* If this user is in the exception class, Set it "E lined" */
+ if(IsConfExemptKline(aconf))
+ {
+ SetExemptKline(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from K/D/G/X lines. congrats.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptGline(aconf))
+ {
+ SetExemptGline(source_p);
+
+ /* dont send both a kline and gline exempt notice */
+ if(!IsConfExemptKline(aconf))
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from G lines.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptDNSBL(aconf))
+ /* kline exempt implies this, don't send both */
+ if(!IsConfExemptKline(aconf))
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from DNS blacklists.",
+ me.name, source_p->name);
+
+ /* If this user is exempt from user limits set it F lined" */
+ if(IsConfExemptLimits(aconf))
+ {
+ SetExemptLimits(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from user limits. congrats.",
+ me.name, source_p->name);
+ }
+
+ /* If this user is exempt from idle time outs */
+ if(IsConfIdlelined(aconf))
+ {
+ SetIdlelined(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from idle limits. congrats.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptFlood(aconf))
+ {
+ SetExemptFlood(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from flood limits.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptSpambot(aconf))
+ {
+ SetExemptSpambot(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from spambot checks.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptJupe(aconf))
+ {
+ SetExemptJupe(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from juped channel warnings.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptResv(aconf))
+ {
+ SetExemptResv(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from resvs.",
+ me.name, source_p->name);
+ }
+
+ if(IsConfExemptShide(aconf))
+ {
+ SetExemptShide(source_p);
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You are exempt from serverhiding.",
+ me.name, source_p->name);
+ }
+}
+
+/*
+ * user_mode - set get current users mode
+ *
+ * m_umode() added 15/10/91 By Darren Reed.
+ * parv[0] - sender
+ * parv[1] - username to change mode for
+ * parv[2] - modes to change
+ */
+int
+user_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ int flag;
+ int i;
+ char *m;
+ const char *pm;
+ struct Client *target_p;
+ int what, setflags;
+ int badflag = NO; /* Only send one bad flag notice */
+ int showsnomask = NO;
+ unsigned int setsnomask;
+ char buf[BUFSIZE];
+ hook_data_umode_changed hdata;
+
+ what = MODE_ADD;
+
+ if(parc < 2)
+ {
+ sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MODE");
+ return 0;
+ }
+
+ if((target_p = MyClient(source_p) ? find_named_person(parv[1]) : find_person(parv[1])) == NULL)
+ {
+ if(MyConnect(source_p))
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ /* Dont know why these were commented out..
+ * put them back using new sendto() funcs
+ */
+
+ if(IsServer(source_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ADMIN,
+ "*** Mode for User %s from %s", parv[1], source_p->name);
+ return 0;
+ }
+
+ if(source_p != target_p || target_p->from != source_p->from)
+ {
+ sendto_one(source_p, form_str(ERR_USERSDONTMATCH), me.name, source_p->name);
+ return 0;
+ }
+
+ if(parc < 3)
+ {
+ m = buf;
+ *m++ = '+';
+
+ for (i = 0; i < 128; i++) /* >= 127 is extended ascii */
+ if (source_p->umodes & user_modes[i])
+ *m++ = (char) i;
+
+ *m = '\0';
+ sendto_one(source_p, form_str(RPL_UMODEIS), me.name, source_p->name, buf);
+ if (source_p->snomask != 0)
+ sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
+ construct_snobuf(source_p->snomask));
+ return 0;
+ }
+
+ /* find flags already set for user */
+ setflags = source_p->umodes;
+ setsnomask = source_p->snomask;
+
+ /*
+ * parse mode change string(s)
+ */
+ for (pm = parv[2]; *pm; pm++)
+ switch (*pm)
+ {
+ case '+':
+ what = MODE_ADD;
+ break;
+ case '-':
+ what = MODE_DEL;
+ break;
+
+ case 'o':
+ if(what == MODE_ADD)
+ {
+ if(IsServer(client_p) && !IsOper(source_p))
+ {
+ ++Count.oper;
+ SetOper(source_p);
+ dlinkAddAlloc(source_p, &oper_list);
+ }
+ }
+ else
+ {
+ /* Only decrement the oper counts if an oper to begin with
+ * found by Pat Szuta, Perly , perly@xnet.com
+ */
+
+ if(!IsOper(source_p))
+ break;
+
+ ClearOper(source_p);
+
+ Count.oper--;
+
+ if(MyConnect(source_p))
+ {
+ source_p->umodes &= ~ConfigFileEntry.oper_only_umodes;
+ if (!(source_p->umodes & UMODE_SERVNOTICE) && source_p->snomask != 0)
+ {
+ source_p->snomask = 0;
+ showsnomask = YES;
+ }
+ source_p->flags2 &= ~OPER_FLAGS;
+
+ MyFree(source_p->localClient->opername);
+ source_p->localClient->opername = NULL;
+
+ dlinkFindDestroy(source_p, &local_oper_list);
+ }
+
+ dlinkFindDestroy(source_p, &oper_list);
+ }
+ break;
+
+ /* we may not get these,
+ * but they shouldnt be in default
+ */
+
+ /* can only be set on burst */
+ case 'S':
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ break;
+
+ case 's':
+ if (MyConnect(source_p))
+ {
+ if(!IsOper(source_p)
+ && (ConfigFileEntry.oper_only_umodes & UMODE_SERVNOTICE))
+ {
+ if (what == MODE_ADD || source_p->umodes & UMODE_SERVNOTICE)
+ badflag = YES;
+ continue;
+ }
+ showsnomask = YES;
+ if(what == MODE_ADD)
+ {
+ if (parc > 3)
+ source_p->snomask = parse_snobuf_to_mask(source_p->snomask, parv[3]);
+ else
+ source_p->snomask |= SNO_GENERAL;
+ }
+ else
+ source_p->snomask = 0;
+ if (source_p->snomask != 0)
+ source_p->umodes |= UMODE_SERVNOTICE;
+ else
+ source_p->umodes &= ~UMODE_SERVNOTICE;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (MyConnect(source_p) && *pm == 'Q' && !ConfigChannel.use_forward) {
+ badflag = YES;
+ break;
+ }
+
+ if((flag = user_modes[(unsigned char) *pm]))
+ {
+ if(MyConnect(source_p)
+ && !IsOper(source_p)
+ && (ConfigFileEntry.oper_only_umodes & flag))
+ {
+ if (what == MODE_ADD || source_p->umodes & flag)
+ badflag = YES;
+ }
+ else
+ {
+ if(what == MODE_ADD)
+ source_p->umodes |= flag;
+ else
+ source_p->umodes &= ~flag;
+ }
+ }
+ else
+ {
+ if(MyConnect(source_p))
+ badflag = YES;
+ }
+ break;
+ }
+
+ if(badflag)
+ sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
+
+ if(MyClient(source_p) && (source_p->snomask & SNO_NCHANGE) && !IsOperN(source_p))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You need oper and N flag for +s +n", me.name, parv[0]);
+ source_p->snomask &= ~SNO_NCHANGE; /* only tcm's really need this */
+ }
+
+ if(MyClient(source_p) && (source_p->umodes & UMODE_OPERWALL) && !IsOperOperwall(source_p))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You need oper and operwall flag for +z", me.name, parv[0]);
+ source_p->umodes &= ~UMODE_OPERWALL;
+ }
+
+ if(MyConnect(source_p) && (source_p->umodes & UMODE_ADMIN) &&
+ (!IsOperAdmin(source_p) || IsOperHiddenAdmin(source_p)))
+ {
+ sendto_one(source_p,
+ ":%s NOTICE %s :*** You need oper and A flag for +a", me.name, parv[0]);
+ source_p->umodes &= ~UMODE_ADMIN;
+ }
+
+ /* let modules providing usermodes know that we've changed our usermode --nenolod */
+ hdata.client = source_p;
+ hdata.oldumodes = setflags;
+ hdata.oldsnomask = setsnomask;
+ call_hook(h_umode_changed, &hdata);
+
+ if(!(setflags & UMODE_INVISIBLE) && IsInvisible(source_p))
+ ++Count.invisi;
+ if((setflags & UMODE_INVISIBLE) && !IsInvisible(source_p))
+ --Count.invisi;
+ /*
+ * compare new flags with old flags and send string which
+ * will cause servers to update correctly.
+ */
+ send_umode_out(client_p, source_p, setflags);
+ if (showsnomask && MyConnect(source_p))
+ sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
+ construct_snobuf(source_p->snomask));
+
+ return (0);
+}
+
+/*
+ * send the MODE string for user (user) to connection client_p
+ * -avalon
+ */
+void
+send_umode(struct Client *client_p, struct Client *source_p, int old, int sendmask, char *umode_buf)
+{
+ int i;
+ int flag;
+ char *m;
+ int what = 0;
+
+ /*
+ * build a string in umode_buf to represent the change in the user's
+ * mode between the new (source_p->flag) and 'old'.
+ */
+ m = umode_buf;
+ *m = '\0';
+
+ for (i = 0; i < 128; i++)
+ {
+ flag = user_modes[i];
+
+ if((flag & old) && !(source_p->umodes & flag))
+ {
+ if(what == MODE_DEL)
+ *m++ = (char) i;
+ else
+ {
+ what = MODE_DEL;
+ *m++ = '-';
+ *m++ = (char) i;
+ }
+ }
+ else if(!(flag & old) && (source_p->umodes & flag))
+ {
+ if(what == MODE_ADD)
+ *m++ = (char) i;
+ else
+ {
+ what = MODE_ADD;
+ *m++ = '+';
+ *m++ = (char) i;
+ }
+ }
+ }
+ *m = '\0';
+
+ if(*umode_buf && client_p)
+ sendto_one(client_p, ":%s MODE %s :%s", source_p->name, source_p->name, umode_buf);
+}
+
+/*
+ * send_umode_out
+ *
+ * inputs -
+ * output - NONE
+ * side effects -
+ */
+void
+send_umode_out(struct Client *client_p, struct Client *source_p, int old)
+{
+ struct Client *target_p;
+ char buf[BUFSIZE];
+ dlink_node *ptr;
+
+ send_umode(NULL, source_p, old, 0, buf);
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if((target_p != client_p) && (target_p != source_p) && (*buf))
+ {
+ sendto_one(target_p, ":%s MODE %s :%s",
+ get_id(source_p, target_p),
+ get_id(source_p, target_p), buf);
+ }
+ }
+
+ if(client_p && MyClient(client_p))
+ send_umode(client_p, source_p, old, 0, buf);
+}
+
+/*
+ * user_welcome
+ *
+ * inputs - client pointer to client to welcome
+ * output - NONE
+ * side effects -
+ */
+void
+user_welcome(struct Client *source_p)
+{
+ sendto_one(source_p, form_str(RPL_WELCOME), me.name, source_p->name,
+ ServerInfo.network_name, source_p->name);
+ sendto_one(source_p, form_str(RPL_YOURHOST), me.name,
+ source_p->name,
+ get_listener_name(source_p->localClient->listener), ircd_version);
+
+ sendto_one(source_p, form_str(RPL_CREATED), me.name, source_p->name, creation);
+ sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name, me.name, ircd_version, umodebuf);
+
+ show_isupport(source_p);
+
+ show_lusers(source_p);
+
+ if(ConfigFileEntry.short_motd)
+ {
+ sendto_one(source_p,
+ "NOTICE %s :*** Notice -- motd was last changed at %s",
+ source_p->name, user_motd_changed);
+
+ sendto_one(source_p,
+ "NOTICE %s :*** Notice -- Please read the motd if you haven't read it",
+ source_p->name);
+
+ sendto_one(source_p, form_str(RPL_MOTDSTART),
+ me.name, source_p->name, me.name);
+
+ sendto_one(source_p, form_str(RPL_MOTD),
+ me.name, source_p->name, "*** This is the short motd ***");
+
+ sendto_one(source_p, form_str(RPL_ENDOFMOTD), me.name, source_p->name);
+ }
+ else
+ send_user_motd(source_p);
+}
+
+/* oper_up()
+ *
+ * inputs - pointer to given client to oper
+ * - pointer to ConfItem to use
+ * output - none
+ * side effects - opers up source_p using aconf for reference
+ */
+int
+oper_up(struct Client *source_p, struct oper_conf *oper_p)
+{
+ unsigned int old = source_p->umodes, oldsnomask = source_p->snomask;
+ hook_data_umode_changed hdata;
+
+ SetOper(source_p);
+
+ if(oper_p->umodes)
+ source_p->umodes |= oper_p->umodes;
+ else if(ConfigFileEntry.oper_umodes)
+ source_p->umodes |= ConfigFileEntry.oper_umodes;
+ else
+ source_p->umodes |= DEFAULT_OPER_UMODES;
+
+ if (oper_p->snomask)
+ {
+ source_p->snomask |= oper_p->snomask;
+ source_p->umodes |= UMODE_SERVNOTICE;
+ }
+ else if (source_p->umodes & UMODE_SERVNOTICE)
+ {
+ /* Only apply these if +s is already set -- jilles */
+ if (ConfigFileEntry.oper_snomask)
+ source_p->snomask |= ConfigFileEntry.oper_snomask;
+ else
+ source_p->snomask |= DEFAULT_OPER_SNOMASK;
+ }
+
+ Count.oper++;
+
+ SetExemptKline(source_p);
+
+ source_p->flags2 |= oper_p->flags;
+ DupString(source_p->localClient->opername, oper_p->name);
+
+ dlinkAddAlloc(source_p, &local_oper_list);
+ dlinkAddAlloc(source_p, &oper_list);
+
+ if(IsOperAdmin(source_p) && !IsOperHiddenAdmin(source_p))
+ source_p->umodes |= UMODE_ADMIN;
+ if(!IsOperN(source_p))
+ source_p->snomask &= ~SNO_NCHANGE;
+ if(!IsOperOperwall(source_p))
+ source_p->umodes &= ~UMODE_OPERWALL;
+ hdata.client = source_p;
+ hdata.oldumodes = old;
+ hdata.oldsnomask = oldsnomask;
+ call_hook(h_umode_changed, &hdata);
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "%s (%s@%s) is now an operator", source_p->name,
+ source_p->username, source_p->host);
+ send_umode_out(source_p, source_p, old);
+ sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
+ construct_snobuf(source_p->snomask));
+ sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
+ sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name,
+ source_p->name, get_oper_privs(oper_p->flags));
+ send_oper_motd(source_p);
+
+ return (1);
+}
+
+void
+construct_umodebuf(void)
+{
+ int i;
+ char *ptr = umodebuf;
+
+ *ptr = '\0';
+
+ for (i = 0; i < 128; i++)
+ if (user_modes[i])
+ *ptr++ = (char) i;
+
+ *ptr++ = '\0';
+}
+
+void
+change_nick_user_host(struct Client *target_p, const char *nick, const char *user,
+ const char *host, int newts, char *format, ...)
+{
+ dlink_node *ptr;
+ struct Channel *chptr;
+ struct membership *mscptr;
+ int changed = irccmp(target_p->name, nick);
+ int changed_case = strcmp(target_p->name, nick);
+ int do_qjm = irccmp(target_p->username, user) || irccmp(target_p->host, host);
+ char mode[10], modeval[NICKLEN * 2 + 2], reason[256], *mptr;
+ va_list ap;
+
+ modeval[0] = '\0';
+
+ if(changed)
+ {
+ target_p->tsinfo = newts;
+ monitor_signoff(target_p);
+ }
+ invalidate_bancache_user(target_p);
+
+ if(do_qjm)
+ {
+ va_start(ap, format);
+ vsnprintf(reason, 255, format, ap);
+ va_end(ap);
+
+ sendto_common_channels_local_butone(target_p, ":%s!%s@%s QUIT :%s",
+ target_p->name, target_p->username, target_p->host,
+ reason);
+
+ DLINK_FOREACH(ptr, target_p->user->channel.head)
+ {
+ mscptr = ptr->data;
+ chptr = mscptr->chptr;
+ mptr = mode;
+
+ if(is_chanop(mscptr))
+ {
+ *mptr++ = 'o';
+ strcat(modeval, nick);
+ strcat(modeval, " ");
+ }
+
+ if(is_voiced(mscptr))
+ {
+ *mptr++ = 'v';
+ strcat(modeval, nick);
+ }
+
+ *mptr = '\0';
+
+ sendto_channel_local_butone(target_p, ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ nick, user, host, chptr->chname);
+ if(*mode)
+ sendto_channel_local_butone(target_p, ALL_MEMBERS, chptr,
+ ":%s MODE %s +%s %s",
+ target_p->servptr->name,
+ chptr->chname, mode, modeval);
+
+ *modeval = '\0';
+ }
+
+ if(MyClient(target_p) && changed_case)
+ sendto_one(target_p, ":%s!%s@%s NICK %s",
+ target_p->name, target_p->username, target_p->host, nick);
+ }
+ else if(changed_case)
+ {
+ sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s",
+ target_p->name, target_p->username,
+ target_p->host, nick);
+ }
+
+ strlcpy(target_p->username, user, USERLEN);
+ strlcpy(target_p->host, host, HOSTLEN);
+
+ if (changed)
+ add_history(target_p, 1);
+
+ del_from_client_hash(target_p->name, target_p);
+ strlcpy(target_p->name, nick, NICKLEN);
+ add_to_client_hash(target_p->name, target_p);
+
+ if(changed)
+ {
+ monitor_signon(target_p);
+ del_all_accepts(target_p);
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * scache.c: Server names cache.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: scache.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "scache.h"
+#include "memory.h"
+
+
+/*
+ * ircd used to store full servernames in anUser as well as in the
+ * whowas info. there can be some 40k such structures alive at any
+ * given time, while the number of unique server names a server sees
+ * in its lifetime is at most a few hundred. by tokenizing server
+ * names internally, the server can easily save 2 or 3 megs of RAM.
+ * -orabidoo
+ */
+
+
+#define SCACHE_HASH_SIZE 257
+
+typedef struct scache_entry
+{
+ char name[HOSTLEN + 1];
+ struct scache_entry *next;
+}
+SCACHE;
+
+static SCACHE *scache_hash[SCACHE_HASH_SIZE];
+
+void
+clear_scache_hash_table(void)
+{
+ memset(scache_hash, 0, sizeof(scache_hash));
+}
+
+static int
+sc_hash(const char *string)
+{
+ int hash_value;
+
+ hash_value = 0;
+ while (*string)
+ {
+ hash_value += ToLower(*string++);
+ }
+
+ return hash_value % SCACHE_HASH_SIZE;
+}
+
+/*
+ * this takes a server name, and returns a pointer to the same string
+ * (up to case) in the server name token list, adding it to the list if
+ * it's not there. care must be taken not to call this with
+ * user-supplied arguments that haven't been verified to be a valid,
+ * existing, servername. use the hash in list.c for those. -orabidoo
+ */
+
+const char *
+find_or_add(const char *name)
+{
+ int hash_index;
+ SCACHE *ptr;
+
+ ptr = scache_hash[hash_index = sc_hash(name)];
+ for (; ptr; ptr = ptr->next)
+ {
+ if(!irccmp(ptr->name, name))
+ return (ptr->name);
+ }
+
+ ptr = (SCACHE *) MyMalloc(sizeof(SCACHE));
+ s_assert(0 != ptr);
+
+ strlcpy(ptr->name, name, sizeof(ptr->name));
+
+ ptr->next = scache_hash[hash_index];
+ scache_hash[hash_index] = ptr;
+ return ptr->name;
+}
+
+/*
+ * count_scache
+ * inputs - pointer to where to leave number of servers cached
+ * - pointer to where to leave total memory usage
+ * output - NONE
+ * side effects -
+ */
+void
+count_scache(size_t * number_servers_cached, size_t * mem_servers_cached)
+{
+ SCACHE *scache_ptr;
+ int i;
+
+ *number_servers_cached = 0;
+ *mem_servers_cached = 0;
+
+ for (i = 0; i < SCACHE_HASH_SIZE; i++)
+ {
+ scache_ptr = scache_hash[i];
+ while (scache_ptr)
+ {
+ *number_servers_cached = *number_servers_cached + 1;
+ *mem_servers_cached = *mem_servers_cached +
+ (strlen(scache_ptr->name) + sizeof(SCACHE *));
+
+ scache_ptr = scache_ptr->next;
+ }
+ }
+}
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * send.c: Functions for sending messages.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: send.c 1379 2006-05-20 14:11:07Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "send.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_serv.h"
+#include "sprintf_irc.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "linebuf.h"
+#include "s_log.h"
+#include "memory.h"
+#include "hook.h"
+
+#define LOG_BUFSIZE 2048
+
+/* send the message to the link the target is attached to */
+#define send_linebuf(a,b) _send_linebuf((a->from ? a->from : a) ,b)
+
+unsigned long current_serial = 0L;
+
+/* send_linebuf()
+ *
+ * inputs - client to send to, linebuf to attach
+ * outputs -
+ * side effects - linebuf is attached to client
+ */
+static int
+_send_linebuf(struct Client *to, buf_head_t *linebuf)
+{
+ if(IsMe(to))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send message to myself!");
+ return 0;
+ }
+
+ if(!MyConnect(to) || IsIOError(to))
+ return 0;
+
+ if(linebuf_len(&to->localClient->buf_sendq) > get_sendq(to))
+ {
+ if(IsServer(to))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Max SendQ limit exceeded for %s: %u > %lu",
+ get_server_name(to, HIDE_IP),
+ linebuf_len(&to->localClient->buf_sendq),
+ get_sendq(to));
+
+ ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
+ log_client_name(to, SHOW_IP),
+ linebuf_len(&to->localClient->buf_sendq),
+ get_sendq(to));
+ }
+
+ if(IsClient(to))
+ to->flags |= FLAGS_SENDQEX;
+
+ dead_link(to);
+ return -1;
+ }
+ else
+ {
+ /* just attach the linebuf to the sendq instead of
+ * generating a new one
+ */
+ linebuf_attach(&to->localClient->buf_sendq, linebuf);
+ }
+
+ /*
+ ** Update statistics. The following is slightly incorrect
+ ** because it counts messages even if queued, but bytes
+ ** only really sent. Queued bytes get updated in SendQueued.
+ */
+ to->localClient->sendM += 1;
+ me.localClient->sendM += 1;
+ if(linebuf_len(&to->localClient->buf_sendq) > 0)
+ send_queued_write(to->localClient->fd, to);
+ return 0;
+}
+
+/* send_linebuf_remote()
+ *
+ * inputs - client to attach to, sender, linebuf
+ * outputs -
+ * side effects - client has linebuf attached
+ */
+static void
+send_linebuf_remote(struct Client *to, struct Client *from, buf_head_t *linebuf)
+{
+ if(to->from)
+ to = to->from;
+
+ /* test for fake direction */
+ if(!MyClient(from) && IsPerson(to) && (to == from->from))
+ {
+ if(IsServer(from))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Send message to %s[%s] dropped from %s(Fake Dir)",
+ to->name, to->from->name, from->name);
+ return;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
+ to->name, to->username, to->host,
+ from->name, from->username, from->host, to->from->name);
+ kill_client_serv_butone(NULL, to, "%s (%s[%s@%s] Ghosted %s)",
+ me.name, to->name, to->username,
+ to->host, to->from->name);
+
+ to->flags |= FLAGS_KILLED;
+
+ exit_client(NULL, to, &me, "Ghosted client");
+ return;
+ }
+
+ _send_linebuf(to, linebuf);
+ return;
+}
+
+/* send_queued_write()
+ *
+ * inputs - fd to have queue sent, client we're sending to
+ * outputs - contents of queue
+ * side effects - write is rescheduled if queue isnt emptied
+ */
+void
+send_queued_write(int fd, void *data)
+{
+ struct Client *to = data;
+ int retlen;
+ int flags;
+#ifdef USE_IODEBUG_HOOKS
+ hook_data_int hd;
+#endif
+ /* cant write anything to a dead socket. */
+ if(IsIOError(to))
+ return;
+
+#ifdef USE_IODEBUG_HOOKS
+ hd.client = to;
+ if(to->localClient->buf_sendq.list.head)
+ hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head->data)->buf +
+ to->localClient->buf_sendq.writeofs;
+#endif
+
+ if(linebuf_len(&to->localClient->buf_sendq))
+ {
+ while ((retlen =
+ linebuf_flush(to->localClient->fd, &to->localClient->buf_sendq)) > 0)
+ {
+ /* We have some data written .. update counters */
+#ifdef USE_IODEBUG_HOOKS
+ hd.arg2 = retlen;
+ call_hook(h_iosend_id, &hd);
+
+ if(to->localClient->buf_sendq.list.head)
+ hd.arg1 =
+ ((buf_line_t *) to->localClient->buf_sendq.list.head->
+ data)->buf + to->localClient->buf_sendq.writeofs;
+#endif
+
+
+ to->localClient->sendB += retlen;
+ me.localClient->sendB += retlen;
+ if(to->localClient->sendB > 1023)
+ {
+ to->localClient->sendK += (to->localClient->sendB >> 10);
+ to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
+ }
+ else if(me.localClient->sendB > 1023)
+ {
+ me.localClient->sendK += (me.localClient->sendB >> 10);
+ me.localClient->sendB &= 0x03ff;
+ }
+ }
+
+ if(retlen == 0 || (retlen < 0 && !ignoreErrno(errno)))
+ {
+ dead_link(to);
+ return;
+ }
+ }
+ if(ignoreErrno(errno))
+ flags = COMM_SELECT_WRITE|COMM_SELECT_RETRY;
+ else
+ flags = COMM_SELECT_WRITE;
+ if(linebuf_len(&to->localClient->buf_sendq))
+ comm_setselect(fd, FDLIST_IDLECLIENT, flags,
+ send_queued_write, to, 0);
+}
+
+/* send_queued_slink_write()
+ *
+ * inputs - fd to have queue sent, client we're sending to
+ * outputs - contents of queue
+ * side effects - write is rescheduled if queue isnt emptied
+ */
+void
+send_queued_slink_write(int fd, void *data)
+{
+ struct Client *to = data;
+ int retlen;
+
+ /*
+ ** Once socket is marked dead, we cannot start writing to it,
+ ** even if the error is removed...
+ */
+ if(IsIOError(to))
+ return;
+
+ /* Next, lets try to write some data */
+ if(to->localClient->slinkq)
+ {
+ retlen = write(to->localClient->ctrlfd,
+ to->localClient->slinkq + to->localClient->slinkq_ofs,
+ to->localClient->slinkq_len);
+
+ if(retlen < 0)
+ {
+ /* If we have a fatal error */
+ if(!ignoreErrno(errno))
+ {
+ dead_link(to);
+ return;
+ }
+ }
+ /* 0 bytes is an EOF .. */
+ else if(retlen == 0)
+ {
+ dead_link(to);
+ return;
+ }
+ else
+ {
+ to->localClient->slinkq_len -= retlen;
+
+ s_assert(to->localClient->slinkq_len >= 0);
+ if(to->localClient->slinkq_len)
+ to->localClient->slinkq_ofs += retlen;
+ else
+ {
+ to->localClient->slinkq_ofs = 0;
+ MyFree(to->localClient->slinkq);
+ to->localClient->slinkq = NULL;
+ }
+ }
+ }
+
+ /* if we have any more data, reschedule a write */
+ if(to->localClient->slinkq_len)
+ comm_setselect(to->localClient->ctrlfd, FDLIST_IDLECLIENT,
+ COMM_SELECT_WRITE|COMM_SELECT_RETRY, send_queued_slink_write, to, 0);
+}
+
+/* sendto_one()
+ *
+ * inputs - client to send to, va_args
+ * outputs - client has message put into its queue
+ * side effects -
+ */
+void
+sendto_one(struct Client *target_p, const char *pattern, ...)
+{
+ va_list args;
+ buf_head_t linebuf;
+
+ /* send remote if to->from non NULL */
+ if(target_p->from != NULL)
+ target_p = target_p->from;
+
+ if(IsIOError(target_p))
+ return;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, NULL);
+ va_end(args);
+
+ _send_linebuf(target_p, &linebuf);
+
+ linebuf_donebuf(&linebuf);
+
+}
+
+/* sendto_one_prefix()
+ *
+ * inputs - client to send to, va_args
+ * outputs - client has message put into its queue
+ * side effects - source(us)/target is chosen based on TS6 capability
+ */
+void
+sendto_one_prefix(struct Client *target_p, struct Client *source_p,
+ const char *command, const char *pattern, ...)
+{
+ struct Client *dest_p;
+ va_list args;
+ buf_head_t linebuf;
+
+ /* send remote if to->from non NULL */
+ if(target_p->from != NULL)
+ dest_p = target_p->from;
+ else
+ dest_p = target_p;
+
+ if(IsIOError(dest_p))
+ return;
+
+ if(IsMe(dest_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
+ return;
+ }
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s %s %s ",
+ get_id(source_p, target_p),
+ command, get_id(target_p, target_p));
+ va_end(args);
+
+ _send_linebuf(dest_p, &linebuf);
+ linebuf_donebuf(&linebuf);
+}
+
+/* sendto_one_notice()
+ *
+ * inputs - client to send to, va_args
+ * outputs - client has a NOTICE put into its queue
+ * side effects - source(us)/target is chosen based on TS6 capability
+ */
+void
+sendto_one_notice(struct Client *target_p, const char *pattern, ...)
+{
+ struct Client *dest_p;
+ va_list args;
+ buf_head_t linebuf;
+
+ /* send remote if to->from non NULL */
+ if(target_p->from != NULL)
+ dest_p = target_p->from;
+ else
+ dest_p = target_p;
+
+ if(IsIOError(dest_p))
+ return;
+
+ if(IsMe(dest_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
+ return;
+ }
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s NOTICE %s ",
+ get_id(&me, target_p), get_id(target_p, target_p));
+ va_end(args);
+
+ _send_linebuf(dest_p, &linebuf);
+ linebuf_donebuf(&linebuf);
+}
+
+
+/* sendto_one_numeric()
+ *
+ * inputs - client to send to, va_args
+ * outputs - client has message put into its queue
+ * side effects - source/target is chosen based on TS6 capability
+ */
+void
+sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ...)
+{
+ struct Client *dest_p;
+ va_list args;
+ buf_head_t linebuf;
+
+ /* send remote if to->from non NULL */
+ if(target_p->from != NULL)
+ dest_p = target_p->from;
+ else
+ dest_p = target_p;
+
+ if(IsIOError(dest_p))
+ return;
+
+ if(IsMe(dest_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
+ return;
+ }
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s %03d %s ",
+ get_id(&me, target_p),
+ numeric, get_id(target_p, target_p));
+ va_end(args);
+
+ _send_linebuf(dest_p, &linebuf);
+ linebuf_donebuf(&linebuf);
+}
+
+/*
+ * sendto_server
+ *
+ * inputs - pointer to client to NOT send to
+ * - caps or'd together which must ALL be present
+ * - caps or'd together which must ALL NOT be present
+ * - printf style format string
+ * - args to format string
+ * output - NONE
+ * side effects - Send a message to all connected servers, except the
+ * client 'one' (if non-NULL), as long as the servers
+ * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
+ *
+ * This function was written in an attempt to merge together the other
+ * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
+ * -davidt
+ */
+void
+sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
+ unsigned long nocaps, const char *format, ...)
+{
+ va_list args;
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ buf_head_t linebuf;
+
+ /* noone to send to.. */
+ if(dlink_list_length(&serv_list) == 0)
+ return;
+
+ if(chptr != NULL && *chptr->chname != '#')
+ return;
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, format);
+ linebuf_putmsg(&linebuf, format, &args, NULL);
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ /* check against 'one' */
+ if(one != NULL && (target_p == one->from))
+ continue;
+
+ /* check we have required capabs */
+ if(!IsCapable(target_p, caps))
+ continue;
+
+ /* check we don't have any forbidden capabs */
+ if(!NotCapable(target_p, nocaps))
+ continue;
+
+ _send_linebuf(target_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+
+}
+
+/* sendto_channel_flags()
+ *
+ * inputs - server not to send to, flags needed, source, channel, va_args
+ * outputs - message is sent to channel members
+ * side effects -
+ */
+void
+sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
+ struct Channel *chptr, const char *pattern, ...)
+{
+ static char buf[BUFSIZE];
+ va_list args;
+ buf_head_t linebuf_local;
+ buf_head_t linebuf_name;
+ buf_head_t linebuf_id;
+ struct Client *target_p;
+ struct membership *msptr;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ linebuf_newbuf(&linebuf_local);
+ linebuf_newbuf(&linebuf_name);
+ linebuf_newbuf(&linebuf_id);
+
+ current_serial++;
+
+ va_start(args, pattern);
+ ircvsnprintf(buf, sizeof(buf), pattern, args);
+ va_end(args);
+
+ if(IsServer(source_p))
+ linebuf_putmsg(&linebuf_local, NULL, NULL,
+ ":%s %s", source_p->name, buf);
+ else
+ linebuf_putmsg(&linebuf_local, NULL, NULL,
+ ":%s!%s@%s %s",
+ source_p->name, source_p->username,
+ source_p->host, buf);
+
+ linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf);
+ linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(IsIOError(target_p->from) || target_p->from == one)
+ continue;
+
+ if(type && ((msptr->flags & type) == 0))
+ continue;
+
+ if(IsDeaf(target_p))
+ continue;
+
+ if(!MyClient(target_p))
+ {
+ /* if we've got a specific type, target must support
+ * CHW.. --fl
+ */
+ if(type && NotCapable(target_p->from, CAP_CHW))
+ continue;
+
+ if(target_p->from->serial != current_serial)
+ {
+ if(has_id(target_p->from))
+ send_linebuf_remote(target_p, source_p, &linebuf_id);
+ else
+ send_linebuf_remote(target_p, source_p, &linebuf_name);
+
+ target_p->from->serial = current_serial;
+ }
+ }
+ else
+ _send_linebuf(target_p, &linebuf_local);
+ }
+
+ linebuf_donebuf(&linebuf_local);
+ linebuf_donebuf(&linebuf_name);
+ linebuf_donebuf(&linebuf_id);
+}
+
+
+/* sendto_channel_local()
+ *
+ * inputs - flags to send to, channel to send to, va_args
+ * outputs - message to local channel members
+ * side effects -
+ */
+void
+sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
+{
+ va_list args;
+ buf_head_t linebuf;
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, NULL);
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(IsIOError(target_p))
+ continue;
+
+ if(type && ((msptr->flags & type) == 0))
+ continue;
+
+ _send_linebuf(target_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/* sendto_channel_local_butone()
+ *
+ * inputs - flags to send to, channel to send to, va_args
+ * - user to ignore when sending
+ * outputs - message to local channel members
+ * side effects -
+ */
+void
+sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
+{
+ va_list args;
+ buf_head_t linebuf;
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, NULL);
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ if(target_p == one)
+ continue;
+
+ if(IsIOError(target_p))
+ continue;
+
+ if(type && ((msptr->flags & type) == 0))
+ continue;
+
+ _send_linebuf(target_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/*
+ * sendto_common_channels_local()
+ *
+ * inputs - pointer to client
+ * - pattern to send
+ * output - NONE
+ * side effects - Sends a message to all people on local server who are
+ * in same channel with user.
+ * used by m_nick.c and exit_one_client.
+ */
+void
+sendto_common_channels_local(struct Client *user, const char *pattern, ...)
+{
+ va_list args;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ dlink_node *uptr;
+ dlink_node *next_uptr;
+ struct Channel *chptr;
+ struct Client *target_p;
+ struct membership *msptr;
+ struct membership *mscptr;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, NULL);
+ va_end(args);
+
+ ++current_serial;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
+ {
+ mscptr = ptr->data;
+ chptr = mscptr->chptr;
+
+ DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
+ {
+ msptr = uptr->data;
+ target_p = msptr->client_p;
+
+ if(IsIOError(target_p) ||
+ target_p->serial == current_serial)
+ continue;
+
+ target_p->serial = current_serial;
+ send_linebuf(target_p, &linebuf);
+ }
+ }
+
+ /* this can happen when the user isnt in any channels, but we still
+ * need to send them the data, ie a nick change
+ */
+ if(MyConnect(user) && (user->serial != current_serial))
+ send_linebuf(user, &linebuf);
+
+ linebuf_donebuf(&linebuf);
+}
+
+/*
+ * sendto_common_channels_local_butone()
+ *
+ * inputs - pointer to client
+ * - pattern to send
+ * output - NONE
+ * side effects - Sends a message to all people on local server who are
+ * in same channel with user, except for user itself.
+ */
+void
+sendto_common_channels_local_butone(struct Client *user, const char *pattern, ...)
+{
+ va_list args;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ dlink_node *uptr;
+ dlink_node *next_uptr;
+ struct Channel *chptr;
+ struct Client *target_p;
+ struct membership *msptr;
+ struct membership *mscptr;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, NULL);
+ va_end(args);
+
+ ++current_serial;
+ /* Skip them -- jilles */
+ user->serial = current_serial;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
+ {
+ mscptr = ptr->data;
+ chptr = mscptr->chptr;
+
+ DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
+ {
+ msptr = uptr->data;
+ target_p = msptr->client_p;
+
+ if(IsIOError(target_p) ||
+ target_p->serial == current_serial)
+ continue;
+
+ target_p->serial = current_serial;
+ send_linebuf(target_p, &linebuf);
+ }
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/* sendto_match_butone()
+ *
+ * inputs - server not to send to, source, mask, type of mask, va_args
+ * output -
+ * side effects - message is sent to matching clients
+ */
+void
+sendto_match_butone(struct Client *one, struct Client *source_p,
+ const char *mask, int what, const char *pattern, ...)
+{
+ static char buf[BUFSIZE];
+ va_list args;
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ buf_head_t linebuf_local;
+ buf_head_t linebuf_name;
+ buf_head_t linebuf_id;
+
+ linebuf_newbuf(&linebuf_local);
+ linebuf_newbuf(&linebuf_name);
+ linebuf_newbuf(&linebuf_id);
+
+ va_start(args, pattern);
+ ircvsnprintf(buf, sizeof(buf), pattern, args);
+ va_end(args);
+
+ if(IsServer(source_p))
+ linebuf_putmsg(&linebuf_local, NULL, NULL,
+ ":%s %s", source_p->name, buf);
+ else
+ linebuf_putmsg(&linebuf_local, NULL, NULL,
+ ":%s!%s@%s %s",
+ source_p->name, source_p->username,
+ source_p->host, buf);
+
+ linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf);
+ linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
+
+ if(what == MATCH_HOST)
+ {
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ if(match(mask, target_p->host))
+ _send_linebuf(target_p, &linebuf_local);
+ }
+ }
+ /* what = MATCH_SERVER, if it doesnt match us, just send remote */
+ else if(match(mask, me.name))
+ {
+ DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+ _send_linebuf(target_p, &linebuf_local);
+ }
+ }
+
+ DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ if(target_p == one)
+ continue;
+
+ if(has_id(target_p))
+ send_linebuf_remote(target_p, source_p, &linebuf_id);
+ else
+ send_linebuf_remote(target_p, source_p, &linebuf_name);
+ }
+
+ linebuf_donebuf(&linebuf_local);
+ linebuf_donebuf(&linebuf_id);
+ linebuf_donebuf(&linebuf_name);
+}
+
+/* sendto_match_servs()
+ *
+ * inputs - source, mask to send to, caps needed, va_args
+ * outputs -
+ * side effects - message is sent to matching servers with caps.
+ */
+void
+sendto_match_servs(struct Client *source_p, const char *mask, int cap,
+ int nocap, const char *pattern, ...)
+{
+ static char buf[BUFSIZE];
+ va_list args;
+ dlink_node *ptr;
+ struct Client *target_p;
+ buf_head_t linebuf_id;
+ buf_head_t linebuf_name;
+
+ if(EmptyString(mask))
+ return;
+
+ linebuf_newbuf(&linebuf_id);
+ linebuf_newbuf(&linebuf_name);
+
+ va_start(args, pattern);
+ ircvsnprintf(buf, sizeof(buf), pattern, args);
+ va_end(args);
+
+ linebuf_putmsg(&linebuf_id, NULL, NULL,
+ ":%s %s", use_id(source_p), buf);
+ linebuf_putmsg(&linebuf_name, NULL, NULL,
+ ":%s %s", source_p->name, buf);
+
+ current_serial++;
+
+ DLINK_FOREACH(ptr, global_serv_list.head)
+ {
+ target_p = ptr->data;
+
+ /* dont send to ourselves, or back to where it came from.. */
+ if(IsMe(target_p) || target_p->from == source_p->from)
+ continue;
+
+ if(target_p->from->serial == current_serial)
+ continue;
+
+ if(match(mask, target_p->name))
+ {
+ /* if we set the serial here, then we'll never do
+ * a match() again if !IsCapable()
+ */
+ target_p->from->serial = current_serial;
+
+ if(cap && !IsCapable(target_p->from, cap))
+ continue;
+
+ if(nocap && !NotCapable(target_p->from, nocap))
+ continue;
+
+ if(has_id(target_p->from))
+ _send_linebuf(target_p->from, &linebuf_id);
+ else
+ _send_linebuf(target_p->from, &linebuf_name);
+ }
+ }
+
+ linebuf_donebuf(&linebuf_id);
+ linebuf_donebuf(&linebuf_name);
+}
+
+/* sendto_anywhere()
+ *
+ * inputs - target, source, va_args
+ * outputs -
+ * side effects - client is sent message with correct prefix.
+ */
+void
+sendto_anywhere(struct Client *target_p, struct Client *source_p,
+ const char *command, const char *pattern, ...)
+{
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+
+ if(MyClient(target_p))
+ {
+ if(IsServer(source_p))
+ linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
+ source_p->name, command,
+ target_p->name);
+ else
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s!%s@%s %s %s ",
+ source_p->name, source_p->username,
+ source_p->host, command,
+ target_p->name);
+ }
+ else
+ linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
+ get_id(source_p, target_p), command,
+ get_id(target_p, target_p));
+ va_end(args);
+
+ if(MyClient(target_p))
+ _send_linebuf(target_p, &linebuf);
+ else
+ send_linebuf_remote(target_p, source_p, &linebuf);
+
+ linebuf_donebuf(&linebuf);
+}
+
+/* sendto_realops_flags()
+ *
+ * inputs - umode needed, level (opers/admin), va_args
+ * output -
+ * side effects - message is sent to opers with matching umodes
+ */
+void
+sendto_realops_flags(int flags, int level, const char *pattern, ...)
+{
+ struct Client *client_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s NOTICE * :*** Notice -- ", me.name);
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
+ {
+ client_p = ptr->data;
+
+ /* If we're sending it to opers and theyre an admin, skip.
+ * If we're sending it to admins, and theyre not, skip.
+ */
+ if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
+ ((level == L_OPER) && IsOperAdmin(client_p)))
+ continue;
+
+ if(client_p->umodes & flags)
+ _send_linebuf(client_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/* sendto_realops_snomask()
+ *
+ * inputs - snomask needed, level (opers/admin), va_args
+ * output -
+ * side effects - message is sent to opers with matching snomasks
+ */
+void
+sendto_realops_snomask(int flags, int level, const char *pattern, ...)
+{
+ static char buf[BUFSIZE];
+ char *snobuf;
+ struct Client *client_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ /* Be very sure not to do things like "Trying to send to myself"
+ * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
+ if (level & L_NETWIDE && ConfigFileEntry.global_snotices)
+ {
+ /* rather a lot of copying around, oh well -- jilles */
+ va_start(args, pattern);
+ ircvsnprintf(buf, sizeof(buf), pattern, args);
+ va_end(args);
+ linebuf_putmsg(&linebuf, pattern, NULL,
+ ":%s NOTICE * :*** Notice -- %s", me.name, buf);
+ snobuf = construct_snobuf(flags);
+ if (snobuf[1] != '\0')
+ {
+ sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
+ ":%s ENCAP * SNOTE %c :%s",
+ me.id, snobuf[1], buf);
+ sendto_server(NULL, NULL, CAP_ENCAP, CAP_TS6,
+ ":%s ENCAP * SNOTE %c :%s",
+ me.name, snobuf[1], buf);
+ }
+ }
+ else
+ {
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s NOTICE * :*** Notice -- ", me.name);
+ va_end(args);
+ }
+ level &= ~L_NETWIDE;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
+ {
+ client_p = ptr->data;
+
+ /* If we're sending it to opers and theyre an admin, skip.
+ * If we're sending it to admins, and theyre not, skip.
+ */
+ if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
+ ((level == L_OPER) && IsOperAdmin(client_p)))
+ continue;
+
+ if(client_p->snomask & flags)
+ _send_linebuf(client_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+/* sendto_realops_snomask_from()
+ *
+ * inputs - snomask needed, level (opers/admin), source server, va_args
+ * output -
+ * side effects - message is sent to opers with matching snomask
+ */
+void
+sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
+ const char *pattern, ...)
+{
+ struct Client *client_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s NOTICE * :*** Notice -- ", source_p->name);
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
+ {
+ client_p = ptr->data;
+
+ /* If we're sending it to opers and theyre an admin, skip.
+ * If we're sending it to admins, and theyre not, skip.
+ */
+ if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
+ ((level == L_OPER) && IsOperAdmin(client_p)))
+ continue;
+
+ if(client_p->snomask & flags)
+ _send_linebuf(client_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/*
+ * sendto_wallops_flags
+ *
+ * inputs - flag types of messages to show to real opers
+ * - client sending request
+ * - var args input message
+ * output - NONE
+ * side effects - Send a wallops to local opers
+ */
+void
+sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
+{
+ struct Client *client_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+
+ if(IsPerson(source_p))
+ linebuf_putmsg(&linebuf, pattern, &args,
+ ":%s!%s@%s WALLOPS :", source_p->name,
+ source_p->username, source_p->host);
+ else
+ linebuf_putmsg(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name);
+
+ va_end(args);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
+ {
+ client_p = ptr->data;
+
+ if(client_p->umodes & flags)
+ _send_linebuf(client_p, &linebuf);
+ }
+
+ linebuf_donebuf(&linebuf);
+}
+
+/* kill_client()
+ *
+ * input - client to send kill to, client to kill, va_args
+ * output -
+ * side effects - we issue a kill for the client
+ */
+void
+kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
+{
+ va_list args;
+ buf_head_t linebuf;
+
+ linebuf_newbuf(&linebuf);
+
+ va_start(args, pattern);
+ linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :",
+ get_id(&me, target_p), get_id(diedie, target_p));
+ va_end(args);
+
+ send_linebuf(target_p, &linebuf);
+ linebuf_donebuf(&linebuf);
+}
+
+
+/*
+ * kill_client_serv_butone
+ *
+ * inputs - pointer to client to not send to
+ * - pointer to client to kill
+ * output - NONE
+ * side effects - Send a KILL for the given client
+ * message to all connected servers
+ * except the client 'one'. Also deal with
+ * client being unknown to leaf, as in lazylink...
+ */
+void
+kill_client_serv_butone(struct Client *one, struct Client *target_p, const char *pattern, ...)
+{
+ static char buf[BUFSIZE];
+ va_list args;
+ struct Client *client_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+ buf_head_t linebuf_id;
+ buf_head_t linebuf_name;
+
+ linebuf_newbuf(&linebuf_name);
+ linebuf_newbuf(&linebuf_id);
+
+ va_start(args, pattern);
+ ircvsnprintf(buf, sizeof(buf), pattern, args);
+ va_end(args);
+
+ linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s KILL %s :%s",
+ me.name, target_p->name, buf);
+ linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s KILL %s :%s",
+ use_id(&me), use_id(target_p), buf);
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
+ {
+ client_p = ptr->data;
+
+ /* ok, if the client we're supposed to not send to has an
+ * ID, then we still want to issue the kill there..
+ */
+ if(one != NULL && (client_p == one->from) &&
+ (!has_id(client_p) || !has_id(target_p)))
+ continue;
+
+ if(has_id(client_p))
+ _send_linebuf(client_p, &linebuf_id);
+ else
+ _send_linebuf(client_p, &linebuf_name);
+ }
+
+ linebuf_donebuf(&linebuf_id);
+ linebuf_donebuf(&linebuf_name);
+}
--- /dev/null
+/*
+ * charybdis: An advanced ircd.
+ * snomask.c: Management for user server-notice masks.
+ *
+ * Copyright (c) 2006 William Pitcock <nenolod@nenolod.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "snomask.h"
+
+/* *INDENT-OFF* */
+int snomask_modes[256] = {
+ /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */
+ /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */
+ /* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2F */
+ /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3F */
+ 0, /* @ */
+ 0, /* A */
+ 0, /* B */
+ SNO_CCONNEXT, /* C */
+ 0, /* D */
+ 0, /* E */
+ 0, /* F */
+ 0, /* G */
+ 0, /* H */
+ 0, /* I */
+ 0, /* J */
+ 0, /* K */
+ 0, /* L */
+ 0, /* M */
+ 0, /* N */
+ 0, /* O */
+ 0, /* P */
+ 0, /* Q */
+ 0, /* R */
+ 0, /* S */
+ 0, /* T */
+ 0, /* U */
+ 0, /* V */
+ 0, /* W */
+ 0, /* X */
+ 0, /* Y */
+ SNO_OPERSPY, /* Z */
+ /* 0x5B */ 0, 0, 0, 0, 0, 0, /* 0x60 */
+ 0, /* a */
+ SNO_BOTS, /* b */
+ SNO_CCONN, /* c */
+ SNO_DEBUG, /* d */
+ 0, /* e */
+ SNO_FULL, /* f */
+ 0, /* g */
+ 0, /* h */
+ 0, /* i */
+ 0, /* j */
+ SNO_SKILL, /* k */
+ 0, /* l */
+ 0, /* m */
+ SNO_NCHANGE, /* n */
+ 0, /* o */
+ 0, /* p */
+ 0, /* q */
+ SNO_REJ, /* r */
+ SNO_GENERAL, /* s */
+ 0, /* t */
+ SNO_UNAUTH, /* u */
+ 0, /* v */
+ 0, /* w */
+ SNO_EXTERNAL, /* x */
+ SNO_SPY, /* y */
+ 0, /* z */
+ /* 0x7B */ 0, 0, 0, 0, 0, /* 0x7F */
+ /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
+ /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
+ /* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xAF */
+ /* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xBF */
+ /* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCF */
+ /* 0xD0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xDF */
+ /* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xEF */
+ /* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xFF */
+};
+/* *INDENT-ON* */
+
+static char snobuf[BUFSIZE];
+
+/*
+ * construct_snobuf
+ *
+ * inputs - client to generate snomask string for
+ * outputs - snomask string of client
+ * side effects - NONE
+ */
+char *
+construct_snobuf(unsigned int val)
+{
+ int i;
+ char *ptr = snobuf;
+
+ *ptr = '\0';
+ *ptr++ = '+';
+
+ for (i = 0; i < 128; i++)
+ if (snomask_modes[i] && (val & snomask_modes[i]))
+ *ptr++ = (char) i;
+
+ *ptr++ = '\0';
+
+ return snobuf;
+}
+
+/*
+ * parse_snobuf_to_mask
+ *
+ * inputs - value to alter bitmask for, snomask itself
+ * outputs - replacement bitmask to set
+ * side effects - NONE
+ */
+unsigned int
+parse_snobuf_to_mask(unsigned int val, const char *sno)
+{
+ const char *p;
+ int what = SNO_ADD;
+
+ if (sno == NULL)
+ return val;
+
+ for (p = sno; *p != '\0'; p++)
+ {
+ switch(*p)
+ {
+ case '+':
+ what = SNO_ADD;
+ break;
+ case '-':
+ what = SNO_DEL;
+ break;
+ default:
+ if (what == SNO_ADD)
+ val |= snomask_modes[(unsigned char) *p];
+ else if (what == SNO_DEL)
+ val &= ~snomask_modes[(unsigned char) *p];
+
+ break;
+ }
+ }
+
+ return val;
+}
+
+/*
+ * find_snomask_slot
+ *
+ * inputs - NONE
+ * outputs - an available umode bitmask or
+ * 0 if no umodes are available
+ * side effects - NONE
+ */
+unsigned int
+find_snomask_slot(void)
+{
+ unsigned int all_umodes = 0, my_umode = 0, i;
+
+ for (i = 0; i < 128; i++)
+ all_umodes |= snomask_modes[i];
+
+ for (my_umode = 1; my_umode && (all_umodes & my_umode);
+ my_umode <<= 1);
+
+ return my_umode;
+}
+
--- /dev/null
+/*
+ * charybdis: A slightly useful ircd.
+ * supported.c: isupport (005) numeric
+ *
+ * Copyright (C) 2006 Jilles Tjoelker
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: supported.c 3131 2007-01-21 15:36:31Z jilles $
+ */
+
+/* From the old supported.h which is
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2004 ircd-ratbox development team
+ */
+/*
+ * - from mirc's versions.txt
+ *
+ * mIRC now supports the numeric 005 tokens: CHANTYPES=# and
+ * PREFIX=(ohv)@%+ and can handle a dynamic set of channel and
+ * nick prefixes.
+ *
+ * mIRC assumes that @ is supported on all networks, any mode
+ * left of @ is assumed to have at least equal power to @, and
+ * any mode right of @ has less power.
+ *
+ * mIRC has internal support for @%+ modes.
+ *
+ * $nick() can now handle all mode letters listed in PREFIX.
+ *
+ * Also added support for CHANMODES=A,B,C,D token (not currently
+ * supported by any servers), which lists all modes supported
+ * by a channel, where:
+ *
+ * A = modes that take a parameter, and add or remove nicks
+ * or addresses to a list, such as +bIe for the ban,
+ * invite, and exception lists.
+ *
+ * B = modes that change channel settings, but which take
+ * a parameter when they are set and unset, such as
+ * +k key, and -k key.
+ *
+ * C = modes that change channel settings, but which take
+ * a parameter only when they are set, such as +l N,
+ * and -l.
+ *
+ * D = modes that change channel settings, such as +imnpst
+ * and take no parameters.
+ *
+ * All unknown/unlisted modes are treated as type D.
+ */
+/* ELIST=[tokens]:
+ *
+ * M = mask search
+ * N = !mask search
+ * U = user count search (< >)
+ * C = creation time search (C> C<)
+ * T = topic search (T> T<)
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "client.h"
+#include "common.h"
+#include "numeric.h"
+#include "ircd.h"
+#include "s_conf.h"
+
+dlink_list isupportlist;
+
+struct isupportitem
+{
+ const char *name;
+ const char *(*func)(void *);
+ void *param;
+ dlink_node node;
+};
+
+void
+add_isupport(const char *name, const char *(*func)(void *), void *param)
+{
+ struct isupportitem *item;
+
+ item = MyMalloc(sizeof(struct isupportitem));
+ item->name = name;
+ item->func = func;
+ item->param = param;
+ dlinkAddTail(item, &item->node, &isupportlist);
+}
+
+void
+delete_isupport(const char *name)
+{
+ dlink_node *ptr, *next_ptr;
+ struct isupportitem *item;
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, isupportlist.head)
+ {
+ item = ptr->data;
+
+ if (!strcmp(item->name, name))
+ {
+ dlinkDelete(ptr, &isupportlist);
+ MyFree(item);
+ }
+ }
+}
+
+/* XXX caching? */
+void
+show_isupport(struct Client *client_p)
+{
+ dlink_node *ptr;
+ struct isupportitem *item;
+ const char *value;
+ char buf[512];
+ int extra_space;
+ int nchars, nparams;
+ int l;
+
+ extra_space = strlen(client_p->name);
+ /* UID */
+ if (!MyClient(client_p) && extra_space < 9)
+ extra_space = 9;
+ /* :<me.name> 005 <nick> <params> :are supported by this server */
+ /* form_str(RPL_ISUPPORT) is %s :are supported by this server */
+ extra_space += strlen(me.name) + 1 + strlen(form_str(RPL_ISUPPORT));
+
+ nchars = extra_space, nparams = 0, buf[0] = '\0';
+ DLINK_FOREACH(ptr, isupportlist.head)
+ {
+ item = ptr->data;
+ value = (*item->func)(item->param);
+ if (value == NULL)
+ continue;
+ l = strlen(item->name) + (EmptyString(value) ? 0 : 1 + strlen(value));
+ if (nchars + l + (nparams > 0) >= sizeof buf || nparams + 1 > 12)
+ {
+ sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
+ nchars = extra_space, nparams = 0, buf[0] = '\0';
+ }
+ if (nparams > 0)
+ strlcat(buf, " ", sizeof buf), nchars++;
+ strlcat(buf, item->name, sizeof buf);
+ if (!EmptyString(value))
+ {
+ strlcat(buf, "=", sizeof buf);
+ strlcat(buf, value, sizeof buf);
+ }
+ nchars += l;
+ nparams++;
+ }
+ if (nparams > 0)
+ sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
+}
+
+const char *
+isupport_intptr(void *ptr)
+{
+ static char buf[15];
+
+ ircsnprintf(buf, sizeof buf, "%d", *(int *)ptr);
+ return buf;
+}
+
+const char *
+isupport_boolean(void *ptr)
+{
+
+ return *(int *)ptr ? "" : NULL;
+}
+
+const char *
+isupport_string(void *ptr)
+{
+
+ return (const char *)ptr;
+}
+
+const char *
+isupport_stringptr(void *ptr)
+{
+
+ return *(const char **)ptr;
+}
+
+const char *
+isupport_chanmodes(void *ptr)
+{
+ static char result[80];
+
+ ircsnprintf(result, sizeof result, "%s%sbq,k,%slj,imnpstrcgzLP%s",
+ ConfigChannel.use_except ? "e" : "",
+ ConfigChannel.use_invex ? "I" : "",
+ ConfigChannel.use_forward ? "f" : "",
+ ConfigChannel.use_forward ? "QF" : "");
+ return result;
+}
+
+const char *
+isupport_chanlimit(void *ptr)
+{
+ static char result[30];
+
+ ircsnprintf(result, sizeof result, "&#:%i", ConfigChannel.max_chans_per_user);
+ return result;
+}
+
+const char *
+isupport_maxlist(void *ptr)
+{
+ static char result[30];
+
+ ircsnprintf(result, sizeof result, "bq%s%s:%i",
+ ConfigChannel.use_except ? "e" : "",
+ ConfigChannel.use_invex ? "I" : "",
+ ConfigChannel.max_bans);
+ return result;
+}
+
+const char *
+isupport_targmax(void *ptr)
+{
+ static char result[200];
+
+ ircsnprintf(result, sizeof result, "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%d,NOTICE:%d,ACCEPT:,MONITOR:",
+ ConfigFileEntry.max_targets,
+ ConfigFileEntry.max_targets);
+ return result;
+}
+
+const char *
+isupport_extban(void *ptr)
+{
+ const char *p;
+ static char result[200];
+
+ p = get_extban_string();
+ if (EmptyString(p))
+ return NULL;
+ ircsnprintf(result, sizeof result, "$:%s", p);
+ return result;
+}
+
+void
+init_isupport(void)
+{
+ static int maxmodes = MAXMODEPARAMS;
+ static int nicklen = NICKLEN-1;
+ static int channellen = LOC_CHANNELLEN;
+ static int topiclen = TOPICLEN;
+
+ add_isupport("CHANTYPES", isupport_string, "&#");
+ add_isupport("EXCEPTS", isupport_boolean, &ConfigChannel.use_except);
+ add_isupport("INVEX", isupport_boolean, &ConfigChannel.use_invex);
+ add_isupport("CHANMODES", isupport_chanmodes, NULL);
+ add_isupport("CHANLIMIT", isupport_chanlimit, NULL);
+ add_isupport("PREFIX", isupport_string, "(ov)@+");
+ add_isupport("MAXLIST", isupport_maxlist, NULL);
+ add_isupport("MODES", isupport_intptr, &maxmodes);
+ add_isupport("NETWORK", isupport_stringptr, &ServerInfo.network_name);
+ add_isupport("KNOCK", isupport_boolean, &ConfigChannel.use_knock);
+ add_isupport("STATUSMSG", isupport_string, "@+");
+ add_isupport("CALLERID", isupport_string, "g");
+ add_isupport("SAFELIST", isupport_string, "");
+ add_isupport("ELIST", isupport_string, "U");
+ add_isupport("CASEMAPPING", isupport_string, "rfc1459");
+ add_isupport("CHARSET", isupport_string, "ascii");
+ add_isupport("NICKLEN", isupport_intptr, &nicklen);
+ add_isupport("CHANNELLEN", isupport_intptr, &channellen);
+ add_isupport("TOPICLEN", isupport_intptr, &topiclen);
+ add_isupport("ETRACE", isupport_string, "");
+ add_isupport("CPRIVMSG", isupport_string, "");
+ add_isupport("CNOTICE", isupport_string, "");
+ add_isupport("DEAF", isupport_string, "D");
+ add_isupport("MONITOR", isupport_intptr, &ConfigFileEntry.max_monitor);
+ add_isupport("FNC", isupport_string, "");
+ add_isupport("TARGMAX", isupport_targmax, NULL);
+ add_isupport("EXTBAN", isupport_extban, NULL);
+}
--- /dev/null
+#!/bin/sh
+
+# $Id: version.c.SH 1028 2006-03-10 15:28:58Z jilles $
+
+spitshell=cat
+package=IRC
+
+echo "Extracting $package/src/version.c..."
+
+if test -r version.c.last
+then
+ generation=`sed -n 's/^char \*generation = \"\(.*\)\";/\1/p' < version.c.last`
+ if test ! "$generation" ; then generation=0; fi
+else
+ generation=0
+fi
+
+generation=`expr $generation + 1`
+
+uname=`uname -a`
+
+creation=`date | \
+awk '{if (NF == 6) \
+ { print $1 " " $2 " " $3 " " $6 " at " $4 " " $5 } \
+else \
+ { print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
+
+$spitshell >version.c <<!SUB!THIS!
+/*
+ * IRC - Internet Relay Chat, src/version.c
+ * Copyright (C) 1990 Chelsea Ashley Dyerman
+ *
+ * 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.
+ */
+
+/*
+ * This file is generated by version.c.SH. Any changes made will go away.
+ */
+
+#include "patchlevel.h"
+#include "serno.h"
+
+const char *generation = "$generation";
+const char *creation = "$creation";
+const char *platform = "$uname";
+const char *ircd_version = PATCHLEVEL;
+const char *serno = SERNO;
+
+const char *infotext[] =
+{
+ "$package --",
+ "Based on the original code written by Jarkko Oikarinen",
+ "Copyright 1988, 1989, 1990, 1991 University of Oulu, Computing Center",
+ "Copyright (c) 1996-2001 Hybrid Development Team",
+ "Copyright (c) 2002-2005 ircd-ratbox Development Team",
+ "Copyright (c) 2005-2006 charybdis 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 1, or",
+ "(at your option) any later version.",
+ "",
+!SUB!THIS!
+
+IFS='
+'
+for i in `grep -v '^$Id' ../CREDITS |tr -d '"'` ; do
+echo " \"$i\"," >> version.c
+done
+$spitshell >>version.c <<!SUB!THISTOO!
+ "",
+ 0,
+};
+!SUB!THISTOO!
--- /dev/null
+/*
+ * ircd-ratbox: A slightly useful ircd.
+ * whowas.c: WHOWAS user cache.
+ *
+ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox 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
+ *
+ * $Id: whowas.c 1717 2006-07-04 14:41:11Z jilles $
+ */
+
+#include "stdinc.h"
+
+#include "whowas.h"
+#include "client.h"
+#include "common.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "ircd_defs.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "s_user.h"
+#include "send.h"
+#include "s_conf.h"
+#include "memory.h"
+
+/* internally defined function */
+static void add_whowas_to_clist(struct Whowas **, struct Whowas *);
+static void del_whowas_from_clist(struct Whowas **, struct Whowas *);
+static void add_whowas_to_list(struct Whowas **, struct Whowas *);
+static void del_whowas_from_list(struct Whowas **, struct Whowas *);
+
+struct Whowas WHOWAS[NICKNAMEHISTORYLENGTH];
+struct Whowas *WHOWASHASH[WW_MAX];
+
+static int whowas_next = 0;
+
+unsigned int hash_whowas_name(const char *name)
+{
+ return fnv_hash_upper((const unsigned char *) name, WW_MAX_BITS);
+}
+
+void add_history(struct Client *client_p, int online)
+{
+ struct Whowas *who = &WHOWAS[whowas_next];
+
+ s_assert(NULL != client_p);
+
+ if(client_p == NULL)
+ return;
+
+ if(who->hashv != -1)
+ {
+ if(who->online)
+ del_whowas_from_clist(&(who->online->whowas), who);
+ del_whowas_from_list(&WHOWASHASH[who->hashv], who);
+ }
+ who->hashv = hash_whowas_name(client_p->name);
+ who->logoff = CurrentTime;
+ /*
+ * NOTE: strcpy ok here, the sizes in the client struct MUST
+ * match the sizes in the whowas struct
+ */
+ strlcpy(who->name, client_p->name, sizeof(who->name));
+ strcpy(who->username, client_p->username);
+ strcpy(who->hostname, client_p->host);
+ strcpy(who->realname, client_p->info);
+ if (!EmptyString(client_p->sockhost) && strcmp(client_p->sockhost, "0") && show_ip(NULL, client_p))
+ strcpy(who->sockhost, client_p->sockhost);
+ else
+ who->sockhost[0] = '\0';
+
+ who->servername = client_p->user->server;
+
+ if(online)
+ {
+ who->online = client_p;
+ add_whowas_to_clist(&(client_p->whowas), who);
+ }
+ else
+ who->online = NULL;
+ add_whowas_to_list(&WHOWASHASH[who->hashv], who);
+ whowas_next++;
+ if(whowas_next == NICKNAMEHISTORYLENGTH)
+ whowas_next = 0;
+}
+
+void off_history(struct Client *client_p)
+{
+ struct Whowas *temp, *next;
+
+ for (temp = client_p->whowas; temp; temp = next)
+ {
+ next = temp->cnext;
+ temp->online = NULL;
+ del_whowas_from_clist(&(client_p->whowas), temp);
+ }
+}
+
+struct Client *get_history(const char *nick, time_t timelimit)
+{
+ struct Whowas *temp;
+ int blah;
+
+ timelimit = CurrentTime - timelimit;
+ blah = hash_whowas_name(nick);
+ temp = WHOWASHASH[blah];
+ for (; temp; temp = temp->next)
+ {
+ if(irccmp(nick, temp->name))
+ continue;
+ if(temp->logoff < timelimit)
+ continue;
+ return temp->online;
+ }
+ return NULL;
+}
+
+void count_whowas_memory(size_t * wwu, size_t * wwum)
+{
+ struct Whowas *tmp;
+ int i;
+ size_t u = 0;
+ size_t um = 0;
+
+ /* count the number of used whowas structs in 'u' */
+ /* count up the memory used of whowas structs in um */
+
+ for (i = 0, tmp = &WHOWAS[0]; i < NICKNAMEHISTORYLENGTH; i++, tmp++)
+ if(tmp->hashv != -1)
+ {
+ u++;
+ um += sizeof(struct Whowas);
+ }
+ *wwu = u;
+ *wwum = um;
+ return;
+}
+
+void
+initwhowas()
+{
+ int i;
+
+ for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
+ {
+ memset((void *) &WHOWAS[i], 0, sizeof(struct Whowas));
+ WHOWAS[i].hashv = -1;
+ }
+ for (i = 0; i < WW_MAX; i++)
+ WHOWASHASH[i] = NULL;
+}
+
+
+static void
+add_whowas_to_clist(struct Whowas **bucket, struct Whowas *whowas)
+{
+ whowas->cprev = NULL;
+ if((whowas->cnext = *bucket) != NULL)
+ whowas->cnext->cprev = whowas;
+ *bucket = whowas;
+}
+
+static void
+del_whowas_from_clist(struct Whowas **bucket, struct Whowas *whowas)
+{
+ if(whowas->cprev)
+ whowas->cprev->cnext = whowas->cnext;
+ else
+ *bucket = whowas->cnext;
+ if(whowas->cnext)
+ whowas->cnext->cprev = whowas->cprev;
+}
+
+static void
+add_whowas_to_list(struct Whowas **bucket, struct Whowas *whowas)
+{
+ whowas->prev = NULL;
+ if((whowas->next = *bucket) != NULL)
+ whowas->next->prev = whowas;
+ *bucket = whowas;
+}
+
+static void
+del_whowas_from_list(struct Whowas **bucket, struct Whowas *whowas)
+{
+ if(whowas->prev)
+ whowas->prev->next = whowas->next;
+ else
+ *bucket = whowas->next;
+ if(whowas->next)
+ whowas->next->prev = whowas->prev;
+}
--- /dev/null
+Makefile
+mkpasswd
+viconf
+convertconf
+fixklines
+convertklines
+encspeed
+convertilines
\ No newline at end of file
--- /dev/null
+# $Id: Makefile.in 6 2005-09-10 01:02:21Z nenolod $
+
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_BIN = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+RM = @RM@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+LDFLAGS = @LDFLAGS@
+MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
+MV = @MV@
+RM = @RM@
+LN = @LN@
+
+IRCDLIBS = @LIBS@
+INCLUDES = -I../include
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libexecdir = @libexecdir@
+confdir = @confdir@
+localstatedir = @localstatedir@
+
+PROGS = viconf mkpasswd convertilines convertklines
+
+all: $(PROGS)
+
+build: all
+
+mkpasswd: mkpasswd.c
+ $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) mkpasswd.c -o mkpasswd $(IRCDLIBS)
+
+viconf: viconf.c
+ $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) viconf.c -o viconf $(IRCDLIBS)
+
+convertilines: convertilines.c
+ $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) convertilines.c -o convertilines $(IRCDLIBS)
+
+convertklines: convertklines.c
+ $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) convertklines.c -o convertklines $(IRCDLIBS)
+
+clean:
+ $(RM) -f encspeed viconf chkconf mkpasswd *~ core *.exe convertklines convertilines
+
+distclean: clean
+ $(RM) -f Makefile
+
+lint:
+ lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(convertklines_SOURCES) $(mkpasswd_SOURCES) $(viconf_SOURCES) $(encspeed_SOURCES) >>../lint.out
+
+depend:
+
+.c.o:
+ $(CC) $(CFLAGS) $(INCLUDES) $(CPPFLAGS) -c $<
+
+# DO NOT DELETE
+
+viconf.o: ../include/config.h ../include/setup.h
+viconf.o:
+
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+exec_suffix = @exec_suffix@
+bindir = @bindir@
+libexecdir = @libexecdir@
+confdir = @confdir@
+localstatedir = @localstatedir@
+# Change this later! -- adrian
+moduledir = @moduledir@
+automoduledir = @moduledir@/autoload
+
+
+
+install-mkdirs:
+ -@if test ! -d $(DESTDIR)$(prefix); then \
+ echo "ircd: setting up tools directory structure"; \
+ mkdir $(DESTDIR)$(prefix); \
+ fi
+ -@if test ! -d $(DESTDIR)$(exec_prefix); then \
+ mkdir $(DESTDIR)$(exec_prefix); \
+ fi
+ -@if test ! -d $(DESTDIR)$(bindir); then \
+ mkdir $(DESTDIR)$(bindir); \
+ fi
+
+install: install-mkdirs build
+ @echo "ircd: installing tools ($(PROGS))"
+ @for i in $(PROGS); do \
+ if test -f $(DESTDIR)$(bindir)/$$i; then \
+ $(MV) $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.old; \
+ fi; \
+ $(INSTALL_BIN) $$i $(DESTDIR)$(bindir); \
+ done; \
+ $(RM) -f $(DESTDIR)$(bindir)/vimotd $(DESTDIR)$(bindir)/viklines
+ $(LN) $(DESTDIR)$(bindir)/viconf $(DESTDIR)$(bindir)/vimotd
+ $(LN) $(DESTDIR)$(bindir)/viconf $(DESTDIR)$(bindir)/viklines
+
--- /dev/null
+$Id: README 6 2005-09-10 01:02:21Z nenolod $
+
+A directory of support programs for ircd.
+
+convertconf.c - converts a Hybrid 5 or 6 conf file to the new
+ style. will not convert I:
+convertilines.c - convert hybrid 5/6 I: to auth {};
+convertklines.c - convert Hybrid 5/6 and early 7beta kline.conf files
+ to the new spreadsheet like format.
+encspeed.c - test the speed of various encryption algorithms used in
+ cryptlinks
+mkkeypair - a small program used for generating a public and private
+ key pair
+mkpasswd.c - makes password for O lines
+rsa_respond/ - a tool to generate an RSA response to the challenge asked
+ by the server, and a tool to generate a keypair for the
+ C/R system
+untabify - converts tab characters to a specific number of spaces
+viconf.c - edit your conf file without having to chdir su etc. etc.
+ also locks the file if file locking is used.
+ viconf is also installed with hard links as vimotd and
+ viklines, to edit those files in a locked mode.
--- /dev/null
+mkpasswd.c documentation
+$Id: README.mkpasswd 6 2005-09-10 01:02:21Z nenolod $
+
+This is documentation for the updated mkpasswd.c included with a number
+of ircd, irc services, and non-IRC related programs
+
+This version of mkpasswd can create DES, Extended DES, BlowFish, and MD5
+passwords, with either randomly generated or user provided salts.
+
+Options:
+-m Generate an MD5 password
+-d Generate a DES password
+-b Generate a BlowFish password
+-e Generate an Extended (BSDi) DES password
+-l Specify a length for a random MD5 or BlowFish salt
+-r Specify a number of rounds for a BlowFish or Extended DES password
+ BlowFish: no more than 6 recommended, no less than 4 accepted
+ Extended DES: default of 25
+-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for MD5,
+ up to 22 for BlowFish, 2 for Extended DES
+-p Specify a plaintext password to use
+-? Get brief help
+-h Get extended help
+
+Without the presence of any parameters, it'll behave like the old mkpasswd,
+creating a DES password with a randomly generated salt and prompting for
+the password (without echo).
+
+A DES salt is a pair of alphanumeric characters ('.' and '/' are permitted
+as well), such as 'a4' or 'Td'.
+
+An MD5 salt consists of up to 16 (though most implementations limit you to
+8) alphanumeric characters (plus '.' and '/'),
+such as 'tGd' or 'J6d4dfG'.
+
+A BlowFish salt consists of up to 22 alphanumeric characters (plus '.' and
+'/'). BlowFish also specifies a number of rounds*, by default 4.
+
+Known bugs:
+The encryption algorithms supported depend on your system's crypt()
+ implementation.
+The maximum length of an MD5 salt is limited to your systems crypt()
+ implementation, typically 8.
+
+Supported Platforms (Known and tested):
+Linux glibc (DES and MD5)
+FreeBSD 3.x (DES (MD5 maybe))
+FreeBSD 4.x (DES, MD5, BlowFish, Extended DES)
+Solaris 2.5-2.6 (DES only)
+Cygwin 1.1.4 (DES only)
+Prior Cygwin with the MD5 libcrypt (MD5 only)
+OpenBSD 2.7 (don't link with -lcrypt) (DES, MD5, Blowfish)
+Mac OS-X (Darwin) (don't link with -lcrypt) (DES only)
+
+An MMK build script is included, as well as an MD5 crypt() implementation
+
+Other systems probably work, but they haven't been amply tested.
+
+* BlowFish's rounds parameter is a logarithm, not an integer value
--- /dev/null
+/* tools/convertilines.c
+ * Copyright (c) 2002 Hybrid Development Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: convertilines.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#define BUFSIZE 512
+
+#define FLAGS_RESTRICTED 0x001
+#define FLAGS_EXCEEDLIMIT 0x002
+#define FLAGS_KLINEEXEMPT 0x004
+#define FLAGS_GLINEEXEMPT 0x008
+#define FLAGS_NEEDIDENT 0x010
+#define FLAGS_NOTILDE 0x020
+
+struct flag_table_struct
+{
+ const char *name;
+ int flag;
+};
+static struct flag_table_struct flag_table[] =
+{
+ { "restricted", FLAGS_RESTRICTED },
+ { "exceed_limit", FLAGS_EXCEEDLIMIT },
+ { "kline_exempt", FLAGS_KLINEEXEMPT },
+ { "gline_exempt", FLAGS_GLINEEXEMPT },
+ { "need_ident", FLAGS_NEEDIDENT },
+ { "no_tilde", FLAGS_NOTILDE },
+ { NULL, 0 }
+};
+
+struct AuthBlock
+{
+ struct AuthBlock *next;
+
+ char **hostname;
+ int hostnum;
+
+ char *spoof;
+ char *passwd;
+ int class;
+ int flags;
+
+ /* indicates one of above */
+ int special;
+ int specialk;
+};
+
+static struct AuthBlock *auth_spoof = NULL;
+static struct AuthBlock *auth_special = NULL;
+static struct AuthBlock *auth_passwd = NULL;
+static struct AuthBlock *auth_general = NULL;
+static struct AuthBlock *auth_restricted = NULL;
+
+static void ConvertConf(FILE* file,FILE *out);
+static void set_flags(struct AuthBlock *, const char *, const char *);
+static void usage(void);
+static char *getfield(char *);
+static struct AuthBlock *find_matching_conf(struct AuthBlock *);
+static void ReplaceQuotes(char *out, char *in);
+static void oldParseOneLine(FILE *out, char *in);
+static void write_auth_entries(FILE *out);
+static void write_specific(FILE *out, struct AuthBlock *);
+static int match(struct AuthBlock *, struct AuthBlock *);
+
+int main(int argc,char *argv[])
+{
+ FILE *in;
+ FILE *out;
+
+ if(argc < 3)
+ usage();
+
+ if((in = fopen(argv[1],"r")) == NULL)
+ {
+ fprintf(stderr, "Can't open %s for reading\n", argv[1]);
+ usage();
+ }
+
+ if((out = fopen(argv[2],"w")) == NULL)
+ {
+ fprintf(stderr, "Can't open %s for writing\n", argv[2]);
+ usage();
+ }
+
+ ConvertConf(in, out);
+
+ return 0;
+}
+
+void usage()
+{
+ fprintf(stderr, "convertilines conf.old conf.new\n");
+ exit(-1);
+}
+
+/*
+ * ConvertConf()
+ * Read configuration file.
+ *
+ *
+ * Inputs - FILE* to config file to convert
+ * - FILE* to output for new style conf
+ *
+ */
+
+#define MAXCONFLINKS 150
+
+static void ConvertConf(FILE* file, FILE *out)
+{
+ char line[BUFSIZE];
+ char quotedLine[BUFSIZE];
+ char* p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if ((p = strchr(line, '\n')))
+ *p = '\0';
+
+ ReplaceQuotes(quotedLine,line);
+
+ if(!*quotedLine || quotedLine[0] == '#' || quotedLine[0] == '\n' ||
+ quotedLine[0] == ' ' || quotedLine[0] == '\t')
+ continue;
+
+ if(quotedLine[0] == '.')
+ {
+ char *filename;
+ char *back;
+
+ if(!strncmp(quotedLine+1,"include ",8))
+ {
+ if( (filename = strchr(quotedLine+8,'"')) )
+ filename++;
+ else
+ {
+ fprintf(stderr, "Bad config line: %s", quotedLine);
+ continue;
+ }
+
+ if((back = strchr(filename,'"')))
+ *back = '\0';
+ else
+ {
+ fprintf(stderr, "Bad config line: %s", quotedLine);
+ continue;
+ }
+
+ }
+ }
+
+ /* Could we test if it's conf line at all? -Vesa */
+ if (quotedLine[1] == ':')
+ oldParseOneLine(out,quotedLine);
+
+ }
+
+ fclose(file);
+
+ write_auth_entries(out);
+ fclose(out);
+}
+
+/*
+ * ReplaceQuotes
+ * Inputs - input line to quote
+ * Output - quoted line
+ * Side Effects - All quoted chars in input are replaced
+ * with quoted values in output, # chars replaced with '\0'
+ * otherwise input is copied to output.
+ */
+static void ReplaceQuotes(char* quotedLine,char *inputLine)
+{
+ char *in;
+ char *out;
+ static char quotes[] = {
+ 0, /* */
+ 0, /* a */
+ '\b', /* b */
+ 0, /* c */
+ 0, /* d */
+ 0, /* e */
+ '\f', /* f */
+ 0, /* g */
+ 0, /* h */
+ 0, /* i */
+ 0, /* j */
+ 0, /* k */
+ 0, /* l */
+ 0, /* m */
+ '\n', /* n */
+ 0, /* o */
+ 0, /* p */
+ 0, /* q */
+ '\r', /* r */
+ 0, /* s */
+ '\t', /* t */
+ 0, /* u */
+ '\v', /* v */
+ 0, /* w */
+ 0, /* x */
+ 0, /* y */
+ 0, /* z */
+ 0,0,0,0,0,0
+ };
+
+ /*
+ * Do quoting of characters and # detection.
+ */
+ for (out = quotedLine,in = inputLine; *in; out++, in++)
+ {
+ if (*in == '\\')
+ {
+ in++;
+ if(*in == '\\')
+ *out = '\\';
+ else if(*in == '#')
+ *out = '#';
+ else
+ *out = quotes[ (unsigned int) (*in & 0x1F) ];
+ }
+ else if (*in == '#')
+ {
+ *out = '\0';
+ return;
+ }
+ else
+ *out = *in;
+ }
+ *out = '\0';
+}
+
+/*
+ * oldParseOneLine
+ * Inputs - pointer to line to parse
+ * - pointer to output to write
+ * Output -
+ * Side Effects - Parse one old style conf line.
+ */
+
+static void oldParseOneLine(FILE *out,char* line)
+{
+ char conf_letter;
+ char* tmp;
+ const char* host_field=NULL;
+ const char* passwd_field=NULL;
+ const char* user_field=NULL;
+ const char* port_field = NULL;
+ const char* classconf_field = NULL;
+ int class_field = 0;
+
+ tmp = getfield(line);
+
+ conf_letter = *tmp;
+
+ for (;;) /* Fake loop, that I can use break here --msa */
+ {
+ /* host field */
+ if ((host_field = getfield(NULL)) == NULL)
+ return;
+
+ /* pass field */
+ if ((passwd_field = getfield(NULL)) == NULL)
+ break;
+
+ /* user field */
+ if ((user_field = getfield(NULL)) == NULL)
+ break;
+
+ /* port field */
+ if ((port_field = getfield(NULL)) == NULL)
+ break;
+
+ /* class field */
+ if ((classconf_field = getfield(NULL)) == NULL)
+ break;
+
+ break;
+ }
+
+ if (!passwd_field)
+ passwd_field = "";
+ if (!user_field)
+ user_field = "";
+ if (!port_field)
+ port_field = "";
+ if (classconf_field)
+ class_field = atoi(classconf_field);
+
+ switch( conf_letter )
+ {
+ case 'i':
+ case 'I':
+ {
+ struct AuthBlock *ptr;
+ struct AuthBlock *tempptr;
+
+ tempptr = malloc(sizeof(struct AuthBlock));
+ memset(tempptr, 0, sizeof(*tempptr));
+
+ if(conf_letter == 'i')
+ {
+ tempptr->flags |= FLAGS_RESTRICTED;
+ tempptr->specialk = 1;
+ }
+
+ if(passwd_field && *passwd_field)
+ tempptr->passwd = strdup(passwd_field);
+
+ tempptr->class = class_field;
+
+ set_flags(tempptr, user_field, host_field);
+
+ /* dont add specials/passworded ones to existing auth blocks */
+ if((ptr = find_matching_conf(tempptr)))
+ {
+ int authindex;
+
+ authindex = ptr->hostnum;
+ ptr->hostnum++;
+
+ ptr->hostname = realloc((void *)ptr->hostname, ptr->hostnum * sizeof(void *));
+
+ ptr->hostname[authindex] = strdup(tempptr->hostname[0]);
+
+ free(tempptr->hostname[0]);
+ free(tempptr->hostname);
+ free(tempptr);
+ }
+ else
+ {
+ ptr = tempptr;
+
+ if(ptr->spoof)
+ {
+ ptr->next = auth_spoof;
+ auth_spoof = ptr;
+ }
+ else if(ptr->special)
+ {
+ ptr->next = auth_special;
+ auth_special = ptr;
+ }
+ else if(ptr->passwd)
+ {
+ ptr->next = auth_passwd;
+ auth_passwd = ptr;
+ }
+ else if(ptr->specialk)
+ {
+ ptr->next = auth_restricted;
+ auth_restricted = ptr;
+ }
+ else
+ {
+ ptr->next = auth_general;
+ auth_general = ptr;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void write_auth_entries(FILE *out)
+{
+ struct AuthBlock *ptr;
+
+ for(ptr = auth_spoof; ptr; ptr = ptr->next)
+ write_specific(out, ptr);
+
+ for(ptr = auth_special; ptr; ptr = ptr->next)
+ write_specific(out, ptr);
+
+ for(ptr = auth_passwd; ptr; ptr = ptr->next)
+ write_specific(out, ptr);
+
+ for(ptr = auth_general; ptr; ptr = ptr->next)
+ write_specific(out, ptr);
+
+ for(ptr = auth_restricted; ptr; ptr = ptr->next)
+ write_specific(out, ptr);
+}
+
+
+static void write_specific(FILE *out, struct AuthBlock *ptr)
+{
+ int i;
+ int prev = 0;
+
+ fprintf(out, "auth {\n");
+
+ for(i = 0; i < ptr->hostnum; i++)
+ fprintf(out, "\tuser = \"%s\";\n", ptr->hostname[i]);
+
+ if(ptr->spoof)
+ fprintf(out, "\tspoof = \"%s\";\n", ptr->spoof);
+
+ if(ptr->passwd)
+ fprintf(out, "\tpassword = \"%s\";\n", ptr->passwd);
+
+ if(ptr->flags)
+ {
+ fprintf(out, "\tflags = ");
+
+ for(i = 0; flag_table[i].flag; i++)
+ {
+ if(ptr->flags & flag_table[i].flag)
+ {
+ fprintf(out, "%s%s",
+ prev ? ", " : "",
+ flag_table[i].name);
+ prev = 1;
+ }
+ }
+
+ fprintf(out, ";\n");
+ }
+
+ fprintf(out, "\tclass = \"%d\";\n", ptr->class);
+ fprintf(out, "};\n");
+}
+
+/*
+ * field breakup for ircd.conf file.
+ */
+static char *getfield(char *newline)
+{
+ static char *line = NULL;
+ char *end, *field;
+
+ if (newline)
+ line = newline;
+
+ if (line == NULL)
+ return(NULL);
+
+ field = line;
+ if ((end = strchr(line,':')) == NULL)
+ {
+ line = NULL;
+ if ((end = strchr(field,'\n')) == NULL)
+ end = field + strlen(field);
+ }
+ else
+ line = end + 1;
+ *end = '\0';
+ return(field);
+}
+
+struct AuthBlock *find_matching_conf(struct AuthBlock *acptr)
+{
+ struct AuthBlock *ptr;
+
+ for(ptr = auth_spoof; ptr; ptr = ptr->next)
+ {
+ if(match(ptr, acptr))
+ return ptr;
+ }
+
+ for(ptr = auth_special; ptr; ptr = ptr->next)
+ {
+ if(match(ptr, acptr))
+ return ptr;
+ }
+
+ for(ptr = auth_passwd; ptr; ptr = ptr->next)
+ {
+ if(match(ptr, acptr))
+ return ptr;
+ }
+
+ for(ptr = auth_restricted; ptr; ptr = ptr->next)
+ {
+ if(match(ptr, acptr))
+ return ptr;
+ }
+
+ for(ptr = auth_general; ptr; ptr = ptr->next)
+ {
+ if(match(ptr, acptr))
+ return ptr;
+ }
+
+
+ return NULL;
+}
+
+static int match(struct AuthBlock *ptr, struct AuthBlock *acptr)
+{
+ if((ptr->class == acptr->class) &&
+ (ptr->flags == acptr->flags))
+ {
+ const char *p1, *p2;
+
+ /* check the spoofs match.. */
+ if(ptr->spoof)
+ p1 = ptr->spoof;
+ else
+ p1 = "";
+
+ if(acptr->spoof)
+ p2 = acptr->spoof;
+ else
+ p2 = "";
+
+ if(strcmp(p1, p2))
+ return 0;
+
+ /* now check the passwords match.. */
+ if(ptr->passwd)
+ p1 = ptr->passwd;
+ else
+ p1 = "";
+
+ if(acptr->passwd)
+ p2 = acptr->passwd;
+ else
+ p2 = "";
+
+ if(strcmp(p1, p2))
+ return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void set_flags(struct AuthBlock *ptr, const char *user_field, const char *host_field)
+{
+ for(; *user_field; user_field++)
+ {
+ switch(*user_field)
+ {
+ case '=':
+ if(host_field)
+ ptr->spoof = strdup(host_field);
+
+ ptr->special = 1;
+ break;
+
+ case '-':
+ ptr->flags |= FLAGS_NOTILDE;
+ ptr->special = 1;
+ break;
+
+ case '+':
+ ptr->flags |= FLAGS_NEEDIDENT;
+ ptr->specialk = 1;
+ break;
+
+ case '^': /* is exempt from k/g lines */
+ ptr->flags |= FLAGS_KLINEEXEMPT;
+ ptr->special = 1;
+ break;
+
+ case '>':
+ ptr->flags |= FLAGS_EXCEEDLIMIT;
+ ptr->special = 1;
+ break;
+
+ case '_':
+ ptr->flags |= FLAGS_GLINEEXEMPT;
+ ptr->special = 1;
+ break;
+
+ case '!':
+ case '$':
+ case '%':
+ case '&':
+ case '<':
+ break;
+
+ default:
+ {
+ int authindex;
+ authindex = ptr->hostnum;
+ ptr->hostnum++;
+
+ ptr->hostname = realloc((void *)ptr->hostname, ptr->hostnum * sizeof(void *));
+
+ /* if the IP field contains something useful, use that */
+ if(strcmp(host_field, "NOMATCH") && (*host_field != 'x') &&
+ strcmp(host_field, "*") && !ptr->spoof)
+ ptr->hostname[authindex] = strdup(host_field);
+ else
+ ptr->hostname[authindex] = strdup(user_field);
+
+ return;
+ }
+ }
+ }
+}
+
--- /dev/null
+/************************************************************************
+ * IRC - Internet Relay Chat, tools/convertklines.c
+ *
+ * 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.
+ *
+ * $Id: convertklines.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#define BUFSIZE 512
+
+static void ConvertConf(FILE* file,FILE *outkline, FILE *outdline);
+static void usage(void);
+static char *getfield(char *);
+static void ReplaceQuotes(char *out, char *in);
+static void parse(FILE *outkline, FILE *outdline, char *in);
+
+int main(int argc,char *argv[])
+{
+ FILE *in;
+ FILE *outkline;
+ FILE *outdline;
+
+ if(argc < 4)
+ usage();
+
+ if (( in = fopen(argv[1],"r")) == NULL )
+ {
+ fprintf(stderr,"Can't open %s for reading\n", argv[1]);
+ usage();
+ }
+
+ if (( outkline = fopen(argv[2],"w")) == NULL )
+ {
+ fprintf(stderr,"Can't open %s for writing\n", argv[2]);
+ usage();
+ }
+
+ if(( outdline = fopen(argv[3], "w")) == NULL )
+ {
+ fprintf(stderr, "Can't open %s for writing\n", argv[3]);
+ usage();
+ }
+
+ ConvertConf(in, outkline, outdline);
+
+ fprintf(stderr, "The kline file has been converted and should be renamed to\n");
+ fprintf(stderr, "the config.h options (normally kline.conf and dline.conf) and\n");
+ fprintf(stderr, "placed in your etc/ dir\n");
+ return 0;
+}
+
+static void usage()
+{
+ fprintf(stderr, "klines and dlines now go in separate files:\n");
+ fprintf(stderr,"convertklines kline.conf.old kline.conf.new dline.conf.new\n");
+ exit(-1);
+}
+
+
+/*
+ * ConvertConf()
+ * Read configuration file.
+ *
+ *
+ * inputs - FILE* to config file to convert
+ * - FILE* to output for new klines
+ * - FILE* to output for new dlines
+ * outputs - -1 if the file cannot be opened
+ * - 0 otherwise
+ */
+
+static void ConvertConf(FILE* file, FILE *outkline, FILE *outdline)
+{
+ char line[BUFSIZE];
+ char quotedLine[BUFSIZE];
+ char* p;
+
+ while (fgets(line, sizeof(line), file))
+ {
+ if ((p = strchr(line, '\n')))
+ *p = '\0';
+
+ ReplaceQuotes(quotedLine,line);
+
+ if (!*quotedLine || quotedLine[0] == '#' || quotedLine[0] == '\n' ||
+ quotedLine[0] == ' ' || quotedLine[0] == '\t')
+ continue;
+
+ /* Could we test if it's conf line at all? -Vesa */
+ if (quotedLine[1] == ':')
+ {
+ parse(outkline, outdline, quotedLine);
+ }
+ }
+
+ fclose(file);
+}
+
+/*
+ * ReplaceQuotes
+ * Inputs - input line to quote
+ * Output - quoted line
+ * Side Effects - All quoted chars in input are replaced
+ * with quoted values in output, # chars replaced with '\0'
+ * otherwise input is copied to output.
+ */
+static void ReplaceQuotes(char* quotedLine,char *inputLine)
+{
+ char *in;
+ char *out;
+ static char quotes[] = {
+ 0, /* */
+ 0, /* a */
+ '\b', /* b */
+ 0, /* c */
+ 0, /* d */
+ 0, /* e */
+ '\f', /* f */
+ 0, /* g */
+ 0, /* h */
+ 0, /* i */
+ 0, /* j */
+ 0, /* k */
+ 0, /* l */
+ 0, /* m */
+ '\n', /* n */
+ 0, /* o */
+ 0, /* p */
+ 0, /* q */
+ '\r', /* r */
+ 0, /* s */
+ '\t', /* t */
+ 0, /* u */
+ '\v', /* v */
+ 0, /* w */
+ 0, /* x */
+ 0, /* y */
+ 0, /* z */
+ 0,0,0,0,0,0
+ };
+
+ /*
+ * Do quoting of characters and # detection.
+ */
+ for (out = quotedLine,in = inputLine; *in; out++, in++)
+ {
+ if (*in == '\\')
+ {
+ in++;
+ if(*in == '\\')
+ *out = '\\';
+ else if(*in == '#')
+ *out = '#';
+ else
+ *out = quotes[ (unsigned int) (*in & 0x1F) ];
+ }
+ else if (*in == '#')
+ {
+ *out = '\0';
+ return;
+ }
+ else
+ *out = *in;
+ }
+ *out = '\0';
+}
+
+/*
+ * parse()
+ * Inputs - pointer to line to parse
+ * - pointer to output to write
+ * Output -
+ * Side Effects - Parse one old style conf line.
+ */
+
+static void parse(FILE *outkline, FILE *outdline, char* line)
+{
+ char conf_letter;
+ char *tmp;
+ const char *user_field = NULL;
+ const char *passwd_field = NULL;
+ const char *host_field = NULL;
+ const char *operpasswd_field = NULL;
+
+ tmp = getfield(line);
+
+ conf_letter = *tmp;
+
+ for (;;) /* Fake loop, that I can use break here --msa */
+ {
+ /* host field */
+ if ((host_field = getfield(NULL)) == NULL)
+ return;
+
+ /* pass field */
+ if ((passwd_field = getfield(NULL)) == NULL)
+ break;
+ else
+ {
+ /* if theres a password, try splitting the operreason out */
+ char *p;
+
+ if((p = strchr(passwd_field, '|')))
+ {
+ *p++ = '\0';
+ operpasswd_field = p;
+ }
+ else
+ operpasswd_field = "";
+ }
+
+ /* user field */
+ if ((user_field = getfield(NULL)) == NULL)
+ break;
+
+ /* what could possibly be after a userfield? */
+ break;
+ }
+
+ if (!passwd_field)
+ {
+ passwd_field = "";
+ operpasswd_field = "";
+ }
+
+ if (!user_field)
+ user_field = "";
+
+ switch( conf_letter )
+ {
+ case 'd':
+ fprintf(stderr, "exempt in old file, ignoring.\n");
+ break;
+
+ case 'D': /* Deny lines (immediate refusal) */
+ if(host_field && passwd_field)
+ fprintf(outdline, "\"%s\",\"%s\",\"%s\",\"\",\"Unknown\",0\n",
+ host_field, passwd_field, operpasswd_field);
+ break;
+
+ case 'K': /* Kill user line on irc.conf */
+ case 'k':
+ if(host_field && passwd_field && user_field)
+ fprintf(outkline, "\"%s\",\"%s\",\"%s\",\"%s\",\"\",\"Unknown\",0\n",
+ user_field, host_field, passwd_field, operpasswd_field);
+ break;
+
+ default:
+ fprintf(stderr, "Error in config file: %s", line);
+ break;
+ }
+}
+
+
+/*
+ * field breakup for ircd.conf file.
+ */
+static char *getfield(char *newline)
+{
+ static char *line = NULL;
+ char *end, *field;
+
+ if (newline)
+ line = newline;
+
+ if (line == NULL)
+ {
+ fprintf(stderr, "returned null!\n");
+ return NULL;
+ }
+
+ field = line;
+
+ if ((end = strchr(line,':')) == NULL)
+ {
+ line = NULL;
+ if ((end = strchr(field,'\n')) == NULL)
+ end = field + strlen(field);
+ }
+ else
+ line = end + 1;
+
+ *end = '\0';
+
+ return field;
+}
+
+
--- /dev/null
+#!/bin/sh
+dd if=/dev/urandom of=randdata count=1 bs=2048
+openssl genrsa -rand randdata -out private.key 2048
+openssl rsa -in private.key -out public.key -pubout
+rm randdata
--- /dev/null
+/* simple password generator by Nelson Minar (minar@reed.edu)
+** copyright 1991, all rights reserved.
+** You can use this code as long as my name stays with it.
+**
+** md5 patch by W. Campbell <wcampbel@botbay.net>
+** Modernization, getopt, etc for the Hybrid IRCD team
+** by W. Campbell
+**
+** /dev/random for salt generation added by
+** Aaron Sethman <androsyn@ratbox.org>
+**
+** $Id: mkpasswd.c 6 2005-09-10 01:02:21Z nenolod $
+*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define FLAG_MD5 0x00000001
+#define FLAG_DES 0x00000002
+#define FLAG_SALT 0x00000004
+#define FLAG_PASS 0x00000008
+#define FLAG_LENGTH 0x00000010
+#define FLAG_BLOWFISH 0x00000020
+#define FLAG_ROUNDS 0x00000040
+#define FLAG_EXT 0x00000080
+
+extern char *getpass();
+extern char *crypt();
+
+static char *make_des_salt(void);
+static char *make_ext_salt(int);
+static char *make_ext_salt_para(int, char *);
+static char *make_md5_salt(int);
+static char *make_md5_salt_para(char *);
+static char *make_bf_salt(int, int);
+static char *make_bf_salt_para(int, char *);
+static char *int_to_base64(int);
+static char *generate_random_salt(char *, int);
+static char *generate_poor_salt(char *, int);
+
+static void full_usage(void);
+static void brief_usage(void);
+
+static char saltChars[] =
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ /* 0 .. 63, ascii - 64 */
+
+extern char *optarg;
+
+int main(int argc, char *argv[])
+{
+ char *plaintext = NULL;
+ int c;
+ char *saltpara = NULL;
+ char *salt;
+ int flag = 0;
+ int length = 0; /* Not Set */
+ int rounds = 0; /* Not set, since extended DES needs 25 and blowfish needs
+ ** 4 by default, a side effect of this being the encryption
+ ** type parameter must be specified before the rounds
+ ** parameter.
+ */
+
+ while( (c=getopt(argc, argv, "mdber:h?l:s:p:")) != -1)
+ {
+ switch(c)
+ {
+ case 'm':
+ flag |= FLAG_MD5;
+ break;
+ case 'd':
+ flag |= FLAG_DES;
+ break;
+ case 'b':
+ flag |= FLAG_BLOWFISH;
+ rounds = 4;
+ break;
+ case 'e':
+ flag |= FLAG_EXT;
+ rounds = 25;
+ break;
+ case 'l':
+ flag |= FLAG_LENGTH;
+ length = atoi(optarg);
+ break;
+ case 'r':
+ flag |= FLAG_ROUNDS;
+ rounds = atoi(optarg);
+ break;
+ case 's':
+ flag |= FLAG_SALT;
+ saltpara = optarg;
+ break;
+ case 'p':
+ flag |= FLAG_PASS;
+ plaintext = optarg;
+ break;
+ case 'h':
+ full_usage();
+ /* NOT REACHED */
+ break;
+ case '?':
+ brief_usage();
+ /* NOT REACHED */
+ break;
+ default:
+ printf("Invalid Option: -%c\n", c);
+ break;
+ }
+ }
+
+ if (flag & FLAG_MD5)
+ {
+ if (length == 0)
+ length = 8;
+ if (flag & FLAG_SALT)
+ salt = make_md5_salt_para(saltpara);
+ else
+ salt = make_md5_salt(length);
+ }
+ else if (flag & FLAG_BLOWFISH)
+ {
+ if (length == 0)
+ length = 22;
+ if (flag & FLAG_SALT)
+ salt = make_bf_salt_para(rounds, saltpara);
+ else
+ salt = make_bf_salt(rounds, length);
+ }
+ else if (flag & FLAG_EXT)
+ {
+ /* XXX - rounds needs to be done */
+ if (flag & FLAG_SALT)
+ {
+ if ((strlen(saltpara) == 4))
+ {
+ salt = make_ext_salt_para(rounds, saltpara);
+ }
+ else
+ {
+ printf("Invalid salt, please enter 4 alphanumeric characters\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ salt = make_ext_salt(rounds);
+ }
+ }
+ else
+ {
+ if (flag & FLAG_SALT)
+ {
+ if ((strlen(saltpara) == 2))
+ {
+ salt = saltpara;
+ }
+ else
+ {
+ printf("Invalid salt, please enter 2 alphanumeric characters\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ salt = make_des_salt();
+ }
+ }
+
+ if (flag & FLAG_PASS)
+ {
+ if (!plaintext)
+ printf("Please enter a valid password\n");
+ }
+ else
+ {
+ plaintext = getpass("plaintext: ");
+ }
+
+ printf("%s\n", crypt(plaintext, salt));
+ return 0;
+}
+
+static char *make_des_salt()
+{
+ static char salt[3];
+ generate_random_salt(salt, 2);
+ salt[2] = '\0';
+ return salt;
+}
+
+char *int_to_base64(int value)
+{
+ static char buf[5];
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ buf[i] = saltChars[value & 63];
+ value >>= 6; /* Right shifting 6 places is the same as dividing by 64 */
+ }
+
+ buf[i] = '\0'; /* not REALLY needed as it's static, and thus initialized
+ ** to \0.
+ */
+ return buf;
+}
+
+char *make_ext_salt(int rounds)
+{
+ static char salt[10];
+
+ sprintf(salt, "_%s", int_to_base64(rounds));
+ generate_random_salt(&salt[5], 4);
+ salt[9] = '\0';
+ return salt;
+}
+
+char *make_ext_salt_para(int rounds, char *saltpara)
+{
+ static char salt[10];
+
+ sprintf(salt, "_%s%s", int_to_base64(rounds), saltpara);
+ return salt;
+}
+
+char *make_md5_salt_para(char *saltpara)
+{
+ static char salt[21];
+ if (saltpara && (strlen(saltpara) <= 16))
+ {
+ /* sprintf used because of portability requirements, the length
+ ** is checked above, so it should not be too much of a concern
+ */
+ sprintf(salt, "$1$%s$", saltpara);
+ return salt;
+ }
+ printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
+ exit(1);
+
+ /* NOT REACHED */
+ return NULL;
+}
+
+char *make_md5_salt(int length)
+{
+ static char salt[21];
+ if (length > 16)
+ {
+ printf("MD5 salt length too long\n");
+ exit(0);
+ }
+ salt[0] = '$';
+ salt[1] = '1';
+ salt[2] = '$';
+ generate_random_salt(&salt[3], length);
+ salt[length+3] = '$';
+ salt[length+4] = '\0';
+ return salt;
+}
+
+char *make_bf_salt_para(int rounds, char *saltpara)
+{
+ static char salt[31];
+ char tbuf[3];
+ if (saltpara && (strlen(saltpara) <= 22))
+ {
+ /* sprintf used because of portability requirements, the length
+ ** is checked above, so it should not be too much of a concern
+ */
+ sprintf(tbuf, "%02d", rounds);
+ sprintf(salt, "$2a$%s$%s$", tbuf, saltpara);
+ return salt;
+ }
+ printf("Invalid Salt, please use up to 22 random alphanumeric characters\n");
+ exit(1);
+
+ /* NOT REACHED */
+ return NULL;
+}
+
+char *make_bf_salt(int rounds, int length)
+{
+ static char salt[31];
+ char tbuf[3];
+ if (length > 22)
+ {
+ printf("BlowFish salt length too long\n");
+ exit(0);
+ }
+ sprintf(tbuf, "%02d", rounds);
+ sprintf(salt, "$2a$%s$", tbuf);
+ generate_random_salt(&salt[7], length);
+ salt[length+7] = '$';
+ salt[length+8] = '\0';
+ return salt;
+}
+
+char *generate_poor_salt(char *salt, int length)
+{
+ int i;
+ srandom(time(NULL));
+ for(i = 0; i < length; i++)
+ {
+ salt[i] = saltChars[random() % 64];
+ }
+ return(salt);
+}
+
+char *generate_random_salt(char *salt, int length)
+{
+ char *buf;
+ int fd, i;
+ if((fd = open("/dev/random", O_RDONLY)) < 0)
+ {
+ return(generate_poor_salt(salt, length));
+ }
+ buf = calloc(1, length);
+ if(read(fd, buf, length) != length)
+ {
+ free(buf);
+ return(generate_poor_salt(salt, length));
+ }
+
+ for(i = 0; i < length; i++)
+ {
+ salt[i] = saltChars[abs(buf[i]) % 64];
+ }
+ free(buf);
+ return(salt);
+}
+
+void full_usage()
+{
+ printf("mkpasswd [-m|-d|-b|-e] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
+ printf("-m Generate an MD5 password\n");
+ printf("-d Generate a DES password\n");
+ printf("-b Generate a BlowFish password\n");
+ printf("-e Generate an Extended DES password\n");
+ printf("-l Specify a length for a random MD5 or BlowFish salt\n");
+ printf("-r Specify a number of rounds for a BlowFish or Extended DES password\n");
+ printf(" BlowFish: default 4, no more than 6 recommended\n");
+ printf(" Extended DES: default 25\n");
+ printf("-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for MD5,\n");
+ printf(" up to 22 for BlowFish, and 4 for Extended DES\n");
+ printf("-p Specify a plaintext password to use\n");
+ printf("Example: mkpasswd -m -s 3dr -p test\n");
+ exit(0);
+}
+
+void brief_usage()
+{
+ printf("mkpasswd - password hash generator\n");
+ printf("Standard DES: mkpasswd [-d] [-s salt] [-p plaintext]\n");
+ printf("Extended DES: mkpasswd -e [-r rounds] [-s salt] [-p plaintext]\n");
+ printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n");
+ printf(" BlowFish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n");
+ printf(" [-p plaintext]\n");
+ printf("Use -h for full usage\n");
+ exit(0);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# untabify - convert tabs to spaces
+#
+# $Id: untabify 6 2005-09-10 01:02:21Z nenolod $
+use Text::Tabs;
+$tabstop = 8;
+while (<>) { print expand($_) }
+
--- /dev/null
+/*
+ * viconf.c
+ *
+ * $Id: viconf.c 6 2005-09-10 01:02:21Z nenolod $
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <signal.h>
+#include "config.h"
+
+
+/* wait.h is in /include on solaris, likely on other SYSV machines as well
+ * but wait.h is normally in /include/sys on BSD boxen,
+ * probably we should have an #ifdef SYSV?
+ * -Dianora
+ */
+
+#ifdef SOL20
+#include <wait.h>
+#else
+#include <sys/wait.h>
+#endif
+
+static int LockedFile(const char *filename);
+static char lockpath[PATH_MAX + 1];
+
+
+int main(int argc, char *argv[])
+{
+ const char *ed, *p, *filename = CPATH;
+
+ if( chdir(DPATH) < 0 )
+ {
+ fprintf(stderr,"Cannot chdir to %s\n", DPATH);
+ exit(errno);
+ }
+
+ if((p = strrchr(argv[0], '/')) == NULL)
+ p = argv[0];
+ else
+ p++;
+#ifdef KPATH
+ if(strcmp(p, "viklines") == 0)
+ filename = KPATH;
+#endif /* KPATH */
+
+ if(strcmp(p, "vimotd") == 0)
+ filename = MPATH;
+
+ if(LockedFile(filename))
+ {
+ fprintf(stderr,"Can't lock %s\n", filename);
+ exit(errno);
+ }
+
+ /* ed config file */
+ switch(fork())
+ {
+ case -1:
+ fprintf(stderr, "error forking, %d\n", errno);
+ exit(errno);
+ case 0: /* Child */
+ if((ed = getenv("EDITOR")) == NULL)
+ ed = "vi";
+ execlp(ed, ed, filename, NULL);
+ fprintf(stderr, "error running editor, %d\n", errno);
+ exit(errno);
+ default:
+ wait(0);
+ }
+
+ unlink(lockpath);
+ return 0;
+}
+
+/*
+ * LockedFile() (copied from m_kline.c in ircd)
+ * Determine if 'filename' is currently locked. If it is locked,
+ * there should be a filename.lock file which contains the current
+ * pid of the editing process. Make sure the pid is valid before
+ * giving up.
+ *
+ * Return: 1 if locked
+ * -1 if couldn't unlock
+ * 0 if was able to lock
+ */
+
+
+
+static int
+LockedFile(const char *filename)
+
+{
+
+ char buffer[1024];
+ FILE *fileptr;
+ int killret;
+ int fd;
+
+ if (!filename)
+ return (0);
+
+ sprintf(lockpath, "%s.lock", filename);
+
+ if ((fileptr = fopen(lockpath, "r")) != NULL)
+ {
+ if (fgets(buffer, sizeof(buffer) - 1, fileptr))
+ {
+ /*
+ * If it is a valid lockfile, 'buffer' should now
+ * contain the pid number of the editing process.
+ * Send the pid a SIGCHLD to see if it is a valid
+ * pid - it could be a remnant left over from a
+ * crashed editor or system reboot etc.
+ */
+
+ killret = kill(atoi(buffer), SIGCHLD);
+ if (killret == 0)
+ {
+ fclose(fileptr);
+ return (1);
+ }
+
+ /*
+ * killret must be -1, which indicates an error (most
+ * likely ESRCH - No such process), so it is ok to
+ * proceed writing klines.
+ */
+ }
+ fclose(fileptr);
+ }
+
+ /*
+ * Delete the outdated lock file
+ */
+ unlink(lockpath);
+
+ /* create exclusive lock */
+ if((fd = open(lockpath, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
+ {
+ fprintf(stderr, "ircd config file locked\n");
+ return (-1);
+ }
+
+ fileptr = fdopen(fd,"w");
+ fprintf(fileptr,"%d\n",(int)getpid());
+ fclose(fileptr);
+ return (0);
+} /* LockedFile() */
--- /dev/null
+#
+# Makefile.in for ircd/unsupported
+#
+# $Id: Makefile.in 1425 2006-05-23 16:41:33Z jilles $
+#
+CC = @CC@
+RM = @RM@
+SED = @SED@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
+PICFLAGS = @PICFLAGS@
+MKDEP = @MKDEP@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
+SHELL = /bin/sh
+AUTOMODULEDIR = @moduledir@/unsupported
+
+SSL_LIBS = @SSL_LIBS@
+SSL_INCLUDES = @SSL_INCLUDES@
+
+IRCDLIBS = @LIBS@ $(SSL_LIBS)
+
+INCLUDES = -I. -I../include -I../libcharybdis -I../adns $(SSL_INCLUDES)
+CPPFLAGS = ${INCLUDES} @CPPFLAGS@
+
+SRCS = \
+ m_clearchan.c \
+ m_force.c
+
+OBJS = ${SRCS:.c=.so}
+
+default: build
+build: all
+all: $(OBJS)
+
+install: all
+ -@if test ! -d $(DESTDIR)$(AUTOMODULEDIR); then \
+ mkdir $(DESTDIR)$(AUTOMODULEDIR); \
+ fi
+ @echo "Installing modules into $(DESTDIR)$(AUTOMODULEDIR) .."
+ @for file in $(OBJS); do \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(AUTOMODULEDIR); \
+ done
+
+.SUFFIXES: .so
+
+.c.so:
+ ${CC} ${PICFLAGS} ${CPPFLAGS} ${CFLAGS} $< -o $@
+
+.PHONY: depend clean distclean
+depend:
+ @${MKDEP} ${CPPFLAGS} ${SRCS} > .depend
+ @sed s/\\\.o/\\\.so/ < .depend > .depend.tmp
+ @sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
+ @echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
+ @echo '# make depend needs it.' >>Makefile.depend
+ @cat .depend.tmp >>Makefile.depend
+ @mv Makefile.depend Makefile
+ @rm -f .depend.tmp .depend
+
+clean:
+ ${RM} -f *.so *~
+
+distclean: clean
+ ${RM} -f Makefile
+
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, contrib/m_clearchan.c
+ * Copyright (C) 2002 Hybrid Development Team
+ * Copyright (C) 2004 ircd-ratbox 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 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.
+ *
+ * $Id: m_clearchan.c 1425 2006-05-23 16:41:33Z jilles $
+ */
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static int mo_clearchan(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message clearchan_msgtab = {
+ "CLEARCHAN", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_clearchan, 2}}
+};
+
+mapi_clist_av1 clearchan_clist[] = { &clearchan_msgtab, NULL };
+
+DECLARE_MODULE_AV1(clearchan, NULL, NULL, clearchan_clist, NULL, NULL, "$Revision: 1425 $");
+
+/*
+** mo_clearchan
+** parv[0] = sender prefix
+** parv[1] = channel
+*/
+static int
+mo_clearchan(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ struct membership *msptr;
+ struct Client *target_p;
+ dlink_node *ptr;
+ dlink_node *next_ptr;
+
+ /* admins only */
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, parv[0]);
+ return 0;
+ }
+
+
+ if((chptr = find_channel(parv[1])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ if(IsMember(source_p, chptr))
+ {
+ sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN",
+ me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ /* quickly make everyone a peon.. */
+ DLINK_FOREACH(ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ msptr->flags &= ~CHFL_CHANOP | CHFL_VOICE;
+ }
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "CLEARCHAN called for [%s] by %s!%s@%s",
+ parv[1], source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "CLEARCHAN called for [%s] by %s!%s@%s",
+ parv[1], source_p->name, source_p->username, source_p->host);
+
+ if(*chptr->chname != '&')
+ {
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS,
+ ":%s WALLOPS :CLEARCHAN called for [%s] by %s!%s@%s",
+ me.name, parv[1], source_p->name, source_p->username, source_p->host);
+
+ /* SJOIN the user to give them ops, and lock the channel */
+ sendto_server(client_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s +ntsi :@%s",
+ me.name, (long) (chptr->channelts - 1),
+ chptr->chname, source_p->name);
+ }
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
+ source_p->name, source_p->username, source_p->host, chptr->chname);
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
+ me.name, chptr->chname, source_p->name);
+
+ add_user_to_channel(chptr, source_p, CHFL_CHANOP);
+
+ /* Take the TS down by 1, so we don't see the channel taken over
+ * again. */
+ if(chptr->channelts)
+ chptr->channelts--;
+
+ chptr->mode.mode = MODE_SECRET | MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS;
+ chptr->mode.key[0] = '\0';
+
+ DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
+ {
+ msptr = ptr->data;
+ target_p = msptr->client_p;
+
+ /* skip the person we just added.. */
+ if(is_chanop(msptr))
+ continue;
+
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s KICK %s %s :CLEARCHAN",
+ source_p->name, chptr->chname, target_p->name);
+
+ if(*chptr->chname != '&')
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+ ":%s KICK %s %s :CLEARCHAN",
+ source_p->name, chptr->chname, target_p->name);
+
+ remove_user_from_channel(msptr);
+ }
+
+ /* Join the user themselves to the channel down here, so they dont see a nicklist
+ * or people being kicked */
+ sendto_one(source_p, ":%s!%s@%s JOIN %s",
+ source_p->name, source_p->username, source_p->host, chptr->chname);
+
+ channel_member_names(chptr, source_p, 1);
+
+ return 0;
+}
--- /dev/null
+/* contrib/m_force.c
+ * Copyright (C) 1996-2002 Hybrid Development Team
+ * Copyright (C) 2004 ircd-ratbox Development Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3.The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: m_force.c 1425 2006-05-23 16:41:33Z jilles $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "channel.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "hostmask.h"
+#include "numeric.h"
+#include "commio.h"
+#include "s_conf.h"
+#include "s_newconf.h"
+#include "s_log.h"
+#include "send.h"
+#include "hash.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "event.h"
+
+
+static int mo_forcejoin(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+static int mo_forcepart(struct Client *client_p, struct Client *source_p,
+ int parc, const char *parv[]);
+
+struct Message forcejoin_msgtab = {
+ "FORCEJOIN", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_forcejoin, 3}}
+};
+
+struct Message forcepart_msgtab = {
+ "FORCEPART", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_forcepart, 3}}
+};
+
+mapi_clist_av1 force_clist[] = { &forcejoin_msgtab, &forcepart_msgtab, NULL };
+
+DECLARE_MODULE_AV1(force, NULL, NULL, force_clist, NULL, NULL, "$Revision: 1425 $");
+
+/*
+ * m_forcejoin
+ * parv[0] = sender prefix
+ * parv[1] = user to force
+ * parv[2] = channel to force them into
+ */
+static int
+mo_forcejoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ int type;
+ char mode;
+ char sjmode;
+ char *newch;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcejoin");
+ return 0;
+ }
+
+ if((hunt_server(client_p, source_p, ":%s FORCEJOIN %s %s", 1, parc, parv)) != HUNTED_ISME)
+ return 0;
+
+ /* if target_p is not existant, print message
+ * to source_p and bail - scuzzy
+ */
+ if((target_p = find_client(parv[1])) == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ if(!IsPerson(target_p))
+ return 0;
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "FORCEJOIN called for %s %s by %s!%s@%s",
+ parv[1], parv[2], source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "FORCEJOIN called for %s %s by %s!%s@%s",
+ parv[1], parv[2], source_p->name, source_p->username, source_p->host);
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS,
+ ":%s WALLOPS :FORCEJOIN called for %s %s by %s!%s@%s",
+ me.name, parv[1], parv[2],
+ source_p->name, source_p->username, source_p->host);
+
+ /* select our modes from parv[2] if they exist... (chanop) */
+ if(*parv[2] == '@')
+ {
+ type = CHFL_CHANOP;
+ mode = 'o';
+ sjmode = '@';
+ }
+ else if(*parv[2] == '+')
+ {
+ type = CHFL_VOICE;
+ mode = 'v';
+ sjmode = '+';
+ }
+ else
+ {
+ type = CHFL_PEON;
+ mode = sjmode = '\0';
+ }
+
+ if(mode != '\0')
+ parv[2]++;
+
+ if((chptr = find_channel(parv[2])) != NULL)
+ {
+ if(IsMember(target_p, chptr))
+ {
+ /* debugging is fun... */
+ sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s",
+ me.name, source_p->name, target_p->name, chptr->chname);
+ return 0;
+ }
+
+ add_user_to_channel(chptr, target_p, type);
+
+ sendto_server(target_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s + :%c%s",
+ me.name, (long) chptr->channelts,
+ chptr->chname, type ? sjmode : ' ', target_p->name);
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ target_p->name, target_p->username,
+ target_p->host, chptr->chname);
+
+ if(type)
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +%c %s",
+ me.name, chptr->chname, mode, target_p->name);
+
+ if(chptr->topic != NULL)
+ {
+ sendto_one(target_p, form_str(RPL_TOPIC), me.name,
+ target_p->name, chptr->chname, chptr->topic);
+ sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
+ me.name, source_p->name, chptr->chname,
+ chptr->topic_info, chptr->topic_time);
+ }
+
+ channel_member_names(chptr, target_p, 1);
+ }
+ else
+ {
+ newch = LOCAL_COPY(parv[2]);
+ if(!check_channel_name(newch))
+ {
+ sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
+ source_p->name, (unsigned char *) newch);
+ return 0;
+ }
+
+ /* channel name must begin with & or # */
+ if(!IsChannelName(newch))
+ {
+ sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
+ source_p->name, (unsigned char *) newch);
+ return 0;
+ }
+
+ /* newch can't be longer than CHANNELLEN */
+ if(strlen(newch) > CHANNELLEN)
+ {
+ sendto_one(source_p, ":%s NOTICE %s :Channel name is too long", me.name,
+ source_p->name);
+ return 0;
+ }
+
+ chptr = get_or_create_channel(target_p, newch, NULL);
+ add_user_to_channel(chptr, target_p, CHFL_CHANOP);
+
+ /* send out a join, make target_p join chptr */
+ sendto_server(target_p, chptr, NOCAPS, NOCAPS,
+ ":%s SJOIN %ld %s +nt :@%s", me.name,
+ (long) chptr->channelts, chptr->chname, target_p->name);
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
+ target_p->name, target_p->username,
+ target_p->host, chptr->chname);
+
+ chptr->mode.mode |= MODE_TOPICLIMIT;
+ chptr->mode.mode |= MODE_NOPRIVMSGS;
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +nt", me.name, chptr->chname);
+
+ target_p->localClient->last_join_time = CurrentTime;
+ channel_member_names(chptr, target_p, 1);
+
+ /* we do this to let the oper know that a channel was created, this will be
+ * seen from the server handling the command instead of the server that
+ * the oper is on.
+ */
+ sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s", me.name,
+ source_p->name, chptr->chname);
+ }
+ return 0;
+}
+
+
+static int
+mo_forcepart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Client *target_p;
+ struct Channel *chptr;
+ struct membership *msptr;
+
+ if(!IsOperAdmin(source_p))
+ {
+ sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcepart");
+ return 0;
+ }
+
+ if((hunt_server(client_p, source_p, ":%s FORCEPART %s %s", 1, parc, parv)) != HUNTED_ISME)
+ return 0;
+
+ /* if target_p == NULL then let the oper know */
+ if((target_p = find_client(parv[1])) == NULL)
+ {
+ sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]);
+ return 0;
+ }
+
+ if(!IsClient(target_p))
+ return 0;
+
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "FORCEPART called for %s %s by %s!%s@%s",
+ parv[1], parv[2], source_p->name, source_p->username, source_p->host);
+ ilog(L_MAIN, "FORCEPART called for %s %s by %s!%s@%s",
+ parv[1], parv[2], source_p->name, source_p->username, source_p->host);
+ sendto_server(NULL, NULL, NOCAPS, NOCAPS,
+ ":%s WALLOPS :FORCEPART called for %s %s by %s!%s@%s",
+ me.name, parv[1], parv[2],
+ source_p->name, source_p->username, source_p->host);
+
+ if((chptr = find_channel(parv[2])) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[1]);
+ return 0;
+ }
+
+ if((msptr = find_channel_membership(chptr, target_p)) == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
+ form_str(ERR_USERNOTINCHANNEL),
+ parv[1], parv[2]);
+ return 0;
+ }
+
+ sendto_server(target_p, chptr, NOCAPS, NOCAPS,
+ ":%s PART %s :%s", target_p->name, chptr->chname, target_p->name);
+
+ sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
+ target_p->name, target_p->username,
+ target_p->host, chptr->chname, target_p->name);
+
+
+ remove_user_from_channel(msptr);
+
+ return 0;
+}